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

Generated for HippoDraw Class Library by doxygen