F:/KPlato/koffice/libs/kwmf/qwmf.cc

Aller à la documentation de ce fichier.
00001 /* Windows Meta File Loader/Painter Class Implementation
00002  *
00003  * Copyright ( C ) 1998 Stefan Taferner
00004  * Modified 2002 thierry lorthiois
00005  *
00006  * This program is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU General Public License as published by the
00008  * Free Software Foundation; either version 2 of the License, or ( at your
00009  * option ) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful, but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014  * General Public License for more details. You should have received a copy
00015  * of the GNU General Public License along with this program; if not, write
00016  * to the Free Software Foundation, Inc, 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  */
00019 
00020 #include <math.h>
00021 #include <assert.h>
00022 
00023 #include <QFileInfo>
00024 #include <QPixmap>
00025 #include <QPainter>
00026 #include <QPainterPath>
00027 #include <QDataStream>
00028 #include <QApplication>
00029 #include <QBuffer>
00030 //Added by qt3to4:
00031 #include <Q3CString>
00032 #include <QPolygon>
00033 
00034 #include <kdebug.h>
00035 
00036 bool qwmfDebug = false;
00037 
00038 #include "qwmf.h"
00039 #include "wmfstruct.h"
00040 #include "metafuncs.h"
00041 
00042 #define QWMF_DEBUG  0
00043 
00044 
00045 class WmfCmd
00046 {
00047 public:
00048     ~WmfCmd() { if ( next ) delete next; }
00049     WmfCmd* next;
00050     unsigned short funcIndex;
00051     long  numParm;
00052     short* parm;
00053 };
00054 
00055 
00056 class WinObjHandle
00057 {
00058 public:
00059         virtual ~WinObjHandle() {}
00060     virtual void apply( QPainter& p ) = 0;
00061 };
00062 
00063 class WinObjBrushHandle: public WinObjHandle
00064 {
00065 public:
00066     virtual void apply( QPainter& p );
00067     QBrush brush;
00068     virtual ~WinObjBrushHandle() {};
00069 };
00070 
00071 class WinObjPenHandle: public WinObjHandle
00072 {
00073 public:
00074     virtual void apply( QPainter& p );
00075     QPen pen;
00076     virtual ~WinObjPenHandle() {};
00077 };
00078 
00079 class WinObjPatternBrushHandle: public WinObjHandle
00080 {
00081 public:
00082     virtual void apply( QPainter& p );
00083     QBrush brush;
00084     QPixmap image;
00085     virtual ~WinObjPatternBrushHandle() {};
00086 };
00087 
00088 class WinObjFontHandle: public WinObjHandle
00089 {
00090 public:
00091     virtual void apply( QPainter& p );
00092     QFont font;
00093     int rotation;
00094     virtual ~WinObjFontHandle() {};
00095 };
00096 
00097 void WinObjBrushHandle::apply( QPainter& p )
00098 {
00099     p.setBrush( brush );
00100 }
00101 
00102 void WinObjPenHandle::apply( QPainter& p )
00103 {
00104     p.setPen( pen );
00105 }
00106 
00107 void WinObjPatternBrushHandle::apply( QPainter& p )
00108 {
00109     p.setBrush( brush );
00110 }
00111 
00112 void WinObjFontHandle::apply( QPainter& p )
00113 {
00114     p.setFont( font );
00115 }
00116 
00117 #define MAX_OBJHANDLE 64
00118 
00119 
00120 
00121 //-----------------------------------------------------------------------------
00122 QWinMetaFile::QWinMetaFile()
00123 {
00124     mValid       = false;
00125     mFirstCmd    = NULL;
00126     mObjHandleTab = NULL;
00127     mDpi         = 1000;
00128 }
00129 
00130 
00131 //-----------------------------------------------------------------------------
00132 QWinMetaFile::~QWinMetaFile()
00133 {
00134     if ( mFirstCmd ) delete mFirstCmd;
00135     if ( mObjHandleTab ) delete[] mObjHandleTab;
00136 }
00137 
00138 
00139 //-----------------------------------------------------------------------------
00140 bool QWinMetaFile::load( const QString &filename )
00141 {
00142     QFile file( filename );
00143 
00144     if ( !file.exists() )
00145     {
00146         kDebug() << "File " << QFile::encodeName(filename) << " does not exist" << endl;
00147         return false;
00148     }
00149 
00150     if ( !file.open( QIODevice::ReadOnly ) )
00151     {
00152         kDebug() << "Cannot open file " << QFile::encodeName(filename) << endl;
00153         return false;
00154     }
00155 
00156     QByteArray ba = file.readAll();
00157     file.close();
00158 
00159     QBuffer buffer( &ba );
00160     buffer.open( QIODevice::ReadOnly );
00161     return load( buffer );
00162 }
00163 
00164 //-----------------------------------------------------------------------------
00165 bool QWinMetaFile::load( QBuffer &buffer )
00166 {
00167     QDataStream st;
00168     WmfEnhMetaHeader eheader;
00169     WmfMetaHeader header;
00170     WmfPlaceableHeader pheader;
00171     WORD checksum;
00172     int filePos, idx, i;
00173     WmfCmd *cmd, *last;
00174     DWORD rdSize;
00175     WORD rdFunc;
00176 
00177     mTextAlign = 0;
00178     mRotation = 0;
00179     mTextColor = Qt::black;
00180     if ( mFirstCmd ) delete mFirstCmd;
00181     mFirstCmd = NULL;
00182 
00183     st.setDevice( &buffer );
00184     st.setByteOrder( QDataStream::LittleEndian ); // Great, I love Qt !
00185 
00186     //----- Read placeable metafile header
00187     st >> pheader.key;
00188     mIsPlaceable = ( pheader.key==( DWORD )APMHEADER_KEY );
00189     if ( mIsPlaceable )
00190     {
00191         st >> pheader.hmf;
00192         st >> pheader.bbox.left;
00193         st >> pheader.bbox.top;
00194         st >> pheader.bbox.right;
00195         st >> pheader.bbox.bottom;
00196         st >> pheader.inch;
00197         st >> pheader.reserved;
00198         st >> pheader.checksum;
00199         checksum = calcCheckSum( &pheader );
00200         if ( pheader.checksum!=checksum ) mIsPlaceable = false;
00201 
00202         mDpi = pheader.inch;
00203         mBBox.setLeft( pheader.bbox.left );
00204         mBBox.setTop( pheader.bbox.top );
00205         mBBox.setRight( pheader.bbox.right );
00206         mBBox.setBottom( pheader.bbox.bottom );
00207         mHeaderBoundingBox = mBBox;
00208         if ( QWMF_DEBUG )
00209         {
00210             kDebug() << endl << "-------------------------------------------------" << endl;
00211             kDebug() << "WMF Placeable Header ( " << static_cast<int>(sizeof( pheader ) ) << "):" << endl;
00212             kDebug() << "  bbox=( " << mBBox.left() << "; " << mBBox.top() << "; " << mBBox.width()
00213                       << "; " << mBBox.height() << ")" << endl;
00214             kDebug() << "  inch=" << pheader.inch << endl;
00215             kDebug() << "  checksum=" << pheader.checksum << "( "
00216                       << (pheader.checksum==checksum?"ok":"wrong") << " )" << endl;
00217         }
00218     }
00219     else buffer.reset();
00220 
00221     //----- Read as enhanced metafile header
00222     filePos = buffer.pos();
00223     st >> eheader.iType;
00224     st >> eheader.nSize;
00225     st >> eheader.rclBounds.left;
00226     st >> eheader.rclBounds.top;
00227     st >> eheader.rclBounds.right;
00228     st >> eheader.rclBounds.bottom;
00229     st >> eheader.rclFrame.left;
00230     st >> eheader.rclFrame.top;
00231     st >> eheader.rclFrame.right;
00232     st >> eheader.rclFrame.bottom;
00233     st >> eheader.dSignature;
00234     mIsEnhanced = ( eheader.dSignature==ENHMETA_SIGNATURE );
00235     if ( mIsEnhanced ) // is it really enhanced ?
00236     {
00237         st >> eheader.nVersion;
00238         st >> eheader.nBytes;
00239         st >> eheader.nRecords;
00240         st >> eheader.nHandles;
00241         st >> eheader.sReserved;
00242         st >> eheader.nDescription;
00243         st >> eheader.offDescription;
00244         st >> eheader.nPalEntries;
00245         st >> eheader.szlDevice.width;
00246         st >> eheader.szlDevice.height;
00247         st >> eheader.szlMillimeters.width;
00248         st >> eheader.szlMillimeters.height;
00249 
00250         if ( QWMF_DEBUG )
00251         {
00252             kDebug() << endl << "-------------------------------------------------" << endl;
00253             kDebug() << "WMF Extended Header:" << endl;
00254             kDebug() << "  iType=" << eheader.iType << endl;
00255             kDebug() << "  nSize=" << eheader.nSize << endl;
00256             kDebug() << "  rclBounds=( " << eheader.rclBounds.left << "; " << eheader.rclBounds.top << "; "
00257                       << eheader.rclBounds.right << "; " << eheader.rclBounds.bottom << ")" << endl;
00258             kDebug() << "  rclFrame=( " << eheader.rclFrame.left << "; " << eheader.rclFrame.top << "; "
00259                       << eheader.rclFrame.right << "; " << eheader.rclFrame.bottom << ")" << endl;
00260             kDebug() << "  nBytes=" << eheader.nBytes << endl;
00261             kDebug() << "\nNOT YET IMPLEMENTED, SORRY." << endl;
00262         }
00263     }
00264     else // no, not enhanced
00265     {
00266         //----- Read as standard metafile header
00267         buffer.seek( filePos );
00268         st >> header.mtType;
00269         st >> header.mtHeaderSize;
00270         st >> header.mtVersion;
00271         st >> header.mtSize;
00272         st >> header.mtNoObjects;
00273         st >> header.mtMaxRecord;
00274         st >> header.mtNoParameters;
00275         if ( QWMF_DEBUG ) {
00276             kDebug() << "WMF Header: " <<  "mtSize=" << header.mtSize << endl;
00277         }
00278     }
00279 
00280     //----- Test header validity
00281     mValid = ((header.mtHeaderSize == 9) && (header.mtNoParameters == 0)) || mIsEnhanced || mIsPlaceable;
00282     if ( mValid )
00283     {
00284         //----- Read Metafile Records
00285         last = NULL;
00286         rdFunc = -1;
00287         while ( !st.atEnd() && (rdFunc != 0) )
00288         {
00289             st >> rdSize;
00290             st >> rdFunc;
00291             idx = findFunc( rdFunc );
00292             rdSize -= 3;
00293 
00294             cmd = new WmfCmd;
00295             cmd->next = NULL;
00296             if ( last ) last->next = cmd;
00297             else mFirstCmd = cmd;
00298 
00299             cmd->funcIndex = idx;
00300             cmd->numParm = rdSize;
00301             cmd->parm = new WORD[ rdSize ];
00302             last = cmd;
00303 
00304             for ( i=0; i<rdSize && !st.atEnd(); i++ )
00305                 st >> cmd->parm[ i ];
00306 
00307 
00308             if ( rdFunc == 0x020B ) {         // SETWINDOWORG: dimensions
00309                 mBBox.setLeft( cmd->parm[ 1 ] );
00310                 mBBox.setTop( cmd->parm[ 0 ] );
00311             }
00312             if ( rdFunc == 0x020C ) {         // SETWINDOWEXT: dimensions
00313                 mBBox.setWidth( cmd->parm[ 1 ] );
00314                 mBBox.setHeight( cmd->parm[ 0 ] );
00315             }
00316 
00317             if ( i<rdSize )
00318             {
00319                 kDebug() << "WMF : file truncated !" << endl;
00320                 return false;
00321             }
00322         }
00323         //----- Test records validities
00324         mValid = (rdFunc == 0) && (mBBox.width() != 0) && (mBBox.height() != 0);
00325         if ( !mValid ) {
00326             kDebug() << "WMF : incorrect file format !" << endl;
00327         }
00328     }
00329     else {
00330         kDebug() << "WMF Header : incorrect header !" << endl;
00331     }
00332 
00333     buffer.close();
00334     return mValid;
00335 }
00336 
00337 
00338 //-----------------------------------------------------------------------------
00339 bool QWinMetaFile::paint( QPaintDevice* aTarget, bool absolute )
00340 {
00341     int idx, i;
00342     WmfCmd* cmd;
00343 
00344     if ( !mValid )  return false;
00345 
00346     assert( aTarget!=NULL );
00347     if ( mPainter.isActive() ) return false;
00348 
00349     if ( mObjHandleTab ) delete[] mObjHandleTab;
00350     mObjHandleTab = new WinObjHandle* [ MAX_OBJHANDLE ];
00351     for ( i=MAX_OBJHANDLE-1; i>=0; i-- )
00352         mObjHandleTab[ i ] = NULL;
00353 
00354     mPainter.resetMatrix();
00355     mWinding = false;
00356     mAbsoluteCoord = absolute;
00357 
00358     mPainter.begin( aTarget );
00359     if ( QWMF_DEBUG )  {
00360         kDebug() << "Bounding box : " << mBBox.left()
00361         << " " << mBBox.top() << " " << mBBox.right() << " " << mBBox.bottom() << endl;
00362     }
00363 
00364     if ( mAbsoluteCoord ) {
00365         mPainter.setWindow( mBBox.top(), mBBox.left(), mBBox.width(), mBBox.height() );
00366     }
00367     mInternalWorldMatrix.reset();
00368 
00369     for ( cmd=mFirstCmd; cmd; cmd=cmd->next )
00370     {
00371         idx = cmd->funcIndex;
00372         ( this->*metaFuncTab[ idx ].method )( cmd->numParm, cmd->parm );
00373 
00374         if ( QWMF_DEBUG )  {
00375             QString str = "", param;
00376             if ( metaFuncTab[ idx ].name == NULL ) {
00377                 str += "UNKNOWN ";
00378             }
00379             if ( metaFuncTab[ idx ].method == &QWinMetaFile::noop ) {
00380                 str += "UNIMPLEMENTED ";
00381             }
00382             str += metaFuncTab[ idx ].name;
00383             str += " : ";
00384 
00385             for ( i=0 ; i < cmd->numParm ; i++ ) {
00386                 param.setNum( cmd->parm[ i ] );
00387                 str += param;
00388                 str += ' ';
00389             }
00390             kDebug() << str << endl;
00391         }
00392     }
00393 /*
00394     // TODO: cleanup this code when QPicture::setBoundingBox() is possible in KOClipart (QT31)
00395     // because actually QPicture::boundingBox() != mBBox()
00396     mWindowsCoord += 1;
00397     if ( mWindowsCoord == 2 )  {
00398         kDebug() << "DRAW ANGLES " << endl;
00399         mPainter.setPen( Qt::white );
00400         mPainter.drawPoint( mBBox.left(), mBBox.top()  );
00401         mPainter.drawPoint( mBBox.right(), mBBox.bottom() );
00402     }
00403 */
00404     mPainter.end();
00405     return true;
00406 }
00407 
00408 
00409 //----------------s-------------------------------------------------------------
00410 // Metafile painter methods
00411 //-----------------------------------------------------------------------------
00412 void QWinMetaFile::setWindowOrg( long, short* parm )
00413 {
00414     if ( mAbsoluteCoord ) {
00415         QRect r = mPainter.window();
00416         mPainter.setWindow( parm[ 1 ], parm[ 0 ], r.width(), r.height() );
00417     }
00418     else {
00419         double dx = mInternalWorldMatrix.dx();
00420         double dy = mInternalWorldMatrix.dy();
00421 
00422         mInternalWorldMatrix.translate( -dx, -dy );
00423         mInternalWorldMatrix.translate( -parm[ 1 ], -parm[ 0 ] );
00424         mPainter.translate( -dx, -dy );
00425         mPainter.translate( -parm[ 1 ], -parm[ 0 ] );
00426     }
00427 }
00428 
00429 
00430 //-----------------------------------------------------------------------------
00431 void QWinMetaFile::setWindowExt( long, short* parm )
00432 {
00433     // negative value allowed for width and height : QABS() forbidden
00434     if ( mAbsoluteCoord ) {
00435         QRect r = mPainter.window();
00436         mPainter.setWindow( r.left(), r.top(), parm[ 1 ], parm[ 0 ] );
00437     }
00438     else {
00439         if ( (parm[ 0 ] != 0) && (parm[ 1 ] != 0) ) {
00440             QRect r = mPainter.window();
00441             double dx = mInternalWorldMatrix.dx();
00442             double dy = mInternalWorldMatrix.dy();
00443             double sx = mInternalWorldMatrix.m11();
00444             double sy = mInternalWorldMatrix.m22();
00445 
00446             mInternalWorldMatrix.translate( -dx, -dy );
00447             mInternalWorldMatrix.scale( 1/sx, 1/sy );
00448             mPainter.translate( -dx, -dy );
00449             mPainter.scale( 1/sx, 1/sy );
00450 
00451             sx = (double)r.width() / (double)parm[ 1 ];
00452             sy = (double)r.height() / (double)parm[ 0 ];
00453 
00454             mInternalWorldMatrix.scale( sx, sy );
00455             mInternalWorldMatrix.translate( dx, dy );
00456             mPainter.scale( sx, sy );
00457             mPainter.translate( dx, dy );
00458         }
00459     }
00460 }
00461 
00462 
00463 //-----------------------------------------------------------------------------
00464 // Drawing
00465 //-----------------------------------------------------------------------------
00466 void QWinMetaFile::lineTo( long, short* parm )
00467 {
00468   mLastPos = QPoint( parm[ 1 ], parm[ 0 ] );
00469 }
00470 
00471 
00472 //-----------------------------------------------------------------------------
00473 void QWinMetaFile::moveTo( long, short* parm )
00474 {
00475   mPainter.drawLine( mLastPos, QPoint( parm[1], parm[0] ) );
00476 }
00477 
00478 
00479 //-----------------------------------------------------------------------------
00480 void QWinMetaFile::ellipse( long, short* parm )
00481 {
00482     mPainter.drawEllipse( parm[ 3 ], parm[ 2 ], parm[ 1 ]-parm[ 3 ], parm[ 0 ]-parm[ 2 ] );
00483 }
00484 
00485 
00486 //-----------------------------------------------------------------------------
00487 void QWinMetaFile::polygon( long, short* parm )
00488 {
00489     QPolygon* pa;              // causing a memleck ???
00490 
00491     pa = pointArray( parm[ 0 ], &parm[ 1 ] );
00492     if( mWinding )
00493       mPainter.drawPolygon( *pa, Qt::WindingFill );
00494     else
00495       mPainter.drawPolygon( *pa, Qt::OddEvenFill );
00496 
00497     delete pa;
00498 }
00499 
00500 
00501 //-----------------------------------------------------------------------------
00502 void QWinMetaFile::polyPolygon( long, short* parm )
00503 {
00504     QRegion region;
00505     int  i, j, startPolygon;
00506 
00507     mPainter.save();
00508 
00509     // define clipping region
00510     QRect win = bbox();
00511     startPolygon = 1+parm[ 0 ];
00512     for ( i=0 ; i < parm[ 0 ] ; i++ ) {
00513         QPolygon pa1( parm[ 1+i ] );
00514         for ( j=0 ; j < parm[ 1+i ] ; j++) {
00515             pa1.setPoint ( j, parm[ startPolygon ], parm[ startPolygon+1 ] );
00516             startPolygon += 2;
00517         }
00518         QRegion r( pa1 );
00519         region = region.eor( r );
00520     }
00521     mPainter.setClipRegion( region );
00522 
00523     // fill polygons
00524     mPainter.fillRect( win.left(), win.top(), win.width(), win.height(), mPainter.brush() );
00525 
00526     // draw polygon's border if necessary
00527     if ( mPainter.pen().style() != Qt::NoPen ) {
00528         mPainter.setClipping( false );
00529         mPainter.setBrush( Qt::NoBrush );
00530 
00531         QPolygon* pa;
00532         int idxPolygon = 1 + parm[ 0 ];
00533         for ( i=0 ; i < parm[ 0 ] ; i++ ) {
00534             pa = pointArray( parm[ 1+i ], &parm[ idxPolygon ] );
00535             mPainter.drawPolygon( *pa );
00536             idxPolygon += parm[ 1+i ] * 2;
00537         }
00538     }
00539 
00540     mPainter.restore();
00541 }
00542 
00543 
00544 //-----------------------------------------------------------------------------
00545 void QWinMetaFile::polyline( long, short* parm )
00546 {
00547     QPolygon* pa;
00548 
00549     pa = pointArray( parm[ 0 ], &parm[ 1 ] );
00550     mPainter.drawPolyline( *pa );
00551 }
00552 
00553 
00554 //-----------------------------------------------------------------------------
00555 void QWinMetaFile::rectangle( long, short* parm )
00556 {
00557     mPainter.drawRect( parm[ 3 ], parm[ 2 ], parm[ 1 ]-parm[ 3 ], parm[ 0 ]-parm[ 2 ] );
00558 }
00559 
00560 
00561 //-----------------------------------------------------------------------------
00562 void QWinMetaFile::roundRect( long, short* parm )
00563 {
00564     int xRnd = 0, yRnd = 0;
00565 
00566     // convert (xRound, yRound) in percentage
00567     if ( (parm[ 3 ] - parm[ 5 ]) != 0  )
00568         xRnd = (parm[ 1 ] * 100) / (parm[ 3 ] - parm[ 5 ])  ;
00569     if ( (parm[ 2 ] - parm[ 4 ]) != 0  )
00570         yRnd = (parm[ 0 ] * 100) / (parm[ 2 ] - parm[ 4 ])  ;
00571 
00572     mPainter.drawRoundRect( parm[ 5 ], parm[ 4 ], parm[ 3 ]-parm[ 5 ], parm[ 2 ]-parm[ 4 ], xRnd, yRnd );
00573 }
00574 
00575 
00576 //-----------------------------------------------------------------------------
00577 void QWinMetaFile::arc( long, short* parm )
00578 {
00579     int xCenter, yCenter, angleStart, aLength;
00580 
00581     xCenter = parm[ 7 ] + ((parm[ 5 ] - parm[ 7 ]) / 2);
00582     yCenter = parm[ 6 ] + ((parm[ 4 ] - parm[ 6 ]) / 2);
00583 
00584     xyToAngle ( parm[ 3 ] - xCenter, yCenter - parm[ 2 ], parm[ 1 ] - xCenter, yCenter - parm[ 0 ], angleStart, aLength );
00585 
00586     mPainter.drawArc( parm[ 7 ], parm[ 6 ], parm[ 5 ]-parm[ 7 ], parm[ 4 ]-parm[ 6 ], angleStart, aLength);
00587 }
00588 
00589 
00590 //-----------------------------------------------------------------------------
00591 void QWinMetaFile::chord( long, short* parm )
00592 {
00593     int xCenter, yCenter, angleStart, aLength;
00594 
00595     xCenter = parm[ 7 ] + ((parm[ 5 ] - parm[ 7 ]) / 2);
00596     yCenter = parm[ 6 ] + ((parm[ 4 ] - parm[ 6 ]) / 2);
00597 
00598     xyToAngle ( parm[ 3 ] - xCenter, yCenter - parm[ 2 ], parm[ 1 ] - xCenter, yCenter - parm[ 0 ], angleStart, aLength );
00599 
00600     mPainter.drawChord( parm[ 7 ], parm[ 6 ], parm[ 5 ]-parm[ 7 ], parm[ 4 ]-parm[ 6 ], angleStart, aLength);
00601 }
00602 
00603 
00604 //-----------------------------------------------------------------------------
00605 void QWinMetaFile::pie( long, short* parm )
00606 {
00607     int xCenter, yCenter, angleStart, aLength;
00608 
00609     xCenter = parm[ 7 ] + ((parm[ 5 ] - parm[ 7 ]) / 2);
00610     yCenter = parm[ 6 ] + ((parm[ 4 ] - parm[ 6 ]) / 2);
00611 
00612     xyToAngle ( parm[ 3 ] - xCenter, yCenter - parm[ 2 ], parm[ 1 ] - xCenter, yCenter - parm[ 0 ], angleStart, aLength );
00613 
00614     mPainter.drawPie( parm[ 7 ], parm[ 6 ], parm[ 5 ]-parm[ 7 ], parm[ 4 ]-parm[ 6 ], angleStart, aLength);
00615 }
00616 
00617 
00618 //-----------------------------------------------------------------------------
00619 void QWinMetaFile::setPolyFillMode( long, short* parm )
00620 {
00621     mWinding = parm[ 0 ];
00622 }
00623 
00624 
00625 //-----------------------------------------------------------------------------
00626 void QWinMetaFile::setBkColor( long, short* parm )
00627 {
00628     mPainter.setBackground( QBrush( color( parm ) ) );
00629 }
00630 
00631 
00632 //-----------------------------------------------------------------------------
00633 void QWinMetaFile::setBkMode( long, short* parm )
00634 {
00635     if ( parm[ 0 ]==1 ) mPainter.setBackgroundMode( Qt::TransparentMode );
00636     else mPainter.setBackgroundMode( Qt::OpaqueMode );
00637 }
00638 
00639 
00640 //-----------------------------------------------------------------------------
00641 void QWinMetaFile::setPixel( long, short* parm )
00642 {
00643     QPen pen = mPainter.pen();
00644     mPainter.setPen( color( parm ) );
00645     mPainter.drawPoint( parm[ 3 ], parm[ 2 ] );
00646     mPainter.setPen( pen );
00647 }
00648 
00649 
00650 //-----------------------------------------------------------------------------
00651 void QWinMetaFile::setRop( long, short* parm )
00652 {
00653     mPainter.setCompositionMode( winToQtComposition( parm[ 0 ] ) );
00654 }
00655 
00656 
00657 //-----------------------------------------------------------------------------
00658 void QWinMetaFile::saveDC( long, short* )
00659 {
00660     mPainter.save();
00661 }
00662 
00663 
00664 //-----------------------------------------------------------------------------
00665 void QWinMetaFile::restoreDC( long, short *parm )
00666 {
00667     for ( int i=0; i > parm[ 0 ] ; i-- )
00668         mPainter.restore();
00669 }
00670 
00671 
00672 //-----------------------------------------------------------------------------
00673 void QWinMetaFile::intersectClipRect( long, short* parm )
00674 {
00675 /*  TODO: better implementation : need QT 3.0.2
00676     QRegion region = mPainter.clipRegion();
00677     if ( region.isEmpty() )
00678         region = bbox();
00679 */
00680     QRegion region( bbox() );
00681 
00682     QRegion newRegion( parm[ 3 ], parm[ 2 ], parm[ 1 ] - parm[ 3 ], parm[ 0 ] - parm[ 2 ] );
00683     region = region.intersect( newRegion );
00684 
00685     mPainter.setClipRegion( region );
00686 }
00687 
00688 
00689 //-----------------------------------------------------------------------------
00690 void QWinMetaFile::excludeClipRect( long, short* parm )
00691 {
00692 /*  TODO: better implementation : need QT 3.0.2
00693     QRegion region = mPainter.clipRegion();
00694     if ( region.isEmpty() )
00695         region = bbox();
00696 */
00697     QRegion region( bbox() );
00698 
00699     QRegion newRegion( parm[ 3 ], parm[ 2 ], parm[ 1 ] - parm[ 3 ], parm[ 0 ] - parm[ 2 ] );
00700     region = region.subtract( newRegion );
00701 
00702     mPainter.setClipRegion( region );
00703 }
00704 
00705 
00706 //-----------------------------------------------------------------------------
00707 // Text
00708 //-----------------------------------------------------------------------------
00709 void QWinMetaFile::setTextColor( long, short* parm )
00710 {
00711     mTextColor = color( parm );
00712 }
00713 
00714 
00715 //-----------------------------------------------------------------------------
00716 void QWinMetaFile::setTextAlign( long, short* parm )
00717 {
00718     mTextAlign = parm[ 0 ];
00719 }
00720 
00721 
00722 //-----------------------------------------------------------------------------
00723 void QWinMetaFile::textOut( long num, short* parm )
00724 {
00725 
00726     short *copyParm = new short[ num + 1 ];
00727 
00728     // re-order parameters
00729     int idxOffset = (parm[ 0 ] / 2) + 1 + (parm[ 0 ] & 1);
00730     copyParm[ 0 ] = parm[ idxOffset ];
00731     copyParm[ 1 ] = parm[ idxOffset + 1 ];
00732     copyParm[ 2 ] = parm[ 0 ];
00733     copyParm[ 3 ] = 0;
00734     memcpy( &copyParm[ 4 ], &parm[ 1 ], parm[ 0 ] );
00735 
00736     extTextOut( num + 1, copyParm );
00737     delete [] copyParm;
00738 }
00739 
00740 
00741 //-----------------------------------------------------------------------------
00742 void QWinMetaFile::extTextOut( long num, short* parm )
00743 {
00744     char* ptStr;
00745     int x, y, width, height;
00746     int idxOffset;
00747 
00748     if ( parm[ 3 ] != 0 )       // ETO_CLIPPED flag add 4 parameters
00749         ptStr = (char*)&parm[ 8 ];
00750     else
00751         ptStr = (char*)&parm[ 4 ];
00752 
00753     Q3CString text( ptStr, parm[ 2 ] + 1 );
00754 
00755     QFontMetrics fm( mPainter.font() );
00756     width = fm.width( text ) + fm.descent();  // because fm.width(text) isn't rigth with Italic text
00757     height = fm.height();
00758 
00759     mPainter.save();
00760 
00761     if ( mTextAlign & 0x01 ) {       // (left, top) position = current logical position
00762         x = mLastPos.x();
00763         y = mLastPos.y();
00764     }
00765     else {                           // (left, top) position = parameters
00766         x = parm[ 1 ];
00767         y = parm[ 0 ];
00768     }
00769 
00770     if ( mRotation ) {
00771         mPainter.translate( parm[ 1 ], parm[ 0 ]);
00772         mPainter.rotate ( mRotation );
00773         mPainter.translate( -parm[ 1 ], -parm[ 0 ] );
00774     }
00775 
00776     // alignment
00777     if ( mTextAlign & 0x06 )
00778         x -= ( width / 2 );
00779     if ( mTextAlign & 0x08 )
00780         y -= (height - fm.descent());
00781 
00782     mPainter.setPen( mTextColor );
00783     idxOffset = (parm[ 2 ] / 2) + 4 + (parm[ 2 ] & 1);
00784     if ( ( parm[ 2 ] > 1 ) && ( num >= (idxOffset + parm[ 2 ]) ) && ( parm[ 3 ] == 0 ) ) {
00785         // offset for each char
00786         int left = x;
00787         mPainter.drawText( left, y, width, height, Qt::AlignLeft | Qt::AlignTop, text.mid(0, 1) );
00788         for ( int i = 1; i < parm[ 2 ] ; i++ ) {
00789             left += parm[ idxOffset + i - 1 ];
00790             mPainter.drawText( left, y, width, height, Qt::AlignLeft | Qt::AlignTop, text.mid(i, 1) );
00791         }
00792     }
00793     else {
00794         mPainter.drawText( x, y, width, height, Qt::AlignLeft | Qt::AlignTop, text );
00795     }
00796 
00797     mPainter.restore();
00798 
00799 }
00800 
00801 
00802 
00803 //-----------------------------------------------------------------------------
00804 // Bitmap
00805 //-----------------------------------------------------------------------------
00806 void QWinMetaFile::dibBitBlt( long num, short* parm )
00807 {
00808     if ( num > 9 ) {      // DIB image
00809         QImage bmpSrc;
00810 
00811         if ( dibToBmp( bmpSrc, (char*)&parm[ 8 ], (num - 8) * 2 ) ) {
00812             long raster = toDWord( parm );
00813 
00814             mPainter.setCompositionMode( winToQtComposition( raster )  );
00815 
00816             // wmf file allow negative width or height
00817             mPainter.save();
00818             if ( parm[ 5 ] < 0 ) {  // width < 0 => horizontal flip
00819                 QMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );
00820                 mPainter.setMatrix( m, true );
00821             }
00822             if ( parm[ 4 ] < 0 ) {  // height < 0 => vertical flip
00823                 QMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );
00824                 mPainter.setMatrix( m, true );
00825             }
00826             mPainter.drawImage( parm[ 7 ], parm[ 6 ], bmpSrc, parm[ 3 ], parm[ 2 ], parm[ 5 ], parm[ 4 ] );
00827             mPainter.restore();
00828         }
00829     }
00830     else {
00831         kDebug() << "QWinMetaFile::dibBitBlt without image: not implemented " << endl;
00832     }
00833 }
00834 
00835 
00836 //-----------------------------------------------------------------------------
00837 void QWinMetaFile::dibStretchBlt( long num, short* parm )
00838 {
00839     QImage bmpSrc;
00840 
00841     if ( dibToBmp( bmpSrc, (char*)&parm[ 10 ], (num - 10) * 2 ) ) {
00842         long raster = toDWord( parm );
00843 
00844         mPainter.setCompositionMode( winToQtComposition( raster )  );
00845 
00846         // wmf file allow negative width or height
00847         mPainter.save();
00848         if ( parm[ 7 ] < 0 ) {  // width < 0 => horizontal flip
00849             QMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );
00850             mPainter.setMatrix( m, true );
00851         }
00852         if ( parm[ 6 ] < 0 ) {  // height < 0 => vertical flip
00853             QMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );
00854             mPainter.setMatrix( m, true );
00855         }
00856         bmpSrc = bmpSrc.copy( parm[ 5 ], parm[ 4 ], parm[ 3 ], parm[ 2 ] );
00857         // TODO: scale the bitmap ( QImage::scale(parm[ 7 ], parm[ 6 ]) is actually too slow )
00858 
00859         mPainter.drawImage( parm[ 9 ], parm[ 8 ], bmpSrc );
00860         mPainter.restore();
00861     }
00862 }
00863 
00864 
00865 //-----------------------------------------------------------------------------
00866 void QWinMetaFile::stretchDib( long num, short* parm )
00867 {
00868     QImage bmpSrc;
00869 
00870     if ( dibToBmp( bmpSrc, (char*)&parm[ 11 ], (num - 11) * 2 ) ) {
00871         long raster = toDWord( parm );
00872 
00873         mPainter.setCompositionMode( winToQtComposition( raster )  );
00874 
00875         // wmf file allow negative width or height
00876         mPainter.save();
00877         if ( parm[ 8 ] < 0 ) {  // width < 0 => horizontal flip
00878             QMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );
00879             mPainter.setMatrix( m, true );
00880         }
00881         if ( parm[ 7 ] < 0 ) {  // height < 0 => vertical flip
00882             QMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );
00883             mPainter.setMatrix( m, true );
00884         }
00885         bmpSrc = bmpSrc.copy( parm[ 6 ], parm[ 5 ], parm[ 4 ], parm[ 3 ] );
00886         // TODO: scale the bitmap ( QImage::scale(parm[ 8 ], parm[ 7 ]) is actually too slow )
00887 
00888         mPainter.drawImage( parm[ 10 ], parm[ 9 ], bmpSrc );
00889         mPainter.restore();
00890     }
00891 }
00892 
00893 
00894 //-----------------------------------------------------------------------------
00895 void QWinMetaFile::dibCreatePatternBrush( long num, short* parm )
00896 {
00897     WinObjPatternBrushHandle* handle = new WinObjPatternBrushHandle;
00898     addHandle( handle );
00899     QImage bmpSrc;
00900 
00901     if ( dibToBmp( bmpSrc, (char*)&parm[ 2 ], (num - 2) * 2 ) ) {
00902         handle->image = QPixmap::fromImage( bmpSrc );
00903         handle->brush.setTexture( handle->image );
00904     }
00905 }
00906 
00907 
00908 //-----------------------------------------------------------------------------
00909 // Object handle
00910 //-----------------------------------------------------------------------------
00911 void QWinMetaFile::selectObject( long, short* parm )
00912 {
00913     int idx = parm[ 0 ];
00914     if ( idx>=0 && idx < MAX_OBJHANDLE && mObjHandleTab[ idx ] )
00915         mObjHandleTab[ idx ]->apply( mPainter );
00916 }
00917 
00918 
00919 //-----------------------------------------------------------------------------
00920 void QWinMetaFile::deleteObject( long, short* parm )
00921 {
00922     deleteHandle( parm[ 0 ] );
00923 }
00924 
00925 
00926 //-----------------------------------------------------------------------------
00927 void QWinMetaFile::createEmptyObject( long, short* )
00928 {
00929     // allocation of an empty object (to keep object counting in sync)
00930     WinObjPenHandle* handle = new WinObjPenHandle;
00931     addHandle( handle );
00932     kDebug() << "QWinMetaFile: unimplemented createObject " << endl;
00933 }
00934 
00935 
00936 //-----------------------------------------------------------------------------
00937 void QWinMetaFile::createBrushIndirect( long, short* parm )
00938 {
00939     static Qt::BrushStyle hatchedStyleTab[] =
00940     {
00941         Qt::HorPattern,
00942         Qt::FDiagPattern,
00943         Qt::BDiagPattern,
00944         Qt::CrossPattern,
00945         Qt::DiagCrossPattern
00946     };
00947     static Qt::BrushStyle styleTab[] =
00948     { Qt::SolidPattern,
00949       Qt::NoBrush,
00950       Qt::FDiagPattern,   /* hatched */
00951       Qt::Dense4Pattern,  /* should be custom bitmap pattern */
00952       Qt::HorPattern,     /* should be BS_INDEXED (?) */
00953       Qt::VerPattern,     /* should be device-independent bitmap */
00954       Qt::Dense6Pattern,  /* should be device-independent packed-bitmap */
00955       Qt::Dense2Pattern,  /* should be BS_PATTERN8x8 */
00956       Qt::Dense3Pattern   /* should be device-independent BS_DIBPATTERN8x8 */
00957     };
00958     Qt::BrushStyle style;
00959     short arg;
00960     WinObjBrushHandle* handle = new WinObjBrushHandle;
00961     addHandle( handle );
00962 
00963     arg = parm[ 0 ];
00964     if ( arg==2 )
00965     {
00966         arg = parm[ 3 ];
00967         if ( arg>=0 && arg<5 ) style = hatchedStyleTab[ arg ];
00968         else
00969         {
00970             kDebug() << "QWinMetaFile::createBrushIndirect: invalid hatched brush " << arg << endl;
00971             style = Qt::SolidPattern;
00972         }
00973     }
00974     else if ( arg>=0 && arg<9 )
00975         style = styleTab[ arg ];
00976     else
00977     {
00978         kDebug() << "QWinMetaFile::createBrushIndirect: invalid brush " << arg << endl;
00979         style = Qt::SolidPattern;
00980     }
00981     handle->brush.setStyle( style );
00982     handle->brush.setColor( color( parm+1 ) );
00983 }
00984 
00985 
00986 //-----------------------------------------------------------------------------
00987 void QWinMetaFile::createPenIndirect( long, short* parm )
00988 {
00989     static Qt::PenStyle styleTab[] =
00990     { Qt::SolidLine, Qt::DashLine, Qt::DotLine, Qt::DashDotLine, Qt::DashDotDotLine,
00991       Qt::NoPen, Qt::SolidLine };
00992     Qt::PenStyle style;
00993     WinObjPenHandle* handle = new WinObjPenHandle;
00994     addHandle( handle );
00995 
00996     if ( parm[ 0 ]>=0 && parm[ 0 ]<6 ) style=styleTab[ parm[ 0 ] ];
00997     else
00998     {
00999         kDebug() << "QWinMetaFile::createPenIndirect: invalid pen " << parm[ 0 ] << endl;
01000         style = Qt::SolidLine;
01001     }
01002 
01003     handle->pen.setStyle( style );
01004     handle->pen.setColor( color( parm+3 ) );
01005     handle->pen.setCapStyle( Qt::RoundCap );
01006 
01007     //int width = 0;
01008     // TODO : width of pen proportional to device context width
01009     // DOESN'T WORK
01010 /*
01011     QRect devRec;
01012     devRec = mPainter.transformed( mBBox );
01013     width = ( parm[ 0 ] * devRec.width() ) / mBBox.width() ;
01014     kDebug() << "CreatePenIndirect: " <<  endl;
01015     kDebug() << "   log coord. : " << mBBox.width() << "   " << mBBox.height() << endl;
01016     kDebug() << "   log. pen : " << parm[ 1 ] << "   " << parm[ 2 ] << endl;
01017     kDebug() << "   dev. pen : " << width << endl;
01018     handle->pen.setWidth( width );
01019 */
01020 }
01021 
01022 
01023 //-----------------------------------------------------------------------------
01024 void QWinMetaFile::createFontIndirect( long , short* parm)
01025 {
01026     WinObjFontHandle* handle = new WinObjFontHandle;
01027     addHandle( handle );
01028 
01029     QString family( (const char*)&parm[ 9 ] );
01030 
01031     mRotation = -parm[ 2 ]  / 10;               // text rotation (in 1/10 degree)
01032                                                 // TODO: memorisation of rotation in object Font
01033     handle->font.setFamily( family );
01034     handle->font.setFixedPitch( ((parm[ 8 ] & 0x01) == 0) );
01035     // TODO: investigation why some test case need -2. (size of font in logical point)
01036     handle->font.setPointSize( qAbs(parm[ 0 ]) - 2 );
01037     handle->font.setWeight( (parm[ 4 ] >> 3) );
01038     handle->font.setItalic( (parm[ 5 ] & 0x01) );
01039     handle->font.setUnderline( (parm[ 5 ] & 0x100) );
01040 }
01041 
01042 
01043 //-----------------------------------------------------------------------------
01044 // Misc
01045 //-----------------------------------------------------------------------------
01046 void QWinMetaFile::noop( long, short* )
01047 {
01048 }
01049 
01050 
01051 void QWinMetaFile::end( long, short* )
01052 {
01053     // end of file :
01054 //    kDebug() << "END bbox=( " << mBBox.left() << "; " << mBBox.top() << "; " << mBBox.width() << "; " << mBBox.height() << ")" << endl;
01055 }
01056 
01057 
01058 //-----------------------------------------------------------------------------
01059 unsigned short QWinMetaFile::calcCheckSum( WmfPlaceableHeader* apmfh )
01060 {
01061     WORD*  lpWord;
01062     WORD   wResult, i;
01063 
01064     // Start with the first word
01065     wResult = *( lpWord = ( WORD* )( apmfh ) );
01066     // XOR in each of the other 9 words
01067     for( i=1; i<=9; i++ )
01068     {
01069         wResult ^= lpWord[ i ];
01070     }
01071     return wResult;
01072 }
01073 
01074 
01075 //-----------------------------------------------------------------------------
01076 int QWinMetaFile::findFunc( unsigned short aFunc ) const
01077 {
01078     int i;
01079 
01080     for ( i=0; metaFuncTab[ i ].name; i++ )
01081         if ( metaFuncTab[ i ].func == aFunc ) return i;
01082 
01083     // here : unknown function
01084     return i;
01085 }
01086 
01087 //-----------------------------------------------------------------------------
01088 QPolygon* QWinMetaFile::pointArray( short num, short* parm )
01089 {
01090     int i;
01091 
01092     mPoints.resize( num );
01093 
01094     for ( i=0; i<num; i++, parm+=2 )
01095         mPoints.setPoint( i, parm[ 0 ], parm[ 1 ] );
01096 
01097     return &mPoints;
01098 }
01099 
01100 //-----------------------------------------------------------------------------
01101 unsigned int QWinMetaFile::toDWord( short* parm )
01102 {
01103     unsigned int l;
01104 
01105 #if !defined( WORDS_BIGENDIAN )
01106     l = *( unsigned int* )( parm );
01107 #else
01108     char *bytes;
01109     char swap[ 4 ];
01110     bytes = ( char* )parm;
01111     swap[ 0 ] = bytes[ 2 ];
01112     swap[ 1 ] = bytes[ 3 ];
01113     swap[ 2 ] = bytes[ 0 ];
01114     swap[ 3 ] = bytes[ 1 ];
01115     l = *( unsigned int* )( swap );
01116 #endif
01117 
01118     return l;
01119 }
01120 
01121 
01122 //-----------------------------------------------------------------------------
01123 QColor QWinMetaFile::color( short* parm )
01124 {
01125     unsigned int colorRef;
01126     int red, green, blue;
01127 
01128     colorRef = toDWord( parm ) & 0xffffff;
01129     red      = colorRef & 255;
01130     green    = ( colorRef>>8 ) & 255;
01131     blue     = ( colorRef>>16 ) & 255;
01132 
01133     return QColor( red, green, blue );
01134 }
01135 
01136 
01137 //-----------------------------------------------------------------------------
01138 void QWinMetaFile::xyToAngle( int xStart, int yStart, int xEnd, int yEnd, int& angleStart, int& angleLength )
01139 {
01140     float aStart, aLength;
01141 
01142     aStart = atan2( yStart,  xStart );
01143     aLength = atan2( yEnd, xEnd ) - aStart;
01144 
01145     angleStart = (int)(aStart * 2880 / 3.14166);
01146     angleLength = (int)(aLength * 2880 / 3.14166);
01147     if ( angleLength < 0 ) angleLength = 5760 + angleLength;
01148 }
01149 
01150 
01151 //-----------------------------------------------------------------------------
01152 void QWinMetaFile::addHandle( WinObjHandle* handle )
01153 {
01154     int idx;
01155 
01156     for ( idx=0; idx < MAX_OBJHANDLE ; idx++ )
01157         if ( mObjHandleTab[ idx ] == NULL )  break;
01158 
01159     if ( idx < MAX_OBJHANDLE )
01160         mObjHandleTab[ idx ] = handle;
01161     else
01162         kDebug() << "QWinMetaFile error: handle table full !" << endl;
01163 }
01164 
01165 //-----------------------------------------------------------------------------
01166 void QWinMetaFile::deleteHandle( int idx )
01167 {
01168     if ( idx >= 0 && idx < MAX_OBJHANDLE && mObjHandleTab[ idx ] )
01169     {
01170         delete mObjHandleTab[ idx ];
01171         mObjHandleTab[ idx ] = NULL;
01172     }
01173 }
01174 
01175 //-----------------------------------------------------------------------------
01176 QPainter::CompositionMode QWinMetaFile::winToQtComposition( short parm ) const
01177 {
01178     static const QPainter::CompositionMode opTab[] =
01179     {
01180         // ### untested (conversion from Qt::RasterOp)
01181         QPainter::CompositionMode_Source, // Qt::CopyROP
01182         QPainter::CompositionMode_Clear, // Qt::ClearROP
01183         QPainter::CompositionMode_SourceOut, // Qt::NandROP
01184         QPainter::CompositionMode_SourceOut, // Qt::NotAndROP
01185         QPainter::CompositionMode_DestinationOut, // Qt::NotCopyROP
01186         QPainter::CompositionMode_DestinationOut, // Qt::AndNotROP
01187         QPainter::CompositionMode_DestinationOut, // Qt::NotROP
01188         QPainter::CompositionMode_Xor, // Qt::XorROP
01189         QPainter::CompositionMode_Source, // Qt::NorROP
01190         QPainter::CompositionMode_SourceIn, // Qt::AndROP
01191         QPainter::CompositionMode_SourceIn, // Qt::NotXorROP
01192         QPainter::CompositionMode_Destination, // Qt::NopROP
01193         QPainter::CompositionMode_Destination, // Qt::NotOrROP
01194         QPainter::CompositionMode_Source, // Qt::CopyROP
01195         QPainter::CompositionMode_Source, // Qt::OrNotROP
01196         QPainter::CompositionMode_SourceOver, // Qt::OrROP
01197         QPainter::CompositionMode_Source // Qt::SetROP
01198     };
01199 
01200     if ( parm > 0 && parm <= 16 )
01201         return opTab[ parm ];
01202     else
01203         return QPainter::CompositionMode_Source;
01204 }
01205 
01206 //-----------------------------------------------------------------------------
01207 QPainter::CompositionMode  QWinMetaFile::winToQtComposition( long parm ) const
01208 {
01209     /* TODO: Ternary raster operations
01210     0x00C000CA  dest = (source AND pattern)
01211     0x00F00021  dest = pattern
01212     0x00FB0A09  dest = DPSnoo
01213     0x005A0049  dest = pattern XOR dest   */
01214     static const struct OpTab
01215     {
01216         long winRasterOp;
01217         QPainter::CompositionMode qtRasterOp;
01218     } opTab[] =
01219     {
01220       // ### untested (conversion from Qt::RasterOp)
01221       { 0x00CC0020, QPainter::CompositionMode_Source }, // CopyROP
01222       { 0x00EE0086, QPainter::CompositionMode_SourceOver }, // OrROP
01223       { 0x008800C6, QPainter::CompositionMode_SourceIn }, // AndROP
01224       { 0x00660046, QPainter::CompositionMode_Xor }, // XorROP
01225       { 0x00440328, QPainter::CompositionMode_DestinationOut }, // AndNotROP
01226       { 0x00330008, QPainter::CompositionMode_DestinationOut }, // NotCopyROP
01227       { 0x001100A6, QPainter::CompositionMode_SourceOut }, // NandROP
01228       { 0x00C000CA, QPainter::CompositionMode_Source }, // CopyROP
01229       { 0x00BB0226, QPainter::CompositionMode_Destination }, // NotOrROP
01230       { 0x00F00021, QPainter::CompositionMode_Source }, // CopyROP
01231       { 0x00FB0A09, QPainter::CompositionMode_Source }, // CopyROP
01232       { 0x005A0049, QPainter::CompositionMode_Source }, // CopyROP
01233       { 0x00550009, QPainter::CompositionMode_DestinationOut }, // NotROP
01234       { 0x00000042, QPainter::CompositionMode_Clear }, // ClearROP
01235       { 0x00FF0062, QPainter::CompositionMode_Source } // SetROP
01236     };
01237 
01238     int i;
01239     for ( i=0 ; i < 15 ; i++ )
01240         if ( opTab[ i ].winRasterOp == parm )
01241             break;
01242 
01243     if ( i < 15 )
01244         return opTab[ i ].qtRasterOp;
01245     else
01246         return QPainter::CompositionMode_Source;
01247 }
01248 
01249 //-----------------------------------------------------------------------------
01250 bool QWinMetaFile::dibToBmp( QImage& bmp, const char* dib, long size )
01251 {
01252     typedef struct _BMPFILEHEADER {
01253         WORD bmType;
01254         DWORD bmSize;
01255         WORD bmReserved1;
01256         WORD bmReserved2;
01257         DWORD bmOffBits;
01258     }  BMPFILEHEADER;
01259 
01260     int sizeBmp = size + 14;
01261     QByteArray pattern;       // BMP header and DIB data
01262     pattern.fill( 0, sizeBmp );  //resize and fill
01263     pattern.insert( 14, QByteArray::fromRawData(dib, size) );
01264 
01265     // add BMP header
01266     BMPFILEHEADER* bmpHeader;
01267     bmpHeader = (BMPFILEHEADER*)((const char*)pattern);
01268     bmpHeader->bmType = 0x4D42;
01269     bmpHeader->bmSize = sizeBmp;
01270 
01271     if ( !bmp.loadFromData( (const uchar*)bmpHeader, pattern.size(), "BMP" ) ) {
01272         kDebug() << "QWinMetaFile::dibToBmp: invalid bitmap " << endl;
01273         return false;
01274     }
01275     else {
01276 //        if ( bmp.save("/home/software/kde-cvs/qt/examples/wmf/test.bmp", "BMP") )
01277 //        if ( bmp.load( "/home/software/kde-cvs/qt/examples/wmf/test.bmp", "BMP" ) )
01278 //            fprintf(stderr, "Bitmap ok \n");
01279         return true;
01280     }
01281 }
01282 

Généré le Wed Nov 22 23:41:13 2006 pour KPlato par  doxygen 1.5.1-p1