diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2021-05-23 20:48:35 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2021-05-29 15:16:28 +0900 |
commit | 8b78a8791bc539bcffe7159f9d9714d577cb3d7d (patch) | |
tree | 1328291f966f19a22d7b13657d3f01a588eb1083 /lib/kwmf/kowmfreadprivate.cpp | |
parent | 95834e2bdc5e01ae1bd21ac0dfa4fa1d2417fae9 (diff) | |
download | koffice-8b78a8791bc539bcffe7159f9d9714d577cb3d7d.tar.gz koffice-8b78a8791bc539bcffe7159f9d9714d577cb3d7d.zip |
Renaming of files in preparation for code style tools.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'lib/kwmf/kowmfreadprivate.cpp')
-rw-r--r-- | lib/kwmf/kowmfreadprivate.cpp | 1251 |
1 files changed, 1251 insertions, 0 deletions
diff --git a/lib/kwmf/kowmfreadprivate.cpp b/lib/kwmf/kowmfreadprivate.cpp new file mode 100644 index 000000000..f812b7660 --- /dev/null +++ b/lib/kwmf/kowmfreadprivate.cpp @@ -0,0 +1,1251 @@ +/* This file is part of the KDE libraries + * Copyright (c) 1998 Stefan Taferner + * 2001/2003 thierry lorthiois (lorthioist@wanadoo.fr) + * With the help of WMF documentation by Caolan Mc Namara + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <math.h> +#include <tqfileinfo.h> +#include <tqimage.h> +#include <tqwmatrix.h> +#include <tqptrlist.h> +#include <tqpointarray.h> +#include <tqdatastream.h> +#include <kdebug.h> + +#include "kowmfreadprivate.h" +#include "kowmfread.h" + + +KoWmfReadPrivate::KoWmfReadPrivate() +{ + mNbrFunc = 0; + mValid = false; + mStandard = false; + mPlaceable = false; + mEnhanced = false; + mBuffer = 0; + mObjHandleTab = 0; +} + + +KoWmfReadPrivate::~KoWmfReadPrivate() +{ + if ( mObjHandleTab != 0 ) { + for ( int i=0 ; i < mNbrObject ; i++ ) { + if ( mObjHandleTab[i] != 0 ) + delete mObjHandleTab[i]; + } + delete[] mObjHandleTab; + } + if ( mBuffer != 0 ) { + mBuffer->close(); + delete mBuffer; + } +} + + +bool KoWmfReadPrivate::load( const TQByteArray& array ) +{ + // delete previous buffer + if ( mBuffer != 0 ) { + mBuffer->close(); + delete mBuffer; + } + + // load into buffer + mBuffer = new TQBuffer( array ); + mBuffer->open( IO_ReadOnly ); + + // read and check the header + WmfEnhMetaHeader eheader; + WmfMetaHeader header; + WmfPlaceableHeader pheader; + unsigned short checksum; + int filePos; + + TQDataStream st( mBuffer ); + st.setByteOrder( TQDataStream::LittleEndian ); + mStackOverflow = mWinding = false; + mTextAlign = mTextRotation = 0; + mTextColor = TQt::black; + mValid = false; + mStandard = false; + mPlaceable = false; + mEnhanced = false; + + //----- Read placeable metafile header + st >> pheader.key; + if ( pheader.key==( TQ_UINT32 )APMHEADER_KEY ) { + mPlaceable = true; + st >> pheader.handle; + st >> pheader.left; + st >> pheader.top; + st >> pheader.right; + st >> pheader.bottom; + st >> pheader.inch; + st >> pheader.reserved; + st >> pheader.checksum; + checksum = calcCheckSum( &pheader ); + if ( pheader.checksum!=checksum ) { + return false; + } + st >> header.fileType; + st >> header.headerSize; + st >> header.version; + st >> header.fileSize; + st >> header.numOfObjects; + st >> header.maxRecordSize; + st >> header.numOfParameters; + mNbrObject = header.numOfObjects; + mBBox.setLeft( pheader.left ); + mBBox.setTop( pheader.top ); + mBBox.setRight( pheader.right ); + mBBox.setBottom( pheader.bottom ); + mDpi = pheader.inch; + } + else { + mBuffer->at( 0 ); + //----- Read as enhanced metafile header + filePos = mBuffer->at(); + st >> eheader.recordType; + st >> eheader.recordSize; + st >> eheader.boundsLeft; + st >> eheader.boundsTop; + st >> eheader.boundsRight; + st >> eheader.boundsBottom; + st >> eheader.frameLeft; + st >> eheader.frameTop; + st >> eheader.frameRight; + st >> eheader.frameBottom; + st >> eheader.signature; + if ( eheader.signature==ENHMETA_SIGNATURE ) { + mEnhanced = true; + st >> eheader.version; + st >> eheader.size; + st >> eheader.numOfRecords; + st >> eheader.numHandles; + st >> eheader.reserved; + st >> eheader.sizeOfDescription; + st >> eheader.offsetOfDescription; + st >> eheader.numPaletteEntries; + st >> eheader.widthDevicePixels; + st >> eheader.heightDevicePixels; + st >> eheader.widthDeviceMM; + st >> eheader.heightDeviceMM; + } + else { + //----- Read as standard metafile header + mStandard = true; + mBuffer->at( filePos ); + st >> header.fileType; + st >> header.headerSize; + st >> header.version; + st >> header.fileSize; + st >> header.numOfObjects; + st >> header.maxRecordSize; + st >> header.numOfParameters; + mNbrObject = header.numOfObjects; + } + } + mOffsetFirstRecord = mBuffer->at(); + + //----- Test header validity + if ( ((header.headerSize == 9) && (header.numOfParameters == 0)) || (mPlaceable) ) { + // valid wmf file + mValid = true; + } + else { + kdDebug() << "KoWmfReadPrivate : incorrect file format !" << endl; + } + + // check bounding rectangle for standard meta file + if ( (mValid) && (mStandard) ) { + TQ_UINT16 numFunction = 1; + TQ_UINT32 size; + bool firstOrg=true, firstExt=true; + + // search functions setWindowOrg and setWindowExt + while ( numFunction ) { + filePos = mBuffer->at(); + st >> size >> numFunction; + + if ( size == 0 ) { + kdDebug() << "KoWmfReadPrivate : incorrect file!" << endl; + mValid = 0; + break; + } + + numFunction &= 0xFF; + if ( numFunction == 11 ) { + TQ_INT16 top, left; + + st >> top >> left; + if ( firstOrg ) { + firstOrg = false; + mBBox.setLeft( left ); + mBBox.setTop( top ); + } + else { + if ( left < mBBox.left() ) mBBox.setLeft( left ); + if ( top < mBBox.top() ) mBBox.setTop( top ); + } + } + if ( numFunction == 12 ) { + TQ_INT16 width, height; + + st >> height >> width; + if ( width < 0 ) width = -width; + if ( height < 0 ) height = -height; + if ( firstExt ) { + firstExt = false; + mBBox.setWidth( width ); + mBBox.setHeight( height ); + } + else { + if ( width > mBBox.width() ) mBBox.setWidth( width ); + if ( height > mBBox.height() ) mBBox.setHeight( height ); + } + } + mBuffer->at( filePos + (size<<1) ); + // ## shouldn't we break from the loop as soon as we found what we were looking for? + } + } + + return (mValid); +} + + +bool KoWmfReadPrivate::play( KoWmfRead* readWmf ) +{ + if ( !(mValid) ) { + kdDebug() << "KoWmfReadPrivate::play : invalid WMF file" << endl; + return false; + } + + if ( mNbrFunc ) { + if ( (mStandard) ) { + kdDebug() << "Standard : " << mBBox.left() << " " << mBBox.top() << " " << mBBox.width() << " " << mBBox.height() << endl; + } + else { + kdDebug() << "DPI : " << mDpi << " : " << mBBox.left() << " " << mBBox.top() << " " << mBBox.width() << " " << mBBox.height() << endl; + kdDebug() << "inch : " << mBBox.width()/mDpi << " " << mBBox.height()/mDpi << endl; + kdDebug() << "mm : " << mBBox.width()*25.4/mDpi << " " << mBBox.height()*25.4/mDpi << endl; + } + kdDebug() << mValid << " " << mStandard << " " << mPlaceable << endl; + } + + // stack of handle + mObjHandleTab = new KoWmfHandle* [ mNbrObject ]; + for ( int i=0; i < mNbrObject ; i++ ) { + mObjHandleTab[ i ] = 0; + } + + TQ_UINT16 numFunction; + TQ_UINT32 size; + int bufferOffset, j; + + // buffer with functions + TQDataStream st( mBuffer ); + st.setByteOrder( TQDataStream::LittleEndian ); + + mReadWmf = readWmf; + mWindow = mBBox; + if ( mReadWmf->begin() ) { + // play wmf functions + mBuffer->at( mOffsetFirstRecord ); + numFunction = j = 1; + mWinding = false; + + while ( ( numFunction ) && ( !mStackOverflow ) ) { + bufferOffset = mBuffer->at(); + st >> size >> numFunction; + + /** + * mapping between n° function and index of table 'metaFuncTab' + * lower 8 digits of the function => entry in the table + */ + numFunction &= 0xFF; + if ( numFunction > 0x5F ) { + numFunction -= 0x90; + } + if ( (numFunction > 111) || (koWmfFunc[ numFunction ].method == 0) ) { + // function outside WMF specification + kdDebug() << "KoWmfReadPrivate::paint : BROKEN WMF file" << endl; + mValid = false; + break; + } + + if ( mNbrFunc ) { + // debug mode + if ( (j+12) > mNbrFunc ) { + // output last 12 functions + int offBuff = mBuffer->at(); + TQ_UINT16 param; + + kdDebug() << j << " : " << numFunction << " : "; + for ( TQ_UINT16 i=0 ; i < (size-3) ; i++ ) { + st >> param; + kdDebug() << param << " "; + } + kdDebug() << endl; + mBuffer->at( offBuff ); + } + if ( j >= mNbrFunc ) { + break; + } + j++; + } + + // execute the function + (this->*koWmfFunc[ numFunction ].method)( size, st ); + + mBuffer->at( bufferOffset + (size<<1) ); + } + + mReadWmf->end(); + } + + for ( int i=0 ; i < mNbrObject ; i++ ) { + if ( mObjHandleTab[ i ] != 0 ) + delete mObjHandleTab[ i ]; + } + delete[] mObjHandleTab; + mObjHandleTab = 0; + + return true; +} + + +//----------------------------------------------------------------------------- +// Metafile painter methods + +void KoWmfReadPrivate::setWindowOrg( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 top, left; + + stream >> top >> left; + mReadWmf->setWindowOrg( left, top ); + mWindow.setLeft( left ); + mWindow.setTop( top ); +// kdDebug() << "Org : (" << left << ", " << top << ") " << endl; +} + +/* TODO : deeper look in negative width and height +*/ + +void KoWmfReadPrivate::setWindowExt( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 width, height; + + // negative value allowed for width and height + stream >> height >> width; + mReadWmf->setWindowExt( width, height ); + mWindow.setWidth( width ); + mWindow.setHeight( height ); +// kdDebug() << "Ext : (" << width << ", " << height << ") "<< endl; +} + + +void KoWmfReadPrivate::OffsetWindowOrg( TQ_UINT32, TQDataStream &stream ) +{ + TQ_INT16 offTop, offLeft; + + stream >> offTop >> offLeft; + mReadWmf->setWindowOrg( mWindow.left() + offLeft, mWindow.top() + offTop ); + mWindow.setLeft( mWindow.left() + offLeft ); + mWindow.setTop( mWindow.top() + offTop ); +} + + +void KoWmfReadPrivate::ScaleWindowExt( TQ_UINT32, TQDataStream &stream ) +{ + TQ_INT16 width, height; + TQ_INT16 heightDenom, heightNum, widthDenom, widthNum; + + stream >> heightDenom >> heightNum >> widthDenom >> widthNum; + + if ( ( widthDenom != 0 ) && ( heightDenom != 0 ) ) { + width = (mWindow.width() * widthNum) / widthDenom; + height = (mWindow.height() * heightNum) / heightDenom; + mReadWmf->setWindowExt( width, height ); + mWindow.setWidth( width ); + mWindow.setHeight( height ); + } +// kdDebug() << "KoWmfReadPrivate::ScaleWindowExt : " << widthDenom << " " << heightDenom << endl; +} + + +//----------------------------------------------------------------------------- +// Drawing + +void KoWmfReadPrivate::lineTo( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 top, left; + + stream >> top >> left; + mReadWmf->lineTo( left, top ); +} + + +void KoWmfReadPrivate::moveTo( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 top, left; + + stream >> top >> left; + mReadWmf->moveTo( left, top ); +} + + +void KoWmfReadPrivate::ellipse( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 top, left, right, bottom; + + stream >> bottom >> right >> top >> left; + mReadWmf->drawEllipse( left, top, right-left, bottom-top ); +} + + +void KoWmfReadPrivate::polygon( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT16 num; + + stream >> num; + + TQPointArray pa( num ); + + pointArray( stream, pa ); + mReadWmf->drawPolygon( pa, mWinding ); +} + + +void KoWmfReadPrivate::polyPolygon( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT16 numberPoly; + TQ_UINT16 sizePoly; + TQPtrList<TQPointArray> listPa; + + stream >> numberPoly; + + listPa.setAutoDelete( true ); + for ( int i=0 ; i < numberPoly ; i++ ) { + stream >> sizePoly; + listPa.append( new TQPointArray( sizePoly ) ); + } + + // list of point array + TQPointArray *pa; + for ( pa = listPa.first() ; pa ; pa = listPa.next() ) { + pointArray( stream, *pa ); + } + + // draw polygon's + mReadWmf->drawPolyPolygon( listPa, mWinding ); + listPa.clear(); +} + + +void KoWmfReadPrivate::polyline( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT16 num; + + stream >> num; + TQPointArray pa( num ); + + pointArray( stream, pa ); + mReadWmf->drawPolyline( pa ); +} + + +void KoWmfReadPrivate::rectangle( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 top, left, right, bottom; + + stream >> bottom >> right >> top >> left; + mReadWmf->drawRect( left, top, right-left, bottom-top ); +} + + +void KoWmfReadPrivate::roundRect( TQ_UINT32, TQDataStream& stream ) +{ + int xRnd = 0, yRnd = 0; + TQ_UINT16 widthCorner, heightCorner; + TQ_INT16 top, left, right, bottom; + + stream >> heightCorner >> widthCorner; + stream >> bottom >> right >> top >> left; + + // convert (widthCorner, heightCorner) in percentage + if ( (right - left) != 0 ) + xRnd = (widthCorner * 100) / (right - left); + if ( (bottom - top) != 0 ) + yRnd = (heightCorner * 100) / (bottom - top); + + mReadWmf->drawRoundRect( left, top, right-left, bottom-top, xRnd, yRnd ); +} + + +void KoWmfReadPrivate::arc( TQ_UINT32, TQDataStream& stream ) +{ + int xCenter, yCenter, angleStart, aLength; + TQ_INT16 topEnd, leftEnd, topStart, leftStart; + TQ_INT16 top, left, right, bottom; + + stream >> topEnd >> leftEnd >> topStart >> leftStart; + stream >> bottom >> right >> top >> left; + + xCenter = left + ((right-left) / 2); + yCenter = top + ((bottom-top) / 2); + xyToAngle ( leftStart-xCenter, yCenter-topStart, leftEnd-xCenter, yCenter-topEnd, angleStart, aLength ); + + mReadWmf->drawArc( left, top, right-left, bottom-top, angleStart, aLength); +} + + +void KoWmfReadPrivate::chord( TQ_UINT32, TQDataStream& stream ) +{ + int xCenter, yCenter, angleStart, aLength; + TQ_INT16 topEnd, leftEnd, topStart, leftStart; + TQ_INT16 top, left, right, bottom; + + stream >> topEnd >> leftEnd >> topStart >> leftStart; + stream >> bottom >> right >> top >> left; + + xCenter = left + ((right-left) / 2); + yCenter = top + ((bottom-top) / 2); + xyToAngle ( leftStart-xCenter, yCenter-topStart, leftEnd-xCenter, yCenter-topEnd, angleStart, aLength ); + + mReadWmf->drawChord( left, top, right-left, bottom-top, angleStart, aLength); +} + + +void KoWmfReadPrivate::pie( TQ_UINT32, TQDataStream& stream ) +{ + int xCenter, yCenter, angleStart, aLength; + TQ_INT16 topEnd, leftEnd, topStart, leftStart; + TQ_INT16 top, left, right, bottom; + + stream >> topEnd >> leftEnd >> topStart >> leftStart; + stream >> bottom >> right >> top >> left; + + xCenter = left + ((right-left) / 2); + yCenter = top + ((bottom-top) / 2); + xyToAngle ( leftStart-xCenter, yCenter-topStart, leftEnd-xCenter, yCenter-topEnd, angleStart, aLength ); + + mReadWmf->drawPie( left, top, right-left, bottom-top, angleStart, aLength); +} + + +void KoWmfReadPrivate::setPolyFillMode( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT16 winding; + + stream >> winding; + mWinding = (winding != 0); +} + + +void KoWmfReadPrivate::setBkColor( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT32 color; + + stream >> color; + mReadWmf->setBackgroundColor( qtColor( color ) ); +} + + +void KoWmfReadPrivate::setBkMode( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT16 bkMode; + + stream >> bkMode; + if ( bkMode == 1 ) + mReadWmf->setBackgroundMode( Qt::TransparentMode ); + else + mReadWmf->setBackgroundMode( Qt::OpaqueMode ); +} + + +void KoWmfReadPrivate::setPixel( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 top, left; + TQ_UINT32 color; + + stream >> color >> top >> left; + + TQPen oldPen = mReadWmf->pen(); + TQPen pen = oldPen; + pen.setColor( qtColor( color ) ); + mReadWmf->setPen( pen ); + mReadWmf->moveTo( left, top ); + mReadWmf->lineTo( left, top ); + mReadWmf->setPen( oldPen ); +} + + +void KoWmfReadPrivate::setRop( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT16 rop; + + stream >> rop; + mReadWmf->setRasterOp( winToTQtRaster( rop ) ); +} + + +void KoWmfReadPrivate::saveDC( TQ_UINT32, TQDataStream& ) +{ + mReadWmf->save(); +} + + +void KoWmfReadPrivate::restoreDC( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 num; + + stream >> num; + for ( int i=0; i > num ; i-- ) + mReadWmf->restore(); +} + + +void KoWmfReadPrivate::intersectClipRect( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 top, left, right, bottom; + + stream >> bottom >> right >> top >> left; + + TQRegion region = mReadWmf->clipRegion(); + TQRegion newRegion( left, top, right-left, bottom-top ); + if ( region.isEmpty() ) { + region = newRegion; + } + else { + region = region.intersect( newRegion ); + } + + mReadWmf->setClipRegion( region ); +} + + +void KoWmfReadPrivate::excludeClipRect( TQ_UINT32, TQDataStream& stream ) +{ + TQ_INT16 top, left, right, bottom; + + stream >> bottom >> right >> top >> left; + + TQRegion region = mReadWmf->clipRegion(); + TQRegion newRegion( left, top, right-left, bottom-top ); + if ( region.isEmpty() ) { + region = newRegion; + } + else { + region = region.subtract( newRegion ); + } + + mReadWmf->setClipRegion( region ); +} + + +//----------------------------------------------------------------------------- +// Text + +void KoWmfReadPrivate::setTextColor( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT32 color; + + stream >> color; + mTextColor = qtColor( color ); +} + + +void KoWmfReadPrivate::setTextAlign( TQ_UINT32, TQDataStream& stream ) +{ + stream >> mTextAlign; +} + + +void KoWmfReadPrivate::textOut( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "textOut : unimplemented " << endl; + } +} + + +void KoWmfReadPrivate::extTextOut( TQ_UINT32 , TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "extTextOut : unimplemented " << endl; + } +} + + + +//----------------------------------------------------------------------------- +// Bitmap + +void KoWmfReadPrivate::SetStretchBltMode( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "SetStretchBltMode : unimplemented " << endl; + } +} + + +void KoWmfReadPrivate::dibBitBlt( TQ_UINT32 size, TQDataStream& stream ) +{ + TQ_UINT32 raster; + TQ_INT16 topSrc, leftSrc, widthSrc, heightSrc; + TQ_INT16 topDst, leftDst; + + stream >> raster; + stream >> topSrc >> leftSrc >> heightSrc >> widthSrc; + stream >> topDst >> leftDst; + + if ( size > 11 ) { // DIB image + TQImage bmpSrc; + + if ( dibToBmp( bmpSrc, stream, (size - 11) * 2 ) ) { + mReadWmf->setRasterOp( winToTQtRaster( raster ) ); + + mReadWmf->save(); + if ( widthSrc < 0 ) { + // negative width => horizontal flip + TQWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F ); + mReadWmf->setWorldMatrix( m, true ); + } + if ( heightSrc < 0 ) { + // negative height => vertical flip + TQWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F ); + mReadWmf->setWorldMatrix( m, true ); + } + mReadWmf->drawImage( leftDst, topDst, bmpSrc, leftSrc, topSrc, widthSrc, heightSrc ); + mReadWmf->restore(); + } + } + else { + kdDebug() << "KoWmfReadPrivate::dibBitBlt without image not implemented " << endl; + } +} + + +void KoWmfReadPrivate::dibStretchBlt( TQ_UINT32 size, TQDataStream& stream ) +{ + TQ_UINT32 raster; + TQ_INT16 topSrc, leftSrc, widthSrc, heightSrc; + TQ_INT16 topDst, leftDst, widthDst, heightDst; + TQImage bmpSrc; + + stream >> raster; + stream >> heightSrc >> widthSrc >> topSrc >> leftSrc; + stream >> heightDst >> widthDst >> topDst >> leftDst; + + if ( dibToBmp( bmpSrc, stream, (size - 13) * 2 ) ) { + mReadWmf->setRasterOp( winToTQtRaster( raster ) ); + + mReadWmf->save(); + if ( widthDst < 0 ) { + // negative width => horizontal flip + TQWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F ); + mReadWmf->setWorldMatrix( m, true ); + } + if ( heightDst < 0 ) { + // negative height => vertical flip + TQWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F ); + mReadWmf->setWorldMatrix( m, true ); + } + bmpSrc = bmpSrc.copy( leftSrc, topSrc, widthSrc, heightSrc ); + // TODO: scale the bitmap : TQImage::scale(widthDst, heightDst) + // is actually too slow + + mReadWmf->drawImage( leftDst, topDst, bmpSrc ); + mReadWmf->restore(); + } +} + + +void KoWmfReadPrivate::stretchDib( TQ_UINT32 size, TQDataStream& stream ) +{ + TQ_UINT32 raster; + TQ_INT16 arg, topSrc, leftSrc, widthSrc, heightSrc; + TQ_INT16 topDst, leftDst, widthDst, heightDst; + TQImage bmpSrc; + + stream >> raster >> arg; + stream >> heightSrc >> widthSrc >> topSrc >> leftSrc; + stream >> heightDst >> widthDst >> topDst >> leftDst; + + if ( dibToBmp( bmpSrc, stream, (size - 14) * 2 ) ) { + mReadWmf->setRasterOp( winToTQtRaster( raster ) ); + + mReadWmf->save(); + if ( widthDst < 0 ) { + // negative width => horizontal flip + TQWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F ); + mReadWmf->setWorldMatrix( m, true ); + } + if ( heightDst < 0 ) { + // negative height => vertical flip + TQWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F ); + mReadWmf->setWorldMatrix( m, true ); + } + bmpSrc = bmpSrc.copy( leftSrc, topSrc, widthSrc, heightSrc ); + // TODO: scale the bitmap ( TQImage::scale(param[ 8 ], param[ 7 ]) is actually too slow ) + + mReadWmf->drawImage( leftDst, topDst, bmpSrc ); + mReadWmf->restore(); + } +} + + +void KoWmfReadPrivate::dibCreatePatternBrush( TQ_UINT32 size, TQDataStream& stream ) +{ + KoWmfPatternBrushHandle* handle = new KoWmfPatternBrushHandle; + + if ( addHandle( handle ) ) { + TQ_UINT32 arg; + TQImage bmpSrc; + + stream >> arg; + if ( dibToBmp( bmpSrc, stream, (size - 5) * 2 ) ) { + handle->image = bmpSrc; + handle->brush.setPixmap( handle->image ); + } + else { + kdDebug() << "KoWmfReadPrivate::dibCreatePatternBrush : incorrect DIB image" << endl; + } + } +} + + +//----------------------------------------------------------------------------- +// Object handle + +void KoWmfReadPrivate::selectObject( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT16 idx; + + stream >> idx; + if ( (idx < mNbrObject) && (mObjHandleTab[ idx ] != 0) ) + mObjHandleTab[ idx ]->apply( mReadWmf ); + else + kdDebug() << "KoWmfReadPrivate::selectObject : selection of an empty object" << endl; +} + + +void KoWmfReadPrivate::deleteObject( TQ_UINT32, TQDataStream& stream ) +{ + TQ_UINT16 idx; + + stream >> idx; + deleteHandle( idx ); +} + + +void KoWmfReadPrivate::createEmptyObject() +{ + // allocation of an empty object (to keep object counting in sync) + KoWmfPenHandle* handle = new KoWmfPenHandle; + + addHandle( handle ); +} + + +void KoWmfReadPrivate::createBrushIndirect( TQ_UINT32, TQDataStream& stream ) +{ + Qt::BrushStyle style; + TQ_UINT16 sty, arg2; + TQ_UINT32 color; + KoWmfBrushHandle* handle = new KoWmfBrushHandle; + + if ( addHandle( handle ) ) { + stream >> sty >> color >> arg2; + + if ( sty == 2 ) { + if ( arg2 < 6 ) + style = koWmfHatchedStyleBrush[ arg2 ]; + else + { + kdDebug() << "KoWmfReadPrivate::createBrushIndirect: invalid hatched brush " << arg2 << endl; + style = Qt::SolidPattern; + } + } + else { + if ( sty < 9 ) + style = koWmfStyleBrush[ sty ]; + else { + kdDebug() << "KoWmfReadPrivate::createBrushIndirect: invalid brush " << sty << endl; + style = Qt::SolidPattern; + } + } + handle->brush.setStyle( style ); + handle->brush.setColor( qtColor( color ) ); + } +} + + +void KoWmfReadPrivate::createPenIndirect( TQ_UINT32, TQDataStream& stream ) +{ + // TODO: userStyle and alternateStyle + Qt::PenStyle penStyle; + TQ_UINT32 color; + TQ_UINT16 style, width, arg; + + KoWmfPenHandle* handle = new KoWmfPenHandle; + + if ( addHandle( handle ) ) { + stream >> style >> width >> arg >> color; + + if ( style < 7 ) + penStyle=koWmfStylePen[ style ]; + else { + kdDebug() << "KoWmfReadPrivate::createPenIndirect: invalid pen " << style << endl; + penStyle = Qt::SolidLine; + } + + handle->pen.setStyle( penStyle ); + handle->pen.setColor( qtColor( color ) ); + handle->pen.setCapStyle( Qt::RoundCap ); + handle->pen.setWidth( width ); + } +} + + +void KoWmfReadPrivate::createFontIndirect( TQ_UINT32 size, TQDataStream& stream ) +{ + TQ_INT16 pointSize, rotation; + TQ_UINT16 weight, property, fixedPitch, arg; + + KoWmfFontHandle* handle = new KoWmfFontHandle; + + if ( addHandle( handle ) ) { + stream >> pointSize >> arg; + stream >> rotation >> arg; + stream >> weight >> property >> arg >> arg; + stream >> fixedPitch; + + // text rotation (in 1/10 degree) + // TODO: memorisation of rotation in object Font + mTextRotation = -rotation / 10; + handle->font.setFixedPitch( ((fixedPitch & 0x01) == 0) ); + // TODO: investigation why some test case need -2 + // size of font in logical point + handle->font.setPointSize( TQABS(pointSize) - 2 ); + handle->font.setWeight( (weight >> 3) ); + handle->font.setItalic( (property & 0x01) ); + handle->font.setUnderline( (property & 0x100) ); + + // font name + int maxChar = (size-12) * 2; + char* nameFont = new char[maxChar]; + stream.readRawBytes( nameFont, maxChar ); + handle->font.setFamily( nameFont ); + delete[] nameFont; + } +} + + +//----------------------------------------------------------------------------- +// Misc functions + +void KoWmfReadPrivate::end( TQ_UINT32, TQDataStream& ) +{ +} + +TQ_UINT16 KoWmfReadPrivate::calcCheckSum( WmfPlaceableHeader* apmfh ) +{ + TQ_UINT16* lpWord; + TQ_UINT16 wResult, i; + + // Start with the first word + wResult = *( lpWord = ( TQ_UINT16* )( apmfh ) ); + // XOR in each of the other 9 words + for( i=1; i<=9; i++ ) + { + wResult ^= lpWord[ i ]; + } + return wResult; +} + + +void KoWmfReadPrivate::notyet( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "unimplemented " << endl; + } +} + +void KoWmfReadPrivate::region( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "region : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::palette( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "palette : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::escape( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "escape : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::setRelAbs( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "setRelAbs : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::setMapMode( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "setMapMode : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::extFloodFill( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "extFloodFill : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::startDoc( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "startDoc : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::startPage( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "startPage : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::endDoc( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "endDoc : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::endPage( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "endPage : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::resetDC( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "resetDC : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::bitBlt( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "bitBlt : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::setDibToDev( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "setDibToDev : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::createBrush( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "createBrush : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::createPatternBrush( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "createPatternBrush : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::createBitmap( TQ_UINT32, TQDataStream& ) +{ + if ( mNbrFunc ) { + kdDebug() << "createBitmap : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::createBitmapIndirect( TQ_UINT32, TQDataStream& ) +{ + createEmptyObject(); + if ( mNbrFunc ) { + kdDebug() << "createBitmapIndirect : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::createPalette( TQ_UINT32, TQDataStream& ) +{ + createEmptyObject(); + if ( mNbrFunc ) { + kdDebug() << "createPalette : unimplemented " << endl; + } +} + +void KoWmfReadPrivate::createRegion( TQ_UINT32, TQDataStream& ) +{ + createEmptyObject(); + if ( mNbrFunc ) { + kdDebug() << "createRegion : unimplemented " << endl; + } +} + + + +//----------------------------------------------------------------------------- +// Utilities and conversion Wmf -> TQt + +bool KoWmfReadPrivate::addHandle( KoWmfHandle* handle ) +{ + int idx; + + for ( idx=0; idx < mNbrObject ; idx++ ) { + if ( mObjHandleTab[ idx ] == 0 ) break; + } + + if ( idx < mNbrObject ) { + mObjHandleTab[ idx ] = handle; + return true; + } + else { + delete handle; + mStackOverflow = true; + kdDebug() << "KoWmfReadPrivate::addHandle : stack overflow = broken file !" << endl; + return false; + } +} + + +void KoWmfReadPrivate::deleteHandle( int idx ) +{ + if ( (idx < mNbrObject) && (mObjHandleTab[idx] != 0) ) { + delete mObjHandleTab[ idx ]; + mObjHandleTab[ idx ] = 0; + } + else { + kdDebug() << "KoWmfReadPrivate::deletehandle() : bad index number" << endl; + } +} + + +void KoWmfReadPrivate::pointArray( TQDataStream& stream, TQPointArray& pa ) +{ + TQ_INT16 left, top; + int i, max; + + for ( i=0, max=pa.size() ; i < max ; i++ ) { + stream >> left >> top; + pa.setPoint( i, left, top ); + } +} + + +void KoWmfReadPrivate::xyToAngle( int xStart, int yStart, int xEnd, int yEnd, int& angleStart, int& angleLength ) +{ + double aStart, aLength; + + aStart = atan2( yStart, xStart ); + aLength = atan2( yEnd, xEnd ) - aStart; + + angleStart = (int)((aStart * 2880) / 3.14166); + angleLength = (int)((aLength * 2880) / 3.14166); + if ( angleLength < 0 ) angleLength = 5760 + angleLength; +} + + +TQt::RasterOp KoWmfReadPrivate::winToTQtRaster( TQ_UINT16 param ) const +{ + if ( param < 17 ) + return koWmfOpTab16[ param ]; + else + return TQt::CopyROP; +} + + +TQt::RasterOp KoWmfReadPrivate::winToTQtRaster( TQ_UINT32 param ) const +{ + /* TODO: Ternary raster operations + 0x00C000CA dest = (source AND pattern) + 0x00F00021 dest = pattern + 0x00FB0A09 dest = DPSnoo + 0x005A0049 dest = pattern XOR dest */ + int i; + + for ( i=0 ; i < 15 ; i++ ) { + if ( koWmfOpTab32[ i ].winRasterOp == param ) break; + } + + if ( i < 15 ) + return koWmfOpTab32[ i ].qtRasterOp; + else + return TQt::CopyROP; +} + + +bool KoWmfReadPrivate::dibToBmp( TQImage& bmp, TQDataStream& stream, TQ_UINT32 size ) +{ + typedef struct _BMPFILEHEADER { + TQ_UINT16 bmType; + TQ_UINT32 bmSize; + TQ_UINT16 bmReserved1; + TQ_UINT16 bmReserved2; + TQ_UINT32 bmOffBits; + } BMPFILEHEADER; + + int sizeBmp = size + 14; + + TQByteArray pattern( sizeBmp ); // BMP header and DIB data + pattern.fill(0); + stream.readRawBytes( &pattern[ 14 ], size ); + + // add BMP header + BMPFILEHEADER* bmpHeader; + bmpHeader = (BMPFILEHEADER*)(pattern.data()); + bmpHeader->bmType = 0x4D42; + bmpHeader->bmSize = sizeBmp; + +// if ( !bmp.loadFromData( (const uchar*)bmpHeader, pattern.size(), "BMP" ) ) { + if ( !bmp.loadFromData( pattern, "BMP" ) ) { + kdDebug() << "KoWmfReadPrivate::dibToBmp: invalid bitmap " << endl; + return false; + } + else { + return true; + } +} + |