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

Generated for HippoDraw Class Library by doxygen