lib Library API Documentation

qwmf.cc

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