00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <math.h>
00022
#include <qfileinfo.h>
00023
#include <qimage.h>
00024
#include <qwmatrix.h>
00025
#include <qptrlist.h>
00026
#include <qpointarray.h>
00027
#include <qdatastream.h>
00028
#include <kdebug.h>
00029
00030
#include "kowmfreadprivate.h"
00031
#include "kowmfread.h"
00032
00033
00034 KoWmfReadPrivate::KoWmfReadPrivate()
00035 {
00036
mNbrFunc = 0;
00037 mValid =
false;
00038 mStandard =
false;
00039 mPlaceable =
false;
00040 mEnhanced =
false;
00041 mBuffer = 0;
00042 mObjHandleTab = 0;
00043 }
00044
00045
00046 KoWmfReadPrivate::~KoWmfReadPrivate()
00047 {
00048
if ( mObjHandleTab != 0 ) {
00049
for (
int i=0 ; i < mNbrObject ; i++ ) {
00050
if ( mObjHandleTab[i] != 0 )
00051
delete mObjHandleTab[i];
00052 }
00053
delete[] mObjHandleTab;
00054 }
00055
if ( mBuffer != 0 ) {
00056 mBuffer->close();
00057
delete mBuffer;
00058 }
00059 }
00060
00061
00062 bool KoWmfReadPrivate::load(
const QByteArray& array )
00063 {
00064
00065
if ( mBuffer != 0 ) {
00066 mBuffer->close();
00067
delete mBuffer;
00068 }
00069
00070
00071 mBuffer =
new QBuffer( array );
00072 mBuffer->open( IO_ReadOnly );
00073
00074
00075 WmfEnhMetaHeader eheader;
00076 WmfMetaHeader header;
00077 WmfPlaceableHeader pheader;
00078
unsigned short checksum;
00079
int filePos;
00080
00081
QDataStream st( mBuffer );
00082 st.setByteOrder( QDataStream::LittleEndian );
00083 mStackOverflow = mWinding =
false;
00084 mTextAlign = mTextRotation = 0;
00085 mTextColor = Qt::black;
00086 mValid =
false;
00087 mStandard =
false;
00088 mPlaceable =
false;
00089 mEnhanced =
false;
00090
00091
00092 st >> pheader.key;
00093
if ( pheader.key==( Q_UINT32 )APMHEADER_KEY ) {
00094 mPlaceable =
true;
00095 st >> pheader.handle;
00096 st >> pheader.left;
00097 st >> pheader.top;
00098 st >> pheader.right;
00099 st >> pheader.bottom;
00100 st >> pheader.inch;
00101 st >> pheader.reserved;
00102 st >> pheader.checksum;
00103 checksum =
calcCheckSum( &pheader );
00104
if ( pheader.checksum!=checksum ) {
00105
return false;
00106 }
00107 st >> header.fileType;
00108 st >> header.headerSize;
00109 st >> header.version;
00110 st >> header.fileSize;
00111 st >> header.numOfObjects;
00112 st >> header.maxRecordSize;
00113 st >> header.numOfParameters;
00114 mNbrObject = header.numOfObjects;
00115
mBBox.setLeft( pheader.left );
00116
mBBox.setTop( pheader.top );
00117
mBBox.setRight( pheader.right );
00118
mBBox.setBottom( pheader.bottom );
00119
mDpi = pheader.inch;
00120 }
00121
else {
00122 mBuffer->at( 0 );
00123
00124 filePos = mBuffer->at();
00125 st >> eheader.recordType;
00126 st >> eheader.recordSize;
00127 st >> eheader.boundsLeft;
00128 st >> eheader.boundsTop;
00129 st >> eheader.boundsRight;
00130 st >> eheader.boundsBottom;
00131 st >> eheader.frameLeft;
00132 st >> eheader.frameTop;
00133 st >> eheader.frameRight;
00134 st >> eheader.frameBottom;
00135 st >> eheader.signature;
00136
if ( eheader.signature==ENHMETA_SIGNATURE ) {
00137 mEnhanced =
true;
00138 st >> eheader.version;
00139 st >> eheader.size;
00140 st >> eheader.numOfRecords;
00141 st >> eheader.numHandles;
00142 st >> eheader.reserved;
00143 st >> eheader.sizeOfDescription;
00144 st >> eheader.offsetOfDescription;
00145 st >> eheader.numPaletteEntries;
00146 st >> eheader.widthDevicePixels;
00147 st >> eheader.heightDevicePixels;
00148 st >> eheader.widthDeviceMM;
00149 st >> eheader.heightDeviceMM;
00150 }
00151
else {
00152
00153 mStandard =
true;
00154 mBuffer->at( filePos );
00155 st >> header.fileType;
00156 st >> header.headerSize;
00157 st >> header.version;
00158 st >> header.fileSize;
00159 st >> header.numOfObjects;
00160 st >> header.maxRecordSize;
00161 st >> header.numOfParameters;
00162 mNbrObject = header.numOfObjects;
00163 }
00164 }
00165 mOffsetFirstRecord = mBuffer->at();
00166
00167
00168
if ( ((header.headerSize == 9) && (header.numOfParameters == 0)) || (mPlaceable) ) {
00169
00170 mValid =
true;
00171 }
00172
else {
00173 kdDebug() <<
"KoWmfReadPrivate : incorrect file format !" << endl;
00174 }
00175
00176
00177
if ( (mValid) && (mStandard) ) {
00178 Q_UINT16 numFunction = 1;
00179 Q_UINT32 size;
00180
bool firstOrg=
true, firstExt=
true;
00181
00182
00183
while ( numFunction ) {
00184 filePos = mBuffer->at();
00185 st >> size >> numFunction;
00186
00187
if ( size == 0 ) {
00188 kdDebug() <<
"KoWmfReadPrivate : incorrect file!" << endl;
00189 mValid = 0;
00190
break;
00191 }
00192
00193 numFunction &= 0xFF;
00194
if ( numFunction == 11 ) {
00195 Q_INT16 top, left;
00196
00197 st >> top >> left;
00198
if ( firstOrg ) {
00199 firstOrg =
false;
00200
mBBox.setLeft( left );
00201
mBBox.setTop( top );
00202 }
00203
else {
00204
if ( left <
mBBox.left() )
mBBox.setLeft( left );
00205
if ( top <
mBBox.top() )
mBBox.setTop( top );
00206 }
00207 }
00208
if ( numFunction == 12 ) {
00209 Q_INT16 width, height;
00210
00211 st >> height >> width;
00212
if ( width < 0 ) width = -width;
00213
if ( height < 0 ) height = -height;
00214
if ( firstExt ) {
00215 firstExt =
false;
00216
mBBox.setWidth( width );
00217
mBBox.setHeight( height );
00218 }
00219
else {
00220
if ( width >
mBBox.width() )
mBBox.setWidth( width );
00221
if ( height >
mBBox.height() )
mBBox.setHeight( height );
00222 }
00223 }
00224 mBuffer->at( filePos + (size<<1) );
00225
00226 }
00227 }
00228
00229
return (mValid);
00230 }
00231
00232
00233 bool KoWmfReadPrivate::play(
KoWmfRead* readWmf )
00234 {
00235
if ( !(mValid) ) {
00236 kdDebug() <<
"KoWmfReadPrivate::play : invalid WMF file" << endl;
00237
return false;
00238 }
00239
00240
if (
mNbrFunc ) {
00241
if ( (mStandard) ) {
00242 kdDebug() <<
"Standard : " <<
mBBox.left() <<
" " <<
mBBox.top() <<
" " <<
mBBox.width() <<
" " <<
mBBox.height() << endl;
00243 }
00244
else {
00245 kdDebug() <<
"DPI : " <<
mDpi <<
" : " <<
mBBox.left() <<
" " <<
mBBox.top() <<
" " <<
mBBox.width() <<
" " <<
mBBox.height() << endl;
00246 kdDebug() <<
"inch : " <<
mBBox.width()/
mDpi <<
" " <<
mBBox.height()/
mDpi << endl;
00247 kdDebug() <<
"mm : " <<
mBBox.width()*25.4/
mDpi <<
" " <<
mBBox.height()*25.4/
mDpi << endl;
00248 }
00249 kdDebug() << mValid <<
" " << mStandard <<
" " << mPlaceable << endl;
00250 }
00251
00252
00253 mObjHandleTab =
new KoWmfHandle* [ mNbrObject ];
00254
for (
int i=0; i < mNbrObject ; i++ ) {
00255 mObjHandleTab[ i ] = 0;
00256 }
00257
00258 Q_UINT16 numFunction;
00259 Q_UINT32 size;
00260
int bufferOffset, j;
00261
00262
00263
QDataStream st( mBuffer );
00264 st.setByteOrder( QDataStream::LittleEndian );
00265
00266 mReadWmf = readWmf;
00267 mWindow =
mBBox;
00268
if ( mReadWmf->
begin() ) {
00269
00270 mBuffer->at( mOffsetFirstRecord );
00271 numFunction = j = 1;
00272 mWinding =
false;
00273
00274
while ( ( numFunction ) && ( !mStackOverflow ) ) {
00275 bufferOffset = mBuffer->at();
00276 st >> size >> numFunction;
00277
00282 numFunction &= 0xFF;
00283
if ( numFunction > 0x5F ) {
00284 numFunction -= 0x90;
00285 }
00286
if ( (numFunction > 111) || (koWmfFunc[ numFunction ].method == 0) ) {
00287
00288 kdDebug() <<
"KoWmfReadPrivate::paint : BROKEN WMF file" << endl;
00289 mValid =
false;
00290
break;
00291 }
00292
00293
if (
mNbrFunc ) {
00294
00295
if ( (j+12) >
mNbrFunc ) {
00296
00297
int offBuff = mBuffer->at();
00298 Q_UINT16 param;
00299
00300 kdDebug() << j <<
" : " << numFunction <<
" : ";
00301
for ( Q_UINT16 i=0 ; i < (size-3) ; i++ ) {
00302 st >> param;
00303 kdDebug() << param <<
" ";
00304 }
00305 kdDebug() << endl;
00306 mBuffer->at( offBuff );
00307 }
00308
if ( j >=
mNbrFunc ) {
00309
break;
00310 }
00311 j++;
00312 }
00313
00314
00315 (this->*koWmfFunc[ numFunction ].method)( size, st );
00316
00317 mBuffer->at( bufferOffset + (size<<1) );
00318 }
00319
00320 mReadWmf->
end();
00321 }
00322
00323
for (
int i=0 ; i < mNbrObject ; i++ ) {
00324
if ( mObjHandleTab[ i ] != 0 )
00325
delete mObjHandleTab[ i ];
00326 }
00327
delete[] mObjHandleTab;
00328 mObjHandleTab = 0;
00329
00330
return true;
00331 }
00332
00333
00334
00335
00336
00337 void KoWmfReadPrivate::setWindowOrg( Q_UINT32,
QDataStream& stream )
00338 {
00339 Q_INT16 top, left;
00340
00341 stream >> top >> left;
00342 mReadWmf->
setWindowOrg( left, top );
00343 mWindow.setLeft( left );
00344 mWindow.setTop( top );
00345
00346 }
00347
00348
00349
00350
00351 void KoWmfReadPrivate::setWindowExt( Q_UINT32,
QDataStream& stream )
00352 {
00353 Q_INT16 width, height;
00354
00355
00356 stream >> height >> width;
00357 mReadWmf->
setWindowExt( width, height );
00358 mWindow.setWidth( width );
00359 mWindow.setHeight( height );
00360
00361 }
00362
00363
00364 void KoWmfReadPrivate::OffsetWindowOrg( Q_UINT32,
QDataStream &stream )
00365 {
00366 Q_INT16 offTop, offLeft;
00367
00368 stream >> offTop >> offLeft;
00369 mReadWmf->
setWindowOrg( mWindow.left() + offLeft, mWindow.top() + offTop );
00370 mWindow.setLeft( mWindow.left() + offLeft );
00371 mWindow.setTop( mWindow.top() + offTop );
00372 }
00373
00374
00375 void KoWmfReadPrivate::ScaleWindowExt( Q_UINT32,
QDataStream &stream )
00376 {
00377 Q_INT16 width, height;
00378 Q_INT16 heightDenom, heightNum, widthDenom, widthNum;
00379
00380 stream >> heightDenom >> heightNum >> widthDenom >> widthNum;
00381
00382
if ( ( widthDenom != 0 ) && ( heightDenom != 0 ) ) {
00383 width = (mWindow.width() * widthNum) / widthDenom;
00384 height = (mWindow.height() * heightNum) / heightDenom;
00385 mReadWmf->
setWindowExt( width, height );
00386 mWindow.setWidth( width );
00387 mWindow.setHeight( height );
00388 }
00389
00390 }
00391
00392
00393
00394
00395
00396 void KoWmfReadPrivate::lineTo( Q_UINT32,
QDataStream& stream )
00397 {
00398 Q_INT16 top, left;
00399
00400 stream >> top >> left;
00401 mReadWmf->
lineTo( left, top );
00402 }
00403
00404
00405 void KoWmfReadPrivate::moveTo( Q_UINT32,
QDataStream& stream )
00406 {
00407 Q_INT16 top, left;
00408
00409 stream >> top >> left;
00410 mReadWmf->
moveTo( left, top );
00411 }
00412
00413
00414 void KoWmfReadPrivate::ellipse( Q_UINT32,
QDataStream& stream )
00415 {
00416 Q_INT16 top, left, right, bottom;
00417
00418 stream >> bottom >> right >> top >> left;
00419 mReadWmf->
drawEllipse( left, top, right-left, bottom-top );
00420 }
00421
00422
00423 void KoWmfReadPrivate::polygon( Q_UINT32,
QDataStream& stream )
00424 {
00425 Q_UINT16 num;
00426
00427 stream >> num;
00428
00429
QPointArray pa( num );
00430
00431 pointArray( stream, pa );
00432 mReadWmf->
drawPolygon( pa, mWinding );
00433 }
00434
00435
00436 void KoWmfReadPrivate::polyPolygon( Q_UINT32,
QDataStream& stream )
00437 {
00438 Q_UINT16 numberPoly;
00439 Q_UINT16 sizePoly;
00440
QPtrList<QPointArray> listPa;
00441
00442 stream >> numberPoly;
00443
00444 listPa.setAutoDelete(
true );
00445
for (
int i=0 ; i < numberPoly ; i++ ) {
00446 stream >> sizePoly;
00447 listPa.append(
new QPointArray( sizePoly ) );
00448 }
00449
00450
00451
QPointArray *pa;
00452
for ( pa = listPa.first() ; pa ; pa = listPa.next() ) {
00453 pointArray( stream, *pa );
00454 }
00455
00456
00457 mReadWmf->
drawPolyPolygon( listPa, mWinding );
00458 listPa.clear();
00459 }
00460
00461
00462 void KoWmfReadPrivate::polyline( Q_UINT32,
QDataStream& stream )
00463 {
00464 Q_UINT16 num;
00465
00466 stream >> num;
00467
QPointArray pa( num );
00468
00469 pointArray( stream, pa );
00470 mReadWmf->
drawPolyline( pa );
00471 }
00472
00473
00474 void KoWmfReadPrivate::rectangle( Q_UINT32,
QDataStream& stream )
00475 {
00476 Q_INT16 top, left, right, bottom;
00477
00478 stream >> bottom >> right >> top >> left;
00479 mReadWmf->
drawRect( left, top, right-left, bottom-top );
00480 }
00481
00482
00483 void KoWmfReadPrivate::roundRect( Q_UINT32,
QDataStream& stream )
00484 {
00485
int xRnd = 0, yRnd = 0;
00486 Q_UINT16 widthCorner, heightCorner;
00487 Q_INT16 top, left, right, bottom;
00488
00489 stream >> heightCorner >> widthCorner;
00490 stream >> bottom >> right >> top >> left;
00491
00492
00493
if ( (right - left) != 0 )
00494 xRnd = (widthCorner * 100) / (right - left);
00495
if ( (bottom - top) != 0 )
00496 yRnd = (heightCorner * 100) / (bottom - top);
00497
00498 mReadWmf->
drawRoundRect( left, top, right-left, bottom-top, xRnd, yRnd );
00499 }
00500
00501
00502 void KoWmfReadPrivate::arc( Q_UINT32,
QDataStream& stream )
00503 {
00504
int xCenter, yCenter, angleStart, aLength;
00505 Q_INT16 topEnd, leftEnd, topStart, leftStart;
00506 Q_INT16 top, left, right, bottom;
00507
00508 stream >> topEnd >> leftEnd >> topStart >> leftStart;
00509 stream >> bottom >> right >> top >> left;
00510
00511 xCenter = left + ((right-left) / 2);
00512 yCenter = top + ((bottom-top) / 2);
00513 xyToAngle ( leftStart-xCenter, yCenter-topStart, leftEnd-xCenter, yCenter-topEnd, angleStart, aLength );
00514
00515 mReadWmf->
drawArc( left, top, right-left, bottom-top, angleStart, aLength);
00516 }
00517
00518
00519 void KoWmfReadPrivate::chord( Q_UINT32,
QDataStream& stream )
00520 {
00521
int xCenter, yCenter, angleStart, aLength;
00522 Q_INT16 topEnd, leftEnd, topStart, leftStart;
00523 Q_INT16 top, left, right, bottom;
00524
00525 stream >> topEnd >> leftEnd >> topStart >> leftStart;
00526 stream >> bottom >> right >> top >> left;
00527
00528 xCenter = left + ((right-left) / 2);
00529 yCenter = top + ((bottom-top) / 2);
00530 xyToAngle ( leftStart-xCenter, yCenter-topStart, leftEnd-xCenter, yCenter-topEnd, angleStart, aLength );
00531
00532 mReadWmf->
drawChord( left, top, right-left, bottom-top, angleStart, aLength);
00533 }
00534
00535
00536 void KoWmfReadPrivate::pie( Q_UINT32,
QDataStream& stream )
00537 {
00538
int xCenter, yCenter, angleStart, aLength;
00539 Q_INT16 topEnd, leftEnd, topStart, leftStart;
00540 Q_INT16 top, left, right, bottom;
00541
00542 stream >> topEnd >> leftEnd >> topStart >> leftStart;
00543 stream >> bottom >> right >> top >> left;
00544
00545 xCenter = left + ((right-left) / 2);
00546 yCenter = top + ((bottom-top) / 2);
00547 xyToAngle ( leftStart-xCenter, yCenter-topStart, leftEnd-xCenter, yCenter-topEnd, angleStart, aLength );
00548
00549 mReadWmf->
drawPie( left, top, right-left, bottom-top, angleStart, aLength);
00550 }
00551
00552
00553 void KoWmfReadPrivate::setPolyFillMode( Q_UINT32,
QDataStream& stream )
00554 {
00555 Q_UINT16 winding;
00556
00557 stream >> winding;
00558 mWinding = (winding != 0);
00559 }
00560
00561
00562 void KoWmfReadPrivate::setBkColor( Q_UINT32,
QDataStream& stream )
00563 {
00564 Q_UINT32 color;
00565
00566 stream >> color;
00567 mReadWmf->
setBackgroundColor( qtColor( color ) );
00568 }
00569
00570
00571 void KoWmfReadPrivate::setBkMode( Q_UINT32,
QDataStream& stream )
00572 {
00573 Q_UINT16 bkMode;
00574
00575 stream >> bkMode;
00576
if ( bkMode == 1 )
00577 mReadWmf->
setBackgroundMode( Qt::TransparentMode );
00578
else
00579 mReadWmf->
setBackgroundMode( Qt::OpaqueMode );
00580 }
00581
00582
00583 void KoWmfReadPrivate::setPixel( Q_UINT32,
QDataStream& stream )
00584 {
00585 Q_INT16 top, left;
00586 Q_UINT32 color;
00587
00588 stream >> color >> top >> left;
00589
00590
QPen oldPen = mReadWmf->
pen();
00591
QPen pen = oldPen;
00592 pen.setColor( qtColor( color ) );
00593 mReadWmf->
setPen( pen );
00594 mReadWmf->
moveTo( left, top );
00595 mReadWmf->
lineTo( left, top );
00596 mReadWmf->
setPen( oldPen );
00597 }
00598
00599
00600 void KoWmfReadPrivate::setRop( Q_UINT32,
QDataStream& stream )
00601 {
00602 Q_UINT16 rop;
00603
00604 stream >> rop;
00605 mReadWmf->
setRasterOp( winToQtRaster( rop ) );
00606 }
00607
00608
00609 void KoWmfReadPrivate::saveDC( Q_UINT32,
QDataStream& )
00610 {
00611 mReadWmf->
save();
00612 }
00613
00614
00615 void KoWmfReadPrivate::restoreDC( Q_UINT32,
QDataStream& stream )
00616 {
00617 Q_INT16 num;
00618
00619 stream >> num;
00620
for (
int i=0; i > num ; i-- )
00621 mReadWmf->
restore();
00622 }
00623
00624
00625 void KoWmfReadPrivate::intersectClipRect( Q_UINT32,
QDataStream& stream )
00626 {
00627 Q_INT16 top, left, right, bottom;
00628
00629 stream >> bottom >> right >> top >> left;
00630
00631
QRegion region = mReadWmf->
clipRegion();
00632
QRegion newRegion( left, top, right-left, bottom-top );
00633
if ( region.isEmpty() ) {
00634 region = newRegion;
00635 }
00636
else {
00637 region = region.intersect( newRegion );
00638 }
00639
00640 mReadWmf->
setClipRegion( region );
00641 }
00642
00643
00644 void KoWmfReadPrivate::excludeClipRect( Q_UINT32,
QDataStream& stream )
00645 {
00646 Q_INT16 top, left, right, bottom;
00647
00648 stream >> bottom >> right >> top >> left;
00649
00650
QRegion region = mReadWmf->
clipRegion();
00651
QRegion newRegion( left, top, right-left, bottom-top );
00652
if ( region.isEmpty() ) {
00653 region = newRegion;
00654 }
00655
else {
00656 region = region.subtract( newRegion );
00657 }
00658
00659 mReadWmf->
setClipRegion( region );
00660 }
00661
00662
00663
00664
00665
00666 void KoWmfReadPrivate::setTextColor( Q_UINT32,
QDataStream& stream )
00667 {
00668 Q_UINT32 color;
00669
00670 stream >> color;
00671 mTextColor = qtColor( color );
00672 }
00673
00674
00675 void KoWmfReadPrivate::setTextAlign( Q_UINT32,
QDataStream& stream )
00676 {
00677 stream >> mTextAlign;
00678 }
00679
00680
00681 void KoWmfReadPrivate::textOut( Q_UINT32,
QDataStream& )
00682 {
00683
if (
mNbrFunc ) {
00684 kdDebug() <<
"textOut : unimplemented " << endl;
00685 }
00686 }
00687
00688
00689
void KoWmfReadPrivate::extTextOut( Q_UINT32 ,
QDataStream& )
00690 {
00691
if ( mNbrFunc ) {
00692 kdDebug() <<
"extTextOut : unimplemented " << endl;
00693 }
00694 }
00695
00696
00697
00698
00699
00700
00701
void KoWmfReadPrivate::SetStretchBltMode( Q_UINT32,
QDataStream& )
00702 {
00703
if (
mNbrFunc ) {
00704 kdDebug() <<
"SetStretchBltMode : unimplemented " << endl;
00705 }
00706 }
00707
00708
00709 void KoWmfReadPrivate::dibBitBlt( Q_UINT32 size,
QDataStream& stream )
00710 {
00711 Q_UINT32 raster;
00712 Q_INT16 topSrc, leftSrc, widthSrc, heightSrc;
00713 Q_INT16 topDst, leftDst;
00714
00715 stream >> raster;
00716 stream >> topSrc >> leftSrc >> heightSrc >> widthSrc;
00717 stream >> topDst >> leftDst;
00718
00719
if ( size > 11 ) {
00720
QImage bmpSrc;
00721
00722
if ( dibToBmp( bmpSrc, stream, (size - 11) * 2 ) ) {
00723 mReadWmf->
setRasterOp( winToQtRaster( raster ) );
00724
00725 mReadWmf->
save();
00726
if ( widthSrc < 0 ) {
00727
00728
QWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );
00729 mReadWmf->
setWorldMatrix( m,
true );
00730 }
00731
if ( heightSrc < 0 ) {
00732
00733
QWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );
00734 mReadWmf->
setWorldMatrix( m,
true );
00735 }
00736 mReadWmf->
drawImage( leftDst, topDst, bmpSrc, leftSrc, topSrc, widthSrc, heightSrc );
00737 mReadWmf->
restore();
00738 }
00739 }
00740
else {
00741 kdDebug() <<
"KoWmfReadPrivate::dibBitBlt without image not implemented " << endl;
00742 }
00743 }
00744
00745
00746 void KoWmfReadPrivate::dibStretchBlt( Q_UINT32 size,
QDataStream& stream )
00747 {
00748 Q_UINT32 raster;
00749 Q_INT16 topSrc, leftSrc, widthSrc, heightSrc;
00750 Q_INT16 topDst, leftDst, widthDst, heightDst;
00751
QImage bmpSrc;
00752
00753 stream >> raster;
00754 stream >> heightSrc >> widthSrc >> topSrc >> leftSrc;
00755 stream >> heightDst >> widthDst >> topDst >> leftDst;
00756
00757
if ( dibToBmp( bmpSrc, stream, (size - 13) * 2 ) ) {
00758 mReadWmf->
setRasterOp( winToQtRaster( raster ) );
00759
00760 mReadWmf->
save();
00761
if ( widthDst < 0 ) {
00762
00763
QWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );
00764 mReadWmf->
setWorldMatrix( m,
true );
00765 }
00766
if ( heightDst < 0 ) {
00767
00768
QWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );
00769 mReadWmf->
setWorldMatrix( m,
true );
00770 }
00771 bmpSrc = bmpSrc.copy( leftSrc, topSrc, widthSrc, heightSrc );
00772
00773
00774
00775 mReadWmf->
drawImage( leftDst, topDst, bmpSrc );
00776 mReadWmf->
restore();
00777 }
00778 }
00779
00780
00781
void KoWmfReadPrivate::stretchDib( Q_UINT32 size,
QDataStream& stream )
00782 {
00783 Q_UINT32 raster;
00784 Q_INT16 arg, topSrc, leftSrc, widthSrc, heightSrc;
00785 Q_INT16 topDst, leftDst, widthDst, heightDst;
00786
QImage bmpSrc;
00787
00788 stream >> raster >> arg;
00789 stream >> heightSrc >> widthSrc >> topSrc >> leftSrc;
00790 stream >> heightDst >> widthDst >> topDst >> leftDst;
00791
00792
if ( dibToBmp( bmpSrc, stream, (size - 14) * 2 ) ) {
00793 mReadWmf->
setRasterOp( winToQtRaster( raster ) );
00794
00795 mReadWmf->
save();
00796
if ( widthDst < 0 ) {
00797
00798
QWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );
00799 mReadWmf->
setWorldMatrix( m,
true );
00800 }
00801
if ( heightDst < 0 ) {
00802
00803
QWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );
00804 mReadWmf->
setWorldMatrix( m,
true );
00805 }
00806 bmpSrc = bmpSrc.copy( leftSrc, topSrc, widthSrc, heightSrc );
00807
00808
00809 mReadWmf->
drawImage( leftDst, topDst, bmpSrc );
00810 mReadWmf->
restore();
00811 }
00812 }
00813
00814
00815 void KoWmfReadPrivate::dibCreatePatternBrush( Q_UINT32 size,
QDataStream& stream )
00816 {
00817 KoWmfPatternBrushHandle* handle =
new KoWmfPatternBrushHandle;
00818
00819
if ( addHandle( handle ) ) {
00820 Q_UINT32 arg;
00821
QImage bmpSrc;
00822
00823 stream >> arg;
00824
if ( dibToBmp( bmpSrc, stream, (size - 5) * 2 ) ) {
00825 handle->image = bmpSrc;
00826 handle->brush.setPixmap( handle->image );
00827 }
00828
else {
00829 kdDebug() <<
"KoWmfReadPrivate::dibCreatePatternBrush : incorrect DIB image" << endl;
00830 }
00831 }
00832 }
00833
00834
00835
00836
00837
00838 void KoWmfReadPrivate::selectObject( Q_UINT32,
QDataStream& stream )
00839 {
00840 Q_UINT16 idx;
00841
00842 stream >> idx;
00843
if ( (idx < mNbrObject) && (mObjHandleTab[ idx ] != 0) )
00844 mObjHandleTab[ idx ]->
apply( mReadWmf );
00845
else
00846 kdDebug() <<
"KoWmfReadPrivate::selectObject : selection of an empty object" << endl;
00847 }
00848
00849
00850 void KoWmfReadPrivate::deleteObject( Q_UINT32,
QDataStream& stream )
00851 {
00852 Q_UINT16 idx;
00853
00854 stream >> idx;
00855 deleteHandle( idx );
00856 }
00857
00858
00859 void KoWmfReadPrivate::createEmptyObject()
00860 {
00861
00862 KoWmfPenHandle* handle =
new KoWmfPenHandle;
00863
00864 addHandle( handle );
00865 }
00866
00867
00868 void KoWmfReadPrivate::createBrushIndirect( Q_UINT32,
QDataStream& stream )
00869 {
00870 Qt::BrushStyle style;
00871 Q_UINT16 sty, arg2;
00872 Q_UINT32 color;
00873 KoWmfBrushHandle* handle =
new KoWmfBrushHandle;
00874
00875
if ( addHandle( handle ) ) {
00876 stream >> sty >> color >> arg2;
00877
00878
if ( sty == 2 ) {
00879
if ( arg2 < 6 )
00880 style = koWmfHatchedStyleBrush[ arg2 ];
00881
else
00882 {
00883 kdDebug() <<
"KoWmfReadPrivate::createBrushIndirect: invalid hatched brush " << arg2 << endl;
00884 style = Qt::SolidPattern;
00885 }
00886 }
00887
else {
00888
if ( sty < 9 )
00889 style = koWmfStyleBrush[ sty ];
00890
else {
00891 kdDebug() <<
"KoWmfReadPrivate::createBrushIndirect: invalid brush " << sty << endl;
00892 style = Qt::SolidPattern;
00893 }
00894 }
00895 handle->brush.setStyle( style );
00896 handle->brush.setColor( qtColor( color ) );
00897 }
00898 }
00899
00900
00901 void KoWmfReadPrivate::createPenIndirect( Q_UINT32,
QDataStream& stream )
00902 {
00903
00904 Qt::PenStyle penStyle;
00905 Q_UINT32 color;
00906 Q_UINT16 style, width, arg;
00907
00908 KoWmfPenHandle* handle =
new KoWmfPenHandle;
00909
00910
if ( addHandle( handle ) ) {
00911 stream >> style >> width >> arg >> color;
00912
00913
if ( style < 7 )
00914 penStyle=koWmfStylePen[ style ];
00915
else {
00916 kdDebug() <<
"KoWmfReadPrivate::createPenIndirect: invalid pen " << style << endl;
00917 penStyle = Qt::SolidLine;
00918 }
00919
00920 handle->pen.setStyle( penStyle );
00921 handle->pen.setColor( qtColor( color ) );
00922 handle->pen.setCapStyle( Qt::RoundCap );
00923 handle->pen.setWidth( width );
00924 }
00925 }
00926
00927
00928 void KoWmfReadPrivate::createFontIndirect( Q_UINT32 size,
QDataStream& stream )
00929 {
00930 Q_INT16 pointSize, rotation;
00931 Q_UINT16 weight, property, fixedPitch, arg;
00932
00933 KoWmfFontHandle* handle =
new KoWmfFontHandle;
00934
00935
if ( addHandle( handle ) ) {
00936 stream >> pointSize >> arg;
00937 stream >> rotation >> arg;
00938 stream >> weight >> property >> arg >> arg;
00939 stream >> fixedPitch;
00940
00941
00942
00943 mTextRotation = -rotation / 10;
00944 handle->font.setFixedPitch( ((fixedPitch & 0x01) == 0) );
00945
00946
00947 handle->font.setPointSize( QABS(pointSize) - 2 );
00948 handle->font.setWeight( (weight >> 3) );
00949 handle->font.setItalic( (property & 0x01) );
00950 handle->font.setUnderline( (property & 0x100) );
00951
00952
00953
int maxChar = (size-12) * 2;
00954
char* nameFont =
new char[maxChar];
00955 stream.readRawBytes( nameFont, maxChar );
00956 handle->font.setFamily( nameFont );
00957
delete[] nameFont;
00958 }
00959 }
00960
00961
00962
00963
00964
00965 void KoWmfReadPrivate::end( Q_UINT32,
QDataStream& )
00966 {
00967 }
00968
00969 Q_UINT16
KoWmfReadPrivate::calcCheckSum( WmfPlaceableHeader* apmfh )
00970 {
00971 Q_UINT16* lpWord;
00972 Q_UINT16 wResult, i;
00973
00974
00975 wResult = *( lpWord = ( Q_UINT16* )( apmfh ) );
00976
00977
for( i=1; i<=9; i++ )
00978 {
00979 wResult ^= lpWord[ i ];
00980 }
00981
return wResult;
00982 }
00983
00984
00985
void KoWmfReadPrivate::notyet( Q_UINT32,
QDataStream& )
00986 {
00987
if ( mNbrFunc ) {
00988 kdDebug() <<
"unimplemented " << endl;
00989 }
00990 }
00991
00992
void KoWmfReadPrivate::region( Q_UINT32,
QDataStream& )
00993 {
00994
if (
mNbrFunc ) {
00995 kdDebug() <<
"region : unimplemented " << endl;
00996 }
00997 }
00998
00999
void KoWmfReadPrivate::palette( Q_UINT32,
QDataStream& )
01000 {
01001
if (
mNbrFunc ) {
01002 kdDebug() <<
"palette : unimplemented " << endl;
01003 }
01004 }
01005
01006
void KoWmfReadPrivate::escape( Q_UINT32,
QDataStream& )
01007 {
01008
if (
mNbrFunc ) {
01009 kdDebug() <<
"escape : unimplemented " << endl;
01010 }
01011 }
01012
01013
void KoWmfReadPrivate::setRelAbs( Q_UINT32,
QDataStream& )
01014 {
01015
if (
mNbrFunc ) {
01016 kdDebug() <<
"setRelAbs : unimplemented " << endl;
01017 }
01018 }
01019
01020
void KoWmfReadPrivate::setMapMode( Q_UINT32,
QDataStream& )
01021 {
01022
if (
mNbrFunc ) {
01023 kdDebug() <<
"setMapMode : unimplemented " << endl;
01024 }
01025 }
01026
01027
void KoWmfReadPrivate::extFloodFill( Q_UINT32,
QDataStream& )
01028 {
01029
if (
mNbrFunc ) {
01030 kdDebug() <<
"extFloodFill : unimplemented " << endl;
01031 }
01032 }
01033
01034
void KoWmfReadPrivate::startDoc( Q_UINT32,
QDataStream& )
01035 {
01036
if (
mNbrFunc ) {
01037 kdDebug() <<
"startDoc : unimplemented " << endl;
01038 }
01039 }
01040
01041
void KoWmfReadPrivate::startPage( Q_UINT32,
QDataStream& )
01042 {
01043
if (
mNbrFunc ) {
01044 kdDebug() <<
"startPage : unimplemented " << endl;
01045 }
01046 }
01047
01048
void KoWmfReadPrivate::endDoc( Q_UINT32,
QDataStream& )
01049 {
01050
if (
mNbrFunc ) {
01051 kdDebug() <<
"endDoc : unimplemented " << endl;
01052 }
01053 }
01054
01055
void KoWmfReadPrivate::endPage( Q_UINT32,
QDataStream& )
01056 {
01057
if (
mNbrFunc ) {
01058 kdDebug() <<
"endPage : unimplemented " << endl;
01059 }
01060 }
01061
01062
void KoWmfReadPrivate::resetDC( Q_UINT32,
QDataStream& )
01063 {
01064
if (
mNbrFunc ) {
01065 kdDebug() <<
"resetDC : unimplemented " << endl;
01066 }
01067 }
01068
01069
void KoWmfReadPrivate::bitBlt( Q_UINT32,
QDataStream& )
01070 {
01071
if (
mNbrFunc ) {
01072 kdDebug() <<
"bitBlt : unimplemented " << endl;
01073 }
01074 }
01075
01076
void KoWmfReadPrivate::setDibToDev( Q_UINT32,
QDataStream& )
01077 {
01078
if (
mNbrFunc ) {
01079 kdDebug() <<
"setDibToDev : unimplemented " << endl;
01080 }
01081 }
01082
01083
void KoWmfReadPrivate::createBrush( Q_UINT32,
QDataStream& )
01084 {
01085
if (
mNbrFunc ) {
01086 kdDebug() <<
"createBrush : unimplemented " << endl;
01087 }
01088 }
01089
01090
void KoWmfReadPrivate::createPatternBrush( Q_UINT32,
QDataStream& )
01091 {
01092
if (
mNbrFunc ) {
01093 kdDebug() <<
"createPatternBrush : unimplemented " << endl;
01094 }
01095 }
01096
01097
void KoWmfReadPrivate::createBitmap( Q_UINT32,
QDataStream& )
01098 {
01099
if (
mNbrFunc ) {
01100 kdDebug() <<
"createBitmap : unimplemented " << endl;
01101 }
01102 }
01103
01104
void KoWmfReadPrivate::createBitmapIndirect( Q_UINT32,
QDataStream& )
01105 {
01106
createEmptyObject();
01107
if (
mNbrFunc ) {
01108 kdDebug() <<
"createBitmapIndirect : unimplemented " << endl;
01109 }
01110 }
01111
01112
void KoWmfReadPrivate::createPalette( Q_UINT32,
QDataStream& )
01113 {
01114
createEmptyObject();
01115
if (
mNbrFunc ) {
01116 kdDebug() <<
"createPalette : unimplemented " << endl;
01117 }
01118 }
01119
01120
void KoWmfReadPrivate::createRegion( Q_UINT32,
QDataStream& )
01121 {
01122
createEmptyObject();
01123
if (
mNbrFunc ) {
01124 kdDebug() <<
"createRegion : unimplemented " << endl;
01125 }
01126 }
01127
01128
01129
01130
01131
01132
01133
bool KoWmfReadPrivate::addHandle(
KoWmfHandle* handle )
01134 {
01135
int idx;
01136
01137
for ( idx=0; idx < mNbrObject ; idx++ ) {
01138
if ( mObjHandleTab[ idx ] == 0 )
break;
01139 }
01140
01141
if ( idx < mNbrObject ) {
01142 mObjHandleTab[ idx ] = handle;
01143
return true;
01144 }
01145
else {
01146
delete handle;
01147 mStackOverflow =
true;
01148 kdDebug() <<
"KoWmfReadPrivate::addHandle : stack overflow = broken file !" << endl;
01149
return false;
01150 }
01151 }
01152
01153
01154
void KoWmfReadPrivate::deleteHandle(
int idx )
01155 {
01156
if ( (idx < mNbrObject) && (mObjHandleTab[idx] != 0) ) {
01157
delete mObjHandleTab[ idx ];
01158 mObjHandleTab[ idx ] = 0;
01159 }
01160
else {
01161 kdDebug() <<
"KoWmfReadPrivate::deletehandle() : bad index number" << endl;
01162 }
01163 }
01164
01165
01166
void KoWmfReadPrivate::pointArray(
QDataStream& stream,
QPointArray& pa )
01167 {
01168 Q_INT16 left, top;
01169
int i, max;
01170
01171
for ( i=0, max=pa.size() ; i < max ; i++ ) {
01172 stream >> left >> top;
01173 pa.setPoint( i, left, top );
01174 }
01175 }
01176
01177
01178
void KoWmfReadPrivate::xyToAngle(
int xStart,
int yStart,
int xEnd,
int yEnd,
int& angleStart,
int& angleLength )
01179 {
01180
double aStart, aLength;
01181
01182 aStart = atan2( yStart, xStart );
01183 aLength = atan2( yEnd, xEnd ) - aStart;
01184
01185 angleStart = (
int)((aStart * 2880) / 3.14166);
01186 angleLength = (
int)((aLength * 2880) / 3.14166);
01187
if ( angleLength < 0 ) angleLength = 5760 + angleLength;
01188 }
01189
01190
01191 Qt::RasterOp KoWmfReadPrivate::winToQtRaster( Q_UINT16 param )
const
01192
{
01193
if ( param < 17 )
01194
return koWmfOpTab16[ param ];
01195
else
01196
return Qt::CopyROP;
01197 }
01198
01199
01200 Qt::RasterOp KoWmfReadPrivate::winToQtRaster( Q_UINT32 param )
const
01201
{
01202
01203
01204
01205
01206
01207
int i;
01208
01209
for ( i=0 ; i < 15 ; i++ ) {
01210
if ( koWmfOpTab32[ i ].winRasterOp == param )
break;
01211 }
01212
01213
if ( i < 15 )
01214
return koWmfOpTab32[ i ].qtRasterOp;
01215
else
01216
return Qt::CopyROP;
01217 }
01218
01219
01220
bool KoWmfReadPrivate::dibToBmp(
QImage& bmp,
QDataStream& stream, Q_UINT32 size )
01221 {
01222
typedef struct _BMPFILEHEADER {
01223 Q_UINT16 bmType;
01224 Q_UINT32 bmSize;
01225 Q_UINT16 bmReserved1;
01226 Q_UINT16 bmReserved2;
01227 Q_UINT32 bmOffBits;
01228 } BMPFILEHEADER;
01229
01230
int sizeBmp = size + 14;
01231
01232
QByteArray pattern( sizeBmp );
01233 pattern.fill(0);
01234 stream.readRawBytes( &pattern[ 14 ], size );
01235
01236
01237 BMPFILEHEADER* bmpHeader;
01238 bmpHeader = (BMPFILEHEADER*)(pattern.data());
01239 bmpHeader->bmType = 0x4D42;
01240 bmpHeader->bmSize = sizeBmp;
01241
01242
01243
if ( !bmp.loadFromData( pattern,
"BMP" ) ) {
01244 kdDebug() <<
"KoWmfReadPrivate::dibToBmp: invalid bitmap " << endl;
01245
return false;
01246 }
01247
else {
01248
return true;
01249 }
01250 }
01251