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