| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svtools.hxx" |
| |
| #include "winmtf.hxx" |
| #include <osl/endian.h> |
| #include <basegfx/matrix/b2dhommatrix.hxx> |
| #include <vcl/dibtools.hxx> |
| |
| //=========================== GDI-Array =================================== |
| |
| #define EMR_HEADER 1 |
| #define EMR_POLYBEZIER 2 |
| #define EMR_POLYGON 3 |
| #define EMR_POLYLINE 4 |
| #define EMR_POLYBEZIERTO 5 |
| #define EMR_POLYLINETO 6 |
| #define EMR_POLYPOLYLINE 7 |
| #define EMR_POLYPOLYGON 8 |
| #define EMR_SETWINDOWEXTEX 9 |
| #define EMR_SETWINDOWORGEX 10 |
| #define EMR_SETVIEWPORTEXTEX 11 |
| #define EMR_SETVIEWPORTORGEX 12 |
| #define EMR_SETBRUSHORGEX 13 |
| #define EMR_EOF 14 |
| #define EMR_SETPIXELV 15 |
| #define EMR_SETMAPPERFLAGS 16 |
| #define EMR_SETMAPMODE 17 |
| #define EMR_SETBKMODE 18 |
| #define EMR_SETPOLYFILLMODE 19 |
| #define EMR_SETROP2 20 |
| #define EMR_SETSTRETCHBLTMODE 21 |
| #define EMR_SETTEXTALIGN 22 |
| #define EMR_SETCOLORADJUSTMENT 23 |
| #define EMR_SETTEXTCOLOR 24 |
| #define EMR_SETBKCOLOR 25 |
| #define EMR_OFFSETCLIPRGN 26 |
| #define EMR_MOVETOEX 27 |
| #define EMR_SETMETARGN 28 |
| #define EMR_EXCLUDECLIPRECT 29 |
| #define EMR_INTERSECTCLIPRECT 30 |
| #define EMR_SCALEVIEWPORTEXTEX 31 |
| #define EMR_SCALEWINDOWEXTEX 32 |
| #define EMR_SAVEDC 33 |
| #define EMR_RESTOREDC 34 |
| #define EMR_SETWORLDTRANSFORM 35 |
| #define EMR_MODIFYWORLDTRANSFORM 36 |
| #define EMR_SELECTOBJECT 37 |
| #define EMR_CREATEPEN 38 |
| #define EMR_CREATEBRUSHINDIRECT 39 |
| #define EMR_DELETEOBJECT 40 |
| #define EMR_ANGLEARC 41 |
| #define EMR_ELLIPSE 42 |
| #define EMR_RECTANGLE 43 |
| #define EMR_ROUNDRECT 44 |
| #define EMR_ARC 45 |
| #define EMR_CHORD 46 |
| #define EMR_PIE 47 |
| #define EMR_SELECTPALETTE 48 |
| #define EMR_CREATEPALETTE 49 |
| #define EMR_SETPALETTEENTRIES 50 |
| #define EMR_RESIZEPALETTE 51 |
| #define EMR_REALIZEPALETTE 52 |
| #define EMR_EXTFLOODFILL 53 |
| #define EMR_LINETO 54 |
| #define EMR_ARCTO 55 |
| #define EMR_POLYDRAW 56 |
| #define EMR_SETARCDIRECTION 57 |
| #define EMR_SETMITERLIMIT 58 |
| #define EMR_BEGINPATH 59 |
| #define EMR_ENDPATH 60 |
| #define EMR_CLOSEFIGURE 61 |
| #define EMR_FILLPATH 62 |
| #define EMR_STROKEANDFILLPATH 63 |
| #define EMR_STROKEPATH 64 |
| #define EMR_FLATTENPATH 65 |
| #define EMR_WIDENPATH 66 |
| #define EMR_SELECTCLIPPATH 67 |
| #define EMR_ABORTPATH 68 |
| |
| #define EMR_GDICOMMENT 70 |
| #define EMR_FILLRGN 71 |
| #define EMR_FRAMERGN 72 |
| #define EMR_INVERTRGN 73 |
| #define EMR_PAINTRGN 74 |
| #define EMR_EXTSELECTCLIPRGN 75 |
| #define EMR_BITBLT 76 |
| #define EMR_STRETCHBLT 77 |
| #define EMR_MASKBLT 78 |
| #define EMR_PLGBLT 79 |
| #define EMR_SETDIBITSTODEVICE 80 |
| #define EMR_STRETCHDIBITS 81 |
| #define EMR_EXTCREATEFONTINDIRECTW 82 |
| #define EMR_EXTTEXTOUTA 83 |
| #define EMR_EXTTEXTOUTW 84 |
| #define EMR_POLYBEZIER16 85 |
| #define EMR_POLYGON16 86 |
| #define EMR_POLYLINE16 87 |
| #define EMR_POLYBEZIERTO16 88 |
| #define EMR_POLYLINETO16 89 |
| #define EMR_POLYPOLYLINE16 90 |
| #define EMR_POLYPOLYGON16 91 |
| #define EMR_POLYDRAW16 92 |
| #define EMR_CREATEMONOBRUSH 93 |
| #define EMR_CREATEDIBPATTERNBRUSHPT 94 |
| #define EMR_EXTCREATEPEN 95 |
| #define EMR_POLYTEXTOUTA 96 |
| #define EMR_POLYTEXTOUTW 97 |
| |
| // WINDOWS VERSION >= 0x400 |
| #define EMR_SETICMMODE 98 |
| #define EMR_CREATECOLORSPACE 99 |
| #define EMR_SETCOLORSPACE 100 |
| #define EMR_DELETECOLORSPACE 101 |
| #define EMR_GLSRECORD 102 |
| #define EMR_GLSBOUNDEDRECORD 103 |
| #define EMR_PIXELFORMAT 104 |
| |
| // WINDOWS VERSION >= 0x500 |
| #define EMR_DRAWESCAPE 105 |
| #define EMR_EXTESCAPE 106 |
| #define EMR_STARTDOC 107 |
| #define EMR_SMALLTEXTOUT 108 |
| #define EMR_FORCEUFIMAPPING 109 |
| #define EMR_NAMEDESCAPE 110 |
| #define EMR_COLORCORRECTPALETTE 111 |
| #define EMR_SETICMPROFILEA 112 |
| #define EMR_SETICMPROFILEW 113 |
| #define EMR_ALPHABLEND 114 |
| #define EMR_ALPHADIBBLEND 115 |
| #define EMR_TRANSPARENTBLT 116 |
| #define EMR_TRANSPARENTDIB 117 |
| #define EMR_GRADIENTFILL 118 |
| #define EMR_SETLINKEDUFIS 119 |
| #define EMR_SETTEXTJUSTIFICATION 120 |
| |
| |
| //----------------------------------------------------------------------------------- |
| |
| #ifdef OSL_BIGENDIAN |
| // currently unused |
| static float GetSwapFloat( SvStream& rSt ) |
| { |
| float fTmp; |
| sal_Int8* pPtr = (sal_Int8*)&fTmp; |
| rSt >> pPtr[3] >> pPtr[2] >> pPtr[1] >> pPtr[0]; // Little Endian <-> Big Endian switch |
| return fTmp; |
| } |
| #endif |
| |
| struct BLENDFUNCTION{ |
| unsigned char aBlendOperation; |
| unsigned char aBlendFlags; |
| unsigned char aSrcConstantAlpha; |
| unsigned char aAlphaFormat; |
| |
| friend SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun ); |
| }; |
| |
| SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun ) |
| { |
| rIn >> rBlendFun.aBlendOperation >> rBlendFun.aBlendFlags >> |
| rBlendFun.aSrcConstantAlpha >> rBlendFun.aAlphaFormat; |
| return rIn; |
| } |
| SvStream& operator>>( SvStream& rIn, XForm& rXForm ) |
| { |
| if ( sizeof( float ) != 4 ) |
| { |
| DBG_ERROR( "EnhWMFReader::sizeof( float ) != 4" ); |
| rXForm = XForm(); |
| } |
| else |
| { |
| #ifdef OSL_BIGENDIAN |
| rXForm.eM11 = GetSwapFloat( rIn ); |
| rXForm.eM12 = GetSwapFloat( rIn ); |
| rXForm.eM21 = GetSwapFloat( rIn ); |
| rXForm.eM22 = GetSwapFloat( rIn ); |
| rXForm.eDx = GetSwapFloat( rIn ); |
| rXForm.eDy = GetSwapFloat( rIn ); |
| #else |
| rIn >> rXForm.eM11 >> rXForm.eM12 >> rXForm.eM21 >> rXForm.eM22 |
| >> rXForm.eDx >> rXForm.eDy; |
| #endif |
| } |
| return rIn; |
| } |
| |
| static sal_Bool ImplReadRegion( PolyPolygon& rPolyPoly, SvStream& rSt, sal_uInt32 nLen ) |
| { |
| sal_Bool bOk = sal_False; |
| if ( nLen ) |
| { |
| sal_uInt32 nHdSize, nType, nCount, nRgnSize, i; |
| rSt >> nHdSize |
| >> nType |
| >> nCount |
| >> nRgnSize; |
| |
| if ( nCount && ( nType == RDH_RECTANGLES ) && |
| ( nLen >= ( ( nCount << 4 ) + ( nHdSize - 16 ) ) ) ) |
| { |
| sal_Int32 nx1, ny1, nx2, ny2; |
| |
| for ( i = 0; i < nCount; i++ ) |
| { |
| rSt >> nx1 >> ny1 >> nx2 >> ny2; |
| |
| Rectangle aRect( Point( nx1, ny1 ), Point( nx2, ny2 ) ); |
| Polygon aPolygon( aRect ); |
| PolyPolygon aPolyPolyOr1( aPolygon ); |
| PolyPolygon aPolyPolyOr2( rPolyPoly ); |
| rPolyPoly.GetUnion( aPolyPolyOr1, aPolyPolyOr2 ); |
| rPolyPoly = aPolyPolyOr2; |
| } |
| bOk = sal_True; |
| } |
| } |
| return bOk; |
| } |
| |
| sal_Bool EnhWMFReader::ReadEnhWMF() |
| { |
| sal_uInt32 nStretchBltMode = 0; |
| sal_uInt32 nRecType, nRecSize, nNextPos, |
| nW, nH, nPoints, nColor, nIndex, |
| nDat32, nNom1, nDen1, nNom2, nDen2; |
| sal_Int32 nX32, nY32, nx32, ny32; |
| sal_Int16 nX16, nY16; |
| |
| sal_Bool bFlag, bStatus = ReadHeader(); |
| |
| while( bStatus && nRecordCount-- ) |
| { |
| *pWMF >> nRecType >> nRecSize; |
| |
| if ( ( nRecSize < 8 ) || ( nRecSize & 3 ) ) // Parameter sind immer durch 4 teilbar |
| { |
| bStatus = sal_False; |
| break; |
| } |
| |
| nNextPos = pWMF->Tell() + ( nRecSize - 8 ); |
| |
| if ( nNextPos > nEndPos ) |
| { |
| bStatus = sal_False; |
| break; |
| } |
| |
| if( aBmpSaveList.Count() && ( nRecType != EMR_STRETCHBLT ) && ( nRecType != EMR_STRETCHDIBITS ) ) |
| pOut->ResolveBitmapActions( aBmpSaveList ); |
| |
| bFlag = sal_False; |
| |
| switch( nRecType ) |
| { |
| case EMR_POLYBEZIERTO : |
| bFlag = sal_True; |
| case EMR_POLYBEZIER : |
| { |
| pWMF->SeekRel( 16 ); |
| *pWMF >> nPoints; |
| sal_uInt16 i = 0; |
| if ( bFlag ) |
| { |
| i++; |
| nPoints++; |
| } |
| Polygon aPoly( (sal_uInt16)nPoints ); |
| for( ; i < (sal_uInt16)nPoints; i++ ) |
| { |
| *pWMF >> nX32 >> nY32; |
| aPoly[ i ] = Point( nX32, nY32 ); |
| } |
| pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); |
| } |
| break; |
| |
| case EMR_POLYGON : |
| { |
| pWMF->SeekRel( 16 ); |
| *pWMF >> nPoints; |
| Polygon aPoly( (sal_uInt16)nPoints ); |
| for( sal_uInt16 k = 0; k < (sal_uInt16)nPoints; k++ ) |
| { |
| *pWMF >> nX32 >> nY32; |
| aPoly[ k ] = Point( nX32, nY32 ); |
| } |
| pOut->DrawPolygon( aPoly, bRecordPath ); |
| } |
| break; |
| |
| case EMR_POLYLINETO : |
| bFlag = sal_True; |
| case EMR_POLYLINE : |
| { |
| pWMF->SeekRel( 0x10 ); |
| *pWMF >> nPoints; |
| sal_uInt16 i = 0; |
| if ( bFlag ) |
| { |
| i++; |
| nPoints++; |
| } |
| Polygon aPolygon( (sal_uInt16)nPoints ); |
| for ( ; i < (sal_uInt16)nPoints; i++ ) |
| { |
| *pWMF >> nX32 >> nY32; |
| aPolygon[ i ] = Point( nX32, nY32 ); |
| } |
| pOut->DrawPolyLine( aPolygon, bFlag, bRecordPath ); |
| } |
| break; |
| |
| case EMR_POLYPOLYLINE : |
| { |
| sal_Int32 i, nPoly; |
| pWMF->SeekRel( 0x10 ); |
| |
| // Anzahl der Polygone: |
| *pWMF >> nPoly >> i; |
| |
| // taking the amount of points of each polygon, retrieving the total number of points |
| if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) |
| { |
| if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) |
| { |
| sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; |
| |
| for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) |
| { |
| *pWMF >> nPoints; |
| pnPoints[ i ] = (sal_uInt16)nPoints; |
| } |
| |
| // Polygonpunkte holen: |
| |
| for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ ) |
| { |
| Polygon aPoly( pnPoints[ i ] ); |
| for( sal_uInt16 k = 0; k < pnPoints[ i ]; k++ ) |
| { |
| *pWMF >> nX32 >> nY32; |
| aPoly[ k ] = Point( nX32, nY32 ); |
| } |
| pOut->DrawPolyLine( aPoly, sal_False, bRecordPath ); |
| } |
| delete[] pnPoints; |
| } |
| } |
| } |
| break; |
| |
| case EMR_POLYPOLYGON : |
| { |
| sal_uInt32 nPoly(0); |
| sal_uInt32 nGesPoints(0); |
| sal_uInt32 nReadPoints(0); |
| pWMF->SeekRel( 0x10 ); |
| |
| // Anzahl der Polygone: |
| *pWMF >> nPoly >> nGesPoints; |
| |
| if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) && !pWMF->IsEof() ) |
| { |
| if ( ( nPoly * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) |
| { |
| sal_uInt32 i(0); |
| sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; |
| |
| for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) |
| { |
| *pWMF >> nPoints; |
| pnPoints[ i ] = (sal_uInt16)nPoints; |
| } |
| |
| if ( ( nGesPoints * (sizeof(sal_uInt32)+sizeof(sal_uInt32)) ) <= ( nEndPos - pWMF->Tell() ) && !pWMF->IsEof()) |
| { |
| PolyPolygon aPolyPoly(nPoly, nPoly); |
| |
| for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) |
| { |
| const sal_uInt16 nPointCount(pnPoints[i]); |
| Point* pPtAry = new Point[nPointCount]; |
| |
| for(sal_uInt16 j(0); j < nPointCount && !pWMF->IsEof(); j++) |
| { |
| *pWMF >> nX32 >> nY32; |
| pPtAry[ j ] = Point( nX32, nY32 ); |
| nReadPoints++; |
| } |
| |
| aPolyPoly.Insert(Polygon(nPointCount, pPtAry)); |
| delete[] pPtAry; |
| } |
| |
| pOut->DrawPolyPolygon( aPolyPoly, bRecordPath ); |
| } |
| |
| delete[] pnPoints; |
| } |
| } |
| |
| OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)"); |
| } |
| break; |
| |
| case EMR_SETWINDOWEXTEX : |
| { // #75383# |
| *pWMF >> nW >> nH; |
| pOut->SetWinExt( Size( nW, nH ) ); |
| } |
| break; |
| |
| case EMR_SETWINDOWORGEX : |
| { |
| *pWMF >> nX32 >> nY32; |
| pOut->SetWinOrg( Point( nX32, nY32 ) ); |
| } |
| break; |
| |
| case EMR_SCALEWINDOWEXTEX : |
| { |
| *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2; |
| pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); |
| } |
| break; |
| |
| case EMR_SETVIEWPORTORGEX : |
| { |
| *pWMF >> nX32 >> nY32; |
| pOut->SetDevOrg( Point( nX32, nY32 ) ); |
| } |
| break; |
| |
| case EMR_SCALEVIEWPORTEXTEX : |
| { |
| *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2; |
| pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); |
| } |
| break; |
| |
| case EMR_SETVIEWPORTEXTEX : |
| { |
| *pWMF >> nW >> nH; |
| pOut->SetDevExt( Size( nW, nH ) ); |
| } |
| break; |
| |
| case EMR_EOF : |
| nRecordCount = 0; // #76846# |
| break; |
| |
| case EMR_SETPIXELV : |
| { |
| *pWMF >> nX32 >> nY32; |
| pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() ); |
| } |
| break; |
| |
| case EMR_SETMAPMODE : |
| { |
| sal_uInt32 nMapMode; |
| *pWMF >> nMapMode; |
| pOut->SetMapMode( nMapMode ); |
| } |
| break; |
| |
| case EMR_SETBKMODE : |
| { |
| *pWMF >> nDat32; |
| pOut->SetBkMode( nDat32 ); |
| } |
| break; |
| |
| case EMR_SETPOLYFILLMODE : |
| break; |
| |
| case EMR_SETROP2 : |
| { |
| *pWMF >> nDat32; |
| pOut->SetRasterOp( nDat32 ); |
| } |
| break; |
| |
| case EMR_SETSTRETCHBLTMODE : |
| { |
| *pWMF >> nStretchBltMode; |
| } |
| break; |
| |
| case EMR_SETTEXTALIGN : |
| { |
| *pWMF >> nDat32; |
| pOut->SetTextAlign( nDat32 ); |
| } |
| break; |
| |
| case EMR_SETTEXTCOLOR : |
| { |
| pOut->SetTextColor( ReadColor() ); |
| } |
| break; |
| |
| case EMR_SETBKCOLOR : |
| { |
| pOut->SetBkColor( ReadColor() ); |
| } |
| break; |
| |
| case EMR_OFFSETCLIPRGN : |
| { |
| *pWMF >> nX32 >> nY32; |
| pOut->MoveClipRegion( Size( nX32, nY32 ) ); |
| } |
| break; |
| |
| case EMR_MOVETOEX : |
| { |
| *pWMF >> nX32 >> nY32; |
| pOut->MoveTo( Point( nX32, nY32 ), bRecordPath ); |
| } |
| break; |
| |
| case EMR_INTERSECTCLIPRECT : |
| { |
| *pWMF >> nX32 >> nY32 >> nx32 >> ny32; |
| pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); |
| } |
| break; |
| |
| case EMR_SAVEDC : |
| { |
| pOut->Push(); |
| } |
| break; |
| |
| case EMR_RESTOREDC : |
| { |
| pOut->Pop(); |
| } |
| break; |
| |
| case EMR_SETWORLDTRANSFORM : |
| { |
| XForm aTempXForm; |
| *pWMF >> aTempXForm; |
| pOut->SetWorldTransform( aTempXForm ); |
| } |
| break; |
| |
| case EMR_MODIFYWORLDTRANSFORM : |
| { |
| sal_uInt32 nMode; |
| XForm aTempXForm; |
| *pWMF >> aTempXForm >> nMode; |
| pOut->ModifyWorldTransform( aTempXForm, nMode ); |
| } |
| break; |
| |
| case EMR_SELECTOBJECT : |
| { |
| *pWMF >> nIndex; |
| pOut->SelectObject( nIndex ); |
| } |
| break; |
| |
| case EMR_CREATEPEN : |
| { |
| *pWMF >> nIndex; |
| if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) |
| { |
| |
| LineInfo aLineInfo; |
| sal_uInt32 nStyle; |
| Size aSize; |
| |
| *pWMF >> nStyle >> aSize.Width() >> aSize.Height(); |
| |
| if ( aSize.Width() ) |
| aLineInfo.SetWidth( aSize.Width() ); |
| |
| sal_Bool bTransparent = sal_False; |
| sal_uInt16 nDashCount = 0; |
| sal_uInt16 nDotCount = 0; |
| switch( nStyle ) |
| { |
| case PS_DASHDOTDOT : |
| nDotCount++; |
| case PS_DASHDOT : |
| nDashCount++; |
| case PS_DOT : |
| nDotCount++; |
| break; |
| case PS_DASH : |
| nDashCount++; |
| break; |
| case PS_NULL : |
| bTransparent = sal_True; |
| aLineInfo.SetStyle( LINE_NONE ); |
| break; |
| default : |
| case PS_INSIDEFRAME : |
| case PS_SOLID : |
| aLineInfo.SetStyle( LINE_SOLID ); |
| } |
| if ( nDashCount | nDotCount ) |
| { |
| aLineInfo.SetStyle( LINE_DASH ); |
| aLineInfo.SetDashCount( nDashCount ); |
| aLineInfo.SetDotCount( nDotCount ); |
| } |
| pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) ); |
| } |
| } |
| break; |
| |
| case EMR_EXTCREATEPEN : |
| { |
| sal_Int32 elpHatch; |
| sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries; |
| Color aColorRef; |
| |
| *pWMF >> nIndex; |
| if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) |
| { |
| *pWMF >> offBmi >> cbBmi >> offBits >> cbBits >> nStyle >> nWidth >> nBrushStyle; |
| aColorRef = ReadColor(); |
| *pWMF >> elpHatch >> elpNumEntries; |
| |
| LineInfo aLineInfo; |
| if ( nWidth ) |
| aLineInfo.SetWidth( nWidth ); |
| |
| sal_Bool bTransparent = sal_False; |
| sal_uInt16 nDashCount = 0; |
| sal_uInt16 nDotCount = 0; |
| |
| switch( nStyle & PS_STYLE_MASK ) |
| { |
| case PS_DASHDOTDOT : |
| nDotCount++; |
| case PS_DASHDOT : |
| nDashCount++; |
| case PS_DOT : |
| nDotCount++; |
| break; |
| case PS_DASH : |
| nDashCount++; |
| break; |
| case PS_NULL : |
| bTransparent = sal_True; |
| aLineInfo.SetStyle( LINE_NONE ); |
| break; |
| |
| default : |
| case PS_INSIDEFRAME : |
| case PS_SOLID : |
| aLineInfo.SetStyle( LINE_SOLID ); |
| } |
| if ( nDashCount | nDotCount ) |
| { |
| aLineInfo.SetStyle( LINE_DASH ); |
| aLineInfo.SetDashCount( nDashCount ); |
| aLineInfo.SetDotCount( nDotCount ); |
| } |
| pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( aColorRef, aLineInfo, bTransparent ) ); |
| } |
| } |
| break; |
| |
| case EMR_CREATEBRUSHINDIRECT : |
| { |
| sal_uInt32 nStyle; |
| *pWMF >> nIndex; |
| if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) |
| { |
| *pWMF >> nStyle; |
| pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? sal_True : sal_False ) ); |
| } |
| } |
| break; |
| |
| case EMR_DELETEOBJECT : |
| { |
| *pWMF >> nIndex; |
| if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) |
| pOut->DeleteObject( nIndex ); |
| } |
| break; |
| |
| case EMR_ELLIPSE : |
| { |
| *pWMF >> nX32 >> nY32 >> nx32 >> ny32; |
| pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) ); |
| } |
| break; |
| |
| case EMR_RECTANGLE : |
| { |
| *pWMF >> nX32 >> nY32 >> nx32 >> ny32; |
| pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); |
| } |
| break; |
| |
| case EMR_ROUNDRECT : |
| { |
| *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nW >> nH; |
| Size aSize( Size( nW, nH ) ); |
| pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize ); |
| } |
| break; |
| |
| case EMR_ARC : |
| { |
| sal_uInt32 nStartX, nStartY, nEndX, nEndY; |
| *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; |
| pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); |
| } |
| break; |
| |
| case EMR_CHORD : |
| { |
| sal_uInt32 nStartX, nStartY, nEndX, nEndY; |
| *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; |
| pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); |
| } |
| break; |
| |
| case EMR_PIE : |
| { |
| sal_uInt32 nStartX, nStartY, nEndX, nEndY; |
| *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; |
| const Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 )); |
| |
| // #i73608# OutputDevice deviates from WMF |
| // semantics. start==end means full ellipse here. |
| if( nStartX == nEndX && nStartY == nEndY ) |
| pOut->DrawEllipse( aRect ); |
| else |
| pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); |
| } |
| break; |
| |
| case EMR_LINETO : |
| { |
| *pWMF >> nX32 >> nY32; |
| pOut->LineTo( Point( nX32, nY32 ), bRecordPath ); |
| } |
| break; |
| |
| case EMR_ARCTO : |
| { |
| sal_uInt32 nStartX, nStartY, nEndX, nEndY; |
| *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; |
| pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), sal_True ); |
| } |
| break; |
| |
| case EMR_BEGINPATH : |
| { |
| pOut->ClearPath(); |
| bRecordPath = sal_True; |
| } |
| break; |
| |
| case EMR_ABORTPATH : |
| pOut->ClearPath(); |
| case EMR_ENDPATH : |
| bRecordPath = sal_False; |
| break; |
| |
| case EMR_CLOSEFIGURE : |
| pOut->ClosePath(); |
| break; |
| |
| case EMR_FILLPATH : |
| pOut->StrokeAndFillPath( sal_False, sal_True ); |
| break; |
| |
| case EMR_STROKEANDFILLPATH : |
| pOut->StrokeAndFillPath( sal_True, sal_True ); |
| break; |
| |
| case EMR_STROKEPATH : |
| pOut->StrokeAndFillPath( sal_True, sal_False ); |
| break; |
| |
| case EMR_SELECTCLIPPATH : |
| { |
| sal_Int32 nClippingMode; |
| *pWMF >> nClippingMode; |
| pOut->SetClipPath( pOut->GetPathObj(), nClippingMode, sal_True ); |
| } |
| break; |
| |
| case EMR_EXTSELECTCLIPRGN : |
| { |
| sal_Int32 iMode, cbRgnData; |
| *pWMF >> cbRgnData |
| >> iMode; |
| |
| PolyPolygon aPolyPoly; |
| if ( cbRgnData ) |
| ImplReadRegion( aPolyPoly, *pWMF, nRecSize ); |
| pOut->SetClipPath( aPolyPoly, iMode, sal_False ); |
| } |
| break; |
| case EMR_ALPHABLEND: |
| { |
| sal_Int32 xDest, yDest, cxDest, cyDest; |
| |
| BLENDFUNCTION aFunc; |
| sal_Int32 xSrc, ySrc; |
| XForm xformSrc; |
| sal_uInt32 BkColorSrc,iUsageSrc ,offBmiSrc,cbBmiSrc,offBitsSrc,cbBitsSrc ,cxSrc,cySrc ; |
| |
| sal_uInt32 nStart = pWMF->Tell() - 8; |
| pWMF->SeekRel( 0x10 ); |
| |
| *pWMF >> xDest >> yDest >> cxDest >> cyDest >> aFunc >> xSrc >> ySrc |
| >> xformSrc >> BkColorSrc >> iUsageSrc >> offBmiSrc >> cbBmiSrc |
| >> offBitsSrc >> cbBitsSrc >>cxSrc>>cySrc ; |
| |
| sal_uInt32 dwRop = SRCAND|SRCINVERT; |
| |
| Bitmap aBitmap; |
| Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); |
| |
| if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) |
| bStatus = sal_False; |
| else |
| { |
| sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; |
| if ( nSize <= ( nEndPos - nStartPos ) ) |
| { |
| char* pBuf = new char[ nSize ]; |
| SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); |
| aTmp.ObjectOwnsMemory( sal_True ); |
| aTmp << (sal_uInt8)'B' |
| << (sal_uInt8)'M' |
| << (sal_uInt32)cbBitsSrc |
| << (sal_uInt16)0 |
| << (sal_uInt16)0 |
| << (sal_uInt32)cbBmiSrc + 14; |
| pWMF->Seek( nStart + offBmiSrc ); |
| pWMF->Read( pBuf + 14, cbBmiSrc ); |
| pWMF->Seek( nStart + offBitsSrc ); |
| pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); |
| aTmp.Seek( 0 ); |
| ReadDIB(aBitmap, aTmp, true); |
| |
| // test if it is sensible to crop |
| if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && |
| ( xSrc >= 0 ) && ( ySrc >= 0 ) && |
| ( xSrc + static_cast< sal_Int32 >(cxSrc) <= static_cast< sal_Int32 >(aBitmap.GetSizePixel().Width()) ) && |
| ( ySrc + static_cast< sal_Int32 >(cySrc) <= static_cast< sal_Int32 >(aBitmap.GetSizePixel().Height()) ) ) |
| { |
| Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); |
| aBitmap.Crop( aCropRect ); |
| } |
| aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND ); |
| } |
| } |
| } |
| break; |
| case EMR_BITBLT : // PASSTHROUGH INTENDED |
| case EMR_STRETCHBLT : |
| { |
| sal_Int32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc; |
| sal_uInt32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc; |
| XForm xformSrc; |
| |
| sal_uInt32 nStart = pWMF->Tell() - 8; |
| |
| pWMF->SeekRel( 0x10 ); |
| *pWMF >> xDest >> yDest >> cxDest >> cyDest >> dwRop >> xSrc >> ySrc |
| >> xformSrc >> nColor >> iUsageSrc >> offBmiSrc >> cbBmiSrc |
| >> offBitsSrc >> cbBitsSrc; |
| |
| if ( nRecType == EMR_STRETCHBLT ) |
| *pWMF >> cxSrc >> cySrc; |
| else |
| cxSrc = cySrc = 0; |
| |
| Bitmap aBitmap; |
| Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); |
| |
| cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative |
| cyDest = abs( (int)cyDest ); // and also 122889 |
| |
| if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) |
| bStatus = sal_False; |
| else |
| { |
| sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; |
| if ( nSize <= ( nEndPos - nStartPos ) ) |
| { |
| char* pBuf = new char[ nSize ]; |
| SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); |
| aTmp.ObjectOwnsMemory( sal_True ); |
| aTmp << (sal_uInt8)'B' |
| << (sal_uInt8)'M' |
| << (sal_uInt32)cbBitsSrc |
| << (sal_uInt16)0 |
| << (sal_uInt16)0 |
| << (sal_uInt32)cbBmiSrc + 14; |
| pWMF->Seek( nStart + offBmiSrc ); |
| pWMF->Read( pBuf + 14, cbBmiSrc ); |
| pWMF->Seek( nStart + offBitsSrc ); |
| pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); |
| aTmp.Seek( 0 ); |
| ReadDIB(aBitmap, aTmp, true); |
| |
| // test if it is sensible to crop |
| if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && |
| ( xSrc >= 0 ) && ( ySrc >= 0 ) && |
| ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) && |
| ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) ) |
| { |
| Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); |
| aBitmap.Crop( aCropRect ); |
| } |
| aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND ); |
| } |
| } |
| } |
| break; |
| |
| case EMR_STRETCHDIBITS : |
| { |
| sal_Int32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest; |
| sal_uInt32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop; |
| sal_uInt32 nStart = pWMF->Tell() - 8; |
| |
| pWMF->SeekRel( 0x10 ); |
| *pWMF >> xDest >> yDest >> xSrc >> ySrc >> cxSrc >> cySrc >> offBmiSrc >> cbBmiSrc >> offBitsSrc |
| >> cbBitsSrc >> iUsageSrc >> dwRop >> cxDest >> cyDest; |
| |
| Bitmap aBitmap; |
| Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); |
| |
| cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative |
| cyDest = abs( (int)cyDest ); // and also 122889 |
| |
| if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) |
| bStatus = sal_False; |
| else |
| { |
| sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; |
| if ( nSize <= ( nEndPos - nStartPos ) ) |
| { |
| char* pBuf = new char[ nSize ]; |
| SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); |
| aTmp.ObjectOwnsMemory( sal_True ); |
| aTmp << (sal_uInt8)'B' |
| << (sal_uInt8)'M' |
| << (sal_uInt32)cbBitsSrc |
| << (sal_uInt16)0 |
| << (sal_uInt16)0 |
| << (sal_uInt32)cbBmiSrc + 14; |
| pWMF->Seek( nStart + offBmiSrc ); |
| pWMF->Read( pBuf + 14, cbBmiSrc ); |
| pWMF->Seek( nStart + offBitsSrc ); |
| pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); |
| aTmp.Seek( 0 ); |
| ReadDIB(aBitmap, aTmp, true); |
| |
| // test if it is sensible to crop |
| if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && |
| ( xSrc >= 0 ) && ( ySrc >= 0 ) && |
| ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) && |
| ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) ) |
| { |
| Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); |
| aBitmap.Crop( aCropRect ); |
| } |
| aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND ); |
| } |
| } |
| } |
| break; |
| |
| case EMR_EXTCREATEFONTINDIRECTW : |
| { |
| *pWMF >> nIndex; |
| if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) |
| { |
| LOGFONTW aLogFont; |
| *pWMF >> aLogFont.lfHeight >> aLogFont.lfWidth >> aLogFont.lfEscapement >> aLogFont.lfOrientation >> aLogFont.lfWeight >> aLogFont.lfItalic |
| >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision >> aLogFont.lfClipPrecision |
| >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily; |
| |
| sal_Unicode lfFaceName[ LF_FACESIZE ]; |
| |
| for ( int i = 0; i < LF_FACESIZE; i++ ) |
| { |
| sal_uInt16 nChar; |
| *pWMF >> nChar; |
| lfFaceName[ i ] = nChar; |
| } |
| aLogFont.alfFaceName = UniString( lfFaceName ); |
| |
| // #123216# Not used in the test case of #121382# (always identity in XForm), also |
| // no hints in ms docu if FontSize should be scaled with WT. Using with the example |
| // from #123216# creates errors, so removing. |
| // |
| // // #121382# Need to apply WorldTransform to FontHeight/Width; this should be completely |
| // // chnaged to basegfx::B2DHomMatrix instead of 'struct XForm', but not now due to time |
| // // constraints and dangers |
| // const XForm& rXF = pOut->GetWorldTransform(); |
| // const basegfx::B2DHomMatrix aWT(rXF.eM11, rXF.eM21, rXF.eDx, rXF.eM12, rXF.eM22, rXF.eDy); |
| // const basegfx::B2DVector aTransVec(aWT * basegfx::B2DVector(aLogFont.lfWidth, aLogFont.lfHeight)); |
| // aLogFont.lfWidth = aTransVec.getX(); |
| // aLogFont.lfHeight = aTransVec.getY(); |
| |
| pOut->CreateObject( nIndex, GDI_FONT, new WinMtfFontStyle( aLogFont ) ); |
| } |
| } |
| break; |
| |
| case EMR_EXTTEXTOUTA : |
| bFlag = sal_True; |
| case EMR_EXTTEXTOUTW : |
| { |
| sal_Int32 nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale; |
| sal_uInt32 nCurPos, nLen, nOffString, nOptions, offDx; |
| sal_Int32* pDX = NULL; |
| |
| nCurPos = pWMF->Tell() - 8; |
| |
| *pWMF >> nLeft >> nTop >> nRight >> nBottom >> nGfxMode >> nXScale >> nYScale |
| >> ptlReferenceX >> ptlReferenceY >> nLen >> nOffString >> nOptions; |
| |
| pWMF->SeekRel( 0x10 ); |
| *pWMF >> offDx; |
| |
| sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT; |
| if ( nOptions & ETO_RTLREADING ) |
| nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT; |
| pOut->SetTextLayoutMode( nTextLayoutMode ); |
| DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in EMF" ); |
| |
| Point aPos( ptlReferenceX, ptlReferenceY ); |
| if ( nLen && ( nLen < SAL_MAX_UINT32 / sizeof(sal_Int32) ) ) |
| { |
| if ( offDx && (( nCurPos + offDx + nLen * 4 ) <= nNextPos ) ) |
| { |
| pWMF->Seek( nCurPos + offDx ); |
| if ( ( nLen * sizeof(sal_uInt32) ) <= ( nEndPos - pWMF->Tell() ) ) |
| { |
| pDX = new sal_Int32[ nLen ]; |
| sal_uInt32 i; |
| for ( i = 0; i < nLen; i++ ) |
| *pWMF >> pDX[ i ]; |
| } |
| } |
| pWMF->Seek( nCurPos + nOffString ); |
| String aText; |
| if ( bFlag ) |
| { |
| if ( nLen <= ( nEndPos - pWMF->Tell() ) ) |
| { |
| sal_Char* pBuf = new sal_Char[ nLen ]; |
| pWMF->Read( pBuf, nLen ); |
| aText = String( pBuf, (sal_uInt16)nLen, pOut->GetCharSet() ); |
| delete[] pBuf; |
| |
| if ( aText.Len() != nLen ) |
| { |
| sal_uInt16 i, j, k; |
| sal_Int32* pOldDx = pDX; |
| pDX = new sal_Int32[ aText.Len() ]; |
| for ( i = 0, j = 0; i < aText.Len(); i++ ) |
| { |
| ByteString aCharacter( aText.GetChar( i ), pOut->GetCharSet() ); |
| pDX[ i ] = 0; |
| for ( k = 0; ( k < aCharacter.Len() ) && ( j < nLen ) && ( i < aText.Len() ); k++ ) |
| pDX[ i ] += pOldDx[ j++ ]; |
| } |
| delete[] pOldDx; |
| } |
| } |
| } |
| else |
| { |
| if ( ( nLen * sizeof(sal_Unicode) ) <= ( nEndPos - pWMF->Tell() ) ) |
| { |
| sal_Unicode* pBuf = new sal_Unicode[ nLen ]; |
| pWMF->Read( pBuf, nLen << 1 ); |
| #ifdef OSL_BIGENDIAN |
| sal_Char nTmp, *pTmp = (sal_Char*)( pBuf + nLen ); |
| while ( pTmp-- != (sal_Char*)pBuf ) |
| { |
| nTmp = *pTmp--; |
| pTmp[ 1 ] = *pTmp; |
| *pTmp = nTmp; |
| } |
| #endif |
| aText = String( pBuf, (xub_StrLen)nLen ); |
| delete[] pBuf; |
| } |
| } |
| pOut->DrawText( aPos, aText, pDX, bRecordPath, nGfxMode ); |
| } |
| delete[] pDX; |
| } |
| break; |
| |
| case EMR_POLYBEZIERTO16 : |
| bFlag = sal_True; |
| case EMR_POLYBEZIER16 : |
| { |
| pWMF->SeekRel( 16 ); |
| *pWMF >> nPoints; |
| sal_uInt16 i = 0; |
| if ( bFlag ) |
| { |
| i++; |
| nPoints++; |
| } |
| Polygon aPoly( (sal_uInt16)nPoints ); |
| for( ; i < (sal_uInt16)nPoints; i++ ) |
| { |
| *pWMF >> nX16 >> nY16; |
| aPoly[ i ] = Point( nX16, nY16 ); |
| } |
| pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); // Line( aPoly, bFlag ); |
| } |
| break; |
| |
| case EMR_POLYGON16 : |
| { |
| pWMF->SeekRel( 16 ); |
| *pWMF >> nPoints; |
| Polygon aPoly( (sal_uInt16)nPoints ); |
| for( sal_uInt16 k = 0; k < (sal_uInt16)nPoints; k++ ) |
| { |
| *pWMF >> nX16 >> nY16; |
| aPoly[ k ] = Point( nX16, nY16 ); |
| } |
| pOut->DrawPolygon( aPoly, bRecordPath ); |
| } |
| break; |
| |
| case EMR_POLYLINETO16 : |
| bFlag = sal_True; |
| case EMR_POLYLINE16 : |
| { |
| pWMF->SeekRel( 16 ); |
| *pWMF >> nPoints; |
| sal_uInt16 i = 0; |
| if ( bFlag ) |
| { |
| i++; |
| nPoints++; |
| } |
| |
| Polygon aPoly( (sal_uInt16)nPoints ); |
| for( ; i < (sal_uInt16)nPoints; i++ ) |
| { |
| *pWMF >> nX16 >> nY16; |
| aPoly[ i ] = Point( nX16, nY16 ); |
| } |
| pOut->DrawPolyLine( aPoly, bFlag, bRecordPath ); |
| } |
| break; |
| |
| case EMR_POLYPOLYLINE16 : |
| { |
| sal_uInt16* pnPoints; |
| |
| sal_Int32 i, nPoly, nGesPoints; |
| pWMF->SeekRel( 0x10 ); |
| // Anzahl der Polygone: |
| *pWMF >> nPoly >> nGesPoints; |
| |
| // taking the amount of points of each polygon, retrieving the total number of points |
| if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) |
| { |
| if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) |
| { |
| pnPoints = new sal_uInt16[ nPoly ]; |
| for ( i = 0; i < nPoly; i++ ) |
| { |
| *pWMF >> nPoints; |
| pnPoints[ i ] = (sal_uInt16)nPoints; |
| } |
| // Polygonpunkte holen: |
| for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ ) |
| { |
| Polygon aPolygon( pnPoints[ i ] ); |
| for ( sal_uInt16 k = 0; k < pnPoints[ i ]; k++ ) |
| { |
| *pWMF >> nX16 >> nY16; |
| aPolygon[ k ] = Point( nX16, nY16 ); |
| } |
| pOut->DrawPolyLine( aPolygon, sal_False, bRecordPath ); |
| } |
| delete[] pnPoints; |
| } |
| } |
| } |
| break; |
| |
| case EMR_POLYPOLYGON16 : |
| { |
| sal_uInt32 nPoly(0); |
| sal_uInt32 nGesPoints(0); |
| pWMF->SeekRel( 0x10 ); |
| // Anzahl der Polygone: |
| *pWMF >> nPoly >> nGesPoints; |
| sal_uInt32 nReadPoints(0); |
| |
| if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) && !pWMF->IsEof() ) |
| { |
| if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof( sal_uInt16 ) ) <= ( nEndPos - pWMF->Tell() ) ) |
| { |
| sal_uInt32 i(0); |
| sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; |
| |
| for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) |
| { |
| *pWMF >> nPoints; |
| pnPoints[ i ] = (sal_uInt16)nPoints; |
| } |
| |
| if ( ( nGesPoints * (sizeof(sal_uInt16)+sizeof(sal_uInt16)) ) <= ( nEndPos - pWMF->Tell() ) && !pWMF->IsEof() ) |
| { |
| PolyPolygon aPolyPoly(nPoly, nPoly); |
| |
| for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) |
| { |
| const sal_uInt16 nPointCount(pnPoints[i]); |
| Point* pPtAry = new Point[nPointCount]; |
| |
| for(sal_uInt16 b(0); b < nPointCount && !pWMF->IsEof(); b++) |
| { |
| *pWMF >> nX16 >> nY16; |
| pPtAry[b] = Point( nX16, nY16 ); |
| nReadPoints++; |
| } |
| |
| aPolyPoly.Insert(Polygon(nPointCount, pPtAry)); |
| delete[] pPtAry; |
| } |
| |
| // create PolyPolygon actions |
| pOut->DrawPolyPolygon( aPolyPoly, bRecordPath ); |
| } |
| |
| delete[] pnPoints; |
| } |
| } |
| |
| OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON16 is unequal imported number (!)"); |
| } |
| break; |
| |
| case EMR_FILLRGN : |
| { |
| sal_uInt32 nLen; |
| PolyPolygon aPolyPoly; |
| pWMF->SeekRel( 0x10 ); |
| *pWMF >> nLen >> nIndex; |
| |
| if ( ImplReadRegion( aPolyPoly, *pWMF, nRecSize ) ) |
| { |
| pOut->Push(); |
| pOut->SelectObject( nIndex ); |
| pOut->DrawPolyPolygon( aPolyPoly, sal_False ); |
| pOut->Pop(); |
| } |
| } |
| break; |
| case EMR_CREATEDIBPATTERNBRUSHPT : |
| { |
| sal_uInt32 nTmp32; |
| sal_uInt32 nOffset; |
| *pWMF >> nIndex; |
| Bitmap aBmp; |
| BitmapReadAccess* pBmp; |
| sal_uInt32 nRed = 0, nGreen = 0, nBlue = 0, nCount = 1; |
| |
| *pWMF >> nTmp32; |
| *pWMF >> nOffset; |
| for ( sal_uInt32 i = 0; i < (nOffset - 20)/4; i ++ ) |
| { |
| *pWMF >> nTmp32; |
| } |
| |
| ReadDIB(aBmp, *pWMF, false); |
| pBmp = aBmp.AcquireReadAccess(); |
| if ( pBmp ) |
| { |
| for ( sal_Int32 y = 0; y < pBmp->Height(); y++ ) |
| { |
| for ( sal_Int32 x = 0; x < pBmp->Width(); x++ ) |
| { |
| const BitmapColor aColor( pBmp->GetColor( y, x ) ); |
| |
| nRed += aColor.GetRed(); |
| nGreen += aColor.GetGreen(); |
| nBlue += aColor.GetBlue(); |
| } |
| } |
| nCount = pBmp->Height() * pBmp->Width(); |
| if ( !nCount ) |
| nCount++; |
| aBmp.ReleaseAccess( pBmp ); |
| } |
| Color aColor( (sal_Char)( nRed / nCount ), (sal_Char)( nGreen / nCount ), (sal_Char)( nBlue / nCount ) ); |
| pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( aColor, sal_False ) ); |
| } |
| break; |
| |
| #ifdef WIN_MTF_ASSERT |
| default : WinMtfAssertHandler( "Unknown Meta Action" ); break; |
| case EMR_MASKBLT : WinMtfAssertHandler( "MaskBlt" ); break; |
| case EMR_PLGBLT : WinMtfAssertHandler( "PlgBlt" ); break; |
| case EMR_SETDIBITSTODEVICE : WinMtfAssertHandler( "SetDIBitsToDevice" ); break; |
| case EMR_FRAMERGN : WinMtfAssertHandler( "FrameRgn" ); break; |
| case EMR_INVERTRGN : WinMtfAssertHandler( "InvertRgn" ); break; |
| case EMR_PAINTRGN : WinMtfAssertHandler( "PaintRgn" ); break; |
| case EMR_FLATTENPATH : WinMtfAssertHandler( "FlattenPath" ); break; |
| case EMR_WIDENPATH : WinMtfAssertHandler( "WidenPath" ); break; |
| case EMR_POLYDRAW : WinMtfAssertHandler( "Polydraw" ); break; |
| case EMR_SETARCDIRECTION : WinMtfAssertHandler( "SetArcDirection" ); break; |
| case EMR_SETPALETTEENTRIES : WinMtfAssertHandler( "SetPaletteEntries" ); break; |
| case EMR_RESIZEPALETTE : WinMtfAssertHandler( "ResizePalette" ); break; |
| case EMR_EXTFLOODFILL : WinMtfAssertHandler( "ExtFloodFill" ); break; |
| case EMR_ANGLEARC : WinMtfAssertHandler( "AngleArc" ); break; |
| case EMR_SETCOLORADJUSTMENT : WinMtfAssertHandler( "SetColorAdjustment" ); break; |
| case EMR_POLYDRAW16 : WinMtfAssertHandler( "PolyDraw16" ); break; |
| case EMR_POLYTEXTOUTA : WinMtfAssertHandler( "PolyTextOutA" ); break; |
| case EMR_POLYTEXTOUTW : WinMtfAssertHandler( "PolyTextOutW" ); break; |
| case EMR_CREATECOLORSPACE : WinMtfAssertHandler( "CreateColorSpace" ); break; |
| case EMR_SETCOLORSPACE : WinMtfAssertHandler( "SetColorSpace" ); break; |
| case EMR_DELETECOLORSPACE : WinMtfAssertHandler( "DeleteColorSpace" ); break; |
| case EMR_GLSRECORD : WinMtfAssertHandler( "GlsRecord" ); break; |
| case EMR_GLSBOUNDEDRECORD : WinMtfAssertHandler( "GlsBoundRecord" ); break; |
| case EMR_PIXELFORMAT : WinMtfAssertHandler( "PixelFormat" ); break; |
| case EMR_DRAWESCAPE : WinMtfAssertHandler( "DrawEscape" ); break; |
| case EMR_EXTESCAPE : WinMtfAssertHandler( "ExtEscape" ); break; |
| case EMR_STARTDOC : WinMtfAssertHandler( "StartDoc" ); break; |
| case EMR_SMALLTEXTOUT : WinMtfAssertHandler( "SmallTextOut" ); break; |
| case EMR_FORCEUFIMAPPING : WinMtfAssertHandler( "ForceUFIMapping" ); break; |
| case EMR_NAMEDESCAPE : WinMtfAssertHandler( "NamedEscape" ); break; |
| case EMR_COLORCORRECTPALETTE : WinMtfAssertHandler( "ColorCorrectPalette" ); break; |
| case EMR_SETICMPROFILEA : WinMtfAssertHandler( "SetICMProfileA" ); break; |
| case EMR_SETICMPROFILEW : WinMtfAssertHandler( "SetICMProfileW" ); break; |
| case EMR_TRANSPARENTBLT : WinMtfAssertHandler( "TransparenBlt" ); break; |
| case EMR_TRANSPARENTDIB : WinMtfAssertHandler( "TransparenDib" ); break; |
| case EMR_GRADIENTFILL : WinMtfAssertHandler( "GradientFill" ); break; |
| case EMR_SETLINKEDUFIS : WinMtfAssertHandler( "SetLinkedUFIS" ); break; |
| |
| case EMR_SETMAPPERFLAGS : WinMtfAssertHandler( "SetMapperFlags", 0 ); break; |
| case EMR_SETICMMODE : WinMtfAssertHandler( "SetICMMode", 0 ); break; |
| case EMR_CREATEMONOBRUSH : WinMtfAssertHandler( "CreateMonoBrush", 0 ); break; |
| case EMR_SETBRUSHORGEX : WinMtfAssertHandler( "SetBrushOrgEx", 0 ); break; |
| case EMR_SETMETARGN : WinMtfAssertHandler( "SetMetArgn", 0 ); break; |
| case EMR_SETMITERLIMIT : WinMtfAssertHandler( "SetMiterLimit", 0 ); break; |
| case EMR_EXCLUDECLIPRECT : WinMtfAssertHandler( "ExcludeClipRect", 0 ); break; |
| case EMR_REALIZEPALETTE : WinMtfAssertHandler( "RealizePalette", 0 ); break; |
| case EMR_SELECTPALETTE : WinMtfAssertHandler( "SelectPalette", 0 ); break; |
| case EMR_CREATEPALETTE : WinMtfAssertHandler( "CreatePalette", 0 ); break; |
| case EMR_ALPHADIBBLEND : WinMtfAssertHandler( "AlphaDibBlend", 0 ); break; |
| case EMR_SETTEXTJUSTIFICATION : WinMtfAssertHandler( "SetTextJustification", 0 ); break; |
| |
| case EMR_GDICOMMENT : |
| case EMR_HEADER : // has already been read at ReadHeader() |
| break; |
| #endif |
| } |
| pWMF->Seek( nNextPos ); |
| } |
| if( aBmpSaveList.Count() ) |
| pOut->ResolveBitmapActions( aBmpSaveList ); |
| |
| if ( bStatus ) |
| pWMF->Seek(nEndPos); |
| |
| return bStatus; |
| }; |
| |
| //----------------------------------------------------------------------------------- |
| |
| sal_Bool EnhWMFReader::ReadHeader() |
| { |
| sal_uInt32 nsal_uInt32, nHeaderSize, nPalEntries; |
| sal_Int32 nLeft, nTop, nRight, nBottom; |
| |
| // METAFILEHEADER SPARE ICH MIR HIER |
| // Einlesen des METAHEADER |
| *pWMF >> nsal_uInt32 >> nHeaderSize; |
| if ( nsal_uInt32 != 1 ) // Typ |
| return sal_False; |
| |
| // bound size |
| Rectangle rclBounds; // rectangle in logical units 1/100th mm |
| *pWMF >> nLeft >> nTop >> nRight >> nBottom; |
| rclBounds.Left() = nLeft; |
| rclBounds.Top() = nTop; |
| rclBounds.Right() = nRight; |
| rclBounds.Bottom() = nBottom; |
| |
| // picture frame size |
| Rectangle rclFrame; // rectangle in device units |
| *pWMF >> nLeft >> nTop >> nRight >> nBottom; |
| rclFrame.Left() = nLeft; |
| rclFrame.Top() = nTop; |
| rclFrame.Right() = nRight; |
| rclFrame.Bottom() = nBottom; |
| |
| *pWMF >> nsal_uInt32; // signature |
| |
| if ( nsal_uInt32 != 0x464d4520 ) |
| return sal_False; |
| |
| *pWMF >> nsal_uInt32; // nVersion |
| *pWMF >> nEndPos; // size of metafile |
| nEndPos += nStartPos; |
| |
| sal_uInt32 nStrmPos = pWMF->Tell(); // checking if nEndPos is valid |
| pWMF->Seek( STREAM_SEEK_TO_END ); |
| if ( pWMF->Tell() < nEndPos ) |
| nEndPos = pWMF->Tell(); |
| pWMF->Seek( nStrmPos ); |
| |
| *pWMF >> nRecordCount; |
| |
| if ( !nRecordCount ) |
| return sal_False; |
| |
| pWMF->SeekRel( 0xc ); |
| |
| sal_Int32 nPixX, nPixY, nMillX, nMillY; |
| *pWMF >> nPalEntries >> nPixX >> nPixY >> nMillX >> nMillY; |
| |
| pOut->SetrclFrame( rclFrame ); |
| pOut->SetrclBounds( rclBounds ); |
| pOut->SetRefPix( Size( nPixX, nPixY ) ); |
| pOut->SetRefMill( Size( nMillX, nMillY ) ); |
| |
| pWMF->Seek( nStartPos + nHeaderSize ); |
| return sal_True; |
| } |
| |
| //----------------------------------------------------------------------------------- |
| |
| Rectangle EnhWMFReader::ReadRectangle( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) |
| { |
| Point aTL ( Point( x1, y1 ) ); |
| Point aBR( Point( --x2, --y2 ) ); |
| return Rectangle( aTL, aBR ); |
| } |
| |
| EnhWMFReader::~EnhWMFReader() |
| { |
| |
| }; |