QtViewImp.cxx
Go to the documentation of this file.
1 
13 // inconsistent dll linkage
14 #ifdef _MSC_VER
15 #include "msdevstudio/MSconfig.h"
16 #endif
17 
18 #include "QtViewImp.h"
19 
20 #include "DrawBorder.h"
21 #include "PlotterEvent.h"
22 #include "QtFont.h"
23 
24 #include "axes/Range.h"
25 #include "graphics/Color.h"
26 #include "plotters/PlotterBase.h"
27 
28 #include <qapplication.h>
29 #include <qpainter.h>
30 #include <qpixmap.h>
31 #include <qwmatrix.h>
32 
33 #include <qfile.h>
34 #include <qdir.h>
35 #include <qdatetime.h>
36 
37 #if QT_VERSION < 0x040000
38 #include <qpointarray.h>
39 #else
40 #include <QtGui/QPolygon>
41 #include <QtCore/QTextStream>
42 #endif
43 
44 #include <cassert>
45 #include <cstdlib>
46 
47 using namespace hippodraw;
48 
49 using std::vector;
50 
51 std::map < Line::Style, Qt::PenStyle > QtViewImp::s_line_style;
52 
55  :DataView (),
56  m_inspector ( 0 ),
57  m_painter ( 0 ),
58  m_font_default ( "helvetica" )
59 {
60  if ( s_line_style.empty () ) {
61  s_line_style [ Line::Solid ] = Qt::SolidLine;
62  s_line_style [ Line::Dash ] = Qt::DashLine;
63  s_line_style [ Line::Dot ] = Qt::DotLine;
64  s_line_style [ Line::DashDot ] = Qt::DashDotLine;
65  s_line_style [ Line::DashDotDot ] = Qt::DashDotDotLine;
66  s_line_style [ Line::Invisible ] = Qt::NoPen;
67  }
68  m_eq_png.clear();
69 }
70 
71 
73 QtViewImp ( PlotterBase * plotter )
74  : DataView ( plotter ),
75  m_inspector ( 0 ),
76  m_painter ( 0 ),
77  m_font_default ( "helvetica" )
78 {
79  if ( s_line_style.empty () ) {
80  s_line_style [ Line::Solid ] = Qt::SolidLine;
81  s_line_style [ Line::Dash ] = Qt::DashLine;
82  s_line_style [ Line::Dot ] = Qt::DotLine;
83  s_line_style [ Line::DashDot ] = Qt::DashDotLine;
84  s_line_style [ Line::DashDotDot ] = Qt::DashDotDotLine;
85  s_line_style [ Line::Invisible ] = Qt::NoPen;
86  }
87  m_eq_png.clear();
88 }
89 
90 void
92 setInspector ( QObject * inspector )
93 {
94  m_inspector = inspector;
95 }
96 
97 void
99 update ( const Observable * display )
100 {
101  if ( display == 0 ) return;
102 
103  if ( m_inspector != 0 ) {
104  Observable * o = const_cast < Observable * > ( display );
105  PlotterBase * plotter = dynamic_cast < PlotterBase * > ( o );
106  PlotterEvent * event = new PlotterEvent ( plotter );
109  }
110 
111 }
112 
113 float QtViewImp::userToDrawXAutoInv ( double xx ) const
114 {
115  if (m_plotter -> isReverse())
116  return userToInvertedMarginX( xx );
117  else
118  return userToMarginX( xx );
119 }
120 
121 float QtViewImp::userToDrawX ( double xx ) const
122 {
123  return userToMarginX( xx );
124 }
125 
126 float QtViewImp::userToDrawY ( double yy ) const
127 {
128  return userToInvertedMarginY( yy );
129 }
130 
131 float QtViewImp::userToDrawColor ( double c ) const
132 {
133  return userToMarginColor( c );
134 }
135 
136 void
137 QtViewImp::
138 #if QT_VERSION < 0x040000
139 transformAndFill ( QPointArray & array,
140 #else
141 transformAndFill ( QPolygon & array,
142 #endif
143  const std::vector< double > & x,
144  const std::vector< double > & y,
145  int (QtViewImp::* xfunc) ( double ) const,
146  int (QtViewImp::* yfunc) ( double ) const )
147 {
148  unsigned int size = x.size();
149  assert ( size == y.size() );
150 
151  for ( unsigned int i = 0; i < size; i++ ) {
152  int ix = (this->*xfunc) ( x[i] );
153  int iy = (this->*yfunc) ( y[i] );
154 
155  array.setPoint ( i , ix, iy );
156  }
157 
158 }
159 
162 void
164 drawViewMethod ( const std::vector< double > & x,
165  const std::vector< double > & y,
166  int, int )
167 {
168 
169  unsigned int size = x.size();
170  assert ( size == y.size() );
171 
172 #if QT_VERSION < 0x040000
173  QPointArray array ( size );
174 #else
175  QPolygon array ( size );
176 #endif
177  transformAndFill ( array, x, y,
179 
180  m_painter->drawLineSegments ( array );
181 
182 }
183 
184 
187 void
189 drawMethod ( const std::vector < double > & x,
190  const std::vector < double > & y,
191  int, // style,
192  int ) //color )
193 {
194 
195  unsigned int size = x.size();
196  assert ( size == y.size() );
197 
198 #if QT_VERSION < 0x040000
199  QPointArray array ( size );
200 #else
201  QPolygon array ( size );
202 #endif
203  transformAndFill ( array, x, y,
205 
206  m_painter->drawPolyline ( array, 0, -1 );
207 }
208 
209 
210 void
212 drawPoints ( const std::vector<double> & x,
213  const std::vector<double> & y,
215  float sym_size,
216  const Color & color )
217 {
218  m_painter->save();
219 
220  int i_sym_size = (int)(sym_size/2);
221 
222  int rgb[3];
223  rgb[0] = color.getRed();
224  rgb[1] = color.getGreen();
225  rgb[2] = color.getBlue();
226  QColor qcolor ( rgb[0], rgb[1], rgb[2] );
227 
228  m_painter->setPen ( qcolor );
229 
230 #if QT_VERSION < 0x040000
231  QPointArray triangleArray ( 3 );
232 #else
233  QPolygon triangleArray ( 3 );
234 #endif
235 
236  for (unsigned int i = 0; i < x.size(); i++)
237  {
238  int originX = toViewX ( x[i] );
239  int originY = toViewY ( y[i] );
240 
241  switch ( type )
242  {
243 
244 
245 
246  case Symbol::SOLIDSQUARE:
247 
248  m_painter->fillRect ( ( toViewX (x[i]) - (i_sym_size) ),
249  ( toViewY (y[i]) - (i_sym_size) ),
250  (i_sym_size*2 + 1 ),
251  (i_sym_size*2 + 1 ),
252  ( qcolor ) );
253 
254  break;
255 
256 
257 
258  case Symbol::SQUARE:
259  m_painter -> drawRect ( toViewX ( x[i] ) - i_sym_size,
260  toViewY ( y[i] ) - i_sym_size,
261  2*i_sym_size + 1,
262  2*i_sym_size + 1 );
263  break;
264 
265  case Symbol::TRIANGLE:
266  triangleArray.setPoint ( 0, ( toViewX (x[i]) ),
267  ( toViewY (y[i]) + (i_sym_size) ) );
268 
269  triangleArray.setPoint ( 1, ( toViewX (x[i]) + (i_sym_size) ),
270  ( toViewY (y[i]) - (i_sym_size) ) );
271 
272 
273  triangleArray.setPoint ( 2, ( toViewX (x[i]) - (i_sym_size) ),
274  ( toViewY (y[i]) - (i_sym_size) ) );
275 
276  m_painter -> setBrush ( Qt::NoBrush );
277  m_painter->drawPolygon (triangleArray);
278  break;
279 
281 
282  triangleArray.setPoint ( 0, ( toViewX (x[i]) ),
283  ( toViewY (y[i]) + (i_sym_size) ) );
284 
285  triangleArray.setPoint ( 1, ( toViewX (x[i]) + (i_sym_size) ),
286  ( toViewY (y[i]) - (i_sym_size) ) );
287 
288 
289  triangleArray.setPoint ( 2, ( toViewX (x[i]) - (i_sym_size) ),
290  ( toViewY (y[i]) - (i_sym_size) ) );
291 
292  m_painter->setBrush (qcolor);
293 
294  m_painter->drawPolygon (triangleArray);
295 
296  break;
297 
298 
299  case Symbol::CIRCLE:
300 
301  m_painter->drawEllipse ( ( toViewX (x[i]) - (i_sym_size) ),
302  ( toViewY (y[i]) - (i_sym_size) ),
303  ( i_sym_size*2 + 1 ),
304  ( i_sym_size*2 + 1 ) );
305 
306  break;
307 
308 
310 
311  m_painter->setBrush (qcolor);
312 
313  m_painter->drawPie ( ( toViewX (x[i]) - (i_sym_size) ),
314  ( toViewY (y[i]) - (i_sym_size) ),
315  ( i_sym_size*2 + 1 ),
316  ( i_sym_size*2 + 1 ),
317  ( 16 * 0 ),
318  ( 16 * 360 ) );
319 
320  break;
321 
322  case Symbol::PLUS:
323  m_painter -> drawLine ( originX - i_sym_size, originY,
324  originX + i_sym_size, originY );
325  m_painter -> drawLine ( originX, originY - i_sym_size,
326  originX, originY + i_sym_size );
327  break;
328 
329  case Symbol::TIMES:
330  m_painter -> drawLine ( originX - i_sym_size, originY - i_sym_size,
331  originX + i_sym_size, originY + i_sym_size );
332  m_painter -> drawLine ( originX + i_sym_size, originY - i_sym_size,
333  originX - i_sym_size, originY + i_sym_size );
334  break;
335 
336  default:
337  break;
338 
339  }
340  }
341 
342  m_painter->restore();
343 
344 }
345 
348 void
350 drawPoints ( const std::vector< double > &,
351  const std::vector< double > &,
352  Symbol::Type,
353  float )
354 {
355 
356 }
357 
365 void
367 drawPoints ( const std::vector< double > & x,
368  const std::vector< double > & y,
369  const std::vector< Color > & colors,
371  float sym_size )
372 {
373  assert ( x.size() == colors.size() );
374  m_painter->save();
375 
376  int i_sym_size = (int)(sym_size/2);
377 
378  if ( i_sym_size == 0 &&
379  type == Symbol::SOLIDSQUARE ) {
380  type = Symbol::SQUARE;
381  }
382 
383 #if QT_VERSION < 0x040000
384  QPointArray triangleArray ( 3 );
385 #else
386  QPolygon triangleArray ( 3 );
387 #endif
388 
389  for (unsigned int i = 0; i < x.size(); i++)
390  {
391  int o_x = toViewX ( x[i] );
392  int o_y = toViewY ( y[i] );
393 
394  const Color & c = colors[i];
395  QColor qcolor ( c.getRed (), c.getGreen(), c.getBlue () );
396  m_painter->setPen ( qcolor );
397 
398  switch ( type )
399  {
400  case Symbol::SOLIDSQUARE:
401  m_painter->fillRect ( ( toViewX (x[i]) - (i_sym_size) ),
402  ( toViewY (y[i]) - (i_sym_size) ),
403  (i_sym_size*2 ),
404  (i_sym_size*2 ),
405  ( qcolor ) );
406 
407  break;
408 
409  case Symbol::SQUARE:
410  m_painter -> drawRect ( o_x -i_sym_size, o_y - i_sym_size,
411  2 * i_sym_size, 2 * i_sym_size );
412  break;
413 
414 
415 
416  case Symbol::TRIANGLE:
417  triangleArray.setPoint ( 0, ( toViewX (x[i]) ),
418  ( toViewY (y[i]) + (i_sym_size) ) );
419 
420  triangleArray.setPoint ( 1, ( toViewX (x[i]) + (i_sym_size) ),
421  ( toViewY (y[i]) - (i_sym_size) ) );
422 
423 
424  triangleArray.setPoint ( 2, ( toViewX (x[i]) - (i_sym_size) ),
425  ( toViewY (y[i]) - (i_sym_size) ) );
426 
427  m_painter->setBrush ( Qt::NoBrush );
428  m_painter->drawPolygon (triangleArray);
429 
430  break;
431 
432 
433 
435 
436  triangleArray.setPoint ( 0, ( toViewX (x[i]) ),
437  ( toViewY (y[i]) + (i_sym_size) ) );
438 
439  triangleArray.setPoint ( 1, ( toViewX (x[i]) + (i_sym_size) ),
440  ( toViewY (y[i]) - (i_sym_size) ) );
441 
442 
443  triangleArray.setPoint ( 2, ( toViewX (x[i]) - (i_sym_size) ),
444  ( toViewY (y[i]) - (i_sym_size) ) );
445 
446  m_painter->setBrush (qcolor);
447 
448  m_painter->drawPolygon (triangleArray);
449 
450  break;
451 
452 
453  case Symbol::CIRCLE:
454 
455  m_painter->drawEllipse ( ( toViewX (x[i]) - (i_sym_size) ),
456  ( toViewY (y[i]) - (i_sym_size) ),
457  (i_sym_size*2 ),
458  (i_sym_size*2 ) );
459 
460  break;
461 
462 
464 
465  m_painter->setBrush (qcolor);
466 
467  m_painter->drawPie ( ( toViewX (x[i]) - (i_sym_size) ),
468  ( toViewY (y[i]) - (i_sym_size) ),
469  ( i_sym_size*2 ),
470  ( i_sym_size*2 ),
471  ( 16 * 0 ),
472  ( 16 * 360 ) );
473 
474  break;
475 
476  case Symbol::PLUS:
477  m_painter -> drawLine ( o_x - i_sym_size, o_y,
478  o_x + i_sym_size, o_y );
479  m_painter -> drawLine ( o_x, o_y - i_sym_size,
480  o_x, o_y + i_sym_size );
481  break;
482 
483  case Symbol::TIMES:
484  m_painter -> drawLine ( o_x - i_sym_size, o_y - i_sym_size,
485  o_x + i_sym_size, o_y + i_sym_size );
486  m_painter -> drawLine ( o_x + i_sym_size, o_y - i_sym_size,
487  o_x - i_sym_size, o_y + i_sym_size );
488  break;
489 
490  default:
491  break;
492 
493  }
494  }
495 
496  m_painter->restore();
497 
498 }
499 
500 QPen
502 createPen ( const Color & color, float size, Line::Style style )
503 {
504  int rgb[3];
505  rgb[0] = color.getRed();
506  rgb[1] = color.getGreen();
507  rgb[2] = color.getBlue();
508  QColor qcolor ( rgb[0], rgb[1], rgb[2] );
509 
510  unsigned int isize = static_cast < unsigned int > ( size );
511  Qt::PenStyle pen_style = s_line_style [ style ];
512 
513  return QPen ( qcolor, isize, pen_style );
514 }
515 
516 void
518 drawPolygon ( const std::vector < double > & x,
519  const std::vector < double > & y,
520  const Color & color,
521  const Color & edge
522  )
523 {
524  m_painter->save();
525 
526  unsigned int size = x.size();
527  assert ( size == y.size() );
528 
529  int rgb[3];
530  rgb[0] = color.getRed();
531  rgb[1] = color.getGreen();
532  rgb[2] = color.getBlue();
533  QColor qcolor ( rgb[0], rgb[1], rgb[2] );
534 
535  int rgb2[3];
536  rgb2[0] = edge.getRed();
537  rgb2[1] = edge.getGreen();
538  rgb2[2] = edge.getBlue();
539  QColor qcolor2 ( rgb2[0], rgb2[1], rgb2[2] );
540 
541 #if QT_VERSION < 0x040000
542  QPointArray array ( size );
543 #else
544  QPolygon array ( size );
545 #endif
546  transformAndFill ( array, x, y,
548 
549  m_painter->setBrush(qcolor);
550  m_painter->setPen(qcolor2);
551  m_painter->drawPolygon(array);
552 
553  m_painter->restore();
554 
555 }
556 
557 void
559 drawPolyLine ( const std::vector< double > & x,
560  const std::vector< double > & y,
561  Line::Style style,
562  const Color & color,
563  float size )
564 {
565  m_painter->save();
566 
567  QPen pen = createPen ( color, size, style );
568  m_painter->setPen ( pen );
569  m_painter -> setBrush ( Qt::NoBrush );
570  drawMethod ( x, y, style, 0 );
571 
572  m_painter->restore();
573 
574 }
575 
576 void
578 drawLines ( const std::vector< double > & x,
579  const std::vector< double > & y,
580  Line::Style style,
581  const Color & color,
582  float size )
583 {
584 
585  m_painter->save();
586 
587  QPen pen = createPen ( color, size, style );
588  m_painter->setPen ( pen );
589 
590  unsigned int xsize = x.size();
591  assert ( xsize == y.size() );
592 
593 #if QT_VERSION < 0x040000
594  QPointArray array ( xsize );
595 #else
596  QPolygon array ( xsize );
597 #endif
598  transformAndFill ( array, x, y,
600 
601  m_painter->drawLineSegments ( array );
602 
603  m_painter->restore();
604 
605 }
606 
607 void
609 drawColorLines ( const std::vector< double > & x,
610  const std::vector< double > & y,
611  Line::Style style,
612  const std::vector < Color > & colors,
613  float size )
614 {
615  unsigned int ssize = x.size();
616  assert ( ssize == y.size() );
617  assert ( ssize == colors.size() );
618 
619  for ( unsigned int i = 0; i < ssize; i+=2 ) {
620 
621  m_painter->save();
622  const Color & color = colors[i];
623  QColor qcolor ( color.getRed (), color.getGreen (), color.getBlue() );
624  QPen pen ( qcolor, static_cast < int > (size) );
625  Qt::PenStyle pen_style = s_line_style [ style ];
626  pen.setStyle ( pen_style );
627  m_painter->setPen ( pen );
628 
629  int x1 = toViewX ( x[i] );
630  int x2 = toViewX ( x[i+1] );
631  int y1 = toViewY ( y[i] );
632  int y2 = toViewY ( y[i+1] );
633  m_painter->drawLine ( x1, y1, x2, y2 );
634 
635  m_painter->restore();
636 
637  }
638 
639 }
640 
643 void
645 drawViewLines ( const std::vector< double > & x,
646  const std::vector< double > & y,
647  Line::Style style,
648  bool,
649  float size )
650 {
651 
652  m_painter->save();
653 
654  QPen pen ( (m_painter->pen()).color(), (int)(size) );
655  Qt::PenStyle pen_style = s_line_style [ style ];
656  pen.setStyle ( pen_style );
657  m_painter->setPen ( pen );
658 
659  drawViewMethod ( x, y, style, 0 ); // last argument was default color
660 
661  m_painter->restore();
662 
663 }
664 
665 void
667 drawViewLines ( const std::vector< double > & x,
668  const std::vector< double > & y,
669  Line::Style style,
670  const Color & color,
671  float size )
672 {
673 
674  m_painter->save();
675 
676  QPen pen = createPen ( color, size, style );
677  m_painter->setPen ( pen );
678 
679  unsigned int xsize = x.size();
680  assert ( xsize == y.size() );
681 
682 #if QT_VERSION < 0x040000
683  QPointArray array ( xsize );
684 #else
685  QPolygon array ( xsize );
686 #endif
687  transformAndFill ( array, x, y,
689 
690  m_painter->drawLineSegments ( array );
691 
692  m_painter->restore();
693 
694 }
695 
696 void
698 draw_Text ( const std::string &s,
699  float xx, float yy, float fontsize,
700  float angle, char xp, char yp, bool resize,
701  QFont & font, const QColor & color )
702 {
703  assert ( fontsize > 0 );
704  int i_x = static_cast< int > ( xx );
705  int i_y = static_cast< int > ( yy );
706  int i_font = static_cast < int > ( fontsize );
707 
708  if ( fontsize > 0 ) {
709  font.setPointSize( i_font );
710  font.setPixelSize( i_font );
711  }
712 
713  if ( m_painter == 0 ) return;
714 
715  m_painter->setFont ( font );
716 
717  m_painter -> setPen ( color );
718 
719  QString qstring ( s.c_str() );
720 
721  QFontMetrics metrics1 ( font );
722  QRect new_rect1 = metrics1.boundingRect ( qstring );
723  int h1 = new_rect1.height ();
724  if ( fontsize > 0 ) {
725  while ( h1 >= fontsize ){
726 
727  i_font-- ;
728 
729  if ( i_font < 1 ) break;
730 
731  font.setPixelSize ( i_font );
732 
733  QFontMetrics metrics2 ( font );
734  QRect new_rect2 = metrics2.boundingRect ( qstring );
735  int h2 = new_rect2.height ();
736 
737  h1 = h2;
738  }
739  }
740 
741  if ( resize == true ) {
742 
743  // This part of the code makes sense only for TextReps. Nobody else
744  // should call draw_Text with resize == true. It will not
745  // work if the text rep draws the strings that appear on the bottom of
746  // the display before the ones that appear near the top.
747 
748  QFontMetrics metrics ( font );
749  QRect new_rect = metrics.boundingRect ( qstring );
750 #if QT_VERSION < 0x040000
751  int lines = qstring.contains ( "\n" );
752 #else
753  int lines = qstring.count();
754 #endif
755  QStringList sl = QStringList::split ( '\n', qstring );
756  int maxw = 0;
757 #if QT_VERSION < 0x040000
758  for ( QValueList<QString>::size_type i = 0; i < sl.count (); i++ ) {
759 #else
760  for ( QList<QString>::size_type i = 0; i < sl.count (); i++ ) {
761 #endif
762  QString s = sl[i];
763  QRect sr = metrics.boundingRect ( s );
764  maxw = std::max ( maxw, sr.width () );
765  }
766  int w = new_rect.width ();
767  int h = new_rect.height ();
768  h *= ( lines + 1 );
769  Rect rect = getDrawRect ();
770 
771  // fix the height if this is not top string
772  int delta_y = i_y - static_cast < int > ( rect.getY () );
773  if ( delta_y > 0 ) {
774  h += delta_y;
775  }
776 
777  // fix the width if this is not left positioned string
778  int delta_x = i_x - static_cast < int > ( rect.getX () );
779  if ( delta_x > 0 ) {
780  w += delta_x;
781  }
782  // need a little extra of the width for some reason.
783 #ifdef _MSC_VER
784  maxw *= 1.6;
785 #endif
786  setDrawRect ( rect.getX (), rect.getY (), 1.2 * maxw, 4. * h );
787  }
788 
789  Rect rect = getDrawRect ();
790 
791  int i_w = static_cast < int > ( rect.getWidth () );
792  int i_h = static_cast < int > ( rect.getHeight () );
793 
794  QRect text_rect = m_painter->boundingRect ( 0, 0,
795  i_h, i_w,
796  Qt::AlignLeft | Qt::AlignTop,
797  qstring );
798  int dx = 0;
799  int dy = 0;
800 
801  if ( angle == 0.0 )
802  {
803 
804  switch ( xp ) {
805  case 'l' :
806  case 'L' :
807  dx = i_x;
808  break;
809  case 'c' :
810  case 'C' :
811  dx = i_x - text_rect.width () / 2;
812  break;
813  case 'r' :
814  case 'R' :
815  dx = i_x - text_rect.width ();
816  break;
817  default:
818  dx = i_x;
819  }
820 
821  switch ( yp ) {
822  case 't' :
823  case 'T' :
824  dy = i_y;
825  break;
826  case 'c' :
827  case 'C' :
828  dy = i_y - text_rect.height () / 2;
829  break;
830  case 'b' :
831  case 'B' :
832  dy = i_y - text_rect.height ();
833  break;
834  default:
835  dy = i_y;
836  }
837 
838  text_rect.moveBy ( dx, dy );
839  text_rect.setWidth ( text_rect.width() + 2 );
840  text_rect.setHeight ( text_rect.height() + 2 );
841 
842  m_painter->drawText ( text_rect, Qt::AlignLeft | Qt::AlignTop,
843  qstring );
844  }
845 
846  else // angle not 0.0
847  {
848  m_painter->save();
849 
850  m_painter->translate ( i_x, i_y );
851 
852  m_painter->rotate ( - angle );
853 
854  switch ( xp ) {
855  case 'l' :
856  case 'L' :
857  dx = 0;
858  break;
859  case 'c' :
860  case 'C' :
861  dx = 0 - text_rect.width () / 2;
862  break;
863  case 'r' :
864  case 'R' :
865  dx = 0 - text_rect.width ();
866  break;
867  default:
868  dx = 0;
869  }
870 
871  switch ( yp ) {
872  case 't' :
873  case 'T' :
874  dy = 0;
875  break;
876  case 'c' :
877  case 'C' :
878  dy = 0 - text_rect.height () / 2;
879  break;
880  case 'b' :
881  case 'B' :
882  dy = 0 - text_rect.height ();
883  break;
884  default:
885  dy = 0;
886  }
887 
888  text_rect.moveBy ( dx, dy );
889  text_rect.setWidth ( text_rect.width() + 2 );
890  text_rect.setHeight ( text_rect.height() + 2 );
891 
892  m_painter->drawText ( text_rect, Qt::AlignLeft | Qt::AlignTop,
893  qstring );
894 
895  m_painter->restore();
896 
897  }
898 
899 }
900 
904 void
906 drawText ( const std::string &s,
907  float xx, float yy,
908  float fontsize, float angle,
909  char xp, char yp, bool resize )
910 {
911  Color black; // default constructor
912  drawText ( s, xx, yy, fontsize, angle, xp, yp, resize, 0, & black );
913 }
914 
915 void
917 drawText ( const std::string &s,
918  float xx, float yy,
919  float fontsize, float angle,
920  char xp, char yp, bool resize,
921  const FontBase * font, const Color * color )
922 {
923  Rect rect = getDrawRect ();
924  if ( color == 0 ) {
925  color = new Color (); // black
926  }
927  QColor qcolor ( color->getRed(), color->getGreen(), color->getBlue() );
928  m_painter -> setPen ( qcolor );
929 
930  if ( font != 0 ) {
931  const QtFont * qtfont = dynamic_cast < const QtFont * > ( font );
932  const QFont & qfont = qtfont -> font();
933  QFont & qf = const_cast < QFont & > ( qfont );
934 
935  draw_Text ( s,
936  (xx + rect.getX()), (yy + rect.getY () ),
937  fontsize, angle,
938  xp, yp, resize, qf, qcolor );
939  }
940  else {
941  draw_Text ( s,
942  (xx + rect.getX()), (yy + rect.getY () ),
943  fontsize, angle,
944  xp, yp, resize, m_font_default, qcolor );
945  }
946 }
947 
948 void
950 drawSquare ( double x1, double y1, double x2, double y2,
951  int red, int green, int blue )
952 {
953  // If reversed, larger coordinate is to the left
954  if (m_plotter -> isReverse()) {
955  if (x1<x2) std::swap(x1,x2);
956  } else {
957  if (x2<x1) std::swap(x1,x2);
958  }
959 
960  if (y2<y1) std::swap(y1,y2);
961 
962  int x = toViewX ( x1 );
963  int w = toViewX ( x2 ) - x + 1;
964  int y = toViewY ( y2 );
965  int h = toViewY ( y1 ) - y + 1;
966 
967  const QColor color ( red, green, blue );
968 
969  m_painter->fillRect ( x, y, w, h, color );
970 }
971 
972 void
974 drawViewSquare ( float x1, float y1, float x2, float y2,
975  int red, int green, int blue )
976 {
977  int x = toCanvasX ( x1 );
978  int w = toCanvasX ( x2 ) - x + 1;
979  int y = toCanvasY ( y2 );
980  int h = toCanvasY ( y1 ) - y + 1;
981 
982  QColor color ( red, green, blue );
983 
984  m_painter->fillRect ( x, y, w, h, color );
985 }
986 
987 void QtViewImp::setCrossX ( double val )
988 {
989  m_plotter->setCrossX ( val );
990 }
991 
992 void QtViewImp::setCrossY ( double val )
993 {
994  m_plotter->setCrossY ( val );
995 }
996 
997 
998 void
1000 setDefaultFont ( const QFont& font )
1001 {
1002  m_font_default = font;
1003 }
1004 
1005 const QFont &
1008 {
1009  return m_font_default;
1010 }
1011 
1012 void
1014 drawImage ( const std::string &filename, int position)
1015 {
1016  QPixmap pixmap;
1017 
1018  // Manually add the directory.
1019  QString fn ( ("temp_latex/"+filename).c_str() );
1020  switch ( position ){
1021  case 0: // Scale to fit the plot
1022  if (pixmap.load(fn)) {
1023  Rect rect = getDrawRect ();
1024  double x=rect.getX();
1025  double y=rect.getY();
1026  double h=rect.getHeight();
1027  double w=h*pixmap.width()/pixmap.height();
1028  setDrawRect(x,y,w,h);
1029  QRect qrect = QRect(static_cast<int>(x),
1030  static_cast<int>(y),
1031  static_cast<int>(w),
1032  static_cast<int>(h) );
1033  m_painter->drawPixmap( qrect, pixmap );
1034  }
1035  break;
1036 
1037  case 1:
1038  if (pixmap.load(fn)) {
1039  Rect rect = getDrawRect ();
1040  Rect mr = getMarginRect ();
1041  double x=rect.getX()+mr.getX();
1042  double y=rect.getY();
1043  double h=pixmap.height()*0.8;
1044  double w=pixmap.width()*0.8;
1045 
1046  // Limit the size
1047  if ( h>36.0 ) {
1048  w=w*36.0 / h;
1049  h = 36.0;
1050  }
1051 
1052  if ( w>mr.getWidth() * 0.8 ) {
1053  double ratio = mr.getWidth() * 0.8 / w ;
1054  h *= ratio;
1055  w *= ratio;
1056  }
1057 
1058  x+=mr.getWidth()/2.0-w/2.0;
1059  QRect qrect = QRect(static_cast<int>(x),
1060  static_cast<int>(y),
1061  static_cast<int>(w),
1062  static_cast<int>(h) );
1063  m_painter->drawPixmap (qrect, pixmap );
1064  }
1065  break;
1066 
1067  case 2:
1068  if (pixmap.load(fn)) {
1069  Rect rect = getDrawRect ();
1070  Rect mr = getMarginRect ();
1071  double x=rect.getX()+mr.getX();
1072  double y=rect.getY();
1073  double h=pixmap.height();
1074  double w=pixmap.width();
1075 
1076  // Limit the size
1077  if ( h>40.0 ) {
1078  w=w*40.0 / h;
1079  h = 40.0;
1080  }
1081 
1082  if ( w>mr.getWidth() * 0.8 ) {
1083  double ratio = mr.getWidth() * 0.8 / w ;
1084  h *= ratio;
1085  w *= ratio;
1086  }
1087 
1088 
1089  x+=mr.getWidth()/2.0-w/2.0;
1090  y+=rect.getHeight()-0.9*h;
1091  QRect qrect = QRect(static_cast<int>(x),
1092  static_cast<int>(y),
1093  static_cast<int>(w),
1094  static_cast<int>(h) );
1095  m_painter->drawPixmap (qrect, pixmap );
1096  }
1097  break;
1098 
1099  case 3:
1100  if (pixmap.load(fn)) {
1101  QWMatrix m;
1102  m.rotate(-90.0);
1103  pixmap = pixmap.xForm(m);
1104 
1105  Rect rect = getDrawRect ();
1106  Rect mr = getMarginRect ();
1107  double x=rect.getX();
1108  double y=rect.getY()+mr.getY();
1109  double h=pixmap.height();
1110  double w=pixmap.width();
1111 
1112  // Limit the size
1113  if ( w>40.0 ) {
1114  h=h*40.0 / w;
1115  w = 40.0;
1116  }
1117 
1118  if ( h>mr.getHeight() * 0.8 ) {
1119  double ratio = mr.getHeight() * 0.8 / h ;
1120  h *= ratio;
1121  w *= ratio;
1122  }
1123 
1124  y+=mr.getHeight()/2.0-h/2.0;
1125  QRect qrect = QRect(static_cast<int>(x),
1126  static_cast<int>(y),
1127  static_cast<int>(w),
1128  static_cast<int>(h) );
1129  m_painter->drawPixmap (qrect, pixmap);
1130  }
1131  break;
1132 
1133  case 4:
1134  if ( pixmap.load ( fn ) ) {
1135  Rect rect = getDrawRect ();
1136  Rect mr = getMarginRect ();
1137  double x = rect.getX()+mr.getX();
1138  double y = rect.getY()+mr.getY();
1139  double h=pixmap.height()*0.7;
1140  double w=pixmap.width()*0.7;
1141 
1142  // Limit the size
1143  if ( h>34.0 ) {
1144  w=w*34.0 / h;
1145  h = 34.0;
1146  }
1147 
1148  if ( w>mr.getWidth() * 0.8 ) {
1149  double ratio = mr.getWidth() * 0.8 / w ;
1150  h *= ratio;
1151  w *= ratio;
1152  }
1153 
1154  x+=mr.getWidth()/2.0-w/2.0;
1155  y+=-30.0-h;
1156  QRect qrect = QRect (static_cast<int>(x),
1157  static_cast<int>(y),
1158  static_cast<int>(w),
1159  static_cast<int>(h) );
1160  m_painter->drawPixmap (qrect, pixmap );
1161  }
1162  break;
1163 
1164 
1165  }
1166 
1167 
1168  // TODO: Show error if failed to load the image.
1169 }
1170 
1171 
1172 void
1174 drawLatex ( const std::string &eq, int position )
1175 {
1176  std::map< const std::string, std::string>::iterator it = m_eq_png.find(eq);
1177  if ( it!=m_eq_png.end() ) {
1178  drawImage (m_eq_png[eq], position);
1179  }
1180  else {
1181  // Work in the temp_latex directory
1182  assert(QDir::setCurrent("temp_latex"));
1183 
1184  // Generate the filenames. It's unique and based on the current time. Need millisecond accuracy.
1185  QString current_time = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
1186  QString tex_filename = "image"+current_time+".tex";
1187  QString png_filename = "image"+current_time+".png";
1188  QString ps_filename = "image"+current_time+".ps";
1189  QString dvi_filename = "image"+current_time+".dvi";
1190  QString tmp_filename = "image"+current_time+".tmp";
1191  QString aux_filename = "image"+current_time+".aux";
1192  QString log_filename = "image"+current_time+".log";
1193 
1194  // Command 1 to 3 generate the png file and command 4 remove all temp files
1195  QString command1 = "latex -interaction=nonstopmode "+tex_filename+" > "+tmp_filename;
1196  QString command2 = "dvips -q -o "+ps_filename+" "+dvi_filename;
1197  QString command3 = "gs < /dev/null -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=ppmraw -sOutputFile=- -r150 -q -dNOPAUSE "+ps_filename+" | pnmcrop -white | pnmmargin -white 10 | pnmtopng -interlace - >"+png_filename;
1198  QString command4 = "rm "+tex_filename+" "+ps_filename+" "+dvi_filename+" "+tmp_filename+" "+aux_filename+" "+log_filename;
1199 
1200  // Write the Latex text to file and call the commands to generate the image
1201  QFile file(tex_filename);
1202  if (file.open(IO_WriteOnly) ) {
1203  QTextStream stream(&file);
1204  // Generate the Latex file ( wither header and ending )
1205  stream << "\\documentclass{article}\n";
1206  stream << "\\pagestyle{empty}\n";
1207  stream << "\\usepackage{xspace,amssymb,amsfonts,amsmath}\n";
1208  stream << "\\usepackage{mathptmx}\n";
1209  stream << "\\usepackage{color}\n";
1210  stream << "\\begin{document}\n";
1211  stream << "\\begin{displaymath}\n";
1212  stream << eq.c_str() <<"\n";
1213  stream << "\\end{displaymath}\n";
1214  stream << "\\end{document}\n";
1215  file.close();
1216 
1217  system(command1.latin1());
1218  system(command2.latin1());
1219  system(command3.latin1());
1220  system(command4.latin1());
1221 
1222  std::string png_fn = png_filename.latin1();
1223  m_eq_png[eq]=png_fn;
1224 
1225  // Make sure return to the original working directory.
1226  QDir::setCurrent("..");
1227  drawImage(png_fn, position);
1228  } else {
1229  QDir::setCurrent("..");
1230  // TODO: Show error if failed to open the text file.
1231  }
1232  }
1233 }
1234 
1235 

Generated for HippoDraw Class Library by doxygen