QtViewImp.cxx

Go to the documentation of this file.
00001 
00013 // inconsistent dll linkage
00014 #ifdef _MSC_VER
00015 #include "msdevstudio/MSconfig.h"
00016 #endif
00017 
00018 #include "QtViewImp.h"
00019 
00020 #include "DrawBorder.h"
00021 #include "PlotterEvent.h"
00022 #include "QtFont.h"
00023 
00024 #include "axes/Range.h"
00025 #include "graphics/Color.h"
00026 #include "plotters/PlotterBase.h"
00027 
00028 #include <qapplication.h>
00029 #include <qpainter.h>
00030 #include <qpixmap.h>
00031 #include <qwmatrix.h>
00032 
00033 #include <qfile.h>
00034 #include <qdir.h>
00035 #include <qdatetime.h>
00036 
00037 #if QT_VERSION < 0x040000
00038 #include <qpointarray.h>
00039 #else
00040 #include <QtGui/QPolygon>
00041 #include <QtCore/QTextStream>
00042 #endif
00043 
00044 #include <cassert>
00045 
00046 using namespace hippodraw;
00047 
00048 using std::vector;
00049 
00050 std::map < Line::Style, Qt::PenStyle > QtViewImp::s_line_style;
00051 
00052 QtViewImp::
00053 QtViewImp ()
00054   :DataView (),
00055    m_inspector ( 0 ),
00056    m_painter ( 0 ),
00057    m_font_default ( "helvetica" )
00058 {
00059   if ( s_line_style.empty () ) {
00060     s_line_style [ Line::Solid ]      = Qt::SolidLine;
00061     s_line_style [ Line::Dash ]       = Qt::DashLine;
00062     s_line_style [ Line::Dot ]        = Qt::DotLine;
00063     s_line_style [ Line::DashDot ]    = Qt::DashDotLine;
00064     s_line_style [ Line::DashDotDot ] = Qt::DashDotDotLine;
00065     s_line_style [ Line::Invisible ]  = Qt::NoPen;
00066   }
00067   m_eq_png.clear();
00068 }
00069    
00070 
00071 QtViewImp::
00072 QtViewImp ( PlotterBase * plotter )
00073   : DataView ( plotter ),
00074     m_inspector ( 0 ),
00075     m_painter ( 0 ),
00076     m_font_default ( "helvetica" )
00077 {
00078   if ( s_line_style.empty () ) {
00079     s_line_style [ Line::Solid ]      = Qt::SolidLine;
00080     s_line_style [ Line::Dash ]       = Qt::DashLine;
00081     s_line_style [ Line::Dot ]        = Qt::DotLine;
00082     s_line_style [ Line::DashDot ]    = Qt::DashDotLine;
00083     s_line_style [ Line::DashDotDot ] = Qt::DashDotDotLine;
00084     s_line_style [ Line::Invisible ]  = Qt::NoPen;
00085   }
00086   m_eq_png.clear();
00087 }
00088 
00089 void
00090 QtViewImp::
00091 setInspector ( QObject * inspector )
00092 {
00093   m_inspector = inspector;
00094 }
00095 
00096 void
00097 QtViewImp::
00098 update ( const Observable * display )
00099 {
00100   if ( display == 0 ) return;
00101 
00102   if (  m_inspector != 0 ) {
00103     Observable * o = const_cast < Observable * > ( display );
00104     PlotterBase * plotter = dynamic_cast < PlotterBase * > ( o );
00105     PlotterEvent * event = new PlotterEvent ( plotter );
00106     QApplication::removePostedEvents ( m_inspector );
00107     QApplication::postEvent ( m_inspector, event );
00108   }
00109 
00110 }
00111 
00112 float QtViewImp::userToDrawXAutoInv ( double xx ) const
00113 {
00114   if (m_plotter -> isReverse())
00115     return userToInvertedMarginX( xx );
00116   else 
00117     return userToMarginX( xx );
00118 }
00119 
00120 float QtViewImp::userToDrawX ( double xx ) const
00121 {
00122   return userToMarginX( xx );
00123 }
00124 
00125 float QtViewImp::userToDrawY ( double yy ) const
00126 {
00127   return  userToInvertedMarginY( yy );
00128 }
00129 
00130 float QtViewImp::userToDrawColor ( double c ) const
00131 {
00132   return userToMarginColor( c );
00133 }
00134 
00135 void
00136 QtViewImp::
00137 #if QT_VERSION < 0x040000
00138 transformAndFill ( QPointArray & array,
00139 #else
00140 transformAndFill ( QPolygon & array,
00141 #endif
00142                    const std::vector< double > & x,
00143                    const std::vector< double > & y,
00144                    int (QtViewImp::* xfunc) ( double ) const,
00145                    int (QtViewImp::* yfunc) ( double ) const )
00146 {
00147   unsigned int size = x.size();
00148   assert ( size == y.size() );
00149 
00150   for ( unsigned int i = 0; i < size; i++ ) {
00151     int ix = (this->*xfunc) ( x[i] );
00152     int iy = (this->*yfunc) ( y[i] );
00153 
00154     array.setPoint ( i , ix, iy );
00155   }
00156 
00157 }
00158 
00161 void 
00162 QtViewImp::
00163 drawViewMethod ( const std::vector< double > & x,
00164                  const std::vector< double > & y,
00165                  int, int )
00166 {
00167 
00168   unsigned int size = x.size();
00169   assert ( size == y.size() );
00170 
00171 #if QT_VERSION < 0x040000
00172   QPointArray array ( size );
00173 #else
00174   QPolygon array ( size );
00175 #endif
00176   transformAndFill ( array, x, y,
00177                      &QtViewImp::toCanvasX, &QtViewImp::toCanvasY );
00178 
00179   m_painter->drawLineSegments ( array );
00180 
00181 }
00182 
00183 
00186 void 
00187 QtViewImp::
00188 drawMethod ( const std::vector < double > & x,
00189              const std::vector < double > & y,
00190              int, // style,
00191              int ) //color )
00192 {
00193 
00194   unsigned int size = x.size();
00195   assert ( size == y.size() );
00196 
00197 #if QT_VERSION < 0x040000
00198   QPointArray array ( size );
00199 #else
00200   QPolygon array ( size );
00201 #endif
00202   transformAndFill ( array, x, y,
00203                      &QtViewImp::toViewX, &QtViewImp::toViewY );
00204 
00205   m_painter->drawPolyline ( array, 0, -1 );
00206 }
00207 
00208 
00209 void 
00210 QtViewImp::
00211 drawPoints ( const std::vector<double> & x,
00212              const std::vector<double> & y,
00213              Symbol::Type type, 
00214              float sym_size, 
00215              const Color & color )
00216 {
00217   m_painter->save();
00218   
00219   int i_sym_size = (int)(sym_size/2);
00220 
00221   int rgb[3];
00222   rgb[0] = color.getRed();
00223   rgb[1] = color.getGreen();
00224   rgb[2] = color.getBlue();
00225   QColor qcolor ( rgb[0], rgb[1], rgb[2] );
00226 
00227   m_painter->setPen ( qcolor );
00228 
00229 #if QT_VERSION < 0x040000
00230   QPointArray triangleArray ( 3 );
00231 #else
00232   QPolygon triangleArray ( 3 );
00233 #endif
00234 
00235   for (unsigned int i = 0; i < x.size(); i++)
00236     {
00237       int originX = toViewX ( x[i] );
00238       int originY = toViewY ( y[i] );
00239       
00240       switch ( type )
00241         {
00242 
00243 
00244 
00245         case Symbol::SOLIDSQUARE:
00246           
00247           m_painter->fillRect ( ( toViewX (x[i]) - (i_sym_size) ), 
00248                                 ( toViewY (y[i]) - (i_sym_size) ),
00249                                 (i_sym_size*2 + 1 ),
00250                                 (i_sym_size*2 + 1 ),
00251                                 ( qcolor ) );
00252           
00253           break;
00254 
00255 
00256 
00257         case Symbol::SQUARE:  
00258           m_painter -> drawRect ( toViewX ( x[i] ) - i_sym_size,
00259                                   toViewY ( y[i] ) - i_sym_size,
00260                                   2*i_sym_size + 1,
00261                                   2*i_sym_size + 1 );
00262           break;
00263 
00264         case Symbol::TRIANGLE:
00265           triangleArray.setPoint ( 0, ( toViewX (x[i]) ), 
00266                               ( toViewY (y[i]) + (i_sym_size) ) );
00267 
00268           triangleArray.setPoint ( 1, ( toViewX (x[i]) + (i_sym_size) ),
00269                               ( toViewY (y[i]) - (i_sym_size) ) );
00270 
00271 
00272           triangleArray.setPoint ( 2, ( toViewX (x[i]) - (i_sym_size) ),
00273                               ( toViewY (y[i]) - (i_sym_size) ) );
00274           
00275           m_painter -> setBrush ( Qt::NoBrush );
00276           m_painter->drawPolygon (triangleArray);
00277           break;
00278 
00279         case Symbol::FILLED_TRIANGLE:
00280           
00281           triangleArray.setPoint ( 0, ( toViewX (x[i]) ), 
00282                               ( toViewY (y[i]) + (i_sym_size) ) );
00283 
00284           triangleArray.setPoint ( 1, ( toViewX (x[i]) + (i_sym_size) ),
00285                               ( toViewY (y[i]) - (i_sym_size) ) );
00286 
00287 
00288           triangleArray.setPoint ( 2, ( toViewX (x[i]) - (i_sym_size) ),
00289                               ( toViewY (y[i]) - (i_sym_size) ) );
00290           
00291           m_painter->setBrush (qcolor);
00292 
00293           m_painter->drawPolygon (triangleArray);
00294           
00295           break;
00296 
00297 
00298         case Symbol::CIRCLE:
00299 
00300           m_painter->drawEllipse ( ( toViewX (x[i]) - (i_sym_size) ), 
00301                                    ( toViewY (y[i]) - (i_sym_size) ),
00302                                    ( i_sym_size*2 + 1 ),
00303                                    ( i_sym_size*2 + 1 ) );
00304           
00305           break;
00306 
00307 
00308         case Symbol::FILLED_CIRCLE:
00309 
00310           m_painter->setBrush (qcolor);
00311 
00312           m_painter->drawPie ( ( toViewX (x[i]) - (i_sym_size) ), 
00313                                ( toViewY (y[i]) - (i_sym_size) ),
00314                                ( i_sym_size*2 + 1 ),
00315                                ( i_sym_size*2 + 1 ),
00316                                ( 16 * 0 ),
00317                                ( 16 * 360 ) );
00318 
00319           break;
00320 
00321         case Symbol::PLUS:
00322           m_painter -> drawLine ( originX - i_sym_size, originY,
00323                                   originX + i_sym_size, originY );
00324           m_painter -> drawLine ( originX, originY - i_sym_size,
00325                                   originX, originY + i_sym_size );
00326           break;
00327           
00328         case Symbol::TIMES:
00329           m_painter -> drawLine ( originX - i_sym_size, originY - i_sym_size,
00330                                   originX + i_sym_size, originY + i_sym_size );
00331           m_painter -> drawLine ( originX + i_sym_size, originY - i_sym_size,
00332                                   originX - i_sym_size, originY + i_sym_size );
00333           break;
00334           
00335         default:
00336           break;
00337         
00338         }
00339     }
00340   
00341   m_painter->restore();
00342   
00343 }
00344 
00347 void 
00348 QtViewImp::
00349 drawPoints ( const std::vector< double > &,
00350              const std::vector< double > &,
00351              Symbol::Type, 
00352              float )
00353 {
00354 
00355 }
00356 
00364 void 
00365 QtViewImp::
00366 drawPoints ( const std::vector< double > & x,
00367              const std::vector< double > & y,
00368              const std::vector< Color > & colors,
00369              Symbol::Type type, 
00370              float sym_size )
00371 {
00372   assert ( x.size() == colors.size() );
00373   m_painter->save();
00374   
00375   int i_sym_size = (int)(sym_size/2);
00376 
00377   if ( i_sym_size == 0 &&
00378        type == Symbol::SOLIDSQUARE ) {
00379     type = Symbol::SQUARE;
00380   }
00381 
00382 #if QT_VERSION < 0x040000
00383   QPointArray triangleArray ( 3 );
00384 #else
00385   QPolygon triangleArray ( 3 );
00386 #endif
00387 
00388   for (unsigned int i = 0; i < x.size(); i++)
00389     {
00390       int o_x = toViewX ( x[i] );
00391       int o_y = toViewY ( y[i] );
00392 
00393       const Color & c = colors[i];
00394       QColor qcolor ( c.getRed (), c.getGreen(), c.getBlue () );
00395       m_painter->setPen ( qcolor );
00396       
00397       switch ( type )
00398         {
00399         case Symbol::SOLIDSQUARE:
00400           m_painter->fillRect ( ( toViewX (x[i]) - (i_sym_size) ), 
00401                                 ( toViewY (y[i]) - (i_sym_size) ),
00402                                 (i_sym_size*2 ),
00403                                 (i_sym_size*2 ),
00404                                 ( qcolor ) );
00405           
00406           break;
00407 
00408         case Symbol::SQUARE:  
00409           m_painter -> drawRect ( o_x -i_sym_size, o_y - i_sym_size,
00410                                   2 * i_sym_size, 2 * i_sym_size );
00411           break;
00412           
00413 
00414 
00415         case Symbol::TRIANGLE:
00416           triangleArray.setPoint ( 0, ( toViewX (x[i]) ), 
00417                               ( toViewY (y[i]) + (i_sym_size) ) );
00418 
00419           triangleArray.setPoint ( 1, ( toViewX (x[i]) + (i_sym_size) ),
00420                               ( toViewY (y[i]) - (i_sym_size) ) );
00421 
00422 
00423           triangleArray.setPoint ( 2, ( toViewX (x[i]) - (i_sym_size) ),
00424                               ( toViewY (y[i]) - (i_sym_size) ) );
00425           
00426           m_painter->setBrush ( Qt::NoBrush );
00427           m_painter->drawPolygon (triangleArray);
00428           
00429           break;
00430 
00431 
00432 
00433         case Symbol::FILLED_TRIANGLE:
00434           
00435           triangleArray.setPoint ( 0, ( toViewX (x[i]) ), 
00436                               ( toViewY (y[i]) + (i_sym_size) ) );
00437 
00438           triangleArray.setPoint ( 1, ( toViewX (x[i]) + (i_sym_size) ),
00439                               ( toViewY (y[i]) - (i_sym_size) ) );
00440 
00441 
00442           triangleArray.setPoint ( 2, ( toViewX (x[i]) - (i_sym_size) ),
00443                               ( toViewY (y[i]) - (i_sym_size) ) );
00444           
00445           m_painter->setBrush (qcolor);
00446 
00447           m_painter->drawPolygon (triangleArray);
00448           
00449           break;
00450 
00451 
00452         case Symbol::CIRCLE:
00453 
00454           m_painter->drawEllipse ( ( toViewX (x[i]) - (i_sym_size) ), 
00455                                    ( toViewY (y[i]) - (i_sym_size) ),
00456                                    (i_sym_size*2 ),
00457                                    (i_sym_size*2 ) );
00458           
00459           break;
00460 
00461 
00462         case Symbol::FILLED_CIRCLE:
00463 
00464           m_painter->setBrush (qcolor);
00465 
00466           m_painter->drawPie ( ( toViewX (x[i]) - (i_sym_size) ), 
00467                                ( toViewY (y[i]) - (i_sym_size) ),
00468                                ( i_sym_size*2 ),
00469                                ( i_sym_size*2 ),
00470                                ( 16 * 0 ),
00471                                ( 16 * 360 ) );
00472 
00473           break;
00474 
00475         case Symbol::PLUS:
00476           m_painter -> drawLine ( o_x - i_sym_size, o_y,
00477                                   o_x + i_sym_size, o_y );
00478           m_painter -> drawLine ( o_x, o_y - i_sym_size,
00479                                   o_x, o_y + i_sym_size );
00480           break;
00481           
00482         case Symbol::TIMES:
00483           m_painter -> drawLine ( o_x - i_sym_size, o_y - i_sym_size,
00484                                   o_x + i_sym_size, o_y + i_sym_size );
00485           m_painter -> drawLine ( o_x + i_sym_size, o_y - i_sym_size,
00486                                   o_x - i_sym_size, o_y + i_sym_size );
00487           break;
00488           
00489         default:
00490           break;
00491         
00492         }
00493     }
00494   
00495   m_painter->restore();
00496 
00497 }
00498 
00499 QPen
00500 QtViewImp::
00501 createPen ( const Color & color, float size, Line::Style style )
00502 {
00503   int rgb[3];
00504   rgb[0] = color.getRed();
00505   rgb[1] = color.getGreen();
00506   rgb[2] = color.getBlue();
00507   QColor qcolor ( rgb[0], rgb[1], rgb[2] );
00508 
00509   unsigned int isize = static_cast < unsigned int > ( size );
00510   Qt::PenStyle pen_style = s_line_style [ style ];
00511 
00512   return QPen ( qcolor, isize, pen_style );
00513 }
00514 
00515 void
00516 QtViewImp::
00517 drawPolygon ( const std::vector < double > & x,
00518               const std::vector < double > & y,
00519               const Color & color,
00520               const Color & edge
00521               )
00522 {
00523   m_painter->save();
00524 
00525   unsigned int size = x.size();
00526   assert ( size == y.size() );
00527 
00528   int rgb[3];
00529   rgb[0] = color.getRed();
00530   rgb[1] = color.getGreen();
00531   rgb[2] = color.getBlue();
00532   QColor qcolor ( rgb[0], rgb[1], rgb[2] );
00533 
00534   int rgb2[3];
00535   rgb2[0] = edge.getRed();
00536   rgb2[1] = edge.getGreen();
00537   rgb2[2] = edge.getBlue();
00538   QColor qcolor2 ( rgb2[0], rgb2[1], rgb2[2] );
00539 
00540 #if QT_VERSION < 0x040000
00541   QPointArray array ( size );
00542 #else
00543   QPolygon array ( size );
00544 #endif
00545   transformAndFill ( array, x, y,
00546                      &QtViewImp::toViewX, &QtViewImp::toViewY );
00547 
00548   m_painter->setBrush(qcolor);
00549   m_painter->setPen(qcolor2);
00550   m_painter->drawPolygon(array);
00551 
00552   m_painter->restore();
00553 
00554 }
00555 
00556 void 
00557 QtViewImp::
00558 drawPolyLine ( const std::vector< double > & x,
00559                const std::vector< double > & y,
00560                Line::Style style,
00561                const Color & color,
00562                float size )
00563 {
00564   m_painter->save();
00565 
00566   QPen pen = createPen ( color, size, style );
00567   m_painter->setPen ( pen );
00568   m_painter -> setBrush ( Qt::NoBrush );
00569   drawMethod ( x, y, style, 0 );
00570 
00571   m_painter->restore();
00572 
00573 }
00574 
00575 void 
00576 QtViewImp::
00577 drawLines ( const std::vector< double > & x,
00578             const std::vector< double > & y,
00579             Line::Style style,
00580             const Color & color,
00581             float size )
00582 {
00583 
00584   m_painter->save();
00585 
00586   QPen pen = createPen ( color, size, style );
00587   m_painter->setPen ( pen );
00588 
00589   unsigned int xsize = x.size();
00590   assert ( xsize == y.size() );
00591 
00592 #if QT_VERSION < 0x040000
00593   QPointArray array ( xsize );
00594 #else
00595   QPolygon array ( xsize );
00596 #endif
00597   transformAndFill ( array, x, y,
00598                      &QtViewImp::toViewX, &QtViewImp::toViewY );
00599 
00600   m_painter->drawLineSegments ( array );
00601   
00602   m_painter->restore();
00603 
00604 }
00605 
00606 void
00607 QtViewImp::
00608 drawColorLines ( const std::vector< double > & x,
00609                  const std::vector< double > & y,
00610                  Line::Style style,
00611                  const std::vector < Color > & colors,
00612                  float size )
00613 {
00614   unsigned int ssize = x.size();
00615   assert ( ssize == y.size() );
00616   assert ( ssize == colors.size() );
00617 
00618   for ( unsigned int i = 0; i < ssize; i+=2 ) {
00619     
00620     m_painter->save();
00621     const Color & color = colors[i];
00622     QColor qcolor ( color.getRed (), color.getGreen (), color.getBlue() );
00623     QPen pen ( qcolor, static_cast < int > (size) );
00624     Qt::PenStyle pen_style = s_line_style [ style ];
00625     pen.setStyle ( pen_style );
00626     m_painter->setPen ( pen );
00627       
00628     int x1 = toViewX ( x[i] );
00629     int x2 = toViewX ( x[i+1] );
00630     int y1 = toViewY ( y[i] );
00631     int y2 = toViewY ( y[i+1] );
00632     m_painter->drawLine ( x1, y1, x2, y2 );
00633 
00634     m_painter->restore();
00635 
00636   }
00637   
00638 }
00639 
00642 void 
00643 QtViewImp::
00644 drawViewLines ( const std::vector< double > & x,
00645                 const std::vector< double > & y,
00646                 Line::Style style,
00647                 bool,
00648                 float size )
00649 {
00650 
00651   m_painter->save();
00652 
00653   QPen pen ( (m_painter->pen()).color(), (int)(size) );
00654   Qt::PenStyle pen_style = s_line_style [ style ];
00655   pen.setStyle ( pen_style );
00656   m_painter->setPen ( pen );
00657 
00658   drawViewMethod ( x, y, style, 0 ); // last argument was default color
00659 
00660   m_painter->restore();
00661 
00662 }
00663 
00664 void 
00665 QtViewImp::
00666 drawViewLines ( const std::vector< double > & x,
00667                 const std::vector< double > & y,
00668                 Line::Style style,
00669                 const Color & color,
00670                 float size )
00671 {
00672 
00673   m_painter->save();
00674 
00675   QPen pen = createPen ( color, size, style );
00676   m_painter->setPen ( pen );
00677 
00678   unsigned int xsize = x.size();
00679   assert ( xsize == y.size() );
00680 
00681 #if QT_VERSION < 0x040000
00682   QPointArray array ( xsize );
00683 #else
00684   QPolygon array ( xsize );
00685 #endif
00686   transformAndFill ( array, x, y,
00687                      &QtViewImp::toCanvasX, &QtViewImp::toCanvasY );
00688 
00689   m_painter->drawLineSegments ( array );
00690 
00691   m_painter->restore();
00692 
00693 }
00694 
00695 void 
00696 QtViewImp::
00697 draw_Text ( const std::string &s, 
00698             float xx, float yy, float fontsize, 
00699             float angle, char xp, char yp, bool resize,
00700             QFont & font, const QColor & color  )
00701 {
00702   assert ( fontsize > 0 );
00703   int i_x = static_cast< int > ( xx );
00704   int i_y = static_cast< int > ( yy );
00705   int i_font = static_cast < int > ( fontsize );
00706   
00707   if ( fontsize > 0 ) {
00708     font.setPointSize( i_font );
00709     font.setPixelSize( i_font );
00710   }
00711   
00712   if ( m_painter == 0 ) return;
00713 
00714   m_painter->setFont ( font );
00715 
00716   m_painter -> setPen ( color );
00717 
00718   QString qstring ( s.c_str() );
00719 
00720   QFontMetrics metrics1 ( font );
00721   QRect new_rect1 = metrics1.boundingRect ( qstring );
00722   int h1 = new_rect1.height ();
00723   if ( fontsize > 0 ) {
00724     while ( h1 >= fontsize ){
00725     
00726       i_font-- ;
00727 
00728       if ( i_font < 1 ) break;
00729 
00730       font.setPixelSize ( i_font );
00731 
00732       QFontMetrics metrics2 ( font );
00733       QRect new_rect2 = metrics2.boundingRect ( qstring );
00734       int h2 = new_rect2.height ();
00735 
00736       h1 = h2;
00737     }
00738   }
00739 
00740   if ( resize == true ) {
00741 
00742     // This part of the code makes sense only for TextReps. Nobody else
00743     // should call draw_Text with resize == true. It will not
00744     // work if the text rep draws the strings that appear on the bottom of
00745     // the display before the ones that appear near the top.
00746 
00747     QFontMetrics metrics ( font );
00748     QRect new_rect = metrics.boundingRect ( qstring );
00749 #if QT_VERSION < 0x040000
00750     int lines = qstring.contains ( "\n" );
00751 #else
00752     int lines = qstring.count();
00753 #endif
00754     QStringList sl = QStringList::split ( '\n', qstring );
00755     int maxw = 0;
00756 #if QT_VERSION < 0x040000
00757     for ( QValueList<QString>::size_type i = 0; i < sl.count (); i++ ) {
00758 #else
00759     for ( QList<QString>::size_type i = 0; i < sl.count (); i++ ) {
00760 #endif
00761       QString s = sl[i];
00762       QRect sr = metrics.boundingRect ( s );
00763       maxw = std::max ( maxw, sr.width () );
00764     }
00765     int w = new_rect.width ();
00766     int h = new_rect.height ();
00767     h *= ( lines + 1 );
00768     Rect rect = getDrawRect ();
00769 
00770     // fix the height if this is not top string
00771     int delta_y = i_y - static_cast < int > ( rect.getY () );
00772     if ( delta_y > 0 ) {
00773       h += delta_y;
00774     }
00775 
00776     // fix the width if this is not left positioned string
00777     int delta_x = i_x - static_cast < int > ( rect.getX () );
00778     if ( delta_x > 0 ) {
00779       w += delta_x;
00780     }
00781     // need a little extra of the width for some reason.
00782 #ifdef _MSC_VER
00783     maxw *= 1.6;
00784 #endif
00785     setDrawRect ( rect.getX (), rect.getY (), 1.2 * maxw, 4. * h );
00786   }
00787 
00788   Rect rect = getDrawRect ();
00789 
00790   int i_w = static_cast < int > ( rect.getWidth () );
00791   int i_h = static_cast < int > ( rect.getHeight () );
00792 
00793   QRect text_rect = m_painter->boundingRect ( 0, 0,
00794                                           i_h, i_w,
00795                                           Qt::AlignLeft | Qt::AlignTop,
00796                                           qstring );
00797   int dx = 0;
00798   int dy = 0;
00799 
00800   if ( angle == 0.0 )
00801     {
00802       
00803       switch ( xp ) {
00804       case 'l' :
00805       case 'L' :
00806         dx = i_x;
00807         break;
00808       case 'c' :
00809       case 'C' :
00810         dx = i_x - text_rect.width () / 2;
00811         break;
00812       case 'r' :
00813       case 'R' :
00814         dx = i_x - text_rect.width ();
00815         break;
00816       default:
00817         dx = i_x;
00818       }
00819 
00820       switch ( yp ) {
00821       case 't' :
00822       case 'T' :
00823         dy = i_y;
00824         break;
00825       case 'c' :
00826       case 'C' :
00827         dy = i_y - text_rect.height () / 2;
00828         break;
00829       case 'b' :
00830       case 'B' :
00831         dy = i_y - text_rect.height ();
00832         break;
00833       default:
00834         dy = i_y;
00835       }
00836 
00837       text_rect.moveBy ( dx, dy );
00838       text_rect.setWidth ( text_rect.width() + 2 );
00839       text_rect.setHeight ( text_rect.height() + 2 );
00840 
00841       m_painter->drawText ( text_rect, Qt::AlignLeft | Qt::AlignTop,
00842                             qstring );
00843     }
00844 
00845   else // angle not 0.0
00846     {
00847       m_painter->save();
00848       
00849       m_painter->translate ( i_x, i_y );
00850       
00851       m_painter->rotate ( - angle );
00852 
00853       switch ( xp ) {
00854       case 'l' :
00855       case 'L' :
00856         dx = 0;
00857         break;
00858       case 'c' :
00859       case 'C' :
00860         dx = 0 - text_rect.width () / 2;
00861         break;
00862       case 'r' :
00863       case 'R' :
00864         dx = 0 - text_rect.width ();
00865         break;
00866       default:
00867         dx = 0;
00868       }
00869 
00870       switch ( yp ) {
00871       case 't' :
00872       case 'T' :
00873         dy = 0;
00874         break;
00875       case 'c' :
00876       case 'C' :
00877         dy = 0 - text_rect.height () / 2;
00878         break;
00879       case 'b' :
00880       case 'B' :
00881         dy = 0 - text_rect.height ();
00882         break;
00883       default:
00884         dy = 0;
00885       }
00886 
00887       text_rect.moveBy ( dx, dy );
00888       text_rect.setWidth ( text_rect.width() + 2 );
00889       text_rect.setHeight ( text_rect.height() + 2 );
00890             
00891       m_painter->drawText ( text_rect, Qt::AlignLeft | Qt::AlignTop,
00892                             qstring );
00893       
00894        m_painter->restore();
00895 
00896     }
00897 
00898 }
00899 
00903 void 
00904 QtViewImp::
00905 drawText ( const std::string &s, 
00906            float xx, float yy,
00907            float fontsize, float angle,
00908            char xp, char yp, bool resize )
00909 {
00910   Color black; // default constructor
00911   drawText ( s, xx, yy, fontsize, angle, xp, yp, resize, 0, & black );
00912 }
00913 
00914 void 
00915 QtViewImp::
00916 drawText ( const std::string &s, 
00917            float xx, float yy,
00918            float fontsize, float angle,
00919            char xp, char yp, bool resize,
00920            const FontBase * font, const Color * color )
00921 {
00922   Rect rect = getDrawRect ();
00923   if ( color == 0 ) {
00924     color = new Color (); // black
00925   }
00926   QColor qcolor ( color->getRed(), color->getGreen(), color->getBlue() );
00927   m_painter -> setPen ( qcolor );
00928 
00929   if ( font != 0 ) {
00930     const QtFont * qtfont = dynamic_cast < const QtFont * > ( font );
00931     const QFont & qfont = qtfont -> font();
00932     QFont & qf = const_cast < QFont & > ( qfont );
00933 
00934     draw_Text ( s, 
00935                 (xx + rect.getX()), (yy + rect.getY () ), 
00936                 fontsize, angle, 
00937                 xp, yp, resize, qf, qcolor );
00938   }
00939   else {
00940     draw_Text ( s, 
00941                 (xx + rect.getX()), (yy + rect.getY () ), 
00942                 fontsize, angle, 
00943                 xp, yp, resize, m_font_default, qcolor );
00944   }
00945 }
00946 
00947 void 
00948 QtViewImp::
00949 drawSquare ( double x1, double y1, double x2, double y2,
00950              int red, int green, int blue )
00951 {
00952   // If reversed, larger coordinate is to the left
00953   if (m_plotter -> isReverse()) {
00954     if (x1<x2) std::swap(x1,x2);
00955   } else {
00956     if (x2<x1) std::swap(x1,x2);
00957   }
00958 
00959   if (y2<y1) std::swap(y1,y2);
00960   
00961   int x = toViewX ( x1 );
00962   int w = toViewX ( x2 ) - x + 1;
00963   int y = toViewY ( y2 );
00964   int h = toViewY ( y1 ) - y + 1;
00965 
00966   const QColor color ( red, green, blue );
00967 
00968   m_painter->fillRect ( x, y, w, h, color );
00969 }
00970 
00971 void 
00972 QtViewImp::
00973 drawViewSquare ( float x1, float y1, float x2, float y2,
00974                  int red, int green, int blue )
00975 {
00976   int x = toCanvasX ( x1 );
00977   int w = toCanvasX ( x2 ) - x + 1;
00978   int y = toCanvasY ( y2 );
00979   int h = toCanvasY ( y1 ) - y + 1;
00980   
00981   QColor color ( red, green, blue );
00982 
00983   m_painter->fillRect ( x, y, w, h, color );
00984 }
00985 
00986 void QtViewImp::setCrossX ( double val )
00987 {
00988   m_plotter->setCrossX ( val );
00989 }
00990 
00991 void QtViewImp::setCrossY ( double val )
00992 {
00993   m_plotter->setCrossY ( val );
00994 }
00995 
00996 
00997 void
00998 QtViewImp::
00999 setDefaultFont ( const QFont& font )
01000 {
01001   m_font_default = font;
01002 }
01003 
01004 const QFont &
01005 QtViewImp::
01006 defaultFont()
01007 {
01008   return m_font_default;
01009 }
01010 
01011 void 
01012 QtViewImp::
01013 drawImage ( const std::string &filename, int position)
01014 {
01015   QPixmap pixmap;
01016 
01017   // Manually add the directory. 
01018   QString fn ( ("temp_latex/"+filename).c_str() );
01019   switch ( position ){
01020   case 0: // Scale to fit the plot
01021     if (pixmap.load(fn)) {
01022       Rect rect = getDrawRect ();
01023       double x=rect.getX();
01024       double y=rect.getY();
01025       double h=rect.getHeight();
01026       double w=h*pixmap.width()/pixmap.height();
01027       setDrawRect(x,y,w,h);
01028       QRect qrect = QRect(static_cast<int>(x),
01029                           static_cast<int>(y),
01030                           static_cast<int>(w),
01031                           static_cast<int>(h) );
01032       m_painter->drawPixmap( qrect, pixmap ); 
01033     }
01034     break;
01035     
01036   case 1:
01037     if (pixmap.load(fn)) {
01038       Rect rect = getDrawRect ();
01039       Rect mr = getMarginRect ();
01040       double x=rect.getX()+mr.getX();
01041       double y=rect.getY();
01042       double h=pixmap.height()*0.8;
01043       double w=pixmap.width()*0.8;
01044 
01045       // Limit the size
01046       if ( h>36.0 ) {
01047         w=w*36.0 / h;
01048         h = 36.0;
01049       }
01050 
01051       if ( w>mr.getWidth() * 0.8 ) {
01052         double ratio = mr.getWidth() * 0.8 / w ;
01053         h *= ratio;
01054         w *= ratio;
01055       }
01056 
01057       x+=mr.getWidth()/2.0-w/2.0;
01058       QRect qrect = QRect(static_cast<int>(x),
01059                           static_cast<int>(y),
01060                           static_cast<int>(w),
01061                           static_cast<int>(h) );
01062       m_painter->drawPixmap (qrect, pixmap );
01063     }
01064     break;
01065 
01066   case 2:
01067     if (pixmap.load(fn)) {
01068       Rect rect = getDrawRect ();
01069       Rect mr = getMarginRect ();
01070       double x=rect.getX()+mr.getX();
01071       double y=rect.getY();
01072       double h=pixmap.height();
01073       double w=pixmap.width();
01074 
01075      // Limit the size
01076       if ( h>40.0 ) {
01077         w=w*40.0 / h;
01078         h = 40.0;
01079       }
01080 
01081       if ( w>mr.getWidth() * 0.8 ) {
01082         double ratio = mr.getWidth() * 0.8 / w ;
01083         h *= ratio;
01084         w *= ratio;
01085       }
01086 
01087 
01088       x+=mr.getWidth()/2.0-w/2.0;
01089       y+=rect.getHeight()-0.9*h;
01090       QRect qrect = QRect(static_cast<int>(x),
01091                           static_cast<int>(y),
01092                           static_cast<int>(w),
01093                           static_cast<int>(h) );
01094       m_painter->drawPixmap (qrect, pixmap );
01095     }
01096     break;
01097 
01098   case 3:
01099     if (pixmap.load(fn)) {
01100       QWMatrix m;
01101       m.rotate(-90.0);
01102       pixmap = pixmap.xForm(m);
01103 
01104       Rect rect = getDrawRect ();
01105       Rect mr = getMarginRect ();
01106       double x=rect.getX();
01107       double y=rect.getY()+mr.getY();
01108       double h=pixmap.height();
01109       double w=pixmap.width();
01110 
01111      // Limit the size
01112       if ( w>40.0 ) {
01113         h=h*40.0 / w;
01114         w = 40.0;
01115       }
01116 
01117       if ( h>mr.getHeight() * 0.8 ) {
01118         double ratio = mr.getHeight() * 0.8 / h ;
01119         h *= ratio;
01120         w *= ratio;
01121       }
01122 
01123       y+=mr.getHeight()/2.0-h/2.0;
01124       QRect qrect = QRect(static_cast<int>(x),
01125                           static_cast<int>(y),
01126                           static_cast<int>(w),
01127                           static_cast<int>(h) );
01128       m_painter->drawPixmap (qrect, pixmap);
01129     }
01130     break;
01131 
01132   case 4:
01133     if ( pixmap.load ( fn ) ) {
01134       Rect rect = getDrawRect ();
01135       Rect mr = getMarginRect ();
01136       double x = rect.getX()+mr.getX();
01137       double y = rect.getY()+mr.getY();
01138       double h=pixmap.height()*0.7;
01139       double w=pixmap.width()*0.7;
01140 
01141      // Limit the size
01142       if ( h>34.0 ) {
01143         w=w*34.0 / h;
01144         h = 34.0;
01145       }
01146 
01147       if ( w>mr.getWidth() * 0.8 ) {
01148         double ratio = mr.getWidth() * 0.8 / w ;
01149         h *= ratio;
01150         w *= ratio;
01151       }
01152 
01153       x+=mr.getWidth()/2.0-w/2.0;
01154       y+=-30.0-h;
01155       QRect qrect = QRect (static_cast<int>(x),
01156                            static_cast<int>(y),
01157                            static_cast<int>(w),
01158                            static_cast<int>(h) );
01159       m_painter->drawPixmap (qrect, pixmap );
01160     }
01161     break;
01162 
01163     
01164   }
01165 
01166 
01167   // TODO: Show error if failed to load the image.
01168 }
01169 
01170 
01171 void
01172 QtViewImp::
01173 drawLatex ( const std::string &eq, int position )
01174 {
01175   std::map< const std::string, std::string>::iterator it = m_eq_png.find(eq);
01176   if ( it!=m_eq_png.end() ) {
01177     drawImage (m_eq_png[eq], position);
01178   }
01179   else {
01180     // Work in the temp_latex directory
01181     assert(QDir::setCurrent("temp_latex"));
01182 
01183     // Generate the filenames. It's unique and based on the current time. Need millisecond accuracy.
01184     QString current_time = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
01185     QString tex_filename = "image"+current_time+".tex";
01186     QString png_filename = "image"+current_time+".png";
01187     QString ps_filename  = "image"+current_time+".ps";
01188     QString dvi_filename = "image"+current_time+".dvi";
01189     QString tmp_filename = "image"+current_time+".tmp";
01190     QString aux_filename = "image"+current_time+".aux";
01191     QString log_filename = "image"+current_time+".log";
01192 
01193     // Command 1 to 3 generate the png file and command 4 remove all temp files
01194     QString command1 = "latex -interaction=nonstopmode "+tex_filename+" > "+tmp_filename;
01195     QString command2 = "dvips -q -o "+ps_filename+" "+dvi_filename;
01196     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;
01197     QString command4 = "rm "+tex_filename+" "+ps_filename+" "+dvi_filename+" "+tmp_filename+" "+aux_filename+" "+log_filename;
01198     
01199     // Write the Latex text to file and call the commands to generate the image
01200     QFile file(tex_filename);
01201     if (file.open(IO_WriteOnly) ) {
01202       QTextStream stream(&file);
01203       // Generate the Latex file ( wither header and ending )
01204       stream << "\\documentclass{article}\n";
01205       stream << "\\pagestyle{empty}\n";
01206       stream << "\\usepackage{xspace,amssymb,amsfonts,amsmath}\n";
01207       stream << "\\usepackage{mathptmx}\n";
01208       stream << "\\usepackage{color}\n";
01209       stream << "\\begin{document}\n";
01210       stream << "\\begin{displaymath}\n";
01211       stream << eq.c_str() <<"\n";
01212       stream << "\\end{displaymath}\n";
01213       stream << "\\end{document}\n";
01214       file.close();
01215       
01216       system(command1.latin1());
01217       system(command2.latin1());
01218       system(command3.latin1());
01219       system(command4.latin1());
01220       
01221       std::string png_fn = png_filename.latin1();
01222       m_eq_png[eq]=png_fn;
01223       
01224       // Make sure return to the original working directory.
01225       QDir::setCurrent("..");
01226       drawImage(png_fn, position);
01227     } else {
01228       QDir::setCurrent("..");
01229       // TODO: Show error if failed to open the text file.
01230     }
01231   }
01232 }
01233 
01234 

Generated for HippoDraw Class Library by doxygen