00001
00013
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,
00192 int )
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 );
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
00744
00745
00746
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
00772 int delta_y = i_y - static_cast < int > ( rect.getY () );
00773 if ( delta_y > 0 ) {
00774 h += delta_y;
00775 }
00776
00777
00778 int delta_x = i_x - static_cast < int > ( rect.getX () );
00779 if ( delta_x > 0 ) {
00780 w += delta_x;
00781 }
00782
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
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;
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 ();
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
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
01019 QString fn ( ("temp_latex/"+filename).c_str() );
01020 switch ( position ){
01021 case 0:
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
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
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
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
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
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
01182 assert(QDir::setCurrent("temp_latex"));
01183
01184
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
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
01201 QFile file(tex_filename);
01202 if (file.open(IO_WriteOnly) ) {
01203 QTextStream stream(&file);
01204
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
01226 QDir::setCurrent("..");
01227 drawImage(png_fn, position);
01228 } else {
01229 QDir::setCurrent("..");
01230
01231 }
01232 }
01233 }
01234
01235