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