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.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Mar 20 14:25:28 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003