lib Library API Documentation

kowmfwrite.cc

00001 /* This file is part of the KDE libraries 00002 * Copyright (c) 2003 thierry lorthiois (lorthioist@wanadoo.fr) 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Library General Public 00006 * License version 2 as published by the Free Software Foundation. 00007 * 00008 * This library is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 * Library General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU Library General Public License 00014 * along with this library; see the file COPYING.LIB. If not, write to 00015 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00016 * Boston, MA 02111-1307, USA. 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; // bounding rectangle 00036 int mDpi; // number of point per inch for the default size 00037 int mMaxRecordSize; 00038 00039 // memory allocation for WMF file 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 // Virtual Painter => create the WMF 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 // reserved placeable and standard header 00078 for ( int i=0 ; i < 10 ; i++ ) { 00079 d->mSt << (Q_UINT32)0; 00080 } 00081 00082 // initialize the stack of objects 00083 // Pen 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 // Brush 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 // End of the wmf file 00103 d->mSt << (Q_UINT32)3 << (Q_UINT16)0; 00104 00105 // adjust header 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 // write headers 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 // we can't delete an object currently selected 00142 // select another object 00143 d->mSt << (Q_UINT32)4 << (Q_UINT16)0x012D << (Q_UINT16)0; 00144 // delete object 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 // SolidLine 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 // select object 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 // we can't delete an object currently selected 00167 // select another object 00168 d->mSt << (Q_UINT32)4 << (Q_UINT16)0x012D << (Q_UINT16)1; 00169 // delete object 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 // SolidPattern 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 // select object 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 // windowOrg 00214 d->mSt << (Q_UINT32)5 << (Q_UINT16)0x020B << (Q_UINT16)top << (Q_UINT16)left; 00215 00216 // windowExt 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 // clipping region == bounding rectangle 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 // convert percentage (roundw, roudh) in (widthCorner, heightCorner) 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 // number of point for each Polygon 00361 for ( pa = listPa.first() ; pa ; pa = listPa.next() ) { 00362 d->mSt << (Q_UINT16)pa->size(); 00363 } 00364 00365 // list of points 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 QImage img; 00378 00379 img = image; 00380 img.setFormat( "BMP" ); 00381 00382 QIODevice io = img.ioDevice(); 00383 io.at( 14 ); // skip the BMP header 00384 d->mSt << io.readAll(); 00385 */ 00386 } 00387 00388 00389 void KoWmfWrite::drawText( int , int , int , int , int , const QString& , double ) { 00390 // d->mSt << (Q_UINT32)3 << (Q_UINT16)0x0A32; 00391 } 00392 00393 //----------------------------------------------------------------------------- 00394 // Utilities and conversion Qt --> Wmf 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
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 Fri Sep 24 18:22:28 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003