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