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
153 transformAndFill ( QPointArray & array,
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 
float userToDrawXAutoInv(double x) const
Definition: QtViewImp.cxx:127
Part of an implementation of the Observable-Observer pattern based on the example in the GOF Patterns...
Definition: Observable.h:39
unsigned int i
hippodraw::QtViewImp class interface
rotate(double a)
setPointSize(int pointSize)
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
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
width() const
virtual float userToMarginColor(double c) const
Converts the user Z coordinate into the margin color (X) coordinate.
Definition: DataView.cxx:165
fillRect(int x, int y, int w, int h, const QBrush &brush)
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
An implementation of FontBase that uses a Qt QFont as implementation.
Definition: QtFont.h:28
drawPolyline(const QPointArray &a, int index=0, int npoints=-1)
void setInspector(QObject *)
Sets the receiver of update messages.
Definition: QtViewImp.cxx:106
static std::map< hippodraw::Line::Style, Qt::PenStyle > s_line_style
The mapping from LineStyle::Type to QPen PenStyle.
Definition: QtViewImp.h:53
QPainter * m_painter
The current Qt QPainter object.
Definition: QtViewImp.h:76
void setCrossY(double val)
Set the crossY value.
Definition: QtViewImp.cxx:1006
setPen(const QPen &pen)
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
drawPolygon(const QPointArray &a, bool winding=FALSE, int index=0, int npoints=-1)
height() const
Type
Enumeration of the type of symbols supported by this class.
Definition: SymbolType.h:28
virtual void update(const Observable *display)
Responds to update message from Observable.
Definition: QtViewImp.cxx:113
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
removePostedEvents(QObject *receiver)
QObject * m_inspector
The receiver of update messages.
Definition: QtViewImp.h:73
rotate(double a)
drawLine(int x1, int y1, int x2, int y2)
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
virtual float userToMarginX(double x) const
Converts the user X coordinate into the margin X coordinate.
Definition: DataView.cxx:122
virtual Rect getDrawRect() const =0
Returns the drawing Rectangle in the devices coordinate system.
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
void setCrossY(double val)
Set the crossY value.
int getRed() const
Definition: Color.cxx:164
QString fn
setPixelSize(int pixelSize)
DrawBorder class interface.
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)
double getWidth() const
A shortcut to get size.width.
Definition: Rectangle.cxx:108
boundingRect(int x, int y, int w, int h, int flags, const QString &, int len=-1, QTextParag **intern=0)
virtual int toViewX(double datX) const =0
Converts the data space coordinate X to the view space coordinate X.
A abstract base class for font handling.
Definition: FontBase.h:32
The abstract base class for views that have a region for drawing data points with area around it for ...
Definition: DataView.h:30
A Color class for creating the color object following the standard RGB color space.
Definition: Color.h:37
The class of derived from ViewBase for drawing to the screen and PostScript generation using Qt toolk...
Definition: QtViewImp.h:47
QtFont class interface.
The base class for the PlotterBase hierarchy.
Definition: PlotterBase.h:55
drawEllipse(int x, int y, int w, int h)
PlotterBase * m_plotter
The plotter object used by this view.
Definition: ViewBase.h:69
drawPixmap(int x, int y, const QPixmap &pixmap, int sx=0, int sy=0, int sw=-1, int sh=-1)
PyArray_TYPES type(numeric::array arr)
Definition: num_util.cpp:249
int getGreen() const
Definition: Color.cxx:169
virtual void setDefaultFont(const QFont &font)
Definition: QtViewImp.cxx:1014
setBrush(const QBrush &brush)
drawText(int x, int y, const QString &, int len=-1, TextDirection dir=Auto)
setCurrent(const QString &path)
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
QPen createPen(const Color &color, float size, hippodraw::Line::Style style)
Creates a QPen object from the arguments.
Definition: QtViewImp.cxx:516
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 int toCanvasY(double dy) const =0
Converts coordinate from view space to canvas space.
intp size(numeric::array arr)
Definition: num_util.cpp:296
open(int m)
load(const QString &fileName, const char *format=0, ColorMode mode=Auto)
Color class interface.
virtual float userToInvertedMarginX(double x) const
Converts the user X coordinate into the inverted X coordinate.
Definition: DataView.cxx:133
A derived class of QCustomEvent to handle updates from PlotterBase.
Definition: PlotterEvent.h:39
virtual const QFont & defaultFont()
Definition: QtViewImp.cxx:1021
float userToDrawX(double x) const
Converts a coordinate in user space to drawing space along the X axis.
Definition: QtViewImp.cxx:135
float userToDrawY(double x) const
Converts a coordinate in user space to drawing space along the Y axis.
Definition: QtViewImp.cxx:140
virtual void setDrawRect(float x, float y, float w, float h)=0
Sets the drawing Rectangle in the devices coordinate system.
void setCrossX(double val)
Set the crossX value.
Class representing a rectangle.
Definition: Rectangle.h:34
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
height() const
Style
Line style constants.
Definition: LineStyle.h:25
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
drawPie(int x, int y, int w, int h, int a, int alen)
hippodraw::PlotterEvent class interface
drawLineSegments(const QPointArray &a, int index=0, int nlines=-1)
width() const
void setCrossX(double val)
Set the crossX value.
Definition: QtViewImp.cxx:1001
double getX() const
A shortcut to get origin.X.
Definition: Rectangle.h:154
hippodraw::Range class interface
const Rect & getMarginRect() const
Returns the rectangle area in which data points are drawn.
Definition: DataView.cxx:45
virtual int toViewY(double datY) const =0
Converts the data space coordinate Y to the view space coordinate Y.
translate(double dx, double dy)
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
virtual float userToInvertedMarginY(double y) const
Converts the user Y coordinate into the top-left based margin Y coordinate.
Definition: DataView.cxx:154
xForm(const QWMatrix &matrix) const
virtual void drawImage(const std::string &filename, int position=0)
Draws a image.
Definition: QtViewImp.cxx:1028
std::string m_tmpDirName
Definition: QtViewImp.h:65
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
float userToDrawColor(double c) const
Converts a coordinate in user space to drawing space along the color (X) axis.
Definition: QtViewImp.cxx:145
pen() const
int getBlue() const
Definition: Color.cxx:174
list< QAction * >::iterator it
double getY() const
A shortcut to get origin.Y.
Definition: Rectangle.h:162
std::map< const std::string, std::string > m_eq_png
The mapping from LaTex equation to PNG filename.
Definition: QtViewImp.h:57
hippodraw::PlotterBase class interface.
virtual int toCanvasX(double dx) const =0
Converts coordinate from view space to canvas space.
virtual void drawLatex(const std::string &eq, int position=0)
Draws a Latex equation.
Definition: QtViewImp.cxx:1188

Generated for HippoDraw Class Library by doxygen