1 //
2 //
3 // This software is provided under the LGPL in March 2009 by the
4 // Cluster Science Centre
5 // QSAS team,
6 // Imperial College, London
7 //
8 // Copyright (C) 2009 Imperial College, London
9 // Copyright (C) 2009-2019 Alan W. Irwin
10 // Copyright (C) 2009 Werner Smekal
11 // Copyright (C) 2009-2012 Andrew Ross
12 // Copyright (C) 2009-2011 Hazen Babcock
13 // Copyright (C) 2010 Hezekiah M. Carty
14 // Copyright (C) 2015 Jim Dishaw
15 // Copyright (C) 2019 António R. Tomé
16 //
17 // This is free software; you can redistribute it and/or modify
18 // it under the terms of the GNU General Lesser Public License as published
19 // by the Free Software Foundation; either version 2 of the License, or
20 // (at your option) any later version.
21 //
22 // This software is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 // GNU Lesser General Public License for more details.
26 //
27 // To received a copy of the GNU Library General Public License
28 // write to the Free Software Foundation, Inc.,
29 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 //
31 // History:
32 //
33 //
34 // March 2009: v1.00
35 // Initial release.
36 //
37 //
38
39
40 #include "qt.h"
41 #include <QMutexLocker>
42
43 // Global variables used in initQtApp (which is called by all
44 // plD_init_* routines other than plD_init_extqt) and used in
45 // closeQtApp (which is called by all plD_tidy_* routines other than
46 // plD_tidy_extqt). The use of these global variables is kept thread-safe by
47 // a QMutexLocker used by both initQtApp and closeQtApp.
48 static int argc;
49 static char **argv;
50 static int internal_qAppCounter = 0;
51 static bool internal_qApp = false;
52
53 // Drivers declaration
54 extern "C" {
55 PLDLLIMPEXP_DRIVER_DATA( const char* ) plD_DEVICE_INFO_qt =
56 #if defined ( PLD_bmpqt )
57 "bmpqt:Qt Windows bitmap driver:0:qt:66:bmpqt\n"
58 #endif
59 #if defined ( PLD_jpgqt )
60 "jpgqt:Qt jpg driver:0:qt:67:jpgqt\n"
61 #endif
62 #if defined ( PLD_pngqt )
63 "pngqt:Qt png driver:0:qt:68:pngqt\n"
64 #endif
65 #if defined ( PLD_ppmqt )
66 "ppmqt:Qt ppm driver:0:qt:69:ppmqt\n"
67 #endif
68 #if defined ( PLD_tiffqt )
69 "tiffqt:Qt tiff driver:0:qt:70:tiffqt\n"
70 #endif
71 #if defined ( PLD_svgqt ) && QT_VERSION >= 0x040300
72 "svgqt:Qt SVG driver:0:qt:71:svgqt\n"
73 #endif
74 #if defined ( PLD_qtwidget )
75 "qtwidget:Qt Widget:1:qt:72:qtwidget\n"
76 #endif
77 #if defined ( PLD_epsqt )
78 "epsqt:Qt EPS driver:0:qt:73:epsqt\n"
79 #endif
80 #if defined ( PLD_pdfqt )
81 "pdfqt:Qt PDF driver:0:qt:74:pdfqt\n"
82 #endif
83 #if defined ( PLD_extqt )
84 "extqt:External Qt driver:0:qt:75:extqt\n"
85 #endif
86 #if defined ( PLD_memqt )
87 "memqt:Memory Qt driver:0:qt:76:memqt\n"
88 #endif
89 ;
90 } // extern "C"
91
92 static DrvOpt qt_options[] = { { "text_vectorize", DRV_INT, &vectorize, "Vectorize fonts on output (0|1)" },
93 { "lines_antialiasing", DRV_INT, &lines_aa, "Toggles antialiasing on lines (0|1)" },
94 { NULL, DRV_INT, NULL, NULL } };
95
96 // The purpose of this routine is to create an internal qApp and the argc and argv data
97 // that qApp needs if an external or internal qApp does not exist already.
98
initQtApp(bool isGUI)99 bool initQtApp( bool isGUI )
100 {
101 QMutexLocker locker( &QtPLDriver::mutex );
102 bool res = false;
103
104 if ( qApp == NULL && internal_qAppCounter == 0 )
105 {
106 internal_qApp = true;
107 argc = 1;
108 argv = new char*[2];
109 argv[0] = new char[10];
110 argv[1] = new char[1];
111 snprintf( argv[0], 10, "qt_driver" );
112 argv[1][0] = '\0';
113 #ifdef Q_WS_X11
114 // On X11 if DISPLAY is not set then cannot open GUI. This allows non-interactive devices to still work in this case.
115 if ( getenv( "DISPLAY" ) == NULL )
116 isGUI = false;
117 #endif
118 new QApplication( argc, argv, isGUI );
119 res = true;
120 }
121
122 // Keep track of the number of uses of the internal qApp.
123 if ( internal_qApp )
124 ++internal_qAppCounter;
125
126 return res;
127 }
128
129 // The purpose of this routine is to delete qApp and associated argv
130 // if those were created internally by initQtApp and if it is the last
131 // use (kept track of by internal_qAppCounter) of that qApp.
closeQtApp()132 void closeQtApp()
133 {
134 QMutexLocker locker( &QtPLDriver::mutex );
135 if ( internal_qApp )
136 {
137 --internal_qAppCounter;
138 if ( qApp != NULL && internal_qAppCounter == 0 )
139 {
140 delete qApp;
141 delete[] argv[0];
142 delete[] argv[1];
143 delete[] argv;
144 argv = NULL;
145 }
146 }
147 }
148
149 //--------------------------------------------------------------------------
150 // qt_family_check ()
151 //
152 // support function to help supress more than one page if family file
153 // output not specified by the user (e.g., with the -fam command-line option).
154 // Adapted directly from svg.c
155 //--------------------------------------------------------------------------
156 static int already_warned = 0;
qt_family_check(PLStream * pls)157 static int qt_family_check( PLStream *pls )
158 {
159 if ( pls->family || pls->page == 1 )
160 {
161 return 0;
162 }
163 else
164 {
165 if ( !already_warned )
166 {
167 already_warned = 1;
168 plwarn( "All pages after the first skipped because family file output not specified.\n" );
169 }
170 return 1;
171 }
172 }
173
174 // Declaration of the driver-specific interface functions
175 #if defined ( PLD_bmpqt ) || defined ( PLD_jpgqt ) || defined ( PLD_pngqt ) || defined ( PLD_ppmqt ) || defined ( PLD_tiffqt ) || defined ( PLD_memqt )
176 void plD_init_rasterqt( PLStream * );
177 void plD_eop_rasterqt( PLStream * );
178 void plD_line_rasterqt( PLStream *, short, short, short, short );
179 void plD_polyline_rasterqt( PLStream *, short*, short*, PLINT );
180 void plD_tidy_rasterqt( PLStream * );
181 void plD_state_rasterqt( PLStream *, PLINT );
182 void plD_esc_rasterqt( PLStream *, PLINT, void* );
183 #endif
184
185 #if defined ( PLD_bmpqt )
186 void plD_dispatch_init_bmpqt( PLDispatchTable *pdt );
187 void plD_bop_bmpqt( PLStream * );
188 #endif
189
190 #if defined ( PLD_jpgqt )
191 void plD_dispatch_init_jpgqt( PLDispatchTable *pdt );
192 void plD_bop_jpgqt( PLStream * );
193 #endif
194
195 #if defined ( PLD_pngqt )
196 void plD_dispatch_init_pngqt( PLDispatchTable *pdt );
197 void plD_bop_pngqt( PLStream * );
198 #endif
199
200 #if defined ( PLD_ppmqt )
201 void plD_dispatch_init_ppmqt( PLDispatchTable *pdt );
202 void plD_bop_ppmqt( PLStream * );
203 #endif
204
205 #if defined ( PLD_tiffqt )
206 void plD_dispatch_init_tiffqt( PLDispatchTable *pdt );
207 void plD_bop_tiffqt( PLStream * );
208 #endif
209
210 #if defined ( PLD_svgqt ) && QT_VERSION >= 0x040300
211 void plD_dispatch_init_svgqt( PLDispatchTable *pdt );
212 void plD_init_svgqt( PLStream * );
213 void plD_bop_svgqt( PLStream * );
214 void plD_eop_svgqt( PLStream * );
215 void plD_line_svgqt( PLStream *, short, short, short, short );
216 void plD_polyline_svgqt( PLStream *, short*, short*, PLINT );
217 void plD_tidy_svgqt( PLStream * );
218 void plD_state_svgqt( PLStream *, PLINT );
219 void plD_esc_svgqt( PLStream *, PLINT, void* );
220 #endif
221
222 #if defined ( PLD_epsqt ) || defined ( PLD_pdfqt )
223 void plD_init_epspdfqt( PLStream * );
224 void plD_bop_epspdfqt_helper( PLStream *, int ifeps );
225 void plD_eop_epspdfqt( PLStream * );
226 void plD_line_epspdfqt( PLStream *, short, short, short, short );
227 void plD_polyline_epspdfqt( PLStream *, short*, short*, PLINT );
228 void plD_tidy_epspdfqt( PLStream * );
229 void plD_state_epspdfqt( PLStream *, PLINT );
230 void plD_esc_epspdfqt( PLStream *, PLINT, void* );
231 #endif
232 #if defined ( PLD_epsqt )
233 void plD_dispatch_init_epsqt( PLDispatchTable *pdt );
234 void plD_bop_epsqt( PLStream * );
235 #endif
236 #if defined ( PLD_pdfqt )
237 void plD_dispatch_init_pdfqt( PLDispatchTable *pdt );
238 void plD_bop_pdfqt( PLStream * );
239 #endif
240
241 #if defined ( PLD_qtwidget )
242 void plD_dispatch_init_qtwidget( PLDispatchTable *pdt );
243 void plD_init_qtwidget( PLStream * );
244 void plD_eop_qtwidget( PLStream * );
245 void plD_wait_qtwidget( PLStream * );
246 void plD_line_qtwidget( PLStream *, short, short, short, short );
247 void plD_polyline_qtwidget( PLStream *, short*, short*, PLINT );
248 void plD_tidy_qtwidget( PLStream * );
249 void plD_state_qtwidget( PLStream *, PLINT );
250 void plD_esc_qtwidget( PLStream *, PLINT, void* );
251 void plD_bop_qtwidget( PLStream * );
252 #endif
253
254 #if defined ( PLD_extqt )
255 void plD_dispatch_init_extqt( PLDispatchTable *pdt );
256 void plD_init_extqt( PLStream * );
257 void plD_eop_extqt( PLStream * );
258 void plD_line_extqt( PLStream *, short, short, short, short );
259 void plD_polyline_extqt( PLStream *, short*, short*, PLINT );
260 void plD_tidy_extqt( PLStream * );
261 void plD_state_extqt( PLStream *, PLINT );
262 void plD_esc_extqt( PLStream *, PLINT, void* );
263 void plD_bop_extqt( PLStream * );
264 #endif
265
266 #if defined ( PLD_memqt )
267 void plD_dispatch_init_memqt( PLDispatchTable *pdt );
268 void plD_init_memqt( PLStream * );
269 void plD_bop_memqt( PLStream * );
270 void plD_eop_memqt( PLStream * );
271 #endif
272
273 ////////////////// Raster driver-specific definitions: class and interface functions /////////
274 #if defined ( PLD_bmpqt ) || defined ( PLD_jpgqt ) || defined ( PLD_pngqt ) || defined ( PLD_ppmqt ) || defined ( PLD_tiffqt ) || defined ( PLD_memqt )
plD_init_rasterqt(PLStream * pls)275 void plD_init_rasterqt( PLStream * pls )
276 {
277 double dpi;
278
279 vectorize = 0;
280 lines_aa = 1;
281 plParseDrvOpts( qt_options );
282
283 // Stream setup
284 pls->color = 1;
285 pls->plbuf_write = 0;
286 pls->dev_fill0 = 1;
287 pls->dev_fill1 = 0;
288 pls->dev_gradient = 1; // driver renders gradient
289 // Let the PLplot core handle dashed lines since
290 // the driver results for this capability have a number of issues.
291 // pls->dev_dash=1;
292 pls->dev_dash = 0;
293 pls->dev_flush = 1;
294 // Driver does not have a clear capability so use (good) PLplot core
295 // fallback for that instead.
296 pls->dev_clear = 0;
297 pls->termin = 0;
298 pls->page = 0;
299 pls->dev_text = 1; // want to draw text
300 pls->dev_unicode = 1; // want unicode
301 pls->has_string_length = 1; // Driver supports string length calculations
302
303 // Needs to be true only because of multi-stream case
304 bool isMaster = initQtApp( true );
305
306 if ( pls->xdpi <= 0. )
307 dpi = DEFAULT_DPI;
308 else
309 dpi = pls->xdpi;
310
311 // Shamelessly copied on the Cairo stuff :)
312 if ( pls->xlength <= 0 || pls->ylength <= 0 )
313 {
314 pls->dev = new QtRasterDevice;
315 pls->xlength = (PLINT) ( ( (QtRasterDevice *) ( pls->dev ) )->m_dWidth );
316 pls->ylength = (PLINT) ( ( (QtRasterDevice *) ( pls->dev ) )->m_dHeight );
317 }
318 else
319 {
320 pls->dev = new QtRasterDevice( pls->xlength, pls->ylength );
321 }
322 ( (QtRasterDevice *) pls->dev )->setPLStream( pls );
323
324 if ( isMaster )
325 handler.setMasterDevice( (QtRasterDevice *) ( pls->dev ) );
326
327 if ( pls->xlength > pls->ylength )
328 ( (QtRasterDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->xlength / (PLFLT) ( PIXELS_X - 1 );
329 else
330 ( (QtRasterDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->ylength / (PLFLT) PIXELS_Y;
331
332 plP_setphy( (PLINT) 0, (PLINT) ( pls->xlength / ( (QtRasterDevice *) ( pls->dev ) )->downscale ), (PLINT) 0, (PLINT) ( pls->ylength / ( (QtRasterDevice *) ( pls->dev ) )->downscale ) );
333
334 plP_setpxl( dpi / 25.4 / ( (QtRasterDevice *) ( pls->dev ) )->downscale, dpi / 25.4 / ( (QtRasterDevice *) ( pls->dev ) )->downscale );
335
336 ( (QtRasterDevice *) ( pls->dev ) )->setResolution( dpi );
337
338 // Initialize family file info
339 plFamInit( pls );
340
341 plOpenFile( pls );
342 }
343
plD_eop_rasterqt(PLStream * pls)344 void plD_eop_rasterqt( PLStream *pls )
345 {
346 if ( qt_family_check( pls ) )
347 {
348 return;
349 }
350 ( (QtRasterDevice *) pls->dev )->savePlot();
351 handler.DeviceChangedPage( (QtRasterDevice *) pls->dev );
352 }
353
plD_line_rasterqt(PLStream * pls,short x1a,short y1a,short x2a,short y2a)354 void plD_line_rasterqt( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
355 {
356 QtRasterDevice* widget = (QtRasterDevice *) pls->dev;
357
358 if ( widget != NULL && qt_family_check( pls ) )
359 {
360 return;
361 }
362 if ( widget == NULL )
363 return;
364
365 widget->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
366 widget->drawLine( x1a, y1a, x2a, y2a );
367 }
368
plD_polyline_rasterqt(PLStream * pls,short * xa,short * ya,PLINT npts)369 void plD_polyline_rasterqt( PLStream *pls, short *xa, short *ya, PLINT npts )
370 {
371 QtRasterDevice * widget = (QtRasterDevice *) pls->dev;
372
373 if ( widget != NULL && qt_family_check( pls ) )
374 {
375 return;
376 }
377 if ( widget == NULL )
378 return;
379
380 widget->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
381 widget->drawPolyline( xa, ya, npts );
382 }
383
plD_esc_rasterqt(PLStream * pls,PLINT op,void * ptr)384 void plD_esc_rasterqt( PLStream * pls, PLINT op, void* ptr )
385 {
386 short *xa, *ya;
387 unsigned char *r, *g, *b;
388 PLFLT *alpha;
389 PLINT i;
390 QtRasterDevice * widget = (QtRasterDevice *) pls->dev;
391 if ( widget != NULL && qt_family_check( pls ) )
392 {
393 return;
394 }
395 if ( widget == NULL )
396 return;
397
398 switch ( op )
399 {
400 // case PLESC_DASH:
401 // widget->setDashed(pls->nms, pls->mark, pls->space);
402 // widget->QtPLDriver::setColor(pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a);
403 // widget->drawPolyline(pls->dev_x, pls->dev_y, pls->dev_npts);
404 // widget->setSolid();
405 // break;
406
407 case PLESC_FILL:
408 xa = new short[pls->dev_npts];
409 ya = new short[pls->dev_npts];
410
411 for ( i = 0; i < pls->dev_npts; i++ )
412 {
413 xa[i] = pls->dev_x[i];
414 ya[i] = pls->dev_y[i];
415 }
416 widget->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
417 widget->drawPolygon( xa, ya, pls->dev_npts );
418
419 delete[] xa;
420 delete[] ya;
421 break;
422
423 case PLESC_GRADIENT:
424 xa = new short[pls->dev_npts];
425 ya = new short[pls->dev_npts];
426 r = new unsigned char[pls->ncol1];
427 g = new unsigned char[pls->ncol1];
428 b = new unsigned char[pls->ncol1];
429 alpha = new PLFLT[pls->ncol1];
430
431 for ( i = 0; i < pls->ncol1; i++ )
432 {
433 r[i] = pls->cmap1[i].r;
434 g[i] = pls->cmap1[i].g;
435 b[i] = pls->cmap1[i].b;
436 alpha[i] = pls->cmap1[i].a;
437 }
438 widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
439
440 for ( i = 0; i < pls->dev_npts; i++ )
441 {
442 xa[i] = pls->dev_x[i];
443 ya[i] = pls->dev_y[i];
444 }
445 widget->drawPolygon( xa, ya, pls->dev_npts );
446
447 delete[] xa;
448 delete[] ya;
449 delete[] r;
450 delete[] g;
451 delete[] b;
452 delete[] alpha;
453 break;
454
455 case PLESC_HAS_TEXT:
456 // call the generic ProcessString function
457 // ProcessString( pls, (EscText *)ptr );
458 widget->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
459 widget->drawText( (EscText *) ptr );
460 break;
461
462 default: break;
463 }
464 }
465
plD_state_rasterqt(PLStream * pls,PLINT op)466 void plD_state_rasterqt( PLStream * pls, PLINT op )
467 {
468 QtRasterDevice * widget = (QtRasterDevice *) pls->dev;
469 if ( widget != NULL && qt_family_check( pls ) )
470 {
471 return;
472 }
473 if ( widget == NULL )
474 return;
475
476 switch ( op )
477 {
478 case PLSTATE_WIDTH:
479 widget->setWidthF( pls->width );
480 break;
481
482 case PLSTATE_COLOR0:
483 ( (QtPLDriver *) widget )->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
484 break;
485
486 case PLSTATE_COLOR1:
487 ( (QtPLDriver *) widget )->QtPLDriver::setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
488 break;
489
490
491 default: break;
492 }
493 }
494
plD_tidy_rasterqt(PLStream * pls)495 void plD_tidy_rasterqt( PLStream * pls )
496 {
497 QtRasterDevice * widget = (QtRasterDevice *) pls->dev;
498
499 if ( widget != NULL )
500 {
501 handler.DeviceClosed( widget );
502 delete widget;
503 pls->dev = NULL;
504 }
505 plCloseFile( pls );
506
507 closeQtApp();
508 }
509 #endif
510
511 #if defined ( PLD_bmpqt )
plD_dispatch_init_bmpqt(PLDispatchTable * pdt)512 void plD_dispatch_init_bmpqt( PLDispatchTable *pdt )
513 {
514 #ifndef ENABLE_DYNDRIVERS
515 pdt->pl_MenuStr = "Qt Windows bitmap Driver";
516 pdt->pl_DevName = "bmpqt";
517 #endif
518 pdt->pl_type = plDevType_FileOriented;
519 pdt->pl_seq = 66;
520 pdt->pl_init = (plD_init_fp) plD_init_rasterqt;
521 pdt->pl_line = (plD_line_fp) plD_line_rasterqt;
522 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
523 pdt->pl_eop = (plD_eop_fp) plD_eop_rasterqt;
524 pdt->pl_bop = (plD_bop_fp) plD_bop_bmpqt;
525 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_rasterqt;
526 pdt->pl_state = (plD_state_fp) plD_state_rasterqt;
527 pdt->pl_esc = (plD_esc_fp) plD_esc_rasterqt;
528 }
529
plD_bop_bmpqt(PLStream * pls)530 void plD_bop_bmpqt( PLStream *pls )
531 {
532 // Plot familying stuff. Not really understood, just copying gd.c
533 plGetFam( pls );
534
535 pls->famadv = 1;
536 pls->page++;
537 if ( qt_family_check( pls ) )
538 {
539 return;
540 }
541 ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "BMP" );
542 ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
543 }
544 #endif
545
546 #if defined ( PLD_jpgqt )
plD_dispatch_init_jpgqt(PLDispatchTable * pdt)547 void plD_dispatch_init_jpgqt( PLDispatchTable *pdt )
548 {
549 #ifndef ENABLE_DYNDRIVERS
550 pdt->pl_MenuStr = "Qt jpg Driver";
551 pdt->pl_DevName = "jpgqt";
552 #endif
553 pdt->pl_type = plDevType_FileOriented;
554 pdt->pl_seq = 67;
555 pdt->pl_init = (plD_init_fp) plD_init_rasterqt;
556 pdt->pl_line = (plD_line_fp) plD_line_rasterqt;
557 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
558 pdt->pl_eop = (plD_eop_fp) plD_eop_rasterqt;
559 pdt->pl_bop = (plD_bop_fp) plD_bop_jpgqt;
560 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_rasterqt;
561 pdt->pl_state = (plD_state_fp) plD_state_rasterqt;
562 pdt->pl_esc = (plD_esc_fp) plD_esc_rasterqt;
563 }
564
plD_bop_jpgqt(PLStream * pls)565 void plD_bop_jpgqt( PLStream *pls )
566 {
567 // Plot familying stuff. Not really understood, just copying gd.c
568 plGetFam( pls );
569
570 pls->famadv = 1;
571 pls->page++;
572 if ( qt_family_check( pls ) )
573 {
574 return;
575 }
576 ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "JPG" );
577 ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
578 }
579 #endif
580
581 #if defined ( PLD_pngqt )
plD_dispatch_init_pngqt(PLDispatchTable * pdt)582 void plD_dispatch_init_pngqt( PLDispatchTable *pdt )
583 {
584 #ifndef ENABLE_DYNDRIVERS
585 pdt->pl_MenuStr = "Qt png Driver";
586 pdt->pl_DevName = "pngqt";
587 #endif
588 pdt->pl_type = plDevType_FileOriented;
589 pdt->pl_seq = 68;
590 pdt->pl_init = (plD_init_fp) plD_init_rasterqt;
591 pdt->pl_line = (plD_line_fp) plD_line_rasterqt;
592 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
593 pdt->pl_eop = (plD_eop_fp) plD_eop_rasterqt;
594 pdt->pl_bop = (plD_bop_fp) plD_bop_pngqt;
595 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_rasterqt;
596 pdt->pl_state = (plD_state_fp) plD_state_rasterqt;
597 pdt->pl_esc = (plD_esc_fp) plD_esc_rasterqt;
598 }
599
plD_bop_pngqt(PLStream * pls)600 void plD_bop_pngqt( PLStream *pls )
601 {
602 // Plot familying stuff. Not really understood, just copying gd.c
603 plGetFam( pls );
604
605 pls->famadv = 1;
606 pls->page++;
607 if ( qt_family_check( pls ) )
608 {
609 return;
610 }
611 ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "PNG" );
612 ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
613 }
614 #endif
615
616 #if defined ( PLD_ppmqt )
plD_dispatch_init_ppmqt(PLDispatchTable * pdt)617 void plD_dispatch_init_ppmqt( PLDispatchTable *pdt )
618 {
619 #ifndef ENABLE_DYNDRIVERS
620 pdt->pl_MenuStr = "Qt ppm Driver";
621 pdt->pl_DevName = "ppmqt";
622 #endif
623 pdt->pl_type = plDevType_FileOriented;
624 pdt->pl_seq = 69;
625 pdt->pl_init = (plD_init_fp) plD_init_rasterqt;
626 pdt->pl_line = (plD_line_fp) plD_line_rasterqt;
627 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
628 pdt->pl_eop = (plD_eop_fp) plD_eop_rasterqt;
629 pdt->pl_bop = (plD_bop_fp) plD_bop_ppmqt;
630 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_rasterqt;
631 pdt->pl_state = (plD_state_fp) plD_state_rasterqt;
632 pdt->pl_esc = (plD_esc_fp) plD_esc_rasterqt;
633 }
634
plD_bop_ppmqt(PLStream * pls)635 void plD_bop_ppmqt( PLStream *pls )
636 {
637 // Plot familying stuff. Not really understood, just copying gd.c
638 plGetFam( pls );
639
640 pls->famadv = 1;
641 pls->page++;
642 if ( qt_family_check( pls ) )
643 {
644 return;
645 }
646 ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "PPM" );
647 ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
648 }
649 #endif
650
651 #if defined ( PLD_tiffqt )
plD_dispatch_init_tiffqt(PLDispatchTable * pdt)652 void plD_dispatch_init_tiffqt( PLDispatchTable *pdt )
653 {
654 #ifndef ENABLE_DYNDRIVERS
655 pdt->pl_MenuStr = "Qt tiff Driver";
656 pdt->pl_DevName = "tiffqt";
657 #endif
658 pdt->pl_type = plDevType_FileOriented;
659 pdt->pl_seq = 70;
660 pdt->pl_init = (plD_init_fp) plD_init_rasterqt;
661 pdt->pl_line = (plD_line_fp) plD_line_rasterqt;
662 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
663 pdt->pl_eop = (plD_eop_fp) plD_eop_rasterqt;
664 pdt->pl_bop = (plD_bop_fp) plD_bop_tiffqt;
665 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_rasterqt;
666 pdt->pl_state = (plD_state_fp) plD_state_rasterqt;
667 pdt->pl_esc = (plD_esc_fp) plD_esc_rasterqt;
668 }
669
plD_bop_tiffqt(PLStream * pls)670 void plD_bop_tiffqt( PLStream *pls )
671 {
672 // Plot familying stuff. Not really understood, just copying gd.c
673 plGetFam( pls );
674
675 pls->famadv = 1;
676 pls->page++;
677 if ( qt_family_check( pls ) )
678 {
679 return;
680 }
681 ( (QtRasterDevice *) pls->dev )->definePlotName( pls->FileName, "TIFF" );
682 ( (QtRasterDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
683 }
684 #endif
685
686 #if defined ( PLD_svgqt ) && QT_VERSION >= 0x040300
plD_dispatch_init_svgqt(PLDispatchTable * pdt)687 void plD_dispatch_init_svgqt( PLDispatchTable *pdt )
688 {
689 #ifndef ENABLE_DYNDRIVERS
690 pdt->pl_MenuStr = "Qt SVG Driver";
691 pdt->pl_DevName = "svgqt";
692 #endif
693 pdt->pl_type = plDevType_FileOriented;
694 pdt->pl_seq = 71;
695 pdt->pl_init = (plD_init_fp) plD_init_svgqt;
696 pdt->pl_line = (plD_line_fp) plD_line_svgqt;
697 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_svgqt;
698 pdt->pl_eop = (plD_eop_fp) plD_eop_svgqt;
699 pdt->pl_bop = (plD_bop_fp) plD_bop_svgqt;
700 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_svgqt;
701 pdt->pl_state = (plD_state_fp) plD_state_svgqt;
702 pdt->pl_esc = (plD_esc_fp) plD_esc_svgqt;
703 }
704
plD_init_svgqt(PLStream * pls)705 void plD_init_svgqt( PLStream * pls )
706 {
707 vectorize = 1;
708 lines_aa = 1;
709 plParseDrvOpts( qt_options );
710
711 // Stream setup
712 pls->color = 1;
713 pls->plbuf_write = 0;
714 pls->dev_fill0 = 1;
715 pls->dev_fill1 = 0;
716 pls->dev_gradient = 1; // driver renders gradient
717 // Let the PLplot core handle dashed lines since
718 // the driver results for this capability have a number of issues.
719 // pls->dev_dash=1;
720 pls->dev_dash = 0;
721 pls->dev_flush = 1;
722 // Driver does not have a clear capability so use (good) PLplot core
723 // fallback for that instead.
724 pls->dev_clear = 0;
725 pls->termin = 0;
726 pls->page = 0;
727 pls->dev_text = 1; // want to draw text
728 pls->dev_unicode = 1; // want unicode
729 pls->has_string_length = 1; // Driver supports string length calculations
730
731 // Needs to be true only because of multi-stream case
732 bool isMaster = initQtApp( true );
733
734 if ( pls->xlength <= 0 || pls->ylength <= 0 )
735 {
736 pls->dev = new QtSVGDevice;
737 pls->xlength = (int) ( ( (QtSVGDevice *) ( pls->dev ) )->m_dWidth );
738 pls->ylength = (int) ( ( (QtSVGDevice *) ( pls->dev ) )->m_dHeight );
739 }
740 else
741 {
742 pls->dev = new QtSVGDevice( pls->xlength, pls->ylength );
743 }
744 ( (QtSVGDevice *) pls->dev )->setPLStream( pls );
745
746 if ( isMaster )
747 handler.setMasterDevice( (QtSVGDevice *) ( pls->dev ) );
748
749 if ( pls->xlength > pls->ylength )
750 ( (QtSVGDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->xlength / (PLFLT) ( PIXELS_X - 1 );
751 else
752 ( (QtSVGDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->ylength / (PLFLT) PIXELS_Y;
753
754 plP_setphy( (PLINT) 0, (PLINT) ( pls->xlength / ( (QtSVGDevice *) ( pls->dev ) )->downscale ), (PLINT) 0, (PLINT) ( pls->ylength / ( (QtSVGDevice *) ( pls->dev ) )->downscale ) );
755
756 plP_setpxl( POINTS_PER_INCH / 25.4 / ( (QtSVGDevice *) ( pls->dev ) )->downscale, POINTS_PER_INCH / 25.4 / ( (QtSVGDevice *) ( pls->dev ) )->downscale );
757
758 // Initialize family file info
759 plFamInit( pls );
760
761 plOpenFile( pls );
762 }
763
plD_bop_svgqt(PLStream * pls)764 void plD_bop_svgqt( PLStream *pls )
765 {
766 // Plot familying stuff. Not really understood, just copying gd.c
767 plGetFam( pls );
768
769 pls->famadv = 1;
770 pls->page++;
771 if ( qt_family_check( pls ) )
772 {
773 return;
774 }
775 ( (QtSVGDevice *) pls->dev )->definePlotName( pls->FileName );
776 ( (QtSVGDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
777 }
778
plD_eop_svgqt(PLStream * pls)779 void plD_eop_svgqt( PLStream *pls )
780 {
781 double downscale;
782 QSize s;
783
784 if ( qt_family_check( pls ) )
785 {
786 return;
787 }
788 ( (QtSVGDevice *) pls->dev )->savePlot();
789 // Once saved, we have to create a new device with the same properties
790 // to be able to plot another page.
791 downscale = ( (QtSVGDevice *) pls->dev )->downscale;
792 s = ( (QtSVGDevice *) pls->dev )->size();
793 bool isMaster = ( handler.isMasterDevice( (QtSVGDevice *) pls->dev ) );
794 delete ( (QtSVGDevice *) pls->dev );
795
796 pls->dev = new QtSVGDevice( s.width(), s.height() );
797 ( (QtSVGDevice *) pls->dev )->downscale = downscale;
798 ( (QtSVGDevice *) pls->dev )->setPLStream( pls );
799
800 if ( isMaster )
801 handler.setMasterDevice( (QtSVGDevice *) pls->dev );
802 handler.DeviceChangedPage( (QtSVGDevice *) pls->dev );
803 }
804
plD_line_svgqt(PLStream * pls,short x1a,short y1a,short x2a,short y2a)805 void plD_line_svgqt( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
806 {
807 QtSVGDevice* widget = (QtSVGDevice *) pls->dev;
808 if ( widget != NULL && qt_family_check( pls ) )
809 {
810 return;
811 }
812 if ( widget == NULL )
813 return;
814
815 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
816 widget->drawLine( x1a, y1a, x2a, y2a );
817 }
818
plD_polyline_svgqt(PLStream * pls,short * xa,short * ya,PLINT npts)819 void plD_polyline_svgqt( PLStream *pls, short *xa, short *ya, PLINT npts )
820 {
821 QtSVGDevice * widget = (QtSVGDevice *) pls->dev;
822 if ( widget != NULL && qt_family_check( pls ) )
823 {
824 return;
825 }
826 if ( widget == NULL )
827 return;
828
829 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
830 widget->drawPolyline( xa, ya, npts );
831 }
832
plD_esc_svgqt(PLStream * pls,PLINT op,void * ptr)833 void plD_esc_svgqt( PLStream * pls, PLINT op, void* ptr )
834 {
835 short *xa, *ya;
836 unsigned char *r, *g, *b;
837 PLFLT *alpha;
838 PLINT i;
839 QtSVGDevice * widget = (QtSVGDevice *) pls->dev;
840 if ( widget != NULL && qt_family_check( pls ) )
841 {
842 return;
843 }
844 if ( widget == NULL )
845 return;
846
847 switch ( op )
848 {
849 case PLESC_FILL:
850 xa = new short[pls->dev_npts];
851 ya = new short[pls->dev_npts];
852
853 for ( i = 0; i < pls->dev_npts; i++ )
854 {
855 xa[i] = pls->dev_x[i];
856 ya[i] = pls->dev_y[i];
857 }
858 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
859 widget->drawPolygon( xa, ya, pls->dev_npts );
860
861 delete[] xa;
862 delete[] ya;
863 break;
864
865 case PLESC_GRADIENT:
866 xa = new short[pls->dev_npts];
867 ya = new short[pls->dev_npts];
868 r = new unsigned char[pls->ncol1];
869 g = new unsigned char[pls->ncol1];
870 b = new unsigned char[pls->ncol1];
871 alpha = new PLFLT[pls->ncol1];
872
873 for ( i = 0; i < pls->ncol1; i++ )
874 {
875 r[i] = pls->cmap1[i].r;
876 g[i] = pls->cmap1[i].g;
877 b[i] = pls->cmap1[i].b;
878 alpha[i] = pls->cmap1[i].a;
879 }
880 widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
881
882 for ( i = 0; i < pls->dev_npts; i++ )
883 {
884 xa[i] = pls->dev_x[i];
885 ya[i] = pls->dev_y[i];
886 }
887 widget->drawPolygon( xa, ya, pls->dev_npts );
888
889 delete[] xa;
890 delete[] ya;
891 delete[] r;
892 delete[] g;
893 delete[] b;
894 delete[] alpha;
895 break;
896
897 case PLESC_HAS_TEXT:
898 // call the generic ProcessString function
899 // ProcessString( pls, (EscText *)ptr );
900 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
901 widget->drawText( (EscText *) ptr );
902 break;
903
904 default:
905 break;
906 }
907 }
908
plD_state_svgqt(PLStream * pls,PLINT op)909 void plD_state_svgqt( PLStream * pls, PLINT op )
910 {
911 QtSVGDevice * widget = (QtSVGDevice *) pls->dev;
912 if ( widget != NULL && qt_family_check( pls ) )
913 {
914 return;
915 }
916 if ( widget == NULL )
917 return;
918
919 switch ( op )
920 {
921 case PLSTATE_WIDTH:
922 widget->setWidthF( pls->width );
923 break;
924
925 case PLSTATE_COLOR0:
926 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
927 break;
928
929 case PLSTATE_COLOR1:
930 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
931 break;
932
933 default: break;
934 }
935 }
936
plD_tidy_svgqt(PLStream * pls)937 void plD_tidy_svgqt( PLStream * pls )
938 {
939 QtSVGDevice * widget = (QtSVGDevice *) pls->dev;
940
941 if ( widget != NULL )
942 {
943 handler.DeviceClosed( widget );
944 delete widget;
945 pls->dev = NULL;
946 }
947 plCloseFile( pls );
948
949 closeQtApp();
950 }
951 #endif
952
953 #if defined ( PLD_epsqt )
plD_dispatch_init_epsqt(PLDispatchTable * pdt)954 void plD_dispatch_init_epsqt( PLDispatchTable *pdt )
955 {
956 #ifndef ENABLE_DYNDRIVERS
957 pdt->pl_MenuStr = "Qt EPS Driver";
958 pdt->pl_DevName = "epsqt";
959 #endif
960 pdt->pl_type = plDevType_FileOriented;
961 pdt->pl_seq = 73;
962 pdt->pl_init = (plD_init_fp) plD_init_epspdfqt;
963 pdt->pl_line = (plD_line_fp) plD_line_epspdfqt;
964 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_epspdfqt;
965 pdt->pl_eop = (plD_eop_fp) plD_eop_epspdfqt;
966 pdt->pl_bop = (plD_bop_fp) plD_bop_epsqt;
967 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_epspdfqt;
968 pdt->pl_state = (plD_state_fp) plD_state_epspdfqt;
969 pdt->pl_esc = (plD_esc_fp) plD_esc_epspdfqt;
970 }
971 #endif
972
973 #if defined ( PLD_pdfqt )
plD_dispatch_init_pdfqt(PLDispatchTable * pdt)974 void plD_dispatch_init_pdfqt( PLDispatchTable *pdt )
975 {
976 #ifndef ENABLE_DYNDRIVERS
977 pdt->pl_MenuStr = "Qt PDF Driver";
978 pdt->pl_DevName = "pdfqt";
979 #endif
980 pdt->pl_type = plDevType_FileOriented;
981 pdt->pl_seq = 74;
982 pdt->pl_init = (plD_init_fp) plD_init_epspdfqt;
983 pdt->pl_line = (plD_line_fp) plD_line_epspdfqt;
984 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_epspdfqt;
985 pdt->pl_eop = (plD_eop_fp) plD_eop_epspdfqt;
986 pdt->pl_bop = (plD_bop_fp) plD_bop_pdfqt;
987 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_epspdfqt;
988 pdt->pl_state = (plD_state_fp) plD_state_epspdfqt;
989 pdt->pl_esc = (plD_esc_fp) plD_esc_epspdfqt;
990 }
991 #endif
992
993 #if defined ( PLD_epsqt ) || defined ( PLD_pdfqt )
plD_init_epspdfqt(PLStream * pls)994 void plD_init_epspdfqt( PLStream * pls )
995 {
996 vectorize = 0;
997 lines_aa = 1;
998 plParseDrvOpts( qt_options );
999
1000 // Stream setup
1001 pls->color = 1;
1002 pls->plbuf_write = 0;
1003 pls->dev_fill0 = 1;
1004 pls->dev_fill1 = 0;
1005 pls->dev_gradient = 1; // driver renders gradient
1006 pls->dev_arc = 1; // driver renders arcs
1007 // Let the PLplot core handle dashed lines since
1008 // the driver results for this capability have a number of issues.
1009 // pls->dev_dash=1;
1010 pls->dev_dash = 0;
1011 pls->dev_flush = 1;
1012 // Driver does not have a clear capability so use (good) PLplot core
1013 // fallback for that instead.
1014 pls->dev_clear = 0;
1015 pls->termin = 0;
1016 pls->page = 0;
1017 pls->dev_text = 1; // want to draw text
1018 pls->dev_unicode = 1; // want unicode
1019 pls->has_string_length = 1; // Driver supports string length calculations
1020
1021 // QPrinter devices won't create if there is no QApplication declared...
1022 // Needs to be true only because of multi-stream case
1023 bool isMaster = initQtApp( true );
1024
1025 if ( pls->xlength <= 0 || pls->ylength <= 0 )
1026 {
1027 pls->dev = new QtEPSDevice;
1028 pls->xlength = (int) ( ( (QtEPSDevice *) ( pls->dev ) )->m_dWidth );
1029 pls->ylength = (int) ( ( (QtEPSDevice *) ( pls->dev ) )->m_dHeight );
1030 }
1031 else
1032 {
1033 pls->dev = new QtEPSDevice( pls->xlength, pls->ylength );
1034 }
1035 ( (QtEPSDevice *) pls->dev )->setPLStream( pls );
1036
1037 if ( isMaster )
1038 handler.setMasterDevice( (QtEPSDevice *) ( pls->dev ) );
1039
1040 if ( pls->xlength > pls->ylength )
1041 ( (QtEPSDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->xlength / (PLFLT) ( PIXELS_X - 1 );
1042 else
1043 ( (QtEPSDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->ylength / (PLFLT) PIXELS_Y;
1044
1045 plP_setphy( (PLINT) 0, (PLINT) ( pls->xlength / ( (QtEPSDevice *) ( pls->dev ) )->downscale ), (PLINT) 0, (PLINT) ( pls->ylength / ( (QtEPSDevice *) ( pls->dev ) )->downscale ) );
1046
1047 plP_setpxl( POINTS_PER_INCH / 25.4 / ( (QtEPSDevice *) ( pls->dev ) )->downscale, POINTS_PER_INCH / 25.4 / ( (QtEPSDevice *) ( pls->dev ) )->downscale );
1048
1049 // Initialize family file info
1050 plFamInit( pls );
1051
1052 plOpenFile( pls );
1053 }
1054
plD_bop_epspdfqt_helper(PLStream * pls,int ifeps)1055 void plD_bop_epspdfqt_helper( PLStream *pls, int ifeps )
1056 {
1057 // Plot familying stuff. Not really understood, just copying gd.c
1058 plGetFam( pls );
1059
1060 pls->famadv = 1;
1061 pls->page++;
1062 if ( qt_family_check( pls ) )
1063 {
1064 return;
1065 }
1066 ( (QtEPSDevice *) pls->dev )->definePlotName( pls->FileName, ifeps );
1067 ( (QtEPSDevice *) pls->dev )->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
1068 }
1069
plD_eop_epspdfqt(PLStream * pls)1070 void plD_eop_epspdfqt( PLStream *pls )
1071 {
1072 double downscale;
1073
1074 if ( qt_family_check( pls ) )
1075 {
1076 return;
1077 }
1078 ( (QtEPSDevice *) pls->dev )->savePlot();
1079 // Once saved, we have to create a new device with the same properties
1080 // to be able to plot another page.
1081 downscale = ( (QtEPSDevice *) pls->dev )->downscale;
1082 bool isMaster = handler.isMasterDevice( (QtEPSDevice *) pls->dev );
1083 delete ( (QtEPSDevice *) pls->dev );
1084
1085 pls->dev = new QtEPSDevice;
1086 ( (QtEPSDevice *) pls->dev )->downscale = downscale;
1087
1088 if ( isMaster )
1089 handler.setMasterDevice( (QtEPSDevice *) pls->dev );
1090 handler.DeviceChangedPage( (QtEPSDevice *) pls->dev );
1091 }
1092
plD_line_epspdfqt(PLStream * pls,short x1a,short y1a,short x2a,short y2a)1093 void plD_line_epspdfqt( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
1094 {
1095 QtEPSDevice* widget = (QtEPSDevice *) pls->dev;
1096 if ( widget != NULL && qt_family_check( pls ) )
1097 {
1098 return;
1099 }
1100 if ( widget == NULL )
1101 return;
1102
1103 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1104 widget->drawLine( x1a, y1a, x2a, y2a );
1105 }
1106
plD_polyline_epspdfqt(PLStream * pls,short * xa,short * ya,PLINT npts)1107 void plD_polyline_epspdfqt( PLStream *pls, short *xa, short *ya, PLINT npts )
1108 {
1109 QtEPSDevice * widget = (QtEPSDevice *) pls->dev;
1110 if ( widget != NULL && qt_family_check( pls ) )
1111 {
1112 return;
1113 }
1114 if ( widget == NULL )
1115 return;
1116
1117 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1118 widget->drawPolyline( xa, ya, npts );
1119 }
1120
plD_esc_epspdfqt(PLStream * pls,PLINT op,void * ptr)1121 void plD_esc_epspdfqt( PLStream * pls, PLINT op, void* ptr )
1122 {
1123 short *xa, *ya;
1124 unsigned char *r, *g, *b;
1125 PLFLT *alpha;
1126 PLINT i;
1127 QtEPSDevice * widget = (QtEPSDevice *) pls->dev;
1128 arc_struct *arc_info = (arc_struct *) ptr;
1129
1130 if ( widget != NULL && qt_family_check( pls ) )
1131 {
1132 return;
1133 }
1134 if ( widget == NULL )
1135 return;
1136
1137 switch ( op )
1138 {
1139 case PLESC_FILL:
1140 xa = new short[pls->dev_npts];
1141 ya = new short[pls->dev_npts];
1142
1143 for ( i = 0; i < pls->dev_npts; i++ )
1144 {
1145 xa[i] = pls->dev_x[i];
1146 ya[i] = pls->dev_y[i];
1147 }
1148 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1149 widget->drawPolygon( xa, ya, pls->dev_npts );
1150
1151 delete[] xa;
1152 delete[] ya;
1153 break;
1154
1155 case PLESC_GRADIENT:
1156 xa = new short[pls->dev_npts];
1157 ya = new short[pls->dev_npts];
1158 r = new unsigned char[pls->ncol1];
1159 g = new unsigned char[pls->ncol1];
1160 b = new unsigned char[pls->ncol1];
1161 alpha = new PLFLT[pls->ncol1];
1162
1163 for ( i = 0; i < pls->ncol1; i++ )
1164 {
1165 r[i] = pls->cmap1[i].r;
1166 g[i] = pls->cmap1[i].g;
1167 b[i] = pls->cmap1[i].b;
1168 alpha[i] = pls->cmap1[i].a;
1169 }
1170 widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
1171
1172 for ( i = 0; i < pls->dev_npts; i++ )
1173 {
1174 xa[i] = pls->dev_x[i];
1175 ya[i] = pls->dev_y[i];
1176 }
1177 widget->drawPolygon( xa, ya, pls->dev_npts );
1178
1179 delete[] xa;
1180 delete[] ya;
1181 delete[] r;
1182 delete[] g;
1183 delete[] b;
1184 delete[] alpha;
1185 break;
1186
1187 case PLESC_HAS_TEXT:
1188 // call the generic ProcessString function
1189 // ProcessString( pls, (EscText *)ptr );
1190 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1191 widget->drawText( (EscText *) ptr );
1192 break;
1193
1194 case PLESC_ARC:
1195 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 );
1196 break;
1197
1198 default: break;
1199 }
1200 }
1201
plD_state_epspdfqt(PLStream * pls,PLINT op)1202 void plD_state_epspdfqt( PLStream * pls, PLINT op )
1203 {
1204 QtEPSDevice * widget = (QtEPSDevice *) pls->dev;
1205 if ( widget != NULL && qt_family_check( pls ) )
1206 {
1207 return;
1208 }
1209 if ( widget == NULL )
1210 return;
1211
1212 switch ( op )
1213 {
1214 case PLSTATE_WIDTH:
1215 widget->setWidthF( pls->width );
1216 break;
1217
1218 case PLSTATE_COLOR0:
1219 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1220 break;
1221
1222 case PLSTATE_COLOR1:
1223 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1224 break;
1225
1226
1227 default: break;
1228 }
1229 }
1230
plD_tidy_epspdfqt(PLStream * pls)1231 void plD_tidy_epspdfqt( PLStream * pls )
1232 {
1233 QtEPSDevice * widget = (QtEPSDevice *) pls->dev;
1234
1235 if ( widget != NULL )
1236 {
1237 handler.DeviceClosed( widget );
1238 delete widget;
1239 pls->dev = NULL;
1240 }
1241 plCloseFile( pls );
1242
1243 closeQtApp();
1244 }
1245 #endif
1246
1247 #if defined ( PLD_epsqt )
plD_bop_epsqt(PLStream * pls)1248 void plD_bop_epsqt( PLStream *pls )
1249 {
1250 plD_bop_epspdfqt_helper( pls, 1 );
1251 }
1252 #endif
1253
1254 #if defined ( PLD_pdfqt )
plD_bop_pdfqt(PLStream * pls)1255 void plD_bop_pdfqt( PLStream *pls )
1256 {
1257 plD_bop_epspdfqt_helper( pls, 0 );
1258 }
1259 #endif
1260
1261 #if defined ( PLD_qtwidget )
plD_dispatch_init_qtwidget(PLDispatchTable * pdt)1262 void plD_dispatch_init_qtwidget( PLDispatchTable *pdt )
1263 {
1264 #ifndef ENABLE_DYNDRIVERS
1265 pdt->pl_MenuStr = "Qt Widget";
1266 pdt->pl_DevName = "qtwidget";
1267 #endif
1268 pdt->pl_type = plDevType_Interactive;
1269 pdt->pl_seq = 72;
1270 pdt->pl_init = (plD_init_fp) plD_init_qtwidget;
1271 pdt->pl_line = (plD_line_fp) plD_line_qtwidget;
1272 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_qtwidget;
1273 pdt->pl_eop = (plD_eop_fp) plD_eop_qtwidget;
1274 pdt->pl_bop = (plD_bop_fp) plD_bop_qtwidget;
1275 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_qtwidget;
1276 pdt->pl_state = (plD_state_fp) plD_state_qtwidget;
1277 pdt->pl_esc = (plD_esc_fp) plD_esc_qtwidget;
1278 pdt->pl_wait = (plD_wait_fp) plD_wait_qtwidget;
1279 }
1280
plD_init_qtwidget(PLStream * pls)1281 void plD_init_qtwidget( PLStream * pls )
1282 {
1283 vectorize = 0;
1284 lines_aa = 1;
1285 plParseDrvOpts( qt_options );
1286
1287 bool isMaster = initQtApp( true );
1288 QtPLWidget* widget;
1289
1290 if ( pls->xlength <= 0 || pls->ylength <= 0 )
1291 {
1292 widget = new QtPLWidget;
1293 pls->dev = (void *) widget;
1294 pls->xlength = (int) widget->m_dWidth;
1295 pls->ylength = (int) widget->m_dHeight;
1296 }
1297 else
1298 {
1299 widget = new QtPLWidget( pls->xlength, pls->ylength );
1300 pls->dev = (void *) widget;
1301 }
1302 widget->setPLStream( pls );
1303
1304 if ( isMaster )
1305 handler.setMasterDevice( widget );
1306
1307 if ( plsc->xlength > plsc->ylength )
1308 widget->downscale = (PLFLT) plsc->xlength / (PLFLT) ( PIXELS_X - 1 );
1309 else
1310 widget->downscale = (PLFLT) plsc->ylength / (PLFLT) PIXELS_Y;
1311
1312 plP_setphy( (PLINT) 0, (PLINT) ( plsc->xlength / widget->downscale ), (PLINT) 0, (PLINT) ( plsc->ylength / widget->downscale ) );
1313
1314 QPicture temp;
1315 QPainter tempPainter( &temp );
1316
1317 plP_setpxl( temp.logicalDpiX() / 25.4 / widget->downscale, temp.logicalDpiY() / 25.4 / widget->downscale );
1318
1319 pls->color = 1; // Is a color device
1320 pls->plbuf_write = 1; // Store commands to device in core buffer
1321 pls->dev_fill0 = 1; // Handle solid fills
1322 pls->dev_fill1 = 0;
1323 pls->dev_gradient = 1; // driver renders gradient
1324 pls->dev_arc = 1; // driver renders arcs
1325 // Let the PLplot core handle dashed lines since
1326 // the driver results for this capability have a number of issues.
1327 // pls->dev_dash=1;
1328 pls->dev_dash = 0;
1329 pls->dev_flush = 1;
1330 // Driver does not have a clear capability so use (good) PLplot core
1331 // fallback for that instead.
1332 pls->dev_clear = 0;
1333 pls->termin = 1;
1334 pls->dev_text = 1; // want to draw text
1335 pls->dev_unicode = 1; // want unicode
1336 pls->has_string_length = 1; // Driver supports string length calculations
1337
1338 widget->setVisible( true );
1339 widget->resize( plsc->xlength, plsc->ylength );
1340 widget->move( plsc->xoffset, plsc->yoffset );
1341
1342 widget->setWindowTitle( pls->plwindow );
1343
1344 qApp->connect( &handler, SIGNAL( MasterChangedPage() ), widget, SLOT( nextPage() ) );
1345 qApp->connect( &handler, SIGNAL( MasterClosed() ), widget, SLOT( close() ) );
1346 }
1347
plD_eop_qtwidget(PLStream * pls)1348 void plD_eop_qtwidget( PLStream *pls )
1349 {
1350 QtPLWidget* widget = ( (QtPLWidget *) pls->dev );
1351
1352 widget->flush();
1353 widget->raise();
1354 }
1355
plD_wait_qtwidget(PLStream * pls)1356 void plD_wait_qtwidget( PLStream *pls )
1357 {
1358 QtPLWidget* widget = ( (QtPLWidget *) pls->dev );
1359 int currentPage = widget->pageNumber;
1360
1361 widget->raise();
1362 while ( currentPage == widget->pageNumber && handler.isMasterDevice( widget ) )
1363 {
1364 qApp->processEvents( QEventLoop::WaitForMoreEvents );
1365 }
1366 }
1367
plD_bop_qtwidget(PLStream * pls)1368 void plD_bop_qtwidget( PLStream *pls )
1369 {
1370 QtPLWidget* widget = ( (QtPLWidget *) pls->dev );
1371 widget->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
1372 }
1373
plD_line_qtwidget(PLStream * pls,short x1a,short y1a,short x2a,short y2a)1374 void plD_line_qtwidget( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
1375 {
1376 QtPLWidget* widget = (QtPLWidget *) pls->dev;
1377 if ( widget == NULL )
1378 return;
1379
1380 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1381 widget->drawLine( x1a, y1a, x2a, y2a );
1382 }
1383
plD_polyline_qtwidget(PLStream * pls,short * xa,short * ya,PLINT npts)1384 void plD_polyline_qtwidget( PLStream *pls, short *xa, short *ya, PLINT npts )
1385 {
1386 QtPLWidget * widget = (QtPLWidget *) pls->dev;
1387 if ( widget == NULL )
1388 return;
1389
1390 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1391 widget->drawPolyline( xa, ya, npts );
1392 }
1393
plD_esc_qtwidget(PLStream * pls,PLINT op,void * ptr)1394 void plD_esc_qtwidget( PLStream * pls, PLINT op, void* ptr )
1395 {
1396 short *xa, *ya;
1397 PLINT i;
1398 unsigned char *r, *g, *b;
1399 PLFLT *alpha;
1400 QtPLWidget * widget = (QtPLWidget *) pls->dev;
1401 arc_struct *arc_info = (arc_struct *) ptr;
1402 if ( widget == NULL )
1403 return;
1404
1405 switch ( op )
1406 {
1407 case PLESC_FILL:
1408 xa = new short[pls->dev_npts];
1409 ya = new short[pls->dev_npts];
1410
1411 for ( i = 0; i < pls->dev_npts; i++ )
1412 {
1413 xa[i] = pls->dev_x[i];
1414 ya[i] = pls->dev_y[i];
1415 }
1416
1417 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1418 widget->drawPolygon( xa, ya, pls->dev_npts );
1419
1420 delete[] xa;
1421 delete[] ya;
1422 break;
1423
1424 case PLESC_GRADIENT:
1425 xa = new short[pls->dev_npts];
1426 ya = new short[pls->dev_npts];
1427 r = new unsigned char[pls->ncol1];
1428 g = new unsigned char[pls->ncol1];
1429 b = new unsigned char[pls->ncol1];
1430 alpha = new PLFLT[pls->ncol1];
1431
1432 for ( i = 0; i < pls->ncol1; i++ )
1433 {
1434 r[i] = pls->cmap1[i].r;
1435 g[i] = pls->cmap1[i].g;
1436 b[i] = pls->cmap1[i].b;
1437 alpha[i] = pls->cmap1[i].a;
1438 }
1439 widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
1440
1441 for ( i = 0; i < pls->dev_npts; i++ )
1442 {
1443 xa[i] = pls->dev_x[i];
1444 ya[i] = pls->dev_y[i];
1445 }
1446 widget->drawPolygon( xa, ya, pls->dev_npts );
1447
1448 delete[] xa;
1449 delete[] ya;
1450 delete[] r;
1451 delete[] g;
1452 delete[] b;
1453 delete[] alpha;
1454 break;
1455
1456 case PLESC_HAS_TEXT:
1457 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1458 widget->drawText( (EscText *) ptr );
1459 break;
1460
1461 case PLESC_ARC:
1462 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 );
1463 break;
1464
1465 case PLESC_FLUSH:
1466 widget->flush();
1467 break;
1468 case PLESC_GETC:
1469 widget->getCursorCmd( (PLGraphicsIn *) ptr );
1470 break;
1471 default: break;
1472 }
1473 }
1474
plD_state_qtwidget(PLStream * pls,PLINT op)1475 void plD_state_qtwidget( PLStream * pls, PLINT op )
1476 {
1477 QtPLWidget * widget = (QtPLWidget *) pls->dev;
1478 if ( widget == NULL )
1479 return;
1480
1481 switch ( op )
1482 {
1483 case PLSTATE_WIDTH:
1484 widget->setWidthF( pls->width );
1485 break;
1486
1487 case PLSTATE_COLOR0:
1488 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1489 break;
1490
1491 case PLSTATE_COLOR1:
1492 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1493 break;
1494
1495
1496 default: break;
1497 }
1498 }
1499
plD_tidy_qtwidget(PLStream * pls)1500 void plD_tidy_qtwidget( PLStream * pls )
1501 {
1502 QtPLWidget * widget = (QtPLWidget *) pls->dev;
1503
1504 if ( widget != NULL )
1505 {
1506 handler.DeviceClosed( widget );
1507 delete widget;
1508 pls->dev = NULL;
1509 }
1510
1511 closeQtApp();
1512 }
1513 #endif
1514
1515 #if defined ( PLD_extqt )
plD_dispatch_init_extqt(PLDispatchTable * pdt)1516 void plD_dispatch_init_extqt( PLDispatchTable *pdt )
1517 {
1518 #ifndef ENABLE_DYNDRIVERS
1519 pdt->pl_MenuStr = "External Qt Widget";
1520 pdt->pl_DevName = "extqt";
1521 #endif
1522 pdt->pl_type = plDevType_Interactive;
1523 pdt->pl_seq = 75;
1524 pdt->pl_init = (plD_init_fp) plD_init_extqt;
1525 pdt->pl_line = (plD_line_fp) plD_line_extqt;
1526 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_extqt;
1527 pdt->pl_eop = (plD_eop_fp) plD_eop_extqt;
1528 pdt->pl_bop = (plD_bop_fp) plD_bop_extqt;
1529 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_extqt;
1530 pdt->pl_state = (plD_state_fp) plD_state_extqt;
1531 pdt->pl_esc = (plD_esc_fp) plD_esc_extqt;
1532 }
1533
plD_init_extqt(PLStream * pls)1534 void plD_init_extqt( PLStream * pls )
1535 {
1536 // N.B. initQtApp() not called here because internal_qApp is always false
1537 // for this device.
1538 vectorize = 0;
1539 lines_aa = 1;
1540
1541 if ( pls->dev == NULL /* || pls->xlength <= 0 || pls->ylength <= 0*/ )
1542 {
1543 printf( "Error: use plsetqtdev to set up the Qt device before calling plinit()\n" );
1544 return;
1545 }
1546
1547 QtExtWidget* widget = (QtExtWidget *) ( pls->dev );
1548
1549 if ( widget->m_dWidth > widget->m_dHeight )
1550 widget->downscale = (PLFLT) widget->m_dWidth / (PLFLT) ( PIXELS_X - 1 );
1551 else
1552 widget->downscale = (PLFLT) widget->m_dHeight / (PLFLT) PIXELS_Y;
1553
1554 plP_setphy( (PLINT) 0, (PLINT) ( widget->m_dWidth / widget->downscale ), (PLINT) 0, (PLINT) ( widget->m_dHeight / widget->downscale ) );
1555
1556 QPicture temp;
1557 QPainter tempPainter( &temp );
1558
1559 plP_setpxl( temp.logicalDpiX() / 25.4 / widget->downscale, temp.logicalDpiY() / 25.4 / widget->downscale );
1560
1561 pls->color = 1; // Is a color device
1562 pls->plbuf_write = 0;
1563 pls->dev_fill0 = 1; // Handle solid fills
1564 pls->dev_fill1 = 0;
1565 pls->dev_gradient = 1; // driver renders gradient
1566 pls->dev_arc = 1; // driver renders arcs
1567 // Let the PLplot core handle dashed lines since
1568 // the driver results for this capability have a number of issues.
1569 // pls->dev_dash=1;
1570 pls->dev_dash = 0;
1571 pls->dev_flush = 1;
1572 // Driver does not have a clear capability so use (good) PLplot core
1573 // fallback for that instead.
1574 pls->dev_clear = 0;
1575 pls->termin = 0;
1576 pls->dev_text = 1; // want to draw text
1577 pls->dev_unicode = 1; // want unicode
1578 pls->has_string_length = 1; // Driver supports string length calculations
1579 }
1580
1581 //
1582 // These functions are separated out (instead of using dynamic_cast)
1583 // for the benefit of the PyQt4 bindings. C++ QtExtWidgets created
1584 // by PyQt4 are not properly type resolved.
1585 //
1586
plD_line_extqt(PLStream * pls,short x1a,short y1a,short x2a,short y2a)1587 void plD_line_extqt( PLStream * pls, short x1a, short y1a, short x2a, short y2a )
1588 {
1589 QtExtWidget * widget = NULL;
1590
1591 widget = (QtExtWidget *) pls->dev;
1592 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1593 widget->drawLine( x1a, y1a, x2a, y2a );
1594 }
1595
plD_polyline_extqt(PLStream * pls,short * xa,short * ya,PLINT npts)1596 void plD_polyline_extqt( PLStream *pls, short *xa, short *ya, PLINT npts )
1597 {
1598 QtExtWidget * widget = NULL;
1599
1600 widget = (QtExtWidget *) pls->dev;
1601 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1602 widget->drawPolyline( xa, ya, npts );
1603 }
1604
plD_esc_extqt(PLStream * pls,PLINT op,void * ptr)1605 void plD_esc_extqt( PLStream * pls, PLINT op, void* ptr )
1606 {
1607 short *xa, *ya;
1608 PLINT i;
1609 unsigned char *r, *g, *b;
1610 PLFLT *alpha;
1611 QtExtWidget * widget = NULL;
1612 arc_struct *arc_info = (arc_struct *) ptr;
1613
1614 widget = (QtExtWidget *) pls->dev;
1615 switch ( op )
1616 {
1617 case PLESC_FILL:
1618 xa = new short[pls->dev_npts];
1619 ya = new short[pls->dev_npts];
1620
1621 for ( i = 0; i < pls->dev_npts; i++ )
1622 {
1623 xa[i] = pls->dev_x[i];
1624 ya[i] = pls->dev_y[i];
1625 }
1626 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1627 widget->drawPolygon( xa, ya, pls->dev_npts );
1628
1629 delete[] xa;
1630 delete[] ya;
1631 break;
1632
1633 case PLESC_GRADIENT:
1634 xa = new short[pls->dev_npts];
1635 ya = new short[pls->dev_npts];
1636 r = new unsigned char[pls->ncol1];
1637 g = new unsigned char[pls->ncol1];
1638 b = new unsigned char[pls->ncol1];
1639 alpha = new PLFLT[pls->ncol1];
1640
1641 for ( i = 0; i < pls->ncol1; i++ )
1642 {
1643 r[i] = pls->cmap1[i].r;
1644 g[i] = pls->cmap1[i].g;
1645 b[i] = pls->cmap1[i].b;
1646 alpha[i] = pls->cmap1[i].a;
1647 }
1648 widget->setGradient( pls->xgradient[0], pls->xgradient[1], pls->ygradient[0], pls->ygradient[1], r, g, b, alpha, pls->ncol1 );
1649
1650 for ( i = 0; i < pls->dev_npts; i++ )
1651 {
1652 xa[i] = pls->dev_x[i];
1653 ya[i] = pls->dev_y[i];
1654 }
1655 widget->drawPolygon( xa, ya, pls->dev_npts );
1656
1657 delete[] xa;
1658 delete[] ya;
1659 delete[] r;
1660 delete[] g;
1661 delete[] b;
1662 delete[] alpha;
1663 break;
1664
1665 case PLESC_HAS_TEXT:
1666 // call the generic ProcessString function
1667 // ProcessString( pls, (EscText *)ptr );
1668 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1669 widget->drawText( (EscText *) ptr );
1670 break;
1671
1672 case PLESC_ARC:
1673 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 );
1674 break;
1675
1676 default: break;
1677 }
1678 }
1679
plD_state_extqt(PLStream * pls,PLINT op)1680 void plD_state_extqt( PLStream * pls, PLINT op )
1681 {
1682 QtExtWidget * widget = NULL;
1683
1684 widget = (QtExtWidget *) pls->dev;
1685 switch ( op )
1686 {
1687 case PLSTATE_WIDTH:
1688 widget->setWidthF( pls->width );
1689 break;
1690
1691 case PLSTATE_COLOR0:
1692 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1693 break;
1694
1695 case PLSTATE_COLOR1:
1696 widget->setColor( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b, pls->curcolor.a );
1697 break;
1698
1699
1700 default: break;
1701 }
1702 }
1703
plD_tidy_extqt(PLStream * pls)1704 void plD_tidy_extqt( PLStream * pls )
1705 {
1706 QtExtWidget * widget = NULL;
1707
1708 widget = (QtExtWidget *) pls->dev;
1709 if ( widget != NULL )
1710 {
1711 handler.DeviceClosed( widget );
1712 delete widget;
1713 pls->dev = NULL;
1714 }
1715
1716 // closeQtApp() not called here because internal_qApp is always false
1717 // for this device.
1718 }
1719
plD_eop_extqt(PLStream *)1720 void plD_eop_extqt( PLStream * /* pls */ )
1721 {
1722 }
1723
plD_bop_extqt(PLStream * pls)1724 void plD_bop_extqt( PLStream *pls )
1725 {
1726 QtExtWidget * widget = NULL;
1727 widget = (QtExtWidget *) pls->dev;
1728 widget->setBackgroundColor( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b, pls->cmap0[0].a );
1729 }
1730 #endif
1731
1732 #if defined ( PLD_memqt )
plD_dispatch_init_memqt(PLDispatchTable * pdt)1733 void plD_dispatch_init_memqt( PLDispatchTable *pdt )
1734 {
1735 #ifndef ENABLE_DYNDRIVERS
1736 pdt->pl_MenuStr = "Qt Memory Driver";
1737 pdt->pl_DevName = "memqt";
1738 #endif
1739 pdt->pl_type = plDevType_FileOriented;
1740 pdt->pl_seq = 76;
1741 pdt->pl_init = (plD_init_fp) plD_init_memqt;
1742 pdt->pl_line = (plD_line_fp) plD_line_rasterqt;
1743 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_rasterqt;
1744 pdt->pl_eop = (plD_eop_fp) plD_eop_memqt;
1745 pdt->pl_bop = (plD_bop_fp) plD_bop_memqt;
1746 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_rasterqt;
1747 pdt->pl_state = (plD_state_fp) plD_state_rasterqt;
1748 pdt->pl_esc = (plD_esc_fp) plD_esc_rasterqt;
1749 }
1750
plD_init_memqt(PLStream * pls)1751 void plD_init_memqt( PLStream * pls )
1752 {
1753 int i;
1754 double dpi;
1755 unsigned char *qt_mem;
1756 unsigned char *input_mem;
1757
1758 vectorize = 0;
1759 lines_aa = 1;
1760 plParseDrvOpts( qt_options );
1761
1762 // Stream setup
1763 pls->color = 1;
1764 pls->plbuf_write = 0;
1765 pls->dev_fill0 = 1;
1766 pls->dev_fill1 = 0;
1767 pls->dev_gradient = 1; // driver renders gradient
1768 pls->dev_arc = 1; // driver renders arcs
1769 // Let the PLplot core handle dashed lines since
1770 // the driver results for this capability have a number of issues.
1771 // pls->dev_dash=1;
1772 pls->dev_dash = 0;
1773 pls->dev_flush = 1;
1774 // Driver does not have a clear capability so use (good) PLplot core
1775 // fallback for that instead.
1776 pls->dev_clear = 0;
1777 pls->termin = 0;
1778 pls->page = 0;
1779 pls->dev_text = 1; // want to draw text
1780 pls->dev_unicode = 1; // want unicode
1781 pls->has_string_length = 1; // Driver supports string length calculations
1782
1783 // Needs to be true only because of multi-stream case
1784 bool isMaster = initQtApp( true );
1785
1786 if ( pls->xdpi <= 0. )
1787 dpi = DEFAULT_DPI;
1788 else
1789 dpi = pls->xdpi;
1790
1791 // Set the plot size to the memory buffer size, on the off chance
1792 // that they are different.
1793 pls->xlength = pls->phyxma;
1794 pls->ylength = pls->phyyma;
1795
1796 // Save a pointer to the user supplied memory
1797 input_mem = (unsigned char *) pls->dev;
1798
1799 // Create a appropriately sized raster device
1800 pls->dev = new QtRasterDevice( pls->xlength, pls->ylength );
1801 ( (QtRasterDevice *) pls->dev )->setPLStream( pls );
1802 ( (QtRasterDevice *) pls->dev )->memory = input_mem;
1803
1804 if ( isMaster )
1805 handler.setMasterDevice( (QtRasterDevice *) ( pls->dev ) );
1806
1807 if ( pls->xlength > pls->ylength )
1808 ( (QtRasterDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->xlength / (PLFLT) ( PIXELS_X - 1 );
1809 else
1810 ( (QtRasterDevice *) ( pls->dev ) )->downscale = (PLFLT) pls->ylength / (PLFLT) PIXELS_Y;
1811
1812 plP_setphy( (PLINT) 0, (PLINT) ( pls->xlength / ( (QtRasterDevice *) ( pls->dev ) )->downscale ), (PLINT) 0, (PLINT) ( pls->ylength / ( (QtRasterDevice *) ( pls->dev ) )->downscale ) );
1813
1814 plP_setpxl( dpi / 25.4 / ( (QtRasterDevice *) ( pls->dev ) )->downscale, dpi / 25.4 / ( (QtRasterDevice *) ( pls->dev ) )->downscale );
1815
1816 // Copy the user supplied memory into the QImage.
1817 // This device assumes that the format of the QImage
1818 // is RGB32 (or ARGB).
1819
1820 qt_mem = ( (QtRasterDevice *) pls->dev )->scanLine( 0 );
1821
1822 for ( i = 0; i < ( pls->xlength * pls->ylength ); i++ )
1823 {
1824 qt_mem[2] = input_mem[0]; // R
1825 qt_mem[1] = input_mem[1]; // G
1826 qt_mem[0] = input_mem[2]; // B
1827 if ( pls->dev_mem_alpha == 1 )
1828 {
1829 qt_mem[3] = input_mem[3];
1830 input_mem += 4;
1831 }
1832 else
1833 {
1834 input_mem += 3;
1835 }
1836 qt_mem += 4;
1837 }
1838
1839 ( (QtRasterDevice *) ( pls->dev ) )->setResolution( dpi );
1840
1841 // This is set so the we'll always make it past the qt_family_check().
1842 pls->family = true;
1843 }
1844
plD_bop_memqt(PLStream *)1845 void plD_bop_memqt( PLStream * /* pls */ )
1846 {
1847 // Do nothing to preserve user data
1848 }
1849
plD_eop_memqt(PLStream * pls)1850 void plD_eop_memqt( PLStream *pls )
1851 {
1852 int i;
1853 unsigned char *memory;
1854 unsigned char *qt_mem;
1855
1856 memory = ( (QtRasterDevice *) pls->dev )->memory;
1857 qt_mem = ( (QtRasterDevice *) pls->dev )->scanLine( 0 );
1858
1859 for ( i = 0; i < ( pls->xlength * pls->ylength ); i++ )
1860 {
1861 memory[0] = qt_mem[2]; // R
1862 memory[1] = qt_mem[1]; // G
1863 memory[2] = qt_mem[0]; // B
1864 if ( pls->dev_mem_alpha == 1 )
1865 {
1866 memory[3] = qt_mem[3];
1867 memory += 4;
1868 }
1869 else
1870 {
1871 memory += 3;
1872 }
1873 qt_mem += 4;
1874 }
1875 }
1876
1877 #endif
1878