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