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.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Sep 28 04:04:03 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003