00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "qt.h"
00026
00027
00028 PLDLLIMPEXP_QT_DATA( int ) vectorize = 0;
00029 PLDLLIMPEXP_QT_DATA( int ) lines_aa = 1;
00030 PLDLLIMPEXP_QT_DATA( MasterHandler ) handler;
00031
00032
00033
00034 MasterHandler::MasterHandler() : QObject()
00035 {
00036 masterDevice = NULL;
00037 }
00038
00039 bool MasterHandler::isMasterDevice( QtPLDriver* d )
00040 {
00041 return d == masterDevice;
00042 }
00043
00044 void MasterHandler::setMasterDevice( QtPLDriver* d )
00045 {
00046 masterDevice = d;
00047 }
00048
00049 void MasterHandler::DeviceChangedPage( QtPLDriver* d )
00050 {
00051 if ( d == masterDevice )
00052 {
00053 emit MasterChangedPage();
00054 }
00055 }
00056
00057 void MasterHandler::DeviceClosed( QtPLDriver* d )
00058 {
00059 if ( d == masterDevice )
00060 {
00061 emit MasterClosed();
00062 masterDevice = NULL;
00063 }
00064 }
00065
00067 QMutex QtPLDriver::mutex;
00068
00069 QtPLDriver::QtPLDriver( PLINT i_iWidth, PLINT i_iHeight )
00070 {
00071 m_dWidth = i_iWidth;
00072 m_dHeight = i_iHeight;
00073 }
00074
00075 QtPLDriver::~QtPLDriver()
00076 {
00077 }
00078
00079 void QtPLDriver::setPLStream( PLStream *p )
00080 {
00081 pls = p;
00082 }
00083
00084 void QtPLDriver::drawArc( short x, short y, short a, short b, PLFLT angle1, PLFLT angle2, PLFLT rotate, bool fill )
00085 {
00086 if ( !m_painterP->isActive() )
00087 return;
00088 QRectF rect( (PLFLT) ( x - a ) * downscale,
00089 m_dHeight - (PLFLT) ( y + b ) * downscale,
00090 (PLFLT) a * downscale * 2,
00091 (PLFLT) b * downscale * 2
00092 );
00093 if ( rotate != 0.0 )
00094 {
00095 m_painterP->save();
00096 m_painterP->translate( (PLFLT) x * downscale, m_dHeight - (PLFLT) y * downscale );
00097 m_painterP->rotate( -rotate );
00098 m_painterP->translate( -(PLFLT) x * downscale, -m_dHeight + (PLFLT) y * downscale );
00099 }
00100
00101 if ( fill )
00102 m_painterP->drawPie( rect, (int) ( angle1 * 16 ), (int) ( ( angle2 - angle1 ) * 16 ) );
00103 else
00104 m_painterP->drawArc( rect, (int) ( angle1 * 16 ), (int) ( ( angle2 - angle1 ) * 16 ) );
00105
00106 if ( rotate != 0.0 )
00107 {
00108 m_painterP->restore();
00109 }
00110 }
00111
00112 void QtPLDriver::drawLine( short x1, short y1, short x2, short y2 )
00113 {
00114 if ( !m_painterP->isActive() )
00115 return;
00116 QLineF line( (PLFLT) x1 * downscale,
00117 m_dHeight - (PLFLT) y1 * downscale,
00118 (PLFLT) x2 * downscale,
00119 m_dHeight - (PLFLT) y2 * downscale
00120 );
00121
00122 m_painterP->drawLine( line );
00123 }
00124
00125 void QtPLDriver::drawPolyline( short * x, short * y, PLINT npts )
00126 {
00127 if ( !m_painterP->isActive() )
00128 return;
00129 QPointF * polyline = new QPointF[npts];
00130 for ( int i = 0; i < npts; ++i )
00131 {
00132 polyline[i].setX( (PLFLT) x[i] * downscale );
00133 polyline[i].setY( m_dHeight - (PLFLT) y[i] * downscale );
00134 }
00135 m_painterP->drawPolyline( polyline, npts );
00136 delete[] polyline;
00137 }
00138
00139 void QtPLDriver::drawPolygon( short * x, short * y, PLINT npts )
00140 {
00141 if ( !m_painterP->isActive() )
00142 return;
00143 QPointF * polygon = new QPointF[npts];
00144 for ( int i = 0; i < npts; ++i )
00145 {
00146 polygon[i].setX( (PLFLT) x[i] * downscale );
00147 polygon[i].setY( m_dHeight - (PLFLT) y[i] * downscale );
00148 }
00149 if ( plsc->dev_eofill )
00150 m_painterP->drawPolygon( polygon, npts, Qt::OddEvenFill );
00151 else
00152 m_painterP->drawPolygon( polygon, npts, Qt::WindingFill );
00153 delete[] polygon;
00154 }
00155
00156
00157 QFont QtPLDriver::getFont( PLUNICODE unicode )
00158 {
00159
00160 unsigned char fontFamily, fontStyle, fontWeight;
00161
00162 plP_fci2hex( unicode, &fontFamily, PL_FCI_FAMILY );
00163 plP_fci2hex( unicode, &fontStyle, PL_FCI_STYLE );
00164 plP_fci2hex( unicode, &fontWeight, PL_FCI_WEIGHT );
00165
00166 QFont f;
00167
00168 f.setPointSizeF( currentFontSize * currentFontScale < 4 ? 4 : currentFontSize * currentFontScale );
00169
00170 switch ( fontFamily )
00171 {
00172 case 1:
00173 f.setStyleHint( QFont::Serif );
00174 break;
00175 case 2:
00176 f.setStyleHint( QFont::TypeWriter );
00177 break;
00178 case 0: case 3: case 4: default:
00179 f.setStyleHint( QFont::SansSerif );
00180 break;
00181 }
00182 f.setFamily( "" );
00183
00184 if ( fontStyle )
00185 f.setItalic( true );
00186 if ( fontWeight )
00187 f.setWeight( QFont::Bold );
00188 else
00189 f.setWeight( QFont::Normal );
00190
00191 f.setUnderline( underlined );
00192 f.setOverline( overlined );
00193
00194 return f;
00195 }
00196
00197 void QtPLDriver::drawTextInPicture( QPainter* p, const QString& text )
00198 {
00199 QRectF rect( 0., 0., 0., 0. );
00200 QRectF bounding;
00201 QPicture tempPic;
00202 QPainter tempPainter( &tempPic );
00203 tempPainter.setFont( p->font() );
00204
00205 if ( vectorize )
00206 {
00207 bounding = tempPainter.boundingRect( rect, Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextDontClip, text );
00208
00209 tempPainter.save();
00210
00211 QPen pen = QPen( Qt::NoPen );
00212 tempPainter.setPen( pen );
00213
00214 double offset = QFontMetrics( tempPainter.font(), &tempPic ).boundingRect( text ).top();
00215
00216 QPainterPath path;
00217 path.addText( QPointF( bounding.left(), bounding.top() - offset ), tempPainter.font(), text );
00218 tempPainter.drawPath( path );
00219 tempPainter.restore();
00220 }
00221 else
00222 {
00223 tempPainter.drawText( rect, Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextDontClip, text, &bounding );
00224 }
00225
00226 tempPainter.end();
00227
00228 p->drawPicture( (int) ( xOffset + bounding.width() / 2. ), (int) -yOffset, tempPic );
00229
00230 xOffset += bounding.width();
00231 }
00232
00233
00234
00235
00236
00237
00238 # define RISE_FACTOR 0.8
00239
00240 QPicture QtPLDriver::getTextPicture( PLUNICODE fci, PLUNICODE* text, int len, PLFLT chrht )
00241 {
00242 char plplotEsc;
00243 plgesc( &plplotEsc );
00244
00245 QPicture res;
00246 QPainter p( &res );
00247
00248 QString currentString;
00249 PLFLT old_sscale, sscale, old_soffset, soffset;
00250 PLINT level = 0;
00251 PLFLT dyOffset = 0.;
00252
00253 yOffset = 0.;
00254 xOffset = 0.;
00255
00256
00257
00258
00259
00260 currentFontSize = chrht * POINTS_PER_INCH / 25.4 * 1.45;
00261 currentFontScale = 1.;
00262 underlined = false;
00263 overlined = false;
00264
00265 p.setFont( getFont( fci ) );
00266
00267 int i = 0;
00268 while ( i < len )
00269 {
00270 if ( text[i] < PL_FCI_MARK )
00271 {
00272 if ( text[i] != (PLUNICODE) plplotEsc )
00273 {
00274 currentString.append( QString( QChar( text[i] ) ) );
00275 ++i;
00276 continue;
00277 }
00278 ++i;
00279 switch ( text[i] )
00280 {
00281 case 'd':
00282 drawTextInPicture( &p, currentString );
00283 currentString.clear();
00284 plP_script_scale( FALSE, &level,
00285 &old_sscale, &sscale, &old_soffset, &soffset );
00286 currentFontScale = sscale;
00287
00288
00289
00290
00291
00292
00293
00294
00295 yOffset = -( currentFontSize * RISE_FACTOR * soffset + dyOffset );
00296
00297 p.setFont( getFont( fci ) );
00298 break;
00299
00300 case 'u':
00301 drawTextInPicture( &p, currentString );
00302
00303 currentString.clear();
00304 plP_script_scale( TRUE, &level,
00305 &old_sscale, &sscale, &old_soffset, &soffset );
00306 currentFontScale = sscale;
00307
00308
00309
00310
00311
00312
00313
00314
00315 yOffset = currentFontSize * RISE_FACTOR * soffset + dyOffset;
00316
00317 p.setFont( getFont( fci ) );
00318 break;
00319
00320 case '-':
00321 drawTextInPicture( &p, currentString );
00322
00323 currentString.clear();
00324 underlined = !underlined;
00325 p.setFont( getFont( fci ) );
00326 break;
00327
00328 case '+':
00329 drawTextInPicture( &p, currentString );
00330
00331 currentString.clear();
00332 overlined = !overlined;
00333 p.setFont( getFont( fci ) );
00334 break;
00335
00336
00337 case '#':
00338 currentString.append( QString( (QChar *) &( text[i] ), 1 ) );
00339 break;
00340
00341 default:
00342 std::cout << "unknown escape char " << ( (QChar) text[i] ).toLatin1() << std::endl;
00343 break;
00344 }
00345 }
00346 else
00347 {
00348 drawTextInPicture( &p, currentString );
00349
00350 currentString.clear();
00351 fci = text[i];
00352 p.setFont( getFont( fci ) );
00353 }
00354 ++i;
00355 }
00356 drawTextInPicture( &p, currentString );
00357
00358 p.end();
00359
00360 return res;
00361 }
00362
00363 void QtPLDriver::drawText( EscText* txt )
00364 {
00365 if ( !m_painterP->isActive() )
00366 return;
00367
00368
00369 if ( txt->unicode_array_len == 0 )
00370 {
00371 printf( "Non unicode string passed to a Qt driver, ignoring\n" );
00372 return;
00373 }
00374
00375
00376 if ( txt->unicode_array_len >= 500 )
00377 {
00378 printf( "Sorry, the Qt drivers only handle strings of length < %d\n", 500 );
00379 return;
00380 }
00381
00382 PLFLT rotation, shear, stride;
00383 plRotationShear( txt->xform, &rotation, &shear, &stride );
00384
00385 double picDpi;
00386 PLUNICODE fci;
00387 plgfci( &fci );
00388 QPicture picText = getTextPicture( fci, txt->unicode_array, txt->unicode_array_len, pls->chrht );
00389 picDpi = picText.logicalDpiY();
00390
00391 if ( pls->get_string_length )
00392 {
00393 pls->string_length = ( (PLFLT) xOffset / picDpi ) * 25.4;
00394 return;
00395 }
00396
00397 m_painterP->setClipping( true );
00398 m_painterP->setClipRect( QRect( (int) ( pls->clpxmi * downscale ), (int) ( m_dHeight - pls->clpyma * downscale ), (int) ( ( pls->clpxma - pls->clpxmi ) * downscale ), (int) ( ( pls->clpyma - pls->clpymi ) * downscale ) ), Qt::ReplaceClip );
00399
00400 rotation -= pls->diorot * M_PI / 2.0;
00401 m_painterP->translate( txt->x * downscale, m_dHeight - txt->y * downscale );
00402 QMatrix rotShearMatrix( cos( rotation ) * stride, -sin( rotation ) * stride, cos( rotation ) * sin( shear ) + sin( rotation ) * cos( shear ), -sin( rotation ) * sin( shear ) + cos( rotation ) * cos( shear ), 0., 0. );
00403
00404 m_painterP->setWorldMatrix( rotShearMatrix, true );
00405
00406 m_painterP->translate( -txt->just * xOffset * m_painterP->device()->logicalDpiY() / picDpi, 0. );
00407
00408 m_painterP->drawPicture( 0, 0, picText );
00409
00410 m_painterP->resetTransform();;
00411 m_painterP->setClipping( false );
00412 }
00413
00414 void QtPLDriver::setColor( int r, int g, int b, double alpha )
00415 {
00416 if ( !m_painterP->isActive() )
00417 return;
00418
00419 QPen p = m_painterP->pen();
00420 p.setColor( QColor( r, g, b, (int) ( alpha * 255 ) ) );
00421 m_painterP->setPen( p );
00422
00423 QBrush B = m_painterP->brush();
00424 B.setColor( QColor( r, g, b, (int) ( alpha * 255 ) ) );
00425 B.setStyle( Qt::SolidPattern );
00426 m_painterP->setBrush( B );
00427 }
00428
00429 void QtPLDriver::setGradient( int x1, int x2, int y1, int y2,
00430 unsigned char *r, unsigned char *g,
00431 unsigned char *b, PLFLT *alpha, PLINT ncol1 )
00432 {
00433 if ( !m_painterP->isActive() || ncol1 < 2 )
00434 return;
00435
00436 int i;
00437 qreal stop_arg;
00438 QLinearGradient linear_gradient;
00439 QGradientStops stops;
00440
00441 linear_gradient = QLinearGradient(
00442 QPointF( (qreal) ( x1 * downscale ), (qreal) ( m_dHeight - y1 * downscale ) ),
00443 QPointF( (qreal) ( x2 * downscale ), (qreal) ( m_dHeight - y2 * downscale ) ) );
00444
00445 for ( i = 0; i < ncol1; i++ )
00446 {
00447 stop_arg = (qreal) i / (qreal) ( ncol1 - 1 );
00448 stops << QGradientStop( stop_arg, QColor( r[i], g[i],
00449 b[i], (int) ( alpha[i] * 255 ) ) );
00450 }
00451 linear_gradient.setStops( stops );
00452 m_painterP->setBrush( linear_gradient );
00453 }
00454
00455 void QtPLDriver::setWidth( PLINT w )
00456 {
00457 if ( !m_painterP->isActive() )
00458 return;
00459
00460 QPen p = m_painterP->pen();
00461 p.setWidth( w );
00462 m_painterP->setPen( p );
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 void QtPLDriver::setSolid()
00481 {
00482 if ( !m_painterP->isActive() )
00483 return;
00484
00485 QPen p = m_painterP->pen();
00486 p.setStyle( Qt::SolidLine );
00487 m_painterP->setPen( p );
00488 }
00489
00491 #if defined ( PLD_bmpqt ) || defined ( PLD_jpgqt ) || defined ( PLD_pngqt ) || defined ( PLD_ppmqt ) || defined ( PLD_tiffqt )
00492 QtRasterDevice::QtRasterDevice( int i_iWidth, int i_iHeight ) :
00493 QtPLDriver( i_iWidth, i_iHeight ),
00494 QImage( i_iWidth, i_iHeight, QImage::Format_RGB32 )
00495 {
00496
00497
00498 m_painterP = new QPainter( this );
00499 QBrush b = m_painterP->brush();
00500 b.setStyle( Qt::SolidPattern );
00501 m_painterP->setBrush( b );
00502 m_painterP->setRenderHint( QPainter::Antialiasing, (bool) lines_aa );
00503 }
00504
00505 QtRasterDevice::~QtRasterDevice()
00506 {
00507 delete m_painterP;
00508 }
00509
00510 void QtRasterDevice::definePlotName( const char* fileName, const char* format )
00511 {
00512
00513 strncpy( this->format, format, 4 );
00514 this->format[4] = '\0';
00515
00516 this->fileName = QString( fileName );
00517 }
00518
00519 void QtRasterDevice::savePlot()
00520 {
00521 m_painterP->end();
00522 save( fileName, format, 85 );
00523
00524 m_painterP->begin( this );
00525 m_painterP->setRenderHint( QPainter::Antialiasing, (bool) lines_aa );
00526 QBrush b = m_painterP->brush();
00527 b.setStyle( Qt::SolidPattern );
00528 m_painterP->setBrush( b );
00529 }
00530
00531 void QtRasterDevice::setBackgroundColor( int r, int g, int b, double alpha )
00532 {
00533 if ( !m_painterP->isActive() )
00534 return;
00535
00536 QBrush brush( QColor( r, g, b, (int) ( alpha * 255 ) ) );
00537 m_painterP->fillRect( 0, 0, width(), height(), brush );
00538 }
00539 #endif
00540
00541 #if defined ( PLD_svgqt ) && QT_VERSION >= 0x040300
00542 QtSVGDevice::QtSVGDevice( int i_iWidth, int i_iHeight ) :
00543 QtPLDriver( i_iWidth, i_iHeight )
00544 {
00545 m_painterP = NULL;
00546 }
00547
00548 QtSVGDevice::~QtSVGDevice()
00549 {
00550 delete m_painterP;
00551 }
00552
00553 void QtSVGDevice::definePlotName( const char* fileName )
00554 {
00555 setFileName( QString( fileName ) );
00556 setResolution( POINTS_PER_INCH );
00557 setSize( QSize( (int) m_dWidth, (int) m_dHeight ) );
00558 #if QT_VERSION >= 0x040500
00559 setViewBox( QRect( 0, 0, (int) m_dWidth, (int) m_dHeight ) );
00560 #endif
00561
00562 m_painterP = new QPainter( this );
00563 }
00564
00565 void QtSVGDevice::savePlot()
00566 {
00567 m_painterP->end();
00568 }
00569
00570 void QtSVGDevice::setBackgroundColor( int r, int g, int b, double alpha )
00571 {
00572 if ( !m_painterP->isActive() )
00573 return;
00574
00575 QBrush brush( QColor( r, g, b, (int) ( alpha * 255 ) ) );
00576 m_painterP->fillRect( 0, 0, width(), height(), brush );
00577 }
00578 #endif
00579
00580 #if defined ( PLD_epsqt ) || defined ( PLD_pdfqt )
00581 QtEPSDevice::QtEPSDevice( int i_iWidth, int i_iHeight )
00582 {
00583 #if QT_VERSION < 0x040400
00584 setPageSize( QPrinter::A4 );
00585 #else
00586 setFullPage( true );
00587 setPaperSize( QSizeF( i_iHeight, i_iWidth ), QPrinter::Point );
00588 #endif
00589 setResolution( POINTS_PER_INCH );
00590 setColorMode( QPrinter::Color );
00591 setOrientation( QPrinter::Landscape );
00592 setPrintProgram( QString( "lpr" ) );
00593
00594 if ( i_iWidth <= 0 || i_iHeight <= 0 )
00595 {
00596 m_dWidth = pageRect().width();
00597 m_dHeight = pageRect().height();
00598 }
00599 else
00600 {
00601 m_dWidth = i_iWidth;
00602 m_dHeight = i_iHeight;
00603 }
00604 m_painterP = NULL;
00605 }
00606
00607 QtEPSDevice::~QtEPSDevice()
00608 {
00609 delete m_painterP;
00610 }
00611
00612 void QtEPSDevice::definePlotName( const char* fileName, int ifeps )
00613 {
00614 setOutputFileName( QString( fileName ) );
00615 if ( ifeps )
00616 {
00617 setOutputFormat( QPrinter::PostScriptFormat );
00618 }
00619 else
00620 {
00621 setOutputFormat( QPrinter::PdfFormat );
00622 }
00623
00624 m_painterP = new QPainter( this );
00625 }
00626
00627 void QtEPSDevice::savePlot()
00628 {
00629 m_painterP->end();
00630 }
00631
00632 void QtEPSDevice::setBackgroundColor( int r, int g, int b, double alpha )
00633 {
00634 if ( !m_painterP->isActive() )
00635 return;
00636
00637 QBrush brush( QColor( r, g, b, (int) ( alpha * 255 ) ) );
00638 m_painterP->fillRect( 0, 0, width(), height(), brush );
00639 }
00640 #endif
00641
00642 #if defined ( PLD_qtwidget ) || defined ( PLD_extqt )
00643 QtPLWidget::QtPLWidget( int i_iWidth, int i_iHeight, QWidget* parent ) :
00644 QWidget( parent ), QtPLDriver( i_iWidth, i_iHeight )
00645 {
00646 m_painterP = new QPainter;
00647
00648 m_dAspectRatio = m_dWidth / m_dHeight;
00649
00650 m_pixPixmap = NULL;
00651
00652 pageNumber = 0;
00653 resize( i_iWidth, i_iHeight );
00654 lastColour.r = -1;
00655 setVisible( true );
00656 QApplication::processEvents();
00657 redrawFromLastFlush = false;
00658 redrawAll = true;
00659
00660 NoPen = QPen( Qt::NoPen );
00661 NoPen.setWidthF( 0. );
00662
00663 locate_mode = 0;
00664 }
00665
00666 QtPLWidget::~QtPLWidget()
00667 {
00668 clearBuffer();
00669 delete m_pixPixmap;
00670 }
00671
00672 void QtPLWidget::clearWidget()
00673 {
00674 clearBuffer();
00675 setBackgroundColor( bgColour.r, bgColour.g, bgColour.b, bgColour.alpha );
00676 redrawAll = true;
00677
00678 update();
00679 }
00680
00681 void QtPLWidget::flush()
00682 {
00683 repaint();
00684 QApplication::processEvents();
00685 }
00686
00687 void QtPLWidget::clearBuffer()
00688 {
00689 lastColour.r = -1;
00690 for ( QLinkedList<BufferElement>::iterator i = m_listBuffer.begin(); i != m_listBuffer.end(); ++i )
00691 {
00692 switch ( i->Element )
00693 {
00694 case LINE:
00695 delete i->Data.Line;
00696 break;
00697 case RECTANGLE:
00698 delete i->Data.Rect;
00699 break;
00700
00701 case POLYLINE:
00702 case POLYGON:
00703 delete i->Data.Polyline;
00704 break;
00705
00706 case TEXT:
00707 delete[] i->Data.TextStruct->text;
00708 delete i->Data.TextStruct;
00709 break;
00710
00711 case SET_COLOUR:
00712 case SET_BG_COLOUR:
00713 delete i->Data.ColourStruct;
00714 break;
00715
00716 case SET_GRADIENT:
00717 delete i->Data.LinearGradient;
00718 break;
00719
00720 case ARC:
00721 delete i->Data.ArcStruct->rect;
00722 delete i->Data.ArcStruct->dx;
00723 delete i->Data.ArcStruct;
00724
00725 default:
00726 break;
00727 }
00728 }
00729
00730 m_listBuffer.clear();
00731 start_iterator = m_listBuffer.constBegin();
00732 redrawAll = true;
00733 }
00734
00735
00736 void QtPLWidget::drawArc( short x, short y, short a, short b, PLFLT angle1, PLFLT angle2, PLFLT rotate, bool fill )
00737 {
00738 BufferElement el;
00739 el.Element = ARC;
00740 el.Data.ArcStruct = new struct ArcStruct_;
00741 el.Data.ArcStruct->rect = new QRectF( (PLFLT) ( x - a ) * downscale,
00742 m_dHeight - (PLFLT) ( y + b ) * downscale,
00743 (PLFLT) a * downscale * 2,
00744 (PLFLT) b * downscale * 2
00745 );
00746 el.Data.ArcStruct->startAngle = (int) ( angle1 * 16 );
00747 el.Data.ArcStruct->spanAngle = (int) ( ( angle2 - angle1 ) * 16 );
00748 el.Data.ArcStruct->rotate = rotate;
00749 el.Data.ArcStruct->dx = new QPointF( (PLFLT) x * downscale, m_dHeight - (PLFLT) y * downscale );
00750 el.Data.ArcStruct->fill = fill;
00751
00752 m_listBuffer.append( el );
00753 redrawFromLastFlush = true;
00754 }
00755
00756
00757 void QtPLWidget::drawLine( short x1, short y1, short x2, short y2 )
00758 {
00759 BufferElement el;
00760 el.Element = LINE;
00761 el.Data.Line = new QLineF( QPointF( (PLFLT) x1 * downscale, (PLFLT) ( m_dHeight - y1 * downscale ) ), QPointF( (PLFLT) x2 * downscale, (PLFLT) ( m_dHeight - y2 * downscale ) ) );
00762
00763 m_listBuffer.append( el );
00764 redrawFromLastFlush = true;
00765 }
00766
00767 void QtPLWidget::drawPolyline( short * x, short * y, PLINT npts )
00768 {
00769 BufferElement el;
00770 el.Element = POLYLINE;
00771 el.Data.Polyline = new QPolygonF;
00772 for ( int i = 0; i < npts; ++i )
00773 {
00774 ( *el.Data.Polyline ) << QPointF( (PLFLT) ( x[i] ) * downscale, (PLFLT) ( m_dHeight - ( y[i] ) * downscale ) );
00775 }
00776
00777 m_listBuffer.append( el );
00778 redrawFromLastFlush = true;
00779 }
00780
00781 void QtPLWidget::drawPolygon( short * x, short * y, PLINT npts )
00782 {
00783 BufferElement el;
00784
00785 bool isRect = false;
00786 if ( npts == 4 )
00787 {
00788 if ( x[0] == x[1] && x[2] == x[3] && y[0] == y[3] && y[1] == y[2] )
00789 {
00790 isRect = true;
00791 }
00792 else if ( x[0] == x[3] && x[1] == x[2] && y[0] == y[1] && y[2] == y[3] )
00793 {
00794 isRect = true;
00795 }
00796 }
00797 if ( npts == 5 )
00798 {
00799 if ( x[0] == x[4] && y[0] == y[4] )
00800 {
00801 if ( x[0] == x[1] && x[2] == x[3] && y[0] == y[3] && y[1] == y[2] )
00802 {
00803 isRect = true;
00804 }
00805 else if ( x[0] == x[3] && x[1] == x[2] && y[0] == y[1] && y[2] == y[3] )
00806 {
00807 isRect = true;
00808 }
00809 }
00810 }
00811
00812 if ( isRect )
00813 {
00814 el.Element = RECTANGLE;
00815
00816 double x1, y1, x2, y2, x0, y0, width, height;
00817 x1 = (PLFLT) ( x[0] ) * downscale;
00818 x2 = (PLFLT) ( x[2] ) * downscale;
00819 y1 = (PLFLT) ( m_dHeight - ( y[0] ) * downscale );
00820 y2 = (PLFLT) ( m_dHeight - ( y[2] ) * downscale );
00821 if ( x1 < x2 )
00822 {
00823 x0 = x1;
00824 width = x2 - x1;
00825 }
00826 else
00827 {
00828 x0 = x2;
00829 width = x1 - x2;
00830 }
00831 if ( y1 < y2 )
00832 {
00833 y0 = y1;
00834 height = y2 - y1;
00835 }
00836 else
00837 {
00838 y0 = y2;
00839 height = y1 - y2;
00840 }
00841 el.Data.Rect = new QRectF( x0, y0, width, height );
00842 }
00843 else
00844 {
00845 el.Element = POLYGON;
00846 el.Data.Polyline = new QPolygonF;
00847 for ( int i = 0; i < npts; ++i )
00848 {
00849 ( *el.Data.Polyline ) << QPointF( (PLFLT) ( x[i] ) * downscale, (PLFLT) ( m_dHeight - ( y[i] ) * downscale ) );
00850 }
00851 }
00852
00853 m_listBuffer.append( el );
00854 redrawFromLastFlush = true;
00855 }
00856
00857 void QtPLWidget::setColor( int r, int g, int b, double alpha )
00858 {
00859 if ( lastColour.r != r || lastColour.g != g || lastColour.b != b || lastColour.alpha != alpha )
00860 {
00861 BufferElement el;
00862 el.Element = SET_COLOUR;
00863 el.Data.ColourStruct = new struct ColourStruct_;
00864 el.Data.ColourStruct->R = r;
00865 el.Data.ColourStruct->G = g;
00866 el.Data.ColourStruct->B = b;
00867 el.Data.ColourStruct->A = (PLINT) ( alpha * 255. );
00868
00869 m_listBuffer.append( el );
00870
00871 lastColour.r = r;
00872 lastColour.g = g;
00873 lastColour.b = b;
00874 lastColour.alpha = alpha;
00875 }
00876
00877
00878 }
00879
00880 void QtPLWidget::setGradient( int x1, int x2, int y1, int y2,
00881 unsigned char *r, unsigned char *g,
00882 unsigned char *b, PLFLT *alpha, PLINT ncol1 )
00883 {
00884 int i;
00885 BufferElement el;
00886 qreal stop_arg;
00887 QGradientStops stops;
00888
00889 el.Element = SET_GRADIENT;
00890
00891 el.Data.LinearGradient = new QLinearGradient;
00892 *el.Data.LinearGradient = QLinearGradient(
00893 QPointF( (qreal) ( x1 * downscale ), (qreal) ( m_dHeight - y1 * downscale ) ),
00894 QPointF( (qreal) ( x2 * downscale ), (qreal) ( m_dHeight - y2 * downscale ) ) );
00895 for ( i = 0; i < ncol1; i++ )
00896 {
00897 stop_arg = (qreal) i / (qreal) ( ncol1 - 1 );
00898 stops << QGradientStop( stop_arg, QColor( r[i], g[i],
00899 b[i], (int) ( alpha[i] * 255 ) ) );
00900 }
00901 ( *el.Data.LinearGradient ).setStops( stops );
00902 m_listBuffer.append( el );
00903
00904
00905
00906
00907 }
00908
00909 void QtPLWidget::setBackgroundColor( int r, int g, int b, double alpha )
00910 {
00911 BufferElement el;
00912 el.Element = SET_BG_COLOUR;
00913 el.Data.ColourStruct = new struct ColourStruct_;
00914 el.Data.ColourStruct->R = r;
00915 el.Data.ColourStruct->G = g;
00916 el.Data.ColourStruct->B = b;
00917 el.Data.ColourStruct->A = (PLINT) ( alpha * 255. );
00918
00919 bgColour.r = r;
00920 bgColour.g = g;
00921 bgColour.b = b;
00922 bgColour.alpha = alpha;
00923 if ( alpha >= 0.999 )
00924 {
00925 clearBuffer();
00926 }
00927 m_listBuffer.append( el );
00928 redrawFromLastFlush = true;
00929 }
00930
00931 void QtPLWidget::setWidth( PLINT w )
00932 {
00933 BufferElement el;
00934 el.Element = SET_WIDTH;
00935 el.Data.intParam = w;
00936 m_listBuffer.append( el );
00937
00938 }
00939
00940 void QtPLWidget::drawText( EscText* txt )
00941 {
00942 if ( pls->get_string_length )
00943 {
00944 PLUNICODE fci;
00945 QPicture picText;
00946 double picDpi;
00947 PLUNICODE *text;
00948
00949 plgfci( &fci );
00950 text = new PLUNICODE[txt->unicode_array_len];
00951 memcpy( text, txt->unicode_array, txt->unicode_array_len * sizeof ( PLUNICODE ) );
00952 picText = getTextPicture( fci,
00953 text,
00954 txt->unicode_array_len,
00955 pls->chrht );
00956
00957
00958
00959
00960
00961
00962
00963 picDpi = picText.logicalDpiY();
00964 pls->string_length = ( (PLFLT) xOffset / picDpi ) * 25.4;
00965 delete[] text;
00966 return;
00967 }
00968
00969 BufferElement el;
00970
00971 el.Element = TEXT;
00972 el.Data.TextStruct = new struct TextStruct_;
00973 el.Data.TextStruct->x = txt->x * downscale;
00974 el.Data.TextStruct->y = m_dHeight - txt->y * downscale;
00975 el.Data.TextStruct->clipxmin = pls->clpxmi * downscale;
00976 el.Data.TextStruct->clipymin = m_dHeight - pls->clpymi * downscale;
00977 el.Data.TextStruct->clipxmax = pls->clpxma * downscale;
00978 el.Data.TextStruct->clipymax = m_dHeight - pls->clpyma * downscale;
00979 PLUNICODE fci;
00980 plgfci( &fci );
00981 el.Data.TextStruct->fci = fci;
00982 PLFLT rotation, shear, stride;
00983 plRotationShear( txt->xform, &rotation, &shear, &stride );
00984 rotation -= pls->diorot * M_PI / 2.0;
00985 el.Data.TextStruct->rotation = rotation;
00986 el.Data.TextStruct->shear = shear;
00987 el.Data.TextStruct->stride = stride;
00988 el.Data.TextStruct->just = txt->just;
00989 el.Data.TextStruct->text = new PLUNICODE[txt->unicode_array_len];
00990 memcpy( el.Data.TextStruct->text, txt->unicode_array, txt->unicode_array_len * sizeof ( PLUNICODE ) );
00991 el.Data.TextStruct->len = txt->unicode_array_len;
00992 el.Data.TextStruct->chrht = pls->chrht;
00993
00994 m_listBuffer.append( el );
00995 redrawFromLastFlush = true;
00996 }
00997
00998 void QtPLWidget::renderText( QPainter* p, struct TextStruct_* s, double x_fact, double x_offset, double y_fact, double y_offset )
00999 {
01000 if ( s->len <= 0 || s->len >= 500 )
01001 return;
01002 QPicture picText = getTextPicture( s->fci, s->text, s->len, s->chrht * y_fact );
01003
01004 double picDpi = picText.logicalDpiY();
01005
01006 p->setClipping( true );
01007 p->setClipRect( QRectF( s->clipxmin * x_fact + x_offset, s->clipymax * y_fact + y_offset, ( s->clipxmax - s->clipxmin ) * x_fact, ( -s->clipymax + s->clipymin ) * y_fact ), Qt::ReplaceClip );
01008 p->translate( s->x * x_fact + x_offset, s->y * y_fact + y_offset );
01009 QMatrix rotShearMatrix( cos( s->rotation ) * s->stride, -sin( s->rotation ) * s->stride, cos( s->rotation ) * sin( s->shear ) + sin( s->rotation ) * cos( s->shear ), -sin( s->rotation ) * sin( s->shear ) + cos( s->rotation ) * cos( s->shear ), 0., 0. );
01010 p->setWorldMatrix( rotShearMatrix, true );
01011
01012 p->translate( -s->just * xOffset * p->device()->logicalDpiY() / picDpi, 0. );
01013
01014 p->drawPicture( 0, 0, picText );
01015
01016 p->resetTransform();
01017
01018 p->setClipping( false );
01019 }
01020
01021 void QtPLWidget::resetPensAndBrushes( QPainter* painter )
01022 {
01023 SolidPen = QPen();
01024 hasPen = true;
01025 painter->setPen( SolidPen );
01026 SolidBrush = QBrush( Qt::SolidPattern );
01027 }
01028
01029 void QtPLWidget::lookupButtonEvent( QMouseEvent * event )
01030 {
01031 Qt::MouseButtons buttons = event->buttons();
01032 Qt::KeyboardModifiers modifiers = event->modifiers();
01033 gin.pX = event->x();
01034 gin.pY = height() - event->y();
01035 gin.dX = (PLFLT) event->x() / width();
01036 gin.dY = (PLFLT) ( height() - event->y() ) / height();
01037
01038 switch ( event->button() )
01039 {
01040 case Qt::LeftButton:
01041 gin.button = 1;
01042 break;
01043 case Qt::MidButton:
01044 gin.button = 2;
01045 break;
01046 case Qt::RightButton:
01047 gin.button = 3;
01048 break;
01049 }
01050
01051
01052
01053 gin.state = 0;
01054 if ( buttons & Qt::LeftButton )
01055 gin.state |= 1 << 8;
01056 if ( buttons & Qt::MidButton )
01057 gin.state |= 1 << 9;
01058 if ( buttons & Qt::RightButton )
01059 gin.state |= 1 << 10;
01060 if ( modifiers & Qt::ShiftModifier )
01061 gin.state |= 1 << 0;
01062 if ( modifiers & Qt::ControlModifier )
01063 gin.state |= 1 << 2;
01064 if ( modifiers & Qt::AltModifier )
01065 gin.state |= 1 << 3;
01066 if ( modifiers & Qt::MetaModifier )
01067 gin.state |= 1 << 3;
01068
01069 gin.keysym = 0x20;
01070 }
01071
01072 void QtPLWidget::locate()
01073 {
01074 if ( plTranslateCursor( &gin ) )
01075 {
01076 if ( locate_mode == 2 )
01077 {
01078 pltext();
01079 if ( gin.keysym < 0xFF && isprint( gin.keysym ) )
01080 std::cout << gin.wX << " " << gin.wY << " " << (char) gin.keysym << std::endl;
01081 else
01082 std::cout << gin.wX << " " << gin.wY << " " << std::hex << gin.keysym << std::endl;
01083
01084 plgra();
01085 }
01086 }
01087 else
01088 {
01089 locate_mode = 0;
01090 QApplication::restoreOverrideCursor();
01091 }
01092 }
01093
01094 void QtPLWidget::mouseEvent( QMouseEvent * event )
01095 {
01096 lookupButtonEvent( event );
01097
01098 if ( locate_mode )
01099 {
01100 if ( event->button() == Qt::LeftButton )
01101 {
01102 locate();
01103 }
01104 }
01105 else
01106 {
01107 if ( event->button() == Qt::RightButton )
01108 {
01109 handler.DeviceChangedPage( this );
01110 }
01111 }
01112 }
01113
01114 void QtPLWidget::mousePressEvent( QMouseEvent * event )
01115 {
01116 mouseEvent( event );
01117 }
01118
01119 void QtPLWidget::mouseReleaseEvent( QMouseEvent * event )
01120 {
01121 mouseEvent( event );
01122 }
01123
01124 void QtPLWidget::mouseMoveEvent( QMouseEvent * event )
01125 {
01126 mouseEvent( event );
01127 }
01128
01129 void QtPLWidget::keyPressEvent( QKeyEvent* event )
01130 {
01131 if ( locate_mode )
01132 {
01133 Qt::KeyboardModifiers modifiers = event->modifiers();
01134 QPoint p = QCursor::pos();
01135 gin.pX = p.x();
01136 gin.pY = height() - p.y();
01137 gin.dX = (PLFLT) p.x() / width();
01138 gin.dY = (PLFLT) ( height() - p.y() ) / height();
01139
01140 switch ( event->key() )
01141 {
01142 case Qt::Key_Escape:
01143 locate_mode = 0;
01144 QApplication::restoreOverrideCursor();
01145 plGinInit( &gin );
01146 break;
01147 case Qt::Key_Shift:
01148 case Qt::Key_Control:
01149 case Qt::Key_Alt:
01150 case Qt::Key_Meta:
01151 case Qt::Key_AltGr:
01152 plGinInit( &gin );
01153 case Qt::Key_Left:
01154 case Qt::Key_Right:
01155 case Qt::Key_Up:
01156 case Qt::Key_Down:
01157 {
01158 int x1, y1, dx = 0, dy = 0;
01159 int xmin = 0, xmax = width() - 1, ymin = 0, ymax = height() - 1;
01160 switch ( event->key() )
01161 {
01162 case Qt::Key_Left:
01163 dx = -1;
01164 break;
01165 case Qt::Key_Right:
01166 dx = 1;
01167 break;
01168 case Qt::Key_Up:
01169 dy = -1;
01170 break;
01171 case Qt::Key_Down:
01172 dy = 1;
01173 break;
01174 }
01175 if ( event->modifiers() & Qt::ShiftModifier )
01176 {
01177 dx *= 5;
01178 dy *= 5;
01179 }
01180 if ( event->modifiers() & Qt::ControlModifier )
01181 {
01182 dx *= 5;
01183 dy *= 5;
01184 }
01185 if ( event->modifiers() & Qt::AltModifier )
01186 {
01187 dx *= 5;
01188 dy *= 5;
01189 }
01190 x1 = gin.pX + dx;
01191 y1 = gin.pY + dy;
01192
01193 if ( x1 < xmin )
01194 dx = xmin - gin.pX;
01195 if ( y1 < ymin )
01196 dy = ymin - gin.pY;
01197 if ( x1 > xmax )
01198 dx = xmax - gin.pX;
01199 if ( y1 > ymax )
01200 dy = ymax - gin.pY;
01201
01202 QCursor::setPos( p.x() + dx, p.y() + dy );
01203 plGinInit( &gin );
01204 break;
01205 }
01206 default:
01207 locate();
01208 break;
01209 }
01210 }
01211 else
01212 {
01213 if ( event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return )
01214 {
01215 handler.DeviceChangedPage( this );
01216 }
01217 if ( event->text() == "Q" )
01218 {
01219
01220 pls->nopause = TRUE;
01221 plexit( "" );
01222 }
01223 else if ( event->text() == "L" )
01224
01225 {
01226 locate_mode = 2;
01227 QApplication::setOverrideCursor( Qt::CrossCursor );
01228 }
01229 }
01230 }
01231
01232 void QtPLWidget::closeEvent( QCloseEvent* event )
01233 {
01234 handler.DeviceClosed( this );
01235 event->ignore();
01236 }
01237
01238 void QtPLWidget::nextPage()
01239 {
01240 clearWidget();
01241 pageNumber++;
01242 }
01243
01244 void QtPLWidget::resizeEvent( QResizeEvent * )
01245 {
01246
01247 redrawAll = true;
01248 delete m_pixPixmap;
01249 m_pixPixmap = NULL;
01250 }
01251
01252 void QtPLWidget::paintEvent( QPaintEvent * )
01253 {
01254 double x_fact, y_fact, x_offset( 0. ), y_offset( 0. );
01255
01256 getPlotParameters( x_fact, y_fact, x_offset, y_offset );
01257
01258 if ( redrawAll || m_pixPixmap == NULL )
01259 {
01260 if ( m_pixPixmap != NULL )
01261 {
01262 delete m_pixPixmap;
01263 }
01264 m_pixPixmap = new QPixmap( width(), height() );
01265 QPainter* painter = new QPainter;
01266 painter->begin( m_pixPixmap );
01267
01268
01269 painter->fillRect( 0, 0, width(), height(), QBrush( Qt::white ) );
01270 painter->fillRect( 0, 0, width(), height(), QBrush( Qt::gray, Qt::Dense4Pattern ) );
01271
01272
01273 resetPensAndBrushes( painter );
01274
01275 start_iterator = m_listBuffer.constBegin();
01276
01277
01278 doPlot( painter, x_fact, y_fact, x_offset, y_offset );
01279 painter->end();
01280
01281
01282
01283 delete painter;
01284 }
01285 else
01286 {
01287 QPainter* painter = new QPainter;
01288 painter->begin( m_pixPixmap );
01289 if ( hasPen )
01290 painter->setPen( SolidPen );
01291 else
01292 painter->setPen( NoPen );
01293
01294
01295 doPlot( painter, x_fact, y_fact, x_offset, y_offset );
01296 painter->end();
01297 }
01298
01299
01300 m_painterP->begin( this );
01301
01302 m_painterP->drawPixmap( 0, 0, *m_pixPixmap );
01303
01304 m_painterP->end();
01305 }
01306
01307 void QtPLWidget::doPlot( QPainter* p, double x_fact, double y_fact, double x_offset, double y_offset )
01308 {
01309 QLineF line;
01310 QVector<qreal> vect;
01311 QRectF rect;
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321 p->setRenderHints( QPainter::Antialiasing, (bool) lines_aa );
01322
01323
01324 p->setBrush( SolidBrush );
01325
01326 QTransform trans;
01327 trans = trans.translate( x_offset, y_offset );
01328 trans = trans.scale( x_fact, y_fact );
01329
01330 p->setTransform( trans );
01331
01332 if ( m_listBuffer.empty() )
01333 {
01334 p->fillRect( 0, 0, 1, 1, QBrush() );
01335 return;
01336 }
01337
01338
01339 for ( QLinkedList<BufferElement>::const_iterator i = start_iterator; i != m_listBuffer.constEnd(); ++i )
01340 {
01341 switch ( i->Element )
01342 {
01343 case SET_COLOUR:
01344 SolidPen.setColor( QColor( i->Data.ColourStruct->R, i->Data.ColourStruct->G, i->Data.ColourStruct->B, i->Data.ColourStruct->A ) );
01345 if ( hasPen )
01346 {
01347 p->setPen( SolidPen );
01348 }
01349 SolidBrush.setColor( QColor( i->Data.ColourStruct->R, i->Data.ColourStruct->G, i->Data.ColourStruct->B, i->Data.ColourStruct->A ) );
01350 p->setBrush( SolidBrush );
01351 break;
01352
01353 case SET_GRADIENT:
01354 p->setBrush( *( i->Data.LinearGradient ) );
01355 break;
01356
01357 case LINE:
01358 if ( !hasPen )
01359 {
01360 p->setPen( SolidPen );
01361 hasPen = true;
01362 }
01363 p->drawLine( *( i->Data.Line ) );
01364
01365 break;
01366
01367 case POLYLINE:
01368 if ( !hasPen )
01369 {
01370 p->setPen( SolidPen );
01371 hasPen = true;
01372 }
01373 p->drawPolyline( *( i->Data.Polyline ) );
01374 break;
01375
01376 case RECTANGLE:
01377 p->setRenderHints( QPainter::Antialiasing, false );
01378 if ( hasPen )
01379 {
01380 p->setPen( NoPen );
01381 hasPen = false;
01382 }
01383 p->drawRect( *( i->Data.Rect ) );
01384 p->setRenderHints( QPainter::Antialiasing, (bool) lines_aa );
01385 break;
01386
01387 case POLYGON:
01388 p->setRenderHints( QPainter::Antialiasing, false );
01389 if ( hasPen )
01390 {
01391 p->setPen( NoPen );
01392 hasPen = false;
01393 }
01394 if ( plsc->dev_eofill )
01395 p->drawPolygon( *( i->Data.Polyline ), Qt::OddEvenFill );
01396 else
01397 p->drawPolygon( *( i->Data.Polyline ), Qt::WindingFill );
01398 p->setRenderHints( QPainter::Antialiasing, (bool) lines_aa );
01399 break;
01400
01401 case TEXT:
01402 if ( !hasPen )
01403 {
01404 p->setPen( SolidPen );
01405 hasPen = true;
01406 }
01407 p->save();
01408 p->resetTransform();
01409
01410 renderText( p, i->Data.TextStruct, x_fact, x_offset, y_fact, y_offset );
01411 p->restore();
01412 break;
01413
01414 case SET_WIDTH:
01415 SolidPen.setWidthF( i->Data.intParam );
01416 if ( hasPen )
01417 {
01418 p->setPen( SolidPen );
01419 }
01420 break;
01421
01422 case SET_BG_COLOUR:
01423 SolidBrush.setColor( QColor( i->Data.ColourStruct->R, i->Data.ColourStruct->G, i->Data.ColourStruct->B, i->Data.ColourStruct->A ) );
01424 p->fillRect( 0, 0, (int) m_dWidth, (int) m_dHeight, SolidBrush );
01425 break;
01426
01427 case ARC:
01428 if ( !hasPen )
01429 {
01430 p->setPen( SolidPen );
01431 hasPen = true;
01432 }
01433 if ( i->Data.ArcStruct->rotate != 0.0 )
01434 {
01435 p->save();
01436 p->translate( *( i->Data.ArcStruct->dx ) );
01437 p->rotate( -i->Data.ArcStruct->rotate );
01438 p->translate( -*( i->Data.ArcStruct->dx ) );
01439 }
01440
01441 if ( i->Data.ArcStruct->fill )
01442 p->drawPie( *( i->Data.ArcStruct->rect ), i->Data.ArcStruct->startAngle, i->Data.ArcStruct->spanAngle );
01443 else
01444 p->drawArc( *( i->Data.ArcStruct->rect ), i->Data.ArcStruct->startAngle, i->Data.ArcStruct->spanAngle );
01445
01446 if ( i->Data.ArcStruct->rotate != 0.0 )
01447 {
01448 p->restore();
01449 }
01450
01451 break;
01452 default:
01453 break;
01454 }
01455 }
01456
01457 start_iterator = m_listBuffer.constEnd();
01458 --start_iterator;
01459 redrawFromLastFlush = false;
01460 redrawAll = false;
01461 }
01462
01463 void QtPLWidget::getPlotParameters( double & io_dXFact, double & io_dYFact, double & io_dXOffset, double & io_dYOffset )
01464 {
01465 double w = (double) width();
01466 double h = (double) height();
01467 if ( w / h > m_dAspectRatio )
01468 {
01469 io_dYFact = h / m_dHeight;
01470 io_dXFact = h * m_dAspectRatio / m_dWidth;
01471 io_dYOffset = 0.;
01472 io_dXOffset = ( w - io_dXFact * m_dWidth ) / 2.;
01473 }
01474 else
01475 {
01476 io_dXFact = w / m_dWidth;
01477 io_dYFact = w / m_dAspectRatio / m_dHeight;
01478 io_dXOffset = 0.;
01479 io_dYOffset = ( h - io_dYFact * m_dHeight ) / 2.;
01480 }
01481 }
01482
01483 void QtPLWidget::getCursorCmd( PLGraphicsIn *ptr )
01484 {
01485 plGinInit( &gin );
01486
01487 locate_mode = 1;
01488 QApplication::setOverrideCursor( Qt::CrossCursor );
01489
01490 while ( gin.pX < 0 && locate_mode )
01491 QCoreApplication::processEvents( QEventLoop::AllEvents, 10 );
01492
01493 QApplication::restoreOverrideCursor();
01494 *ptr = gin;
01495 }
01496
01497 #endif
01498
01499 #if defined ( PLD_extqt )
01500 QtExtWidget::QtExtWidget( int i_iWidth, int i_iHeight, QWidget* parent ) :
01501 QtPLWidget( i_iWidth, i_iHeight, parent )
01502 {
01503 cursorParameters.isTracking = false;
01504 cursorParameters.cursor_x = -1.0;
01505 cursorParameters.cursor_y = -1.0;
01506 killed = false;
01507 }
01508
01509 QtExtWidget::~QtExtWidget()
01510 {
01511 killed = true;
01512 QCoreApplication::processEvents( QEventLoop::AllEvents, 10 );
01513 delete m_pixPixmap;
01514 delete m_painterP;
01515 m_pixPixmap = NULL;
01516 m_painterP = NULL;
01517 }
01518
01519 void QtExtWidget::captureMousePlotCoords( PLFLT* x, PLFLT* y )
01520 {
01521 setMouseTracking( true );
01522 cursorParameters.isTracking = true;
01523 cursorParameters.cursor_x =
01524 cursorParameters.cursor_y = -1.;
01525 do
01526 {
01527 QCoreApplication::processEvents( QEventLoop::AllEvents, 10 );
01528 } while ( cursorParameters.isTracking && !killed );
01529
01530 *x = cursorParameters.cursor_x;
01531 *y = cursorParameters.cursor_y;
01532 }
01533
01534 void QtExtWidget::mouseMoveEvent( QMouseEvent* event )
01535 {
01536 if ( !cursorParameters.isTracking )
01537 return;
01538
01539 double x_fact, y_fact, x_offset, y_offset;
01540
01541 getPlotParameters( x_fact, y_fact, x_offset, y_offset );
01542
01543 cursorParameters.cursor_x = (PLFLT) event->x();
01544 cursorParameters.cursor_y = (PLFLT) event->y();
01545
01546 double ratio_x;
01547 double ratio_y;
01548 ratio_x = ( cursorParameters.cursor_x - x_offset ) / ( width() - 2. * x_offset );
01549 ratio_y = ( cursorParameters.cursor_y - y_offset ) / ( height() - 2. * y_offset );
01550
01551 PLFLT a, b;
01552 PLINT c;
01553 plcalc_world( ratio_x, 1. - ratio_y, &a, &b, &c );
01554
01555 if ( c < 0 )
01556 {
01557 cursorParameters.cursor_x = -1.;
01558 cursorParameters.cursor_y = -1.;
01559 }
01560
01561 update();
01562 }
01563
01564 void QtExtWidget::mousePressEvent( QMouseEvent* event )
01565 {
01566 }
01567
01568 void QtExtWidget::mouseReleaseEvent( QMouseEvent* event )
01569 {
01570 if ( !cursorParameters.isTracking )
01571 return;
01572
01573 double x_fact, y_fact, x_offset, y_offset;
01574
01575 getPlotParameters( x_fact, y_fact, x_offset, y_offset );
01576
01577 cursorParameters.cursor_x = (PLFLT) event->x();
01578 cursorParameters.cursor_y = (PLFLT) event->y();
01579 cursorParameters.isTracking = false;
01580 setMouseTracking( false );
01581
01582 double ratio_x;
01583 double ratio_y;
01584 ratio_x = ( cursorParameters.cursor_x - x_offset ) / ( width() - 2. * x_offset );
01585 ratio_y = ( cursorParameters.cursor_y - y_offset ) / ( height() - 2. * y_offset );
01586
01587 PLFLT a, b;
01588 PLINT c;
01589 plcalc_world( ratio_x, 1. - ratio_y, &a, &b, &c );
01590
01591 if ( c < 0 )
01592 {
01593 cursorParameters.cursor_x = -1.;
01594 cursorParameters.cursor_y = -1.;
01595 }
01596 else
01597 {
01598 cursorParameters.cursor_x = a;
01599 cursorParameters.cursor_y = b;
01600 }
01601
01602 update();
01603 }
01604
01605 void QtExtWidget::paintEvent( QPaintEvent* event )
01606 {
01607 QtPLWidget::paintEvent( event );
01608
01609 if ( !cursorParameters.isTracking || cursorParameters.cursor_x < 0 )
01610 return;
01611
01612 QPainter p( this );
01613
01614 p.setPen( QPen( Qt::white ) );
01615
01616 p.drawLine( (int) cursorParameters.cursor_x, 0, (int) cursorParameters.cursor_x, height() );
01617 p.drawLine( 0, (int) cursorParameters.cursor_y, width(), (int) cursorParameters.cursor_y );
01618
01619 p.end();
01620 }
01621
01622 void plsetqtdev( QtExtWidget* widget )
01623 {
01624 plsc->dev = (void *) widget;
01625 widget->setPLStream( plsc );
01626 }
01627
01628 void plsetqtdev( QtExtWidget* widget, int argc, char** argv )
01629 {
01630 plparseopts( &argc, (const char **) argv, PL_PARSE_FULL );
01631 plsc->dev = (void *) widget;
01632 widget->setPLStream( plsc );
01633 }
01634
01635 void plfreeqtdev()
01636 {
01637 delete ( (QtExtWidget *) plsc->dev );
01638 plsc->dev = NULL;
01639 }
01640 #endif
01641
01642 #include "moc_files.h"