00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <math.h>
00020 #include <QFile>
00021 #include <QDataStream>
00022
00023 #include <QPolygon>
00024 #include <Q3PtrList>
00025
00026 #include <kdebug.h>
00027
00028 #include "kowmfstruct.h"
00029 #include "kowmfreadprivate.h"
00030 #include "kowmfwrite.h"
00031
00035 class KoWmfWritePrivate
00036 {
00037 public:
00038 QRect mBBox;
00039 int mDpi;
00040 int mMaxRecordSize;
00041
00042
00043 QFile mFileOut;
00044 QDataStream mSt;
00045 };
00046
00047
00048
00049 KoWmfWrite::KoWmfWrite( const QString& fileName ) {
00050 d = new KoWmfWritePrivate;
00051
00052 d->mDpi = 1024;
00053 d->mMaxRecordSize = 0;
00054 d->mFileOut.setFileName( fileName );
00055 }
00056
00057 KoWmfWrite::~KoWmfWrite() {
00058 delete d;
00059 }
00060
00061
00062 void KoWmfWrite::setDefaultDpi( int dpi ) {
00063 d->mDpi = dpi;
00064 }
00065
00066
00067
00068
00069
00070 bool KoWmfWrite::begin() {
00071
00072 if ( !d->mFileOut.open( QIODevice::WriteOnly ) )
00073 {
00074 kDebug() << "Cannot open file " << QFile::encodeName(d->mFileOut.fileName()) << endl;
00075 return false;
00076 }
00077 d->mSt.setDevice( &d->mFileOut );
00078 d->mSt.setByteOrder( QDataStream::LittleEndian );
00079
00080
00081 for ( int i=0 ; i < 10 ; i++ ) {
00082 d->mSt << (quint32)0;
00083 }
00084
00085
00086
00087 d->mSt << (quint32)8 << (quint16)0x02FA;
00088 d->mSt << (quint16)5 << (quint16)0 << (quint16)0 << (quint32)0;
00089
00090 d->mSt << (quint32)7 << (quint16)0x02FC;
00091 d->mSt << (quint16)1 << (quint32)0 << (quint16)0;
00092 for ( int i=0 ; i < 4 ; i++ ) {
00093 d->mSt << (quint32)8 << (quint16)0x02FA << (quint16)0 << (quint32)0 << (quint32)0;
00094 }
00095 d->mMaxRecordSize = 8;
00096
00097 return true;
00098 }
00099
00100
00101 bool KoWmfWrite::end() {
00102 WmfPlaceableHeader pheader = { 0x9AC6CDD7, 0, 0, 0, 0, 0, 0, 0, 0 };
00103 quint16 checksum;
00104
00105
00106 d->mSt << (quint32)3 << (quint16)0;
00107
00108
00109 pheader.left = d->mBBox.left();
00110 pheader.top = d->mBBox.top();
00111 pheader.right = d->mBBox.right();
00112 pheader.bottom = d->mBBox.bottom();
00113 pheader.inch = d->mDpi;
00114 checksum = KoWmfReadPrivate::calcCheckSum( &pheader );
00115
00116
00117 d->mFileOut.reset();
00118 d->mSt << (quint32)0x9AC6CDD7 << (quint16)0;
00119 d->mSt << (qint16)d->mBBox.left() << (qint16)d->mBBox.top() << (qint16)d->mBBox.right() << (qint16)d->mBBox.bottom();
00120 d->mSt << (quint16)d->mDpi << (quint32)0 << checksum;
00121 d->mSt << (quint16)1 << (quint16)9 << (quint16)0x300 << (quint32)(d->mFileOut.size()/2);
00122 d->mSt << (quint16)6 << (quint32)d->mMaxRecordSize << (quint16)0;
00123
00124 d->mFileOut.close();
00125
00126 return true;
00127 }
00128
00129
00130 void KoWmfWrite::save() {
00131 d->mSt << (quint32)3 << (quint16)0x001E;
00132 }
00133
00134
00135 void KoWmfWrite::restore() {
00136 d->mSt << (quint32)4 << (quint16)0x0127 << (quint16)1;
00137 }
00138
00139
00140 void KoWmfWrite::setPen( const QPen &pen ) {
00141 int style;
00142 int max = sizeof(koWmfStylePen) / sizeof(Qt::SolidLine);
00143
00144
00145
00146 d->mSt << (quint32)4 << (quint16)0x012D << (quint16)0;
00147
00148 d->mSt << (quint32)4 << (quint16)0x01f0 << (quint16)2;
00149
00150 for ( style=0 ; style < max ; style++ ) {
00151 if ( koWmfStylePen[ style ] == pen.style() ) break;
00152 }
00153 if ( style == max ) {
00154
00155 style = 0;
00156 }
00157 d->mSt << (quint32)8 << (quint16)0x02FA;
00158 d->mSt << (quint16)style << (quint16)pen.width() << (quint16)0 << (quint32)winColor( pen.color() );
00159
00160
00161 d->mSt << (quint32)4 << (quint16)0x012D << (quint16)2;
00162 }
00163
00164
00165 void KoWmfWrite::setBrush( const QBrush &brush ) {
00166 int style;
00167 int max = sizeof(koWmfStyleBrush) / sizeof(Qt::NoBrush);
00168
00169
00170
00171 d->mSt << (quint32)4 << (quint16)0x012D << (quint16)1;
00172
00173 d->mSt << (quint32)4 << (quint16)0x01f0 << (quint16)3;
00174
00175 for ( style=0 ; style < max ; style++ ) {
00176 if ( koWmfStyleBrush[ style ] == brush.style() ) break;
00177 }
00178 if ( style == max ) {
00179
00180 style = 0;
00181 }
00182 d->mSt << (quint32)7 << (quint16)0x02FC;
00183 d->mSt << (quint16)style << (quint32)winColor( brush.color() ) << (quint16)0;
00184
00185
00186 d->mSt << (quint32)4 << (quint16)0x012D << (quint16)3;
00187 }
00188
00189
00190 void KoWmfWrite::setFont( const QFont & ) {
00191 }
00192
00193
00194 void KoWmfWrite::setBackgroundColor( const QColor &c ) {
00195 d->mSt << (quint32)5 << (quint16)0x0201 << (quint32)winColor( c );
00196 }
00197
00198
00199 void KoWmfWrite::setBackgroundMode( Qt::BGMode mode ) {
00200 d->mSt << (quint32)4 << (quint16)0x0102;
00201 if ( mode == Qt::TransparentMode )
00202 d->mSt << (quint16)1;
00203 else
00204 d->mSt << (quint16)0;
00205 }
00206
00207
00208 void KoWmfWrite::setCompositionMode( QPainter::CompositionMode op ) {
00209 d->mSt << (quint32)5 << (quint16)0x0104 << (quint32)qtRasterToWin32( op );
00210 }
00211
00212
00213 void KoWmfWrite::setWindow( int left, int top, int width, int height ) {
00214 d->mBBox.setRect( left, top, width, height );
00215
00216
00217 d->mSt << (quint32)5 << (quint16)0x020B << (quint16)top << (quint16)left;
00218
00219
00220 d->mSt << (quint32)5 << (quint16)0x020C << (quint16)height << (quint16)width;
00221 }
00222
00223
00224 void KoWmfWrite::setClipRegion( const QRegion & ) {
00225
00226 }
00227
00228
00229 void KoWmfWrite::clipping( bool enable ) {
00230 if ( !enable ) {
00231
00232 setClipRegion( d->mBBox );
00233 }
00234 }
00235
00236
00237 void KoWmfWrite::moveTo( int left, int top ) {
00238 d->mSt << (quint32)5 << (quint16)0x0214 << (quint16)top << (quint16)left;
00239 }
00240
00241
00242 void KoWmfWrite::lineTo( int left, int top ) {
00243 d->mSt << (quint32)5 << (quint16)0x0213 << (quint16)top << (quint16)left;
00244 }
00245
00246
00247 void KoWmfWrite::drawRect( int left, int top, int width, int height ) {
00248 QRect rec( left, top, width, height );
00249
00250 d->mSt << (quint32)7 << (quint16)0x041B;
00251 d->mSt << (quint16)rec.bottom() << (quint16)rec.right() << (quint16)rec.top() << (quint16)rec.left();
00252 }
00253
00254
00255 void KoWmfWrite::drawRoundRect( int left, int top, int width, int height , int roudw, int roudh ) {
00256 int widthCorner, heightCorner;
00257 QRect rec( left, top, width, height );
00258
00259
00260 widthCorner = ( roudw * width ) / 100;
00261 heightCorner = ( roudh * height ) / 100;
00262
00263 d->mSt << (quint32)9 << (quint16)0x061C << (quint16)heightCorner << (quint16)widthCorner;
00264 d->mSt << (quint16)rec.bottom() << (quint16)rec.right() << (quint16)rec.top() << (quint16)rec.left();
00265
00266 d->mMaxRecordSize = qMax( d->mMaxRecordSize, 9 );
00267 }
00268
00269
00270 void KoWmfWrite::drawEllipse( int left, int top, int width, int height ) {
00271 QRect rec( left, top, width, height );
00272
00273 d->mSt << (quint32)7 << (quint16)0x0418;
00274 d->mSt << (quint16)rec.bottom() << (quint16)rec.right() << (quint16)rec.top() << (quint16)rec.left();
00275 }
00276
00277
00278 void KoWmfWrite::drawArc( int left, int top, int width, int height , int a, int alen ) {
00279 int xCenter, yCenter;
00280 int offXStart, offYStart, offXEnd, offYEnd;
00281
00282 angleToxy( offXStart, offYStart, offXEnd, offYEnd, a, alen );
00283 xCenter = left + (width / 2);
00284 yCenter = top + (height / 2);
00285
00286 d->mSt << (quint32)11 << (quint16)0x0817;
00287 d->mSt << (quint16)(yCenter + offYEnd) << (quint16)(xCenter + offXEnd);
00288 d->mSt << (quint16)(yCenter + offYStart) << (quint16)(xCenter + offXStart);
00289 d->mSt << (quint16)(top + height) << (quint16)(left + width);
00290 d->mSt << (quint16)top << (quint16)left;
00291
00292 d->mMaxRecordSize = qMax( d->mMaxRecordSize, 11 );
00293 }
00294
00295
00296 void KoWmfWrite::drawPie( int left, int top, int width, int height , int a, int alen ) {
00297 int xCenter, yCenter;
00298 int offXStart, offYStart, offXEnd, offYEnd;
00299
00300 angleToxy( offXStart, offYStart, offXEnd, offYEnd, a, alen );
00301 xCenter = left + (width / 2);
00302 yCenter = top + (height / 2);
00303
00304 d->mSt << (quint32)11 << (quint16)0x081A;
00305 d->mSt << (quint16)(yCenter + offYEnd) << (quint16)(xCenter + offXEnd);
00306 d->mSt << (quint16)(yCenter + offYStart) << (quint16)(xCenter + offXStart);
00307 d->mSt << (quint16)(top + height) << (quint16)(left + width);
00308 d->mSt << (quint16)top << (quint16)left;
00309
00310 d->mMaxRecordSize = qMax( d->mMaxRecordSize, 11 );
00311 }
00312
00313
00314 void KoWmfWrite::drawChord( int left, int top, int width, int height , int a, int alen ) {
00315 int xCenter, yCenter;
00316 int offXStart, offYStart, offXEnd, offYEnd;
00317
00318 angleToxy( offXStart, offYStart, offXEnd, offYEnd, a, alen );
00319 xCenter = left + (width / 2);
00320 yCenter = top + (height / 2);
00321
00322 d->mSt << (quint32)11 << (quint16)0x0830;
00323 d->mSt << (quint16)(yCenter + offYEnd) << (quint16)(xCenter + offXEnd);
00324 d->mSt << (quint16)(yCenter + offYStart) << (quint16)(xCenter + offXStart);
00325 d->mSt << (quint16)(top + height) << (quint16)(left + width);
00326 d->mSt << (quint16)top << (quint16)left;
00327
00328 d->mMaxRecordSize = qMax( d->mMaxRecordSize, 11 );
00329 }
00330
00331
00332 void KoWmfWrite::drawPolyline( const QPolygon &pa ) {
00333 int size = 4 + (pa.size() * 2);
00334
00335 d->mSt << (quint32)size << (quint16)0x0325 << (quint16)pa.size();
00336 pointArray( pa );
00337
00338 d->mMaxRecordSize = qMax( d->mMaxRecordSize, size );
00339 }
00340
00341
00342 void KoWmfWrite::drawPolygon( const QPolygon &pa, bool ) {
00343 int size = 4 + (pa.size() * 2);
00344
00345 d->mSt << (quint32)size << (quint16)0x0324 << (quint16)pa.size();
00346 pointArray( pa );
00347
00348 d->mMaxRecordSize = qMax( d->mMaxRecordSize, size );
00349 }
00350
00351
00352 void KoWmfWrite::drawPolyPolygon( Q3PtrList<QPolygon>& listPa, bool ) {
00353
00354 QPolygon *pa;
00355 int sizeArrayPoly = 0;
00356
00357 for ( pa = listPa.first() ; pa ; pa = listPa.next() ) {
00358 sizeArrayPoly += (pa->size() * 2);
00359 }
00360 int size = 4 + listPa.count() + sizeArrayPoly;
00361 d->mSt << (quint32)size << (quint16)0x0538 << (quint16)listPa.count();
00362
00363
00364 for ( pa = listPa.first() ; pa ; pa = listPa.next() ) {
00365 d->mSt << (quint16)pa->size();
00366 }
00367
00368
00369 for ( pa = listPa.first() ; pa ; pa = listPa.next() ) {
00370 pointArray( *pa );
00371 }
00372
00373 d->mMaxRecordSize = qMax( d->mMaxRecordSize, size );
00374
00375 }
00376
00377
00378 void KoWmfWrite::drawImage( int , int , const QImage &, int , int , int , int ) {
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 }
00390
00391
00392 void KoWmfWrite::drawText( int , int , int , int , int , const QString& , double ) {
00393
00394 }
00395
00396
00397
00398
00399 void KoWmfWrite::pointArray( const QPolygon &pa ) {
00400 int left, top, i, max;
00401
00402 for ( i=0, max=pa.size() ; i < max ; i++ ) {
00403 pa.point( i, &left, &top );
00404 d->mSt << (qint16)left << (qint16)top;
00405 }
00406 }
00407
00408
00409 quint32 KoWmfWrite::winColor( QColor color ) {
00410 quint32 c;
00411
00412 c = (color.red() & 0xFF);
00413 c += ( (color.green() & 0xFF) << 8 );
00414 c += ( (color.blue() & 0xFF) << 16 );
00415
00416 return c;
00417 }
00418
00419
00420 void KoWmfWrite::angleToxy( int &xStart, int &yStart, int &xEnd, int &yEnd, int a, int alen ) {
00421 double angleStart, angleLength;
00422
00423 angleStart = ((double)a * 3.14166) / 2880;
00424 angleLength = ((double)alen * 3.14166) / 2880;
00425
00426 xStart = (int)(cos(angleStart) * 50);
00427 yStart = -(int)(sin(angleStart) * 50);
00428 xEnd = (int)(cos(angleLength) * 50);
00429 yEnd = -(int)(sin(angleLength) * 50);
00430 }
00431
00432
00433 quint16 KoWmfWrite::qtRasterToWin16( QPainter::CompositionMode op ) const {
00434 int i;
00435
00436 for ( i=0 ; i < 17 ; i++ ) {
00437 if ( koWmfOpTab16[ i ] == op ) break;
00438 }
00439
00440 if ( i < 17 )
00441 return (quint16)i;
00442 else
00443 return (quint16)0;
00444 }
00445
00446
00447 quint32 KoWmfWrite::qtRasterToWin32( QPainter::CompositionMode op ) const {
00448 int i;
00449
00450 for ( i=0 ; i < 15 ; i++ ) {
00451 if ( koWmfOpTab32[ i ].qtRasterOp == op ) break;
00452 }
00453
00454 if ( i < 15 )
00455 return koWmfOpTab32[ i ].winRasterOp;
00456 else
00457 return koWmfOpTab32[ 0 ].winRasterOp;
00458 }
00459