F:/KPlato/koffice/libs/kwmf/kowmfwrite.cc

Aller à la documentation de ce fichier.
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., 51 Franklin Street, Fifth Floor,
00016  * Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include <math.h>
00020 #include <QFile>
00021 #include <QDataStream>
00022 //Added by qt3to4:
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;      // bounding rectangle
00039     int      mDpi;       // number of point per inch for the default size
00040     int      mMaxRecordSize;
00041 
00042     // memory allocation for WMF file
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 // Virtual Painter => create the WMF
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     // reserved placeable and standard header
00081     for ( int i=0 ; i < 10 ; i++ ) {
00082         d->mSt << (quint32)0;
00083     }
00084 
00085     // initialize the stack of objects
00086     // Pen
00087     d->mSt << (quint32)8 << (quint16)0x02FA;
00088     d->mSt << (quint16)5 << (quint16)0 << (quint16)0 << (quint32)0;
00089     // Brush
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     // End of the wmf file
00106     d->mSt << (quint32)3 << (quint16)0;
00107 
00108     // adjust header
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     // write headers
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     // we can't delete an object currently selected
00145     // select another object
00146     d->mSt << (quint32)4 << (quint16)0x012D << (quint16)0;
00147     // delete object
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         // SolidLine
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     // select object
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     // we can't delete an object currently selected
00170     // select another object
00171     d->mSt << (quint32)4 << (quint16)0x012D << (quint16)1;
00172     // delete object
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         // SolidPattern
00180         style = 0;
00181     }
00182     d->mSt << (quint32)7 << (quint16)0x02FC;
00183     d->mSt << (quint16)style << (quint32)winColor( brush.color() ) << (quint16)0;
00184 
00185     // select object
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     // windowOrg
00217     d->mSt << (quint32)5 << (quint16)0x020B << (quint16)top << (quint16)left;
00218 
00219     // windowExt
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         // clipping region == bounding rectangle
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     // convert percentage (roundw, roudh) in (widthCorner, heightCorner)
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     // number of point for each Polygon
00364     for ( pa = listPa.first() ; pa ; pa = listPa.next() ) {
00365         d->mSt << (quint16)pa->size();
00366     }
00367 
00368     // list of points
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     QImage img;
00381 
00382     img = image;
00383     img.setFormat( "BMP" );
00384 
00385     QIODevice io = img.ioDevice();
00386     io.at( 14 );   // skip the BMP header
00387     d->mSt << io.readAll();
00388 */
00389 }
00390 
00391 
00392 void KoWmfWrite::drawText( int , int , int , int , int , const QString& , double ) {
00393 //    d->mSt << (quint32)3 << (quint16)0x0A32;
00394 }
00395 
00396 //-----------------------------------------------------------------------------
00397 // Utilities and conversion Qt --> Wmf
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 

Généré le Wed Nov 22 23:41:13 2006 pour KPlato par  doxygen 1.5.1-p1