PLplot  5.10.0
qt.cpp
Go to the documentation of this file.
00001 //
00002 //
00003 // This software is provided under the LGPL in March 2009 by the
00004 // Cluster Science Centre
00005 // QSAS team,
00006 // Imperial College, London
00007 //
00008 // Copyright (C) 2009  Imperial College, London
00009 // Copyright (C) 2009  Alan W. Irwin
00010 //
00011 // This is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU General Lesser Public License as published
00013 // by the Free Software Foundation; either version 2 of the License, or
00014 // (at your option) any later version.
00015 //
00016 // This software is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 // GNU Lesser General Public License for more details.
00020 //
00021 // To received a copy of the GNU Library General Public License
00022 // write to the Free Software Foundation, Inc.,
00023 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00024 //
00025 // History:
00026 //
00027 //
00028 // March 2009:  v1.00
00029 // Initial release.
00030 //
00031 //
00032 
00033 
00034 #include "qt.h"
00035 #include <QMutexLocker>
00036 
00037 // global variables initialised in init(), used in tidy()
00038 // QApplication* app=NULL;
00039 static int  argc;           // argc and argv have to exist when tidy() is used, thus they are made global
00040 static char **argv;
00041 static int  appCounter = 0; // to be rigorous, all uses should be placed between mutexes
00042 
00043 // Drivers declaration
00044 extern "C" {
00045 PLDLLIMPEXP_DRIVER_DATA( const char* ) plD_DEVICE_INFO_qt =
00046 #if defined ( PLD_bmpqt )
00047     "bmpqt:Qt Windows bitmap driver:0:qt:66:bmpqt\n"
00048 #endif
00049 #if defined ( PLD_jpgqt )
00050     "jpgqt:Qt jpg driver:0:qt:67:jpgqt\n"
00051 #endif
00052 #if defined ( PLD_pngqt )
00053     "pngqt:Qt png driver:0:qt:68:pngqt\n"
00054 #endif
00055 #if defined ( PLD_ppmqt )
00056     "ppmqt:Qt ppm driver:0:qt:69:ppmqt\n"
00057 #endif
00058 #if defined ( PLD_tiffqt )
00059     "tiffqt:Qt tiff driver:0:qt:70:tiffqt\n"
00060 #endif
00061 #if defined ( PLD_svgqt ) && QT_VERSION >= 0x040300
00062     "svgqt:Qt SVG driver:0:qt:71:svgqt\n"
00063 #endif
00064 #if defined ( PLD_qtwidget )
00065     "qtwidget:Qt Widget:1:qt:72:qtwidget\n"
00066 #endif
00067 #if defined ( PLD_epsqt )
00068     "epsqt:Qt EPS driver:0:qt:73:epsqt\n"
00069 #endif
00070 #if defined ( PLD_pdfqt )
00071     "pdfqt:Qt PDF driver:0:qt:74:pdfqt\n"
00072 #endif
00073 #if defined ( PLD_extqt )
00074     "extqt:External Qt driver:0:qt:75:extqt\n"
00075 #endif
00076 #if defined ( PLD_memqt )
00077     "memqt:Memory Qt driver:0:qt:76:memqt\n"
00078 #endif
00079 ;
00080 }  // extern "C"
00081 
00082 static DrvOpt qt_options[] = { { "text_vectorize",     DRV_INT, &vectorize, "Vectorize fonts on output (0|1)"     },
00083                                { "lines_antialiasing", DRV_INT, &lines_aa,  "Toggles antialiasing on lines (0|1)" },
00084                                { NULL,                 DRV_INT, NULL,       NULL                                  } };
00085 
00086 bool initQtApp( bool isGUI )
00087 {
00088     QMutexLocker locker( &QtPLDriver::mutex );
00089     bool         res = false;
00090     ++appCounter;
00091     if ( qApp == NULL && appCounter == 1 )
00092     {
00093         argc    = 1;
00094         argv    = new char*[2];
00095         argv[0] = new char[10];
00096         argv[1] = new char[1];
00097         snprintf( argv[0], 10, "qt_driver" );
00098         argv[1][0] = '\0';
00099 #ifdef Q_WS_X11
00100         // On X11 if DISPLAY is not set then cannot open GUI. This allows non-interactive devices to still work in this case.
00101         if ( getenv( "DISPLAY" ) == NULL )
00102             isGUI = false;
00103 #endif
00104         new QApplication( argc, argv, isGUI );
00105         res = true;
00106     }
00107     return res;
00108 }
00109 
00110 void closeQtApp()
00111 {
00112     QMutexLocker locker( &QtPLDriver::mutex );
00113     --appCounter;
00114     if ( qApp != NULL && appCounter == 0 )
00115     {
00116         delete qApp;
00117         delete[] argv[0];
00118         delete[] argv[1];
00119         delete[] argv;
00120         argv = NULL;
00121     }
00122 }
00123 
00124 //--------------------------------------------------------------------------
00125 // qt_family_check ()
00126 //
00127 // support function to help supress more than one page if family file
00128 // output not specified by the user  (e.g., with the -fam command-line option).
00129 // Adapted directly from svg.c
00130 //--------------------------------------------------------------------------
00131 static int already_warned = 0;
00132 static int qt_family_check( PLStream *pls )
00133 {
00134     if ( pls->family || pls->page == 1 )
00135     {
00136         return 0;
00137     }
00138     else
00139     {
00140         if ( !already_warned )
00141         {
00142             already_warned = 1;
00143             plwarn( "All pages after the first skipped because family file output not specified.\n" );
00144         }
00145         return 1;
00146     }
00147 }
00148 
00149 // Declaration of the driver-specific interface functions
00150 #if defined ( PLD_bmpqt ) || defined ( PLD_jpgqt ) || defined ( PLD_pngqt ) || defined ( PLD_ppmqt ) || defined ( PLD_tiffqt ) || defined ( PLD_memqt )
00151 void plD_init_rasterqt( PLStream * );
00152 void plD_eop_rasterqt( PLStream * );
00153 void plD_line_rasterqt( PLStream *, short, short, short, short );
00154 void plD_polyline_rasterqt( PLStream *, short*, short*, PLINT );
00155 void plD_tidy_rasterqt( PLStream * );
00156 void plD_state_rasterqt( PLStream *, PLINT );
00157 void plD_esc_rasterqt( PLStream *, PLINT, void* );
00158 #endif
00159 
00160 #if defined ( PLD_bmpqt )
00161 void plD_dispatch_init_bmpqt( PLDispatchTable *pdt );
00162 void plD_bop_bmpqt( PLStream * );
00163 #endif
00164 
00165 #if defined ( PLD_jpgqt )
00166 void plD_dispatch_init_jpgqt( PLDispatchTable *pdt );
00167 void plD_bop_jpgqt( PLStream * );
00168 #endif
00169 
00170 #if defined ( PLD_pngqt )
00171 void plD_dispatch_init_pngqt( PLDispatchTable *pdt );
00172 void plD_bop_pngqt( PLStream * );
00173 #endif
00174 
00175 #if defined ( PLD_ppmqt )
00176 void plD_dispatch_init_ppmqt( PLDispatchTable *pdt );
00177 void plD_bop_ppmqt( PLStream * );
00178 #endif
00179 
00180 #if defined ( PLD_tiffqt )
00181 void plD_dispatch_init_tiffqt( PLDispatchTable *pdt );
00182 void plD_bop_tiffqt( PLStream * );
00183 #endif
00184 
00185 #if defined ( PLD_svgqt ) && QT_VERSION >= 0x040300
00186 void plD_dispatch_init_svgqt( PLDispatchTable *pdt );
00187 void plD_init_svgqt( PLStream * );
00188 void plD_bop_svgqt( PLStream * );
00189 void plD_eop_svgqt( PLStream * );
00190 void plD_line_svgqt( PLStream *, short, short, short, short );
00191 void plD_polyline_svgqt( PLStream *, short*, short*, PLINT );
00192 void plD_tidy_svgqt( PLStream * );
00193 void plD_state_svgqt( PLStream *, PLINT );
00194 void plD_esc_svgqt( PLStream *, PLINT, void* );
00195 #endif
00196 
00197 #if defined ( PLD_epsqt ) || defined ( PLD_pdfqt )
00198 void plD_init_epspdfqt( PLStream * );
00199 void plD_bop_epspdfqt_helper( PLStream *, int ifeps );
00200 void plD_eop_epspdfqt( PLStream * );
00201 void plD_line_epspdfqt( PLStream *, short, short, short, short );
00202 void plD_polyline_epspdfqt( PLStream *, short*, short*, PLINT );
00203 void plD_tidy_epspdfqt( PLStream * );
00204 void plD_state_epspdfqt( PLStream *, PLINT );
00205 void plD_esc_epspdfqt( PLStream *, PLINT, void* );
00206 #endif
00207 #if defined ( PLD_epsqt )
00208 void plD_dispatch_init_epsqt( PLDispatchTable *pdt );
00209 void plD_bop_epsqt( PLStream * );
00210 #endif
00211 #if defined ( PLD_pdfqt )
00212 void plD_dispatch_init_pdfqt( PLDispatchTable *pdt );
00213 void plD_bop_pdfqt( PLStream * );
00214 #endif
00215 
00216 #if defined ( PLD_qtwidget )
00217 void plD_dispatch_init_qtwidget( PLDispatchTable *pdt );
00218 void plD_init_qtwidget( PLStream * );
00219 void plD_eop_qtwidget( PLStream * );
00220 void plD_line_qtwidget( PLStream *, short, short, short, short );
00221 void plD_polyline_qtwidget( PLStream *, short*, short*, PLINT );
00222 void plD_tidy_qtwidget( PLStream * );
00223 void plD_state_qtwidget( PLStream *, PLINT );
00224 void plD_esc_qtwidget( PLStream *, PLINT, void* );
00225 void plD_bop_qtwidget( PLStream * );
00226 #endif
00227 
00228 #if defined ( PLD_extqt )
00229 void plD_dispatch_init_extqt( PLDispatchTable *pdt );
00230 void plD_init_extqt( PLStream * );
00231 void plD_eop_extqt( PLStream * );
00232 void plD_line_extqt( PLStream *, short, short, short, short );
00233 void plD_polyline_extqt( PLStream *, short*, short*, PLINT );
00234 void plD_tidy_extqt( PLStream * );
00235 void plD_state_extqt( PLStream *, PLINT );
00236 void plD_esc_extqt( PLStream *, PLINT, void* );
00237 void plD_bop_extqt( PLStream * );
00238 #endif
00239 
00240 #if defined ( PLD_memqt )
00241 void plD_dispatch_init_memqt( PLDispatchTable *pdt );
00242 void plD_init_memqt( PLStream * );
00243 void plD_bop_memqt( PLStream * );
00244 void plD_eop_memqt( PLStream * );
00245 #endif
00246 
00248 #if defined ( PLD_bmpqt ) || defined ( PLD_jpgqt ) || defined ( PLD_pngqt ) || defined ( PLD_ppmqt ) || defined ( PLD_tiffqt ) || defined ( PLD_memqt )
00249 void plD_init_rasterqt( PLStream * pls )
00250 {
00251     double dpi;
00252 
00253     vectorize = 0;
00254     lines_aa  = 1;
00255     plParseDrvOpts( qt_options );
00256 
00257     // Stream setup
00258     pls->color        = 1;
00259     pls->plbuf_write  = 0;
00260     pls->dev_fill0    = 1;
00261     pls->dev_fill1    = 0;
00262     pls->dev_gradient = 1;      // driver renders gradient
00263     // Let the PLplot core handle dashed lines since
00264     // the driver results for this capability have a number of issues.
00265     // pls->dev_dash=1;
00266     pls->dev_dash  = 0;
00267     pls->dev_flush = 1;
00268     // Driver does not have a clear capability so use (good) PLplot core
00269     // fallback for that instead.
00270     pls->dev_clear         = 0;
00271     pls->termin            = 0;
00272     pls->page              = 0;
00273     pls->dev_text          = 1; // want to draw text
00274     pls->dev_unicode       = 1; // want unicode
00275     pls->has_string_length = 1; // Driver supports string length calculations
00276 
00277     // Needs to be true only because of multi-stream case
00278     bool isMaster = initQtApp( true );
00279 
00280     if ( pls->xdpi <= 0. )
00281         dpi = DEFAULT_DPI;
00282     else
00283         dpi = pls->xdpi;
00284 
00285     // Shamelessly copied on the Cairo stuff :)
00286     if ( pls->xlength <= 0 || pls->ylength <= 0 )
00287     {
00288         pls->dev     = new QtRasterDevice;
00289         pls->xlength = (PLINT) ( ( (QtRasterDevice *) ( pls->dev ) )->m_dWidth );
00290         pls->ylength = (PLINT) ( ( (QtRasterDevice *) ( pls->dev ) )->m_dHeight );
00291     }
00292     else
00293     {
00294         pls->dev = new QtRasterDevice( pls->xlength, pls->ylength );
00295     }
00296     ( (QtRasterDevice *) pls->dev )->setPLStream( pls );
00297 
00298     if ( isMaster )
00299         handler.setMasterDevice( (QtRasterDevice *) ( pls->dev ) );
00300 
00301     if ( pls->xlength > pls->ylength )
00302         ( (QtRasterDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->xlength / (PLFLT) ( PIXELS_X - 1 );
00303     else
00304         ( (QtRasterDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->ylength / (PLFLT) PIXELS_Y;
00305 
00306     plP_setphy( (PLINT) 0, (PLINT) ( pls->xlength / ( (QtRasterDevice *) ( pls->dev ) )->downscale ), (PLINT) 0, (PLINT) ( pls->ylength / ( (QtRasterDevice *) ( pls->dev ) )->downscale ) );
00307 
00308     plP_setpxl( dpi / 25.4 / ( (QtRasterDevice *) ( pls->dev ) )->downscale, dpi / 25.4 / ( (QtRasterDevice *) ( pls->dev ) )->downscale );
00309 
00310     ( (QtRasterDevice *) ( pls->dev ) )->setResolution( dpi );
00311 
00312     // Initialize family file info
00313     plFamInit( pls );
00314 
00315     plOpenFile( pls );
00316 }
00317 
00318 void plD_eop_rasterqt( PLStream *pls )
00319 {
00320     if ( qt_family_check( pls ) )
00321     {
00322         return;
00323     }
00324     ( (QtRasterDevice *) pls->dev )->savePlot();
00325     handler.DeviceChangedPage( (QtRasterDevice *) pls->dev );
00326 }
00327 
00328 void plD_line_rasterqt( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
00329 {
00330     QtRasterDevice* widget = (QtRasterDevice *) pls->dev;
00331 
00332     if ( widget != NULL && qt_family_check( pls ) )
00333     {
00334         return;
00335     }
00336     if ( widget == NULL )
00337         return;
00338 
00339     widget->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00340     widget->drawLine( x1a, y1a, x2a, y2a );
00341 }
00342 
00343 void plD_polyline_rasterqt( PLStream *pls, short *xa, short *ya, PLINT npts )
00344 {
00345     QtRasterDevice * widget = (QtRasterDevice *) pls->dev;
00346 
00347     if ( widget != NULL && qt_family_check( pls ) )
00348     {
00349         return;
00350     }
00351     if ( widget == NULL )
00352         return;
00353 
00354     widget->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00355     widget->drawPolyline( xa, ya, npts );
00356 }
00357 
00358 void plD_esc_rasterqt( PLStream * pls, PLINT op, void* ptr )
00359 {
00360     short          *xa, *ya;
00361     unsigned char  *r, *g, *b;
00362     PLFLT          *alpha;
00363     PLINT          i;
00364     QtRasterDevice * widget = (QtRasterDevice *) pls->dev;
00365     if ( widget != NULL && qt_family_check( pls ) )
00366     {
00367         return;
00368     }
00369     if ( widget == NULL )
00370         return;
00371 
00372     switch ( op )
00373     {
00374     //     case PLESC_DASH:
00375     //       widget->setDashed(pls->nms, pls->mark, pls->space);
00376     //       widget->QtPLDriver::setColor(pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a);
00377     //       widget->drawPolyline(pls->dev_x, pls->dev_y, pls->dev_npts);
00378     //       widget->setSolid();
00379     //       break;
00380 
00381     case PLESC_FILL:
00382         xa = new short[pls->dev_npts];
00383         ya = new short[pls->dev_npts];
00384 
00385         for ( i = 0; i < pls->dev_npts; i++ )
00386         {
00387             xa[i] = pls->dev_x[i];
00388             ya[i] = pls->dev_y[i];
00389         }
00390         widget->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00391         widget->drawPolygon( xa, ya, pls->dev_npts );
00392 
00393         delete[] xa;
00394         delete[] ya;
00395         break;
00396 
00397     case PLESC_GRADIENT:
00398         xa    = new short[pls->dev_npts];
00399         ya    = new short[pls->dev_npts];
00400         r     = new unsigned char[pls->ncol1];
00401         g     = new unsigned char[pls->ncol1];
00402         b     = new unsigned char[pls->ncol1];
00403         alpha = new PLFLT[pls->ncol1];
00404 
00405         for ( i = 0; i < pls->ncol1; i++ )
00406         {
00407             r[i]     = pls->cmap1[i].r;
00408             g[i]     = pls->cmap1[i].g;
00409             b[i]     = pls->cmap1[i].b;
00410             alpha[i] = pls->cmap1[i].a;
00411         }
00412         widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
00413 
00414         for ( i = 0; i < pls->dev_npts; i++ )
00415         {
00416             xa[i] = pls->dev_x[i];
00417             ya[i] = pls->dev_y[i];
00418         }
00419         widget->drawPolygon( xa, ya, pls->dev_npts );
00420 
00421         delete[] xa;
00422         delete[] ya;
00423         delete[] r;
00424         delete[] g;
00425         delete[] b;
00426         delete[] alpha;
00427         break;
00428 
00429     case PLESC_HAS_TEXT:
00430         //  call the generic ProcessString function
00431         //  ProcessString( pls, (EscText *)ptr );
00432         widget->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00433         widget->drawText( (EscText *) ptr );
00434         break;
00435 
00436     default: break;
00437     }
00438 }
00439 
00440 void plD_state_rasterqt( PLStream * pls, PLINT op )
00441 {
00442     QtRasterDevice * widget = (QtRasterDevice *) pls->dev;
00443     if ( widget != NULL && qt_family_check( pls ) )
00444     {
00445         return;
00446     }
00447     if ( widget == NULL )
00448         return;
00449 
00450     switch ( op )
00451     {
00452     case PLSTATE_WIDTH:
00453         widget->setWidthF( pls->width );
00454         break;
00455 
00456     case PLSTATE_COLOR0:
00457         ( (QtPLDriver *) widget )->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00458         break;
00459 
00460     case PLSTATE_COLOR1:
00461         ( (QtPLDriver *) widget )->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00462         break;
00463 
00464 
00465     default: break;
00466     }
00467 }
00468 
00469 void plD_tidy_rasterqt( PLStream * pls )
00470 {
00471     QtRasterDevice * widget = (QtRasterDevice *) pls->dev;
00472 
00473     if ( widget != NULL )
00474     {
00475         handler.DeviceClosed( widget );
00476         delete widget;
00477         pls->dev = NULL;
00478     }
00479     plCloseFile( pls );
00480 
00481     closeQtApp();
00482 }
00483 #endif
00484 
00485 #if defined ( PLD_bmpqt )
00486 void plD_dispatch_init_bmpqt( PLDispatchTable *pdt )
00487 {
00488 #ifndef ENABLE_DYNDRIVERS
00489     pdt->pl_MenuStr = "Qt Windows bitmap Driver";
00490     pdt->pl_DevName = "bmpqt";
00491 #endif
00492     pdt->pl_type     = plDevType_FileOriented;
00493     pdt->pl_seq      = 66;
00494     pdt->pl_init     = (plD_init_fp) plD_init_rasterqt;
00495     pdt->pl_line     = (plD_line_fp) plD_line_rasterqt;
00496     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
00497     pdt->pl_eop      = (plD_eop_fp) plD_eop_rasterqt;
00498     pdt->pl_bop      = (plD_bop_fp) plD_bop_bmpqt;
00499     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_rasterqt;
00500     pdt->pl_state    = (plD_state_fp) plD_state_rasterqt;
00501     pdt->pl_esc      = (plD_esc_fp) plD_esc_rasterqt;
00502 }
00503 
00504 void plD_bop_bmpqt( PLStream *pls )
00505 {
00506     // Plot familying stuff. Not really understood, just copying gd.c
00507     plGetFam( pls );
00508 
00509     pls->famadv = 1;
00510     pls->page++;
00511     if ( qt_family_check( pls ) )
00512     {
00513         return;
00514     }
00515     ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "BMP" );
00516     ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
00517 }
00518 #endif
00519 
00520 #if defined ( PLD_jpgqt )
00521 void plD_dispatch_init_jpgqt( PLDispatchTable *pdt )
00522 {
00523 #ifndef ENABLE_DYNDRIVERS
00524     pdt->pl_MenuStr = "Qt jpg Driver";
00525     pdt->pl_DevName = "jpgqt";
00526 #endif
00527     pdt->pl_type     = plDevType_FileOriented;
00528     pdt->pl_seq      = 67;
00529     pdt->pl_init     = (plD_init_fp) plD_init_rasterqt;
00530     pdt->pl_line     = (plD_line_fp) plD_line_rasterqt;
00531     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
00532     pdt->pl_eop      = (plD_eop_fp) plD_eop_rasterqt;
00533     pdt->pl_bop      = (plD_bop_fp) plD_bop_jpgqt;
00534     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_rasterqt;
00535     pdt->pl_state    = (plD_state_fp) plD_state_rasterqt;
00536     pdt->pl_esc      = (plD_esc_fp) plD_esc_rasterqt;
00537 }
00538 
00539 void plD_bop_jpgqt( PLStream *pls )
00540 {
00541     // Plot familying stuff. Not really understood, just copying gd.c
00542     plGetFam( pls );
00543 
00544     pls->famadv = 1;
00545     pls->page++;
00546     if ( qt_family_check( pls ) )
00547     {
00548         return;
00549     }
00550     ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "JPG" );
00551     ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
00552 }
00553 #endif
00554 
00555 #if defined ( PLD_pngqt )
00556 void plD_dispatch_init_pngqt( PLDispatchTable *pdt )
00557 {
00558 #ifndef ENABLE_DYNDRIVERS
00559     pdt->pl_MenuStr = "Qt png Driver";
00560     pdt->pl_DevName = "pngqt";
00561 #endif
00562     pdt->pl_type     = plDevType_FileOriented;
00563     pdt->pl_seq      = 68;
00564     pdt->pl_init     = (plD_init_fp) plD_init_rasterqt;
00565     pdt->pl_line     = (plD_line_fp) plD_line_rasterqt;
00566     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
00567     pdt->pl_eop      = (plD_eop_fp) plD_eop_rasterqt;
00568     pdt->pl_bop      = (plD_bop_fp) plD_bop_pngqt;
00569     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_rasterqt;
00570     pdt->pl_state    = (plD_state_fp) plD_state_rasterqt;
00571     pdt->pl_esc      = (plD_esc_fp) plD_esc_rasterqt;
00572 }
00573 
00574 void plD_bop_pngqt( PLStream *pls )
00575 {
00576     // Plot familying stuff. Not really understood, just copying gd.c
00577     plGetFam( pls );
00578 
00579     pls->famadv = 1;
00580     pls->page++;
00581     if ( qt_family_check( pls ) )
00582     {
00583         return;
00584     }
00585     ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "PNG" );
00586     ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
00587 }
00588 #endif
00589 
00590 #if defined ( PLD_ppmqt )
00591 void plD_dispatch_init_ppmqt( PLDispatchTable *pdt )
00592 {
00593 #ifndef ENABLE_DYNDRIVERS
00594     pdt->pl_MenuStr = "Qt ppm Driver";
00595     pdt->pl_DevName = "ppmqt";
00596 #endif
00597     pdt->pl_type     = plDevType_FileOriented;
00598     pdt->pl_seq      = 69;
00599     pdt->pl_init     = (plD_init_fp) plD_init_rasterqt;
00600     pdt->pl_line     = (plD_line_fp) plD_line_rasterqt;
00601     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
00602     pdt->pl_eop      = (plD_eop_fp) plD_eop_rasterqt;
00603     pdt->pl_bop      = (plD_bop_fp) plD_bop_ppmqt;
00604     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_rasterqt;
00605     pdt->pl_state    = (plD_state_fp) plD_state_rasterqt;
00606     pdt->pl_esc      = (plD_esc_fp) plD_esc_rasterqt;
00607 }
00608 
00609 void plD_bop_ppmqt( PLStream *pls )
00610 {
00611     // Plot familying stuff. Not really understood, just copying gd.c
00612     plGetFam( pls );
00613 
00614     pls->famadv = 1;
00615     pls->page++;
00616     if ( qt_family_check( pls ) )
00617     {
00618         return;
00619     }
00620     ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "PPM" );
00621     ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
00622 }
00623 #endif
00624 
00625 #if defined ( PLD_tiffqt )
00626 void plD_dispatch_init_tiffqt( PLDispatchTable *pdt )
00627 {
00628 #ifndef ENABLE_DYNDRIVERS
00629     pdt->pl_MenuStr = "Qt tiff Driver";
00630     pdt->pl_DevName = "tiffqt";
00631 #endif
00632     pdt->pl_type     = plDevType_FileOriented;
00633     pdt->pl_seq      = 70;
00634     pdt->pl_init     = (plD_init_fp) plD_init_rasterqt;
00635     pdt->pl_line     = (plD_line_fp) plD_line_rasterqt;
00636     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
00637     pdt->pl_eop      = (plD_eop_fp) plD_eop_rasterqt;
00638     pdt->pl_bop      = (plD_bop_fp) plD_bop_tiffqt;
00639     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_rasterqt;
00640     pdt->pl_state    = (plD_state_fp) plD_state_rasterqt;
00641     pdt->pl_esc      = (plD_esc_fp) plD_esc_rasterqt;
00642 }
00643 
00644 void plD_bop_tiffqt( PLStream *pls )
00645 {
00646     // Plot familying stuff. Not really understood, just copying gd.c
00647     plGetFam( pls );
00648 
00649     pls->famadv = 1;
00650     pls->page++;
00651     if ( qt_family_check( pls ) )
00652     {
00653         return;
00654     }
00655     ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "TIFF" );
00656     ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
00657 }
00658 #endif
00659 
00660 #if defined ( PLD_svgqt ) && QT_VERSION >= 0x040300
00661 void plD_dispatch_init_svgqt( PLDispatchTable *pdt )
00662 {
00663 #ifndef ENABLE_DYNDRIVERS
00664     pdt->pl_MenuStr = "Qt SVG Driver";
00665     pdt->pl_DevName = "svgqt";
00666 #endif
00667     pdt->pl_type     = plDevType_FileOriented;
00668     pdt->pl_seq      = 71;
00669     pdt->pl_init     = (plD_init_fp) plD_init_svgqt;
00670     pdt->pl_line     = (plD_line_fp) plD_line_svgqt;
00671     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_svgqt;
00672     pdt->pl_eop      = (plD_eop_fp) plD_eop_svgqt;
00673     pdt->pl_bop      = (plD_bop_fp) plD_bop_svgqt;
00674     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_svgqt;
00675     pdt->pl_state    = (plD_state_fp) plD_state_svgqt;
00676     pdt->pl_esc      = (plD_esc_fp) plD_esc_svgqt;
00677 }
00678 
00679 void plD_init_svgqt( PLStream * pls )
00680 {
00681     vectorize = 1;
00682     lines_aa  = 1;
00683     plParseDrvOpts( qt_options );
00684 
00685     // Stream setup
00686     pls->color        = 1;
00687     pls->plbuf_write  = 0;
00688     pls->dev_fill0    = 1;
00689     pls->dev_fill1    = 0;
00690     pls->dev_gradient = 1;      // driver renders gradient
00691     // Let the PLplot core handle dashed lines since
00692     // the driver results for this capability have a number of issues.
00693     // pls->dev_dash=1;
00694     pls->dev_dash  = 0;
00695     pls->dev_flush = 1;
00696     // Driver does not have a clear capability so use (good) PLplot core
00697     // fallback for that instead.
00698     pls->dev_clear         = 0;
00699     pls->termin            = 0;
00700     pls->page              = 0;
00701     pls->dev_text          = 1; // want to draw text
00702     pls->dev_unicode       = 1; // want unicode
00703     pls->has_string_length = 1; // Driver supports string length calculations
00704 
00705     // Needs to be true only because of multi-stream case
00706     bool isMaster = initQtApp( true );
00707 
00708     if ( pls->xlength <= 0 || pls->ylength <= 0 )
00709     {
00710         pls->dev     = new QtSVGDevice;
00711         pls->xlength = (int) ( ( (QtSVGDevice *) ( pls->dev ) )->m_dWidth );
00712         pls->ylength = (int) ( ( (QtSVGDevice *) ( pls->dev ) )->m_dHeight );
00713     }
00714     else
00715     {
00716         pls->dev = new QtSVGDevice( pls->xlength, pls->ylength );
00717     }
00718     ( (QtSVGDevice *) pls->dev )->setPLStream( pls );
00719 
00720     if ( isMaster )
00721         handler.setMasterDevice( (QtSVGDevice *) ( pls->dev ) );
00722 
00723     if ( pls->xlength > pls->ylength )
00724         ( (QtSVGDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->xlength / (PLFLT) ( PIXELS_X - 1 );
00725     else
00726         ( (QtSVGDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->ylength / (PLFLT) PIXELS_Y;
00727 
00728     plP_setphy( (PLINT) 0, (PLINT) ( pls->xlength / ( (QtSVGDevice *) ( pls->dev ) )->downscale ), (PLINT) 0, (PLINT) ( pls->ylength / ( (QtSVGDevice *) ( pls->dev ) )->downscale ) );
00729 
00730     plP_setpxl( POINTS_PER_INCH / 25.4 / ( (QtSVGDevice *) ( pls->dev ) )->downscale, POINTS_PER_INCH / 25.4 / ( (QtSVGDevice *) ( pls->dev ) )->downscale );
00731 
00732     // Initialize family file info
00733     plFamInit( pls );
00734 
00735     plOpenFile( pls );
00736 }
00737 
00738 void plD_bop_svgqt( PLStream *pls )
00739 {
00740     // Plot familying stuff. Not really understood, just copying gd.c
00741     plGetFam( pls );
00742 
00743     pls->famadv = 1;
00744     pls->page++;
00745     if ( qt_family_check( pls ) )
00746     {
00747         return;
00748     }
00749     ( (QtSVGDevice *) pls->dev )->definePlotName( pls->FileName );
00750     ( (QtSVGDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
00751 }
00752 
00753 void plD_eop_svgqt( PLStream *pls )
00754 {
00755     double downscale;
00756     QSize  s;
00757 
00758     if ( qt_family_check( pls ) )
00759     {
00760         return;
00761     }
00762     ( (QtSVGDevice *) pls->dev )->savePlot();
00763     // Once saved, we have to create a new device with the same properties
00764     // to be able to plot another page.
00765     downscale = ( (QtSVGDevice *) pls->dev )->downscale;
00766     s         = ( (QtSVGDevice *) pls->dev )->size();
00767     bool isMaster = ( handler.isMasterDevice( (QtSVGDevice *) pls->dev ) );
00768     delete ( (QtSVGDevice *) pls->dev );
00769 
00770     pls->dev = new QtSVGDevice( s.width(), s.height() );
00771     ( (QtSVGDevice *) pls->dev )->downscale = downscale;
00772     ( (QtSVGDevice *) pls->dev )->setPLStream( pls );
00773 
00774     if ( isMaster )
00775         handler.setMasterDevice( (QtSVGDevice *) pls->dev );
00776     handler.DeviceChangedPage( (QtSVGDevice *) pls->dev );
00777 }
00778 
00779 void plD_line_svgqt( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
00780 {
00781     QtSVGDevice* widget = (QtSVGDevice *) pls->dev;
00782     if ( widget != NULL && qt_family_check( pls ) )
00783     {
00784         return;
00785     }
00786     if ( widget == NULL )
00787         return;
00788 
00789     widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00790     widget->drawLine( x1a, y1a, x2a, y2a );
00791 }
00792 
00793 void plD_polyline_svgqt( PLStream *pls, short *xa, short *ya, PLINT npts )
00794 {
00795     QtSVGDevice * widget = (QtSVGDevice *) pls->dev;
00796     if ( widget != NULL && qt_family_check( pls ) )
00797     {
00798         return;
00799     }
00800     if ( widget == NULL )
00801         return;
00802 
00803     widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00804     widget->drawPolyline( xa, ya, npts );
00805 }
00806 
00807 void plD_esc_svgqt( PLStream * pls, PLINT op, void* ptr )
00808 {
00809     short         *xa, *ya;
00810     unsigned char *r, *g, *b;
00811     PLFLT         *alpha;
00812     PLINT         i;
00813     QtSVGDevice   * widget = (QtSVGDevice *) pls->dev;
00814     if ( widget != NULL && qt_family_check( pls ) )
00815     {
00816         return;
00817     }
00818     if ( widget == NULL )
00819         return;
00820 
00821     switch ( op )
00822     {
00823     case PLESC_FILL:
00824         xa = new short[pls->dev_npts];
00825         ya = new short[pls->dev_npts];
00826 
00827         for ( i = 0; i < pls->dev_npts; i++ )
00828         {
00829             xa[i] = pls->dev_x[i];
00830             ya[i] = pls->dev_y[i];
00831         }
00832         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00833         widget->drawPolygon( xa, ya, pls->dev_npts );
00834 
00835         delete[] xa;
00836         delete[] ya;
00837         break;
00838 
00839     case PLESC_GRADIENT:
00840         xa    = new short[pls->dev_npts];
00841         ya    = new short[pls->dev_npts];
00842         r     = new unsigned char[pls->ncol1];
00843         g     = new unsigned char[pls->ncol1];
00844         b     = new unsigned char[pls->ncol1];
00845         alpha = new PLFLT[pls->ncol1];
00846 
00847         for ( i = 0; i < pls->ncol1; i++ )
00848         {
00849             r[i]     = pls->cmap1[i].r;
00850             g[i]     = pls->cmap1[i].g;
00851             b[i]     = pls->cmap1[i].b;
00852             alpha[i] = pls->cmap1[i].a;
00853         }
00854         widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
00855 
00856         for ( i = 0; i < pls->dev_npts; i++ )
00857         {
00858             xa[i] = pls->dev_x[i];
00859             ya[i] = pls->dev_y[i];
00860         }
00861         widget->drawPolygon( xa, ya, pls->dev_npts );
00862 
00863         delete[] xa;
00864         delete[] ya;
00865         delete[] r;
00866         delete[] g;
00867         delete[] b;
00868         delete[] alpha;
00869         break;
00870 
00871     case PLESC_HAS_TEXT:
00872         // call the generic ProcessString function
00873         //  ProcessString( pls, (EscText *)ptr );
00874         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00875         widget->drawText( (EscText *) ptr );
00876         break;
00877 
00878     default:
00879         break;
00880     }
00881 }
00882 
00883 void plD_state_svgqt( PLStream * pls, PLINT op )
00884 {
00885     QtSVGDevice * widget = (QtSVGDevice *) pls->dev;
00886     if ( widget != NULL && qt_family_check( pls ) )
00887     {
00888         return;
00889     }
00890     if ( widget == NULL )
00891         return;
00892 
00893     switch ( op )
00894     {
00895     case PLSTATE_WIDTH:
00896         widget->setWidthF( pls->width );
00897         break;
00898 
00899     case PLSTATE_COLOR0:
00900         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00901         break;
00902 
00903     case PLSTATE_COLOR1:
00904         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
00905         break;
00906 
00907     default: break;
00908     }
00909 }
00910 
00911 void plD_tidy_svgqt( PLStream * pls )
00912 {
00913     QtSVGDevice * widget = (QtSVGDevice *) pls->dev;
00914 
00915     if ( widget != NULL )
00916     {
00917         handler.DeviceClosed( widget );
00918         delete widget;
00919         pls->dev = NULL;
00920     }
00921     plCloseFile( pls );
00922 
00923     closeQtApp();
00924 }
00925 #endif
00926 
00927 #if defined ( PLD_epsqt )
00928 void plD_dispatch_init_epsqt( PLDispatchTable *pdt )
00929 {
00930 #ifndef ENABLE_DYNDRIVERS
00931     pdt->pl_MenuStr = "Qt EPS Driver";
00932     pdt->pl_DevName = "epsqt";
00933 #endif
00934     pdt->pl_type     = plDevType_FileOriented;
00935     pdt->pl_seq      = 73;
00936     pdt->pl_init     = (plD_init_fp) plD_init_epspdfqt;
00937     pdt->pl_line     = (plD_line_fp) plD_line_epspdfqt;
00938     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_epspdfqt;
00939     pdt->pl_eop      = (plD_eop_fp) plD_eop_epspdfqt;
00940     pdt->pl_bop      = (plD_bop_fp) plD_bop_epsqt;
00941     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_epspdfqt;
00942     pdt->pl_state    = (plD_state_fp) plD_state_epspdfqt;
00943     pdt->pl_esc      = (plD_esc_fp) plD_esc_epspdfqt;
00944 }
00945 #endif
00946 
00947 #if defined ( PLD_pdfqt )
00948 void plD_dispatch_init_pdfqt( PLDispatchTable *pdt )
00949 {
00950 #ifndef ENABLE_DYNDRIVERS
00951     pdt->pl_MenuStr = "Qt PDF Driver";
00952     pdt->pl_DevName = "pdfqt";
00953 #endif
00954     pdt->pl_type     = plDevType_FileOriented;
00955     pdt->pl_seq      = 74;
00956     pdt->pl_init     = (plD_init_fp) plD_init_epspdfqt;
00957     pdt->pl_line     = (plD_line_fp) plD_line_epspdfqt;
00958     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_epspdfqt;
00959     pdt->pl_eop      = (plD_eop_fp) plD_eop_epspdfqt;
00960     pdt->pl_bop      = (plD_bop_fp) plD_bop_pdfqt;
00961     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_epspdfqt;
00962     pdt->pl_state    = (plD_state_fp) plD_state_epspdfqt;
00963     pdt->pl_esc      = (plD_esc_fp) plD_esc_epspdfqt;
00964 }
00965 #endif
00966 
00967 #if defined ( PLD_epsqt ) || defined ( PLD_pdfqt )
00968 void plD_init_epspdfqt( PLStream * pls )
00969 {
00970     vectorize = 0;
00971     lines_aa  = 1;
00972     plParseDrvOpts( qt_options );
00973 
00974     // Stream setup
00975     pls->color        = 1;
00976     pls->plbuf_write  = 0;
00977     pls->dev_fill0    = 1;
00978     pls->dev_fill1    = 0;
00979     pls->dev_gradient = 1;      // driver renders gradient
00980     pls->dev_arc      = 1;      // driver renders arcs
00981     // Let the PLplot core handle dashed lines since
00982     // the driver results for this capability have a number of issues.
00983     // pls->dev_dash=1;
00984     pls->dev_dash  = 0;
00985     pls->dev_flush = 1;
00986     // Driver does not have a clear capability so use (good) PLplot core
00987     // fallback for that instead.
00988     pls->dev_clear         = 0;
00989     pls->termin            = 0;
00990     pls->page              = 0;
00991     pls->dev_text          = 1; // want to draw text
00992     pls->dev_unicode       = 1; // want unicode
00993     pls->has_string_length = 1; // Driver supports string length calculations
00994 
00995     // QPrinter devices won't create if there is no QApplication declared...
00996     // Needs to be true only because of multi-stream case
00997     bool isMaster = initQtApp( true );
00998 
00999     if ( pls->xlength <= 0 || pls->ylength <= 0 )
01000     {
01001         pls->dev     = new QtEPSDevice;
01002         pls->xlength = (int) ( ( (QtEPSDevice *) ( pls->dev ) )->m_dWidth );
01003         pls->ylength = (int) ( ( (QtEPSDevice *) ( pls->dev ) )->m_dHeight );
01004     }
01005     else
01006     {
01007         pls->dev = new QtEPSDevice( pls->xlength, pls->ylength );
01008     }
01009     ( (QtEPSDevice *) pls->dev )->setPLStream( pls );
01010 
01011     if ( isMaster )
01012         handler.setMasterDevice( (QtEPSDevice *) ( pls->dev ) );
01013 
01014     if ( pls->xlength > pls->ylength )
01015         ( (QtEPSDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->xlength / (PLFLT) ( PIXELS_X - 1 );
01016     else
01017         ( (QtEPSDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->ylength / (PLFLT) PIXELS_Y;
01018 
01019     plP_setphy( (PLINT) 0, (PLINT) ( pls->xlength / ( (QtEPSDevice *) ( pls->dev ) )->downscale ), (PLINT) 0, (PLINT) ( pls->ylength / ( (QtEPSDevice *) ( pls->dev ) )->downscale ) );
01020 
01021     plP_setpxl( POINTS_PER_INCH / 25.4 / ( (QtEPSDevice *) ( pls->dev ) )->downscale, POINTS_PER_INCH / 25.4 / ( (QtEPSDevice *) ( pls->dev ) )->downscale );
01022 
01023     // Initialize family file info
01024     plFamInit( pls );
01025 
01026     plOpenFile( pls );
01027 }
01028 
01029 void plD_bop_epspdfqt_helper( PLStream *pls, int ifeps )
01030 {
01031     // Plot familying stuff. Not really understood, just copying gd.c
01032     plGetFam( pls );
01033 
01034     pls->famadv = 1;
01035     pls->page++;
01036     if ( qt_family_check( pls ) )
01037     {
01038         return;
01039     }
01040     ( (QtEPSDevice *) pls->dev )->definePlotName( pls->FileName, ifeps );
01041     ( (QtEPSDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
01042 }
01043 
01044 void plD_eop_epspdfqt( PLStream *pls )
01045 {
01046     double downscale;
01047 
01048     if ( qt_family_check( pls ) )
01049     {
01050         return;
01051     }
01052     ( (QtEPSDevice *) pls->dev )->savePlot();
01053     // Once saved, we have to create a new device with the same properties
01054     // to be able to plot another page.
01055     downscale = ( (QtEPSDevice *) pls->dev )->downscale;
01056     bool isMaster = handler.isMasterDevice( (QtEPSDevice *) pls->dev );
01057     delete ( (QtEPSDevice *) pls->dev );
01058 
01059     pls->dev = new QtEPSDevice;
01060     ( (QtEPSDevice *) pls->dev )->downscale = downscale;
01061 
01062     if ( isMaster )
01063         handler.setMasterDevice( (QtEPSDevice *) pls->dev );
01064     handler.DeviceChangedPage( (QtEPSDevice *) pls->dev );
01065 }
01066 
01067 void plD_line_epspdfqt( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
01068 {
01069     QtEPSDevice* widget = (QtEPSDevice *) pls->dev;
01070     if ( widget != NULL && qt_family_check( pls ) )
01071     {
01072         return;
01073     }
01074     if ( widget == NULL )
01075         return;
01076 
01077     widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01078     widget->drawLine( x1a, y1a, x2a, y2a );
01079 }
01080 
01081 void plD_polyline_epspdfqt( PLStream *pls, short *xa, short *ya, PLINT npts )
01082 {
01083     QtEPSDevice * widget = (QtEPSDevice *) pls->dev;
01084     if ( widget != NULL && qt_family_check( pls ) )
01085     {
01086         return;
01087     }
01088     if ( widget == NULL )
01089         return;
01090 
01091     widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01092     widget->drawPolyline( xa, ya, npts );
01093 }
01094 
01095 void plD_esc_epspdfqt( PLStream * pls, PLINT op, void* ptr )
01096 {
01097     short         *xa, *ya;
01098     unsigned char *r, *g, *b;
01099     PLFLT         *alpha;
01100     PLINT         i;
01101     QtEPSDevice   * widget  = (QtEPSDevice *) pls->dev;
01102     arc_struct    *arc_info = (arc_struct *) ptr;
01103 
01104     if ( widget != NULL && qt_family_check( pls ) )
01105     {
01106         return;
01107     }
01108     if ( widget == NULL )
01109         return;
01110 
01111     switch ( op )
01112     {
01113     case PLESC_FILL:
01114         xa = new short[pls->dev_npts];
01115         ya = new short[pls->dev_npts];
01116 
01117         for ( i = 0; i < pls->dev_npts; i++ )
01118         {
01119             xa[i] = pls->dev_x[i];
01120             ya[i] = pls->dev_y[i];
01121         }
01122         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01123         widget->drawPolygon( xa, ya, pls->dev_npts );
01124 
01125         delete[] xa;
01126         delete[] ya;
01127         break;
01128 
01129     case PLESC_GRADIENT:
01130         xa    = new short[pls->dev_npts];
01131         ya    = new short[pls->dev_npts];
01132         r     = new unsigned char[pls->ncol1];
01133         g     = new unsigned char[pls->ncol1];
01134         b     = new unsigned char[pls->ncol1];
01135         alpha = new PLFLT[pls->ncol1];
01136 
01137         for ( i = 0; i < pls->ncol1; i++ )
01138         {
01139             r[i]     = pls->cmap1[i].r;
01140             g[i]     = pls->cmap1[i].g;
01141             b[i]     = pls->cmap1[i].b;
01142             alpha[i] = pls->cmap1[i].a;
01143         }
01144         widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
01145 
01146         for ( i = 0; i < pls->dev_npts; i++ )
01147         {
01148             xa[i] = pls->dev_x[i];
01149             ya[i] = pls->dev_y[i];
01150         }
01151         widget->drawPolygon( xa, ya, pls->dev_npts );
01152 
01153         delete[] xa;
01154         delete[] ya;
01155         delete[] r;
01156         delete[] g;
01157         delete[] b;
01158         delete[] alpha;
01159         break;
01160 
01161     case PLESC_HAS_TEXT:
01162         // call the generic ProcessString function
01163         //  ProcessString( pls, (EscText *)ptr );
01164         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01165         widget->drawText( (EscText *) ptr );
01166         break;
01167 
01168     case PLESC_ARC:
01169         widget->drawArc( arc_info->x, arc_info->y, arc_info->a, arc_info->b, arc_info->angle1, arc_info->angle2, arc_info->rotate, arc_info->fill );
01170         break;
01171 
01172     default: break;
01173     }
01174 }
01175 
01176 void plD_state_epspdfqt( PLStream * pls, PLINT op )
01177 {
01178     QtEPSDevice * widget = (QtEPSDevice *) pls->dev;
01179     if ( widget != NULL && qt_family_check( pls ) )
01180     {
01181         return;
01182     }
01183     if ( widget == NULL )
01184         return;
01185 
01186     switch ( op )
01187     {
01188     case PLSTATE_WIDTH:
01189         widget->setWidthF( pls->width );
01190         break;
01191 
01192     case PLSTATE_COLOR0:
01193         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01194         break;
01195 
01196     case PLSTATE_COLOR1:
01197         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01198         break;
01199 
01200 
01201     default: break;
01202     }
01203 }
01204 
01205 void plD_tidy_epspdfqt( PLStream * pls )
01206 {
01207     QtEPSDevice * widget = (QtEPSDevice *) pls->dev;
01208 
01209     if ( widget != NULL )
01210     {
01211         handler.DeviceClosed( widget );
01212         delete widget;
01213         pls->dev = NULL;
01214     }
01215     plCloseFile( pls );
01216 
01217     closeQtApp();
01218 }
01219 #endif
01220 
01221 #if defined ( PLD_epsqt )
01222 void plD_bop_epsqt( PLStream *pls )
01223 {
01224     plD_bop_epspdfqt_helper( pls, 1 );
01225 }
01226 #endif
01227 
01228 #if defined ( PLD_pdfqt )
01229 void plD_bop_pdfqt( PLStream *pls )
01230 {
01231     plD_bop_epspdfqt_helper( pls, 0 );
01232 }
01233 #endif
01234 
01235 #if defined ( PLD_qtwidget )
01236 void plD_dispatch_init_qtwidget( PLDispatchTable *pdt )
01237 {
01238 #ifndef ENABLE_DYNDRIVERS
01239     pdt->pl_MenuStr = "Qt Widget";
01240     pdt->pl_DevName = "qtwidget";
01241 #endif
01242     pdt->pl_type     = plDevType_Interactive;
01243     pdt->pl_seq      = 72;
01244     pdt->pl_init     = (plD_init_fp) plD_init_qtwidget;
01245     pdt->pl_line     = (plD_line_fp) plD_line_qtwidget;
01246     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_qtwidget;
01247     pdt->pl_eop      = (plD_eop_fp) plD_eop_qtwidget;
01248     pdt->pl_bop      = (plD_bop_fp) plD_bop_qtwidget;
01249     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_qtwidget;
01250     pdt->pl_state    = (plD_state_fp) plD_state_qtwidget;
01251     pdt->pl_esc      = (plD_esc_fp) plD_esc_qtwidget;
01252 }
01253 
01254 void plD_init_qtwidget( PLStream * pls )
01255 {
01256     vectorize = 0;
01257     lines_aa  = 1;
01258     plParseDrvOpts( qt_options );
01259 
01260     bool      isMaster = initQtApp( true );
01261     QtPLWidget* widget;
01262 
01263     if ( pls->xlength <= 0 || pls->ylength <= 0 )
01264     {
01265         widget       = new QtPLWidget;
01266         pls->dev     = (void *) widget;
01267         pls->xlength = (int) widget->m_dWidth;
01268         pls->ylength = (int) widget->m_dHeight;
01269     }
01270     else
01271     {
01272         widget   = new QtPLWidget( pls->xlength, pls->ylength );
01273         pls->dev = (void *) widget;
01274     }
01275     widget->setPLStream( pls );
01276 
01277     if ( isMaster )
01278         handler.setMasterDevice( widget );
01279 
01280     if ( plsc->xlength > plsc->ylength )
01281         widget->downscale = (PLFLT) plsc->xlength / (PLFLT) ( PIXELS_X - 1 );
01282     else
01283         widget->downscale = (PLFLT) plsc->ylength / (PLFLT) PIXELS_Y;
01284 
01285     plP_setphy( (PLINT) 0, (PLINT) ( plsc->xlength / widget->downscale ), (PLINT) 0, (PLINT) ( plsc->ylength / widget->downscale ) );
01286 
01287     QPicture temp;
01288     QPainter tempPainter( &temp );
01289 
01290     plP_setpxl( temp.logicalDpiX() / 25.4 / widget->downscale, temp.logicalDpiY() / 25.4 / widget->downscale );
01291 
01292     pls->color        = 1;      // Is a color device
01293     pls->plbuf_write  = 1;      // Store commands to device in core buffer
01294     pls->dev_fill0    = 1;      // Handle solid fills
01295     pls->dev_fill1    = 0;
01296     pls->dev_gradient = 1;      // driver renders gradient
01297     pls->dev_arc      = 1;      // driver renders arcs
01298     // Let the PLplot core handle dashed lines since
01299     // the driver results for this capability have a number of issues.
01300     // pls->dev_dash=1;
01301     pls->dev_dash  = 0;
01302     pls->dev_flush = 1;
01303     // Driver does not have a clear capability so use (good) PLplot core
01304     // fallback for that instead.
01305     pls->dev_clear         = 0;
01306     pls->termin            = 1;
01307     pls->dev_text          = 1; // want to draw text
01308     pls->dev_unicode       = 1; // want unicode
01309     pls->has_string_length = 1; // Driver supports string length calculations
01310 
01311     widget->setVisible( true );
01312     widget->resize( plsc->xlength, plsc->ylength );
01313     widget->move( plsc->xoffset, plsc->yoffset );
01314 
01315     widget->setWindowTitle( pls->plwindow );
01316 
01317     qApp->connect( &handler, SIGNAL( MasterChangedPage() ), widget, SLOT( nextPage() ) );
01318     qApp->connect( &handler, SIGNAL( MasterClosed() ), widget, SLOT( close() ) );
01319 }
01320 
01321 void plD_eop_qtwidget( PLStream *pls )
01322 {
01323     QtPLWidget* widget    = ( (QtPLWidget *) pls->dev );
01324     int       currentPage = widget->pageNumber;
01325     widget->flush();
01326     widget->raise();
01327     while ( currentPage == widget->pageNumber && handler.isMasterDevice( widget ) && !pls->nopause )
01328     {
01329         qApp->processEvents( QEventLoop::WaitForMoreEvents );
01330     }
01331 }
01332 
01333 void plD_bop_qtwidget( PLStream *pls )
01334 {
01335     QtPLWidget* widget = ( (QtPLWidget *) pls->dev );
01336     widget->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
01337 }
01338 
01339 void plD_line_qtwidget( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
01340 {
01341     QtPLWidget* widget = (QtPLWidget *) pls->dev;
01342     if ( widget == NULL )
01343         return;
01344 
01345     widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01346     widget->drawLine( x1a, y1a, x2a, y2a );
01347 }
01348 
01349 void plD_polyline_qtwidget( PLStream *pls, short *xa, short *ya, PLINT npts )
01350 {
01351     QtPLWidget * widget = (QtPLWidget *) pls->dev;
01352     if ( widget == NULL )
01353         return;
01354 
01355     widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01356     widget->drawPolyline( xa, ya, npts );
01357 }
01358 
01359 void plD_esc_qtwidget( PLStream * pls, PLINT op, void* ptr )
01360 {
01361     short         *xa, *ya;
01362     PLINT         i;
01363     unsigned char *r, *g, *b;
01364     PLFLT         *alpha;
01365     QtPLWidget    * widget  = (QtPLWidget *) pls->dev;
01366     arc_struct    *arc_info = (arc_struct *) ptr;
01367     if ( widget == NULL )
01368         return;
01369 
01370     switch ( op )
01371     {
01372     case PLESC_FILL:
01373         xa = new short[pls->dev_npts];
01374         ya = new short[pls->dev_npts];
01375 
01376         for ( i = 0; i < pls->dev_npts; i++ )
01377         {
01378             xa[i] = pls->dev_x[i];
01379             ya[i] = pls->dev_y[i];
01380         }
01381 
01382         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01383         widget->drawPolygon( xa, ya, pls->dev_npts );
01384 
01385         delete[] xa;
01386         delete[] ya;
01387         break;
01388 
01389     case PLESC_GRADIENT:
01390         xa    = new short[pls->dev_npts];
01391         ya    = new short[pls->dev_npts];
01392         r     = new unsigned char[pls->ncol1];
01393         g     = new unsigned char[pls->ncol1];
01394         b     = new unsigned char[pls->ncol1];
01395         alpha = new PLFLT[pls->ncol1];
01396 
01397         for ( i = 0; i < pls->ncol1; i++ )
01398         {
01399             r[i]     = pls->cmap1[i].r;
01400             g[i]     = pls->cmap1[i].g;
01401             b[i]     = pls->cmap1[i].b;
01402             alpha[i] = pls->cmap1[i].a;
01403         }
01404         widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
01405 
01406         for ( i = 0; i < pls->dev_npts; i++ )
01407         {
01408             xa[i] = pls->dev_x[i];
01409             ya[i] = pls->dev_y[i];
01410         }
01411         widget->drawPolygon( xa, ya, pls->dev_npts );
01412 
01413         delete[] xa;
01414         delete[] ya;
01415         delete[] r;
01416         delete[] g;
01417         delete[] b;
01418         delete[] alpha;
01419         break;
01420 
01421     case PLESC_HAS_TEXT:
01422         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01423         widget->drawText( (EscText *) ptr );
01424         break;
01425 
01426     case PLESC_ARC:
01427         widget->drawArc( arc_info->x, arc_info->y, arc_info->a, arc_info->b, arc_info->angle1, arc_info->angle2, arc_info->rotate, arc_info->fill );
01428         break;
01429 
01430     case PLESC_FLUSH:
01431         widget->flush();
01432         break;
01433     case PLESC_GETC:
01434         widget->getCursorCmd( (PLGraphicsIn *) ptr );
01435         break;
01436     default: break;
01437     }
01438 }
01439 
01440 void plD_state_qtwidget( PLStream * pls, PLINT op )
01441 {
01442     QtPLWidget * widget = (QtPLWidget *) pls->dev;
01443     if ( widget == NULL )
01444         return;
01445 
01446     switch ( op )
01447     {
01448     case PLSTATE_WIDTH:
01449         widget->setWidthF( pls->width );
01450         break;
01451 
01452     case PLSTATE_COLOR0:
01453         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01454         break;
01455 
01456     case PLSTATE_COLOR1:
01457         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01458         break;
01459 
01460 
01461     default: break;
01462     }
01463 }
01464 
01465 void plD_tidy_qtwidget( PLStream * pls )
01466 {
01467     QtPLWidget * widget = (QtPLWidget *) pls->dev;
01468 
01469     if ( widget != NULL )
01470     {
01471         handler.DeviceClosed( widget );
01472         delete widget;
01473         pls->dev = NULL;
01474     }
01475 
01476     closeQtApp();
01477 }
01478 #endif
01479 
01480 #if defined ( PLD_extqt )
01481 void plD_dispatch_init_extqt( PLDispatchTable *pdt )
01482 {
01483 #ifndef ENABLE_DYNDRIVERS
01484     pdt->pl_MenuStr = "External Qt Widget";
01485     pdt->pl_DevName = "extqt";
01486 #endif
01487     pdt->pl_type     = plDevType_Interactive;
01488     pdt->pl_seq      = 75;
01489     pdt->pl_init     = (plD_init_fp) plD_init_extqt;
01490     pdt->pl_line     = (plD_line_fp) plD_line_extqt;
01491     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_extqt;
01492     pdt->pl_eop      = (plD_eop_fp) plD_eop_extqt;
01493     pdt->pl_bop      = (plD_bop_fp) plD_bop_extqt;
01494     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_extqt;
01495     pdt->pl_state    = (plD_state_fp) plD_state_extqt;
01496     pdt->pl_esc      = (plD_esc_fp) plD_esc_extqt;
01497 }
01498 
01499 void plD_init_extqt( PLStream * pls )
01500 {
01501     vectorize = 0;
01502     lines_aa  = 1;
01503 
01504     if ( pls->dev == NULL /* || pls->xlength <= 0 || pls->ylength <= 0*/ )
01505     {
01506         printf( "Error: use plsetqtdev to set up the Qt device before calling plinit()\n" );
01507         return;
01508     }
01509 
01510     QtExtWidget* widget = (QtExtWidget *) ( pls->dev );
01511 
01512     if ( widget->m_dWidth > widget->m_dHeight )
01513         widget->downscale = (PLFLT) widget->m_dWidth / (PLFLT) ( PIXELS_X - 1 );
01514     else
01515         widget->downscale = (PLFLT) widget->m_dHeight / (PLFLT) PIXELS_Y;
01516 
01517     plP_setphy( (PLINT) 0, (PLINT) ( widget->m_dWidth / widget->downscale ), (PLINT) 0, (PLINT) ( widget->m_dHeight / widget->downscale ) );
01518 
01519     QPicture temp;
01520     QPainter tempPainter( &temp );
01521 
01522     plP_setpxl( temp.logicalDpiX() / 25.4 / widget->downscale, temp.logicalDpiY() / 25.4 / widget->downscale );
01523 
01524     pls->color        = 1;      // Is a color device
01525     pls->plbuf_write  = 0;
01526     pls->dev_fill0    = 1;      // Handle solid fills
01527     pls->dev_fill1    = 0;
01528     pls->dev_gradient = 1;      // driver renders gradient
01529     pls->dev_arc      = 1;      // driver renders arcs
01530     // Let the PLplot core handle dashed lines since
01531     // the driver results for this capability have a number of issues.
01532     // pls->dev_dash=1;
01533     pls->dev_dash  = 0;
01534     pls->dev_flush = 1;
01535     // Driver does not have a clear capability so use (good) PLplot core
01536     // fallback for that instead.
01537     pls->dev_clear         = 0;
01538     pls->termin            = 0;
01539     pls->dev_text          = 1; // want to draw text
01540     pls->dev_unicode       = 1; // want unicode
01541     pls->has_string_length = 1; // Driver supports string length calculations
01542 }
01543 
01544 //
01545 // These functions are separated out (instead of using dynamic_cast)
01546 // for the benefit of the PyQt4 bindings. C++ QtExtWidgets created
01547 // by PyQt4 are not properly type resolved.
01548 //
01549 
01550 void plD_line_extqt( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
01551 {
01552     QtExtWidget * widget = NULL;
01553 
01554     widget = (QtExtWidget *) pls->dev;
01555     widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01556     widget->drawLine( x1a, y1a, x2a, y2a );
01557 }
01558 
01559 void plD_polyline_extqt( PLStream *pls, short *xa, short *ya, PLINT npts )
01560 {
01561     QtExtWidget * widget = NULL;
01562 
01563     widget = (QtExtWidget *) pls->dev;
01564     widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01565     widget->drawPolyline( xa, ya, npts );
01566 }
01567 
01568 void plD_esc_extqt( PLStream * pls, PLINT op, void* ptr )
01569 {
01570     short         *xa, *ya;
01571     PLINT         i;
01572     unsigned char *r, *g, *b;
01573     PLFLT         *alpha;
01574     QtExtWidget   * widget  = NULL;
01575     arc_struct    *arc_info = (arc_struct *) ptr;
01576 
01577     widget = (QtExtWidget *) pls->dev;
01578     switch ( op )
01579     {
01580     case PLESC_FILL:
01581         xa = new short[pls->dev_npts];
01582         ya = new short[pls->dev_npts];
01583 
01584         for ( i = 0; i < pls->dev_npts; i++ )
01585         {
01586             xa[i] = pls->dev_x[i];
01587             ya[i] = pls->dev_y[i];
01588         }
01589         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01590         widget->drawPolygon( xa, ya, pls->dev_npts );
01591 
01592         delete[] xa;
01593         delete[] ya;
01594         break;
01595 
01596     case PLESC_GRADIENT:
01597         xa    = new short[pls->dev_npts];
01598         ya    = new short[pls->dev_npts];
01599         r     = new unsigned char[pls->ncol1];
01600         g     = new unsigned char[pls->ncol1];
01601         b     = new unsigned char[pls->ncol1];
01602         alpha = new PLFLT[pls->ncol1];
01603 
01604         for ( i = 0; i < pls->ncol1; i++ )
01605         {
01606             r[i]     = pls->cmap1[i].r;
01607             g[i]     = pls->cmap1[i].g;
01608             b[i]     = pls->cmap1[i].b;
01609             alpha[i] = pls->cmap1[i].a;
01610         }
01611         widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
01612 
01613         for ( i = 0; i < pls->dev_npts; i++ )
01614         {
01615             xa[i] = pls->dev_x[i];
01616             ya[i] = pls->dev_y[i];
01617         }
01618         widget->drawPolygon( xa, ya, pls->dev_npts );
01619 
01620         delete[] xa;
01621         delete[] ya;
01622         delete[] r;
01623         delete[] g;
01624         delete[] b;
01625         delete[] alpha;
01626         break;
01627 
01628     case PLESC_HAS_TEXT:
01629         // call the generic ProcessString function
01630         //  ProcessString( pls, (EscText *)ptr );
01631         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01632         widget->drawText( (EscText *) ptr );
01633         break;
01634 
01635     case PLESC_ARC:
01636         widget->drawArc( arc_info->x, arc_info->y, arc_info->a, arc_info->b, arc_info->angle1, arc_info->angle2, arc_info->rotate, arc_info->fill );
01637         break;
01638 
01639     default: break;
01640     }
01641 }
01642 
01643 void plD_state_extqt( PLStream * pls, PLINT op )
01644 {
01645     QtExtWidget * widget = NULL;
01646 
01647     widget = (QtExtWidget *) pls->dev;
01648     switch ( op )
01649     {
01650     case PLSTATE_WIDTH:
01651         widget->setWidthF( pls->width );
01652         break;
01653 
01654     case PLSTATE_COLOR0:
01655         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01656         break;
01657 
01658     case PLSTATE_COLOR1:
01659         widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
01660         break;
01661 
01662 
01663     default: break;
01664     }
01665 }
01666 
01667 void plD_tidy_extqt( PLStream * pls )
01668 {
01669     QtExtWidget * widget = NULL;
01670 
01671     widget = (QtExtWidget *) pls->dev;
01672     if ( widget != NULL )
01673     {
01674         handler.DeviceClosed( widget );
01675         delete widget;
01676         pls->dev = NULL;
01677     }
01678 
01679     closeQtApp();
01680 }
01681 
01682 void plD_eop_extqt( PLStream * /* pls */ )
01683 {
01684 }
01685 
01686 void plD_bop_extqt( PLStream *pls )
01687 {
01688     QtExtWidget * widget = NULL;
01689     widget = (QtExtWidget *) pls->dev;
01690     widget->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
01691 }
01692 #endif
01693 
01694 #if defined ( PLD_memqt )
01695 void plD_dispatch_init_memqt( PLDispatchTable *pdt )
01696 {
01697 #ifndef ENABLE_DYNDRIVERS
01698     pdt->pl_MenuStr = "Qt Memory Driver";
01699     pdt->pl_DevName = "memqt";
01700 #endif
01701     pdt->pl_type     = plDevType_FileOriented;
01702     pdt->pl_seq      = 76;
01703     pdt->pl_init     = (plD_init_fp) plD_init_memqt;
01704     pdt->pl_line     = (plD_line_fp) plD_line_rasterqt;
01705     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
01706     pdt->pl_eop      = (plD_eop_fp) plD_eop_memqt;
01707     pdt->pl_bop      = (plD_bop_fp) plD_bop_memqt;
01708     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_rasterqt;
01709     pdt->pl_state    = (plD_state_fp) plD_state_rasterqt;
01710     pdt->pl_esc      = (plD_esc_fp) plD_esc_rasterqt;
01711 }
01712 
01713 void plD_init_memqt( PLStream * pls )
01714 {
01715     int           i;
01716     double        dpi;
01717     unsigned char *qt_mem;
01718     unsigned char *input_mem;
01719 
01720     vectorize = 0;
01721     lines_aa  = 1;
01722     plParseDrvOpts( qt_options );
01723 
01724     // Stream setup
01725     pls->color        = 1;
01726     pls->plbuf_write  = 0;
01727     pls->dev_fill0    = 1;
01728     pls->dev_fill1    = 0;
01729     pls->dev_gradient = 1;      // driver renders gradient
01730     pls->dev_arc      = 1;      // driver renders arcs
01731     // Let the PLplot core handle dashed lines since
01732     // the driver results for this capability have a number of issues.
01733     // pls->dev_dash=1;
01734     pls->dev_dash  = 0;
01735     pls->dev_flush = 1;
01736     // Driver does not have a clear capability so use (good) PLplot core
01737     // fallback for that instead.
01738     pls->dev_clear         = 0;
01739     pls->termin            = 0;
01740     pls->page              = 0;
01741     pls->dev_text          = 1; // want to draw text
01742     pls->dev_unicode       = 1; // want unicode
01743     pls->has_string_length = 1; // Driver supports string length calculations
01744 
01745     // Needs to be true only because of multi-stream case
01746     bool isMaster = initQtApp( true );
01747 
01748     if ( pls->xdpi <= 0. )
01749         dpi = DEFAULT_DPI;
01750     else
01751         dpi = pls->xdpi;
01752 
01753     // Set the plot size to the memory buffer size, on the off chance
01754     // that they are different.
01755     pls->xlength = pls->phyxma;
01756     pls->ylength = pls->phyyma;
01757 
01758     // Save a pointer to the user supplied memory
01759     input_mem = (unsigned char *) pls->dev;
01760 
01761     // Create a appropriately sized raster device
01762     pls->dev = new QtRasterDevice( pls->xlength, pls->ylength );
01763     ( (QtRasterDevice *) pls->dev )->setPLStream( pls );
01764     ( (QtRasterDevice *) pls->dev )->memory = input_mem;
01765 
01766     if ( isMaster )
01767         handler.setMasterDevice( (QtRasterDevice *) ( pls->dev ) );
01768 
01769     if ( pls->xlength > pls->ylength )
01770         ( (QtRasterDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->xlength / (PLFLT) ( PIXELS_X - 1 );
01771     else
01772         ( (QtRasterDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->ylength / (PLFLT) PIXELS_Y;
01773 
01774     plP_setphy( (PLINT) 0, (PLINT) ( pls->xlength / ( (QtRasterDevice *) ( pls->dev ) )->downscale ), (PLINT) 0, (PLINT) ( pls->ylength / ( (QtRasterDevice *) ( pls->dev ) )->downscale ) );
01775 
01776     plP_setpxl( dpi / 25.4 / ( (QtRasterDevice *) ( pls->dev ) )->downscale, dpi / 25.4 / ( (QtRasterDevice *) ( pls->dev ) )->downscale );
01777 
01778     // Copy the user supplied memory into the QImage.
01779 //       This device assumes that the format of the QImage
01780 //       is RGB32 (or ARGB).
01781 
01782     qt_mem = ( (QtRasterDevice *) pls->dev )->scanLine( 0 );
01783 
01784     for ( i = 0; i < ( pls->xlength * pls->ylength ); i++ )
01785     {
01786         qt_mem[2] = input_mem[0]; // R
01787         qt_mem[1] = input_mem[1]; // G
01788         qt_mem[0] = input_mem[2]; // B
01789         if ( pls->dev_mem_alpha == 1 )
01790         {
01791             qt_mem[3]  = input_mem[3];
01792             input_mem += 4;
01793         }
01794         else
01795         {
01796             input_mem += 3;
01797         }
01798         qt_mem += 4;
01799     }
01800 
01801     ( (QtRasterDevice *) ( pls->dev ) )->setResolution( dpi );
01802 
01803     // This is set so the we'll always make it past the qt_family_check().
01804     pls->family = true;
01805 }
01806 
01807 void plD_bop_memqt( PLStream * /* pls */ )
01808 {
01809     // Do nothing to preserve user data
01810 }
01811 
01812 void plD_eop_memqt( PLStream *pls )
01813 {
01814     int           i;
01815     unsigned char *memory;
01816     unsigned char *qt_mem;
01817 
01818     memory = ( (QtRasterDevice *) pls->dev )->memory;
01819     qt_mem = ( (QtRasterDevice *) pls->dev )->scanLine( 0 );
01820 
01821     for ( i = 0; i < ( pls->xlength * pls->ylength ); i++ )
01822     {
01823         memory[0] = qt_mem[2];           // R
01824         memory[1] = qt_mem[1];           // G
01825         memory[2] = qt_mem[0];           // B
01826         if ( pls->dev_mem_alpha == 1 )
01827         {
01828             memory[3] = qt_mem[3];
01829             memory   += 4;
01830         }
01831         else
01832         {
01833             memory += 3;
01834         }
01835         qt_mem += 4;
01836     }
01837 }
01838 
01839 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines