xref: /aoo41x/main/svtools/source/filter/wmf/winwmf.cxx (revision 45fd3b9a)
1c82f2877SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3c82f2877SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4c82f2877SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5c82f2877SAndrew Rist  * distributed with this work for additional information
6c82f2877SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7c82f2877SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8c82f2877SAndrew Rist  * "License"); you may not use this file except in compliance
9c82f2877SAndrew Rist  * with the License.  You may obtain a copy of the License at
10c82f2877SAndrew Rist  *
11c82f2877SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12c82f2877SAndrew Rist  *
13c82f2877SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14c82f2877SAndrew Rist  * software distributed under the License is distributed on an
15c82f2877SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16c82f2877SAndrew Rist  * KIND, either express or implied.  See the License for the
17c82f2877SAndrew Rist  * specific language governing permissions and limitations
18c82f2877SAndrew Rist  * under the License.
19c82f2877SAndrew Rist  *
20c82f2877SAndrew Rist  *************************************************************/
21c82f2877SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_svtools.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include "winmtf.hxx"
26cdf0e10cSrcweir #include <vcl/gdimtf.hxx>
27cdf0e10cSrcweir #include <rtl/crc.h>
28cdf0e10cSrcweir #include <rtl/tencinfo.h>
29cdf0e10cSrcweir #include <osl/endian.h>
301a11d300SArmin Le Grand #include <vcl/svapp.hxx>
31*45fd3b9aSArmin Le Grand #include <vcl/dibtools.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir //====================== MS-Windows-defines ===============================
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #define W_META_SETBKCOLOR           0x0201
36cdf0e10cSrcweir #define W_META_SETBKMODE            0x0102
37cdf0e10cSrcweir #define W_META_SETMAPMODE           0x0103
38cdf0e10cSrcweir #define W_META_SETROP2              0x0104
39cdf0e10cSrcweir #define W_META_SETRELABS            0x0105
40cdf0e10cSrcweir #define W_META_SETPOLYFILLMODE      0x0106
41cdf0e10cSrcweir #define W_META_SETSTRETCHBLTMODE    0x0107
42cdf0e10cSrcweir #define W_META_SETTEXTCHAREXTRA     0x0108
43cdf0e10cSrcweir #define W_META_SETTEXTCOLOR         0x0209
44cdf0e10cSrcweir #define W_META_SETTEXTJUSTIFICATION 0x020A
45cdf0e10cSrcweir #define W_META_SETWINDOWORG         0x020B
46cdf0e10cSrcweir #define W_META_SETWINDOWEXT         0x020C
47cdf0e10cSrcweir #define W_META_SETVIEWPORTORG       0x020D
48cdf0e10cSrcweir #define W_META_SETVIEWPORTEXT       0x020E
49cdf0e10cSrcweir #define W_META_OFFSETWINDOWORG      0x020F
50cdf0e10cSrcweir #define W_META_SCALEWINDOWEXT       0x0410
51cdf0e10cSrcweir #define W_META_OFFSETVIEWPORTORG    0x0211
52cdf0e10cSrcweir #define W_META_SCALEVIEWPORTEXT     0x0412
53cdf0e10cSrcweir #define W_META_LINETO               0x0213
54cdf0e10cSrcweir #define W_META_MOVETO               0x0214
55cdf0e10cSrcweir #define W_META_EXCLUDECLIPRECT      0x0415
56cdf0e10cSrcweir #define W_META_INTERSECTCLIPRECT    0x0416
57cdf0e10cSrcweir #define W_META_ARC                  0x0817
58cdf0e10cSrcweir #define W_META_ELLIPSE              0x0418
59cdf0e10cSrcweir #define W_META_FLOODFILL            0x0419
60cdf0e10cSrcweir #define W_META_PIE                  0x081A
61cdf0e10cSrcweir #define W_META_RECTANGLE            0x041B
62cdf0e10cSrcweir #define W_META_ROUNDRECT            0x061C
63cdf0e10cSrcweir #define W_META_PATBLT               0x061D
64cdf0e10cSrcweir #define W_META_SAVEDC               0x001E
65cdf0e10cSrcweir #define W_META_SETPIXEL             0x041F
66cdf0e10cSrcweir #define W_META_OFFSETCLIPRGN        0x0220
67cdf0e10cSrcweir #define W_META_TEXTOUT              0x0521
68cdf0e10cSrcweir #define W_META_BITBLT               0x0922
69cdf0e10cSrcweir #define W_META_STRETCHBLT           0x0B23
70cdf0e10cSrcweir #define W_META_POLYGON              0x0324
71cdf0e10cSrcweir #define W_META_POLYLINE             0x0325
72cdf0e10cSrcweir #define W_META_ESCAPE               0x0626
73cdf0e10cSrcweir #define W_META_RESTOREDC            0x0127
74cdf0e10cSrcweir #define W_META_FILLREGION           0x0228
75cdf0e10cSrcweir #define W_META_FRAMEREGION          0x0429
76cdf0e10cSrcweir #define W_META_INVERTREGION         0x012A
77cdf0e10cSrcweir #define W_META_PAINTREGION          0x012B
78cdf0e10cSrcweir #define W_META_SELECTCLIPREGION     0x012C
79cdf0e10cSrcweir #define W_META_SELECTOBJECT         0x012D
80cdf0e10cSrcweir #define W_META_SETTEXTALIGN         0x012E
81cdf0e10cSrcweir #define W_META_DRAWTEXT             0x062F
82cdf0e10cSrcweir #define W_META_CHORD                0x0830
83cdf0e10cSrcweir #define W_META_SETMAPPERFLAGS       0x0231
84cdf0e10cSrcweir #define W_META_EXTTEXTOUT           0x0a32
85cdf0e10cSrcweir #define W_META_SETDIBTODEV          0x0d33
86cdf0e10cSrcweir #define W_META_SELECTPALETTE        0x0234
87cdf0e10cSrcweir #define W_META_REALIZEPALETTE       0x0035
88cdf0e10cSrcweir #define W_META_ANIMATEPALETTE       0x0436
89cdf0e10cSrcweir #define W_META_SETPALENTRIES        0x0037
90cdf0e10cSrcweir #define W_META_POLYPOLYGON          0x0538
91cdf0e10cSrcweir #define W_META_RESIZEPALETTE        0x0139
92cdf0e10cSrcweir #define W_META_DIBBITBLT            0x0940
93cdf0e10cSrcweir #define W_META_DIBSTRETCHBLT        0x0b41
94cdf0e10cSrcweir #define W_META_DIBCREATEPATTERNBRUSH 0x0142
95cdf0e10cSrcweir #define W_META_STRETCHDIB           0x0f43
96cdf0e10cSrcweir #define W_META_EXTFLOODFILL         0x0548
97cdf0e10cSrcweir #define W_META_RESETDC              0x014C
98cdf0e10cSrcweir #define W_META_STARTDOC             0x014D
99cdf0e10cSrcweir #define W_META_STARTPAGE            0x004F
100cdf0e10cSrcweir #define W_META_ENDPAGE              0x0050
101cdf0e10cSrcweir #define W_META_ABORTDOC             0x0052
102cdf0e10cSrcweir #define W_META_ENDDOC               0x005E
103cdf0e10cSrcweir #define W_META_DELETEOBJECT         0x01f0
104cdf0e10cSrcweir #define W_META_CREATEPALETTE        0x00f7
105cdf0e10cSrcweir #define W_META_CREATEBRUSH          0x00F8
106cdf0e10cSrcweir #define W_META_CREATEPATTERNBRUSH   0x01F9
107cdf0e10cSrcweir #define W_META_CREATEPENINDIRECT    0x02FA
108cdf0e10cSrcweir #define W_META_CREATEFONTINDIRECT   0x02FB
109cdf0e10cSrcweir #define W_META_CREATEBRUSHINDIRECT  0x02FC
110cdf0e10cSrcweir #define W_META_CREATEBITMAPINDIRECT 0x02FD
111cdf0e10cSrcweir #define W_META_CREATEBITMAP         0x06FE
112cdf0e10cSrcweir #define W_META_CREATEREGION         0x06FF
113cdf0e10cSrcweir 
114cdf0e10cSrcweir //=================== Methoden von WMFReader ==============================
115cdf0e10cSrcweir 
ReadPoint()116cdf0e10cSrcweir inline Point WMFReader::ReadPoint()
117cdf0e10cSrcweir {
118cdf0e10cSrcweir 	short nX, nY;
119cdf0e10cSrcweir 	*pWMF >> nX >> nY;
120cdf0e10cSrcweir 	return Point( nX, nY );
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
123cdf0e10cSrcweir // ------------------------------------------------------------------------
124cdf0e10cSrcweir 
ReadYX()125cdf0e10cSrcweir inline Point WMFReader::ReadYX()
126cdf0e10cSrcweir {
127cdf0e10cSrcweir 	short nX, nY;
128cdf0e10cSrcweir 	*pWMF >> nY >> nX;
129cdf0e10cSrcweir 	return Point( nX, nY );
130cdf0e10cSrcweir }
131cdf0e10cSrcweir 
132cdf0e10cSrcweir // ------------------------------------------------------------------------
133cdf0e10cSrcweir 
ReadRectangle()134cdf0e10cSrcweir Rectangle WMFReader::ReadRectangle()
135cdf0e10cSrcweir {
136cdf0e10cSrcweir 	Point aBR, aTL;
137cdf0e10cSrcweir 	aBR = ReadYX();
138cdf0e10cSrcweir 	aTL = ReadYX();
139cdf0e10cSrcweir 	aBR.X()--;
140cdf0e10cSrcweir 	aBR.Y()--;
141cdf0e10cSrcweir 	return Rectangle( aTL, aBR );
142cdf0e10cSrcweir }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir // ------------------------------------------------------------------------
145cdf0e10cSrcweir 
ReadYXExt()146cdf0e10cSrcweir Size WMFReader::ReadYXExt()
147cdf0e10cSrcweir {
148cdf0e10cSrcweir 	short nW, nH;
149cdf0e10cSrcweir 	*pWMF >> nH >> nW;
150cdf0e10cSrcweir 	return Size( nW, nH );
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir // ------------------------------------------------------------------------
154cdf0e10cSrcweir 
ReadRecordParams(sal_uInt16 nFunc)155cdf0e10cSrcweir void WMFReader::ReadRecordParams( sal_uInt16 nFunc )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir 	switch( nFunc )
158cdf0e10cSrcweir 	{
159cdf0e10cSrcweir 		case W_META_SETBKCOLOR:
160cdf0e10cSrcweir 		{
161cdf0e10cSrcweir 			pOut->SetBkColor( ReadColor() );
162cdf0e10cSrcweir 		}
163cdf0e10cSrcweir 		break;
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 		case W_META_SETBKMODE:
166cdf0e10cSrcweir 		{
167cdf0e10cSrcweir 			sal_uInt16 nDat;
168cdf0e10cSrcweir 			*pWMF >> nDat;
169cdf0e10cSrcweir 			pOut->SetBkMode( nDat );
170cdf0e10cSrcweir 		}
171cdf0e10cSrcweir 		break;
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 		// !!!
174cdf0e10cSrcweir 		case W_META_SETMAPMODE:
175cdf0e10cSrcweir 		{
176cdf0e10cSrcweir 			sal_Int16 nMapMode;
177cdf0e10cSrcweir 			*pWMF >> nMapMode;
178cdf0e10cSrcweir 			pOut->SetMapMode( nMapMode );
179cdf0e10cSrcweir 		}
180cdf0e10cSrcweir 		break;
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 		case W_META_SETROP2:
183cdf0e10cSrcweir 		{
184cdf0e10cSrcweir 			sal_uInt16 nROP2;
185cdf0e10cSrcweir 			*pWMF >> nROP2;
186cdf0e10cSrcweir 			pOut->SetRasterOp( nROP2 );
187cdf0e10cSrcweir 		}
188cdf0e10cSrcweir 		break;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir 		case W_META_SETTEXTCOLOR:
191cdf0e10cSrcweir 		{
192cdf0e10cSrcweir 			pOut->SetTextColor( ReadColor() );
193cdf0e10cSrcweir 		}
194cdf0e10cSrcweir 		break;
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 		case W_META_SETWINDOWORG:
197cdf0e10cSrcweir 		{
198cdf0e10cSrcweir 			pOut->SetWinOrg( ReadYX() );
199cdf0e10cSrcweir 		}
200cdf0e10cSrcweir 		break;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 		case W_META_SETWINDOWEXT:
203cdf0e10cSrcweir 		{
204cdf0e10cSrcweir 			short nWidth, nHeight;
205cdf0e10cSrcweir 			*pWMF >> nHeight >> nWidth;
206cdf0e10cSrcweir 			pOut->SetWinExt( Size( nWidth, nHeight ) );
207cdf0e10cSrcweir 		}
208cdf0e10cSrcweir 		break;
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 		case W_META_OFFSETWINDOWORG:
211cdf0e10cSrcweir 		{
212cdf0e10cSrcweir 			short nXAdd, nYAdd;
213cdf0e10cSrcweir 			*pWMF >> nYAdd >> nXAdd;
214cdf0e10cSrcweir 			pOut->SetWinOrgOffset( nXAdd, nYAdd );
215cdf0e10cSrcweir 		}
216cdf0e10cSrcweir 		break;
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 		case W_META_SCALEWINDOWEXT:
219cdf0e10cSrcweir 		{
220cdf0e10cSrcweir 			short nXNum, nXDenom, nYNum, nYDenom;
221cdf0e10cSrcweir 			*pWMF >> nYDenom >> nYNum >> nXDenom >> nXNum;
222cdf0e10cSrcweir 			pOut->ScaleWinExt( (double)nXNum / nXDenom, (double)nYNum / nYDenom );
223cdf0e10cSrcweir 		}
224cdf0e10cSrcweir 		break;
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 		case W_META_SETVIEWPORTORG:
227cdf0e10cSrcweir 		case W_META_SETVIEWPORTEXT:
228cdf0e10cSrcweir 		break;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 		case W_META_OFFSETVIEWPORTORG:
231cdf0e10cSrcweir 		{
232cdf0e10cSrcweir 			short nXAdd, nYAdd;
233cdf0e10cSrcweir 			*pWMF >> nYAdd >> nXAdd;
234cdf0e10cSrcweir 			pOut->SetDevOrgOffset( nXAdd, nYAdd );
235cdf0e10cSrcweir 		}
236cdf0e10cSrcweir 		break;
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 		case W_META_SCALEVIEWPORTEXT:
239cdf0e10cSrcweir 		{
240cdf0e10cSrcweir 			short nXNum, nXDenom, nYNum, nYDenom;
241cdf0e10cSrcweir 			*pWMF >> nYDenom >> nYNum >> nXDenom >> nXNum;
242cdf0e10cSrcweir 			pOut->ScaleDevExt( (double)nXNum / nXDenom, (double)nYNum / nYDenom );
243cdf0e10cSrcweir 		}
244cdf0e10cSrcweir 		break;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 		case W_META_LINETO:
247cdf0e10cSrcweir 		{
248cdf0e10cSrcweir 			pOut->LineTo( ReadYX() );
249cdf0e10cSrcweir 		}
250cdf0e10cSrcweir 		break;
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 		case W_META_MOVETO:
253cdf0e10cSrcweir 		{
254cdf0e10cSrcweir 			pOut->MoveTo( ReadYX() );
255cdf0e10cSrcweir 		}
256cdf0e10cSrcweir 		break;
257cdf0e10cSrcweir 
258cdf0e10cSrcweir 		case W_META_INTERSECTCLIPRECT:
259cdf0e10cSrcweir 		{
260cdf0e10cSrcweir 			pOut->IntersectClipRect( ReadRectangle() );
261cdf0e10cSrcweir 		}
262cdf0e10cSrcweir 		break;
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 		case W_META_RECTANGLE:
265cdf0e10cSrcweir 		{
266cdf0e10cSrcweir 			pOut->DrawRect( ReadRectangle() );
267cdf0e10cSrcweir 		}
268cdf0e10cSrcweir 		break;
269cdf0e10cSrcweir 
270cdf0e10cSrcweir 		case W_META_ROUNDRECT:
271cdf0e10cSrcweir 		{
272cdf0e10cSrcweir 			Size aSize( ReadYXExt() );
273cdf0e10cSrcweir 			pOut->DrawRoundRect( ReadRectangle(), Size( aSize.Width() / 2, aSize.Height() / 2 ) );
274cdf0e10cSrcweir 		}
275cdf0e10cSrcweir 		break;
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 		case W_META_ELLIPSE:
278cdf0e10cSrcweir 		{
279cdf0e10cSrcweir 			pOut->DrawEllipse( ReadRectangle() );
280cdf0e10cSrcweir 		}
281cdf0e10cSrcweir 		break;
282cdf0e10cSrcweir 
283cdf0e10cSrcweir 		case W_META_ARC:
284cdf0e10cSrcweir 		{
285cdf0e10cSrcweir 			Point aEnd( ReadYX() );
286cdf0e10cSrcweir 			Point aStart( ReadYX() );
287cdf0e10cSrcweir 			Rectangle aRect( ReadRectangle() );
288cdf0e10cSrcweir 			aRect.Justify();
289cdf0e10cSrcweir 			pOut->DrawArc( aRect, aStart, aEnd );
290cdf0e10cSrcweir 		}
291cdf0e10cSrcweir 		break;
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 		case W_META_PIE:
294cdf0e10cSrcweir 		{
295cdf0e10cSrcweir 			Point     aEnd( ReadYX() );
296cdf0e10cSrcweir 			Point     aStart( ReadYX() );
297cdf0e10cSrcweir             Rectangle aRect( ReadRectangle() );
298cdf0e10cSrcweir 			aRect.Justify();
299cdf0e10cSrcweir 
300cdf0e10cSrcweir             // #i73608# OutputDevice deviates from WMF
301cdf0e10cSrcweir             // semantics. start==end means full ellipse here.
302cdf0e10cSrcweir             if( aStart == aEnd )
303cdf0e10cSrcweir                 pOut->DrawEllipse( aRect );
304cdf0e10cSrcweir             else
305cdf0e10cSrcweir                 pOut->DrawPie( aRect, aStart, aEnd );
306cdf0e10cSrcweir 		}
307cdf0e10cSrcweir 		break;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 		case W_META_CHORD:
310cdf0e10cSrcweir 		{
311cdf0e10cSrcweir 			Point aEnd( ReadYX() );
312cdf0e10cSrcweir 			Point aStart( ReadYX() );
313cdf0e10cSrcweir 			Rectangle aRect( ReadRectangle() );
314cdf0e10cSrcweir 			aRect.Justify();
315cdf0e10cSrcweir 			pOut->DrawChord( aRect, aStart, aEnd );
316cdf0e10cSrcweir 		}
317cdf0e10cSrcweir 		break;
318cdf0e10cSrcweir 
319cdf0e10cSrcweir 		case W_META_POLYGON:
320cdf0e10cSrcweir 		{
321cdf0e10cSrcweir 			sal_uInt16 i,nPoints;
322cdf0e10cSrcweir 			*pWMF >> nPoints;
323cdf0e10cSrcweir 			Polygon aPoly( nPoints );
324cdf0e10cSrcweir 			for( i = 0; i < nPoints; i++ )
325cdf0e10cSrcweir 				aPoly[ i ] = ReadPoint();
326cdf0e10cSrcweir 			pOut->DrawPolygon( aPoly );
327cdf0e10cSrcweir 		}
328cdf0e10cSrcweir 		break;
329cdf0e10cSrcweir 
330cdf0e10cSrcweir 		case W_META_POLYPOLYGON:
331cdf0e10cSrcweir 		{
3327342c28dSArmin Le Grand             sal_uInt16 nPolyCount(0);
3337342c28dSArmin Le Grand 
3347342c28dSArmin Le Grand             // get number of polygons
3357342c28dSArmin Le Grand             *pWMF >> nPolyCount;
3367342c28dSArmin Le Grand 
3377342c28dSArmin Le Grand             if(nPolyCount && !pWMF->IsEof())
3387342c28dSArmin Le Grand             {
3397342c28dSArmin Le Grand     			sal_uInt16*	pnPoints = new sal_uInt16[nPolyCount];
3407342c28dSArmin Le Grand                 sal_uInt16 a(0);
3417342c28dSArmin Le Grand                 PolyPolygon aPolyPoly(nPolyCount, nPolyCount);
3427342c28dSArmin Le Grand 
3437342c28dSArmin Le Grand                 for(a = 0; a < nPolyCount && !pWMF->IsEof(); a++)
3447342c28dSArmin Le Grand                 {
3457342c28dSArmin Le Grand                     *pWMF >> pnPoints[a];
3467342c28dSArmin Le Grand                 }
3477342c28dSArmin Le Grand 
3487342c28dSArmin Le Grand                 for(a = 0; a < nPolyCount && !pWMF->IsEof(); a++)
3497342c28dSArmin Le Grand                 {
3507342c28dSArmin Le Grand                     const sal_uInt16 nPointCount(pnPoints[a]);
3517342c28dSArmin Le Grand         			Point* pPtAry = new Point[nPointCount];
3527342c28dSArmin Le Grand 
3537342c28dSArmin Le Grand                     for(sal_uInt16 b(0); b < nPointCount && !pWMF->IsEof(); b++)
3547342c28dSArmin Le Grand                     {
3557342c28dSArmin Le Grand                         pPtAry[b] = ReadPoint();
3567342c28dSArmin Le Grand                     }
3577342c28dSArmin Le Grand 
3587342c28dSArmin Le Grand                     aPolyPoly.Insert(Polygon(nPointCount, pPtAry));
3597342c28dSArmin Le Grand                     delete[] pPtAry;
3607342c28dSArmin Le Grand                 }
3617342c28dSArmin Le Grand 
3627342c28dSArmin Le Grand                 delete[] pnPoints;
3637342c28dSArmin Le Grand     			pOut->DrawPolyPolygon(aPolyPoly);
3647342c28dSArmin Le Grand             }
365cdf0e10cSrcweir 		}
366cdf0e10cSrcweir 		break;
367cdf0e10cSrcweir 
368cdf0e10cSrcweir 		case W_META_POLYLINE:
369cdf0e10cSrcweir 		{
370cdf0e10cSrcweir 			sal_uInt16 i,nPoints;
371cdf0e10cSrcweir 			*pWMF >> nPoints;
372cdf0e10cSrcweir 			Polygon aPoly( nPoints );
373cdf0e10cSrcweir 			for( i = 0; i < nPoints; i++ )
374cdf0e10cSrcweir 				aPoly[ i ] = ReadPoint();
375cdf0e10cSrcweir 			pOut->DrawPolyLine( aPoly );
376cdf0e10cSrcweir 		}
377cdf0e10cSrcweir 		break;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir 		case W_META_SAVEDC:
380cdf0e10cSrcweir 		{
381cdf0e10cSrcweir 			pOut->Push();
382cdf0e10cSrcweir 		}
383cdf0e10cSrcweir 		break;
384cdf0e10cSrcweir 
385cdf0e10cSrcweir 		case W_META_RESTOREDC:
386cdf0e10cSrcweir 		{
387cdf0e10cSrcweir 			pOut->Pop();
388cdf0e10cSrcweir 		}
389cdf0e10cSrcweir 		break;
390cdf0e10cSrcweir 
391cdf0e10cSrcweir 		case W_META_SETPIXEL:
392cdf0e10cSrcweir 		{
393cdf0e10cSrcweir 			const Color aColor = ReadColor();
394cdf0e10cSrcweir 			pOut->DrawPixel( ReadYX(), aColor );
395cdf0e10cSrcweir 		}
396cdf0e10cSrcweir 		break;
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 		case W_META_OFFSETCLIPRGN:
399cdf0e10cSrcweir 		{
400cdf0e10cSrcweir 			pOut->MoveClipRegion( ReadYXExt() );
401cdf0e10cSrcweir 		}
402cdf0e10cSrcweir 		break;
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 		case W_META_TEXTOUT:
405cdf0e10cSrcweir 		{
406cdf0e10cSrcweir 			sal_uInt16 nLength;
407cdf0e10cSrcweir 			*pWMF >> nLength;
408cdf0e10cSrcweir 			if ( nLength )
409cdf0e10cSrcweir 			{
410cdf0e10cSrcweir 				char*	pChar = new char[ ( nLength + 1 ) &~ 1 ];
411cdf0e10cSrcweir 				pWMF->Read( pChar, ( nLength + 1 ) &~ 1 );
412cdf0e10cSrcweir 				String aText( pChar, nLength, pOut->GetCharSet() );
413cdf0e10cSrcweir 				delete[] pChar;
414cdf0e10cSrcweir 				Point aPosition( ReadYX() );
415cdf0e10cSrcweir 				pOut->DrawText( aPosition, aText );
416cdf0e10cSrcweir 			}
417cdf0e10cSrcweir 		}
418cdf0e10cSrcweir 		break;
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 		case W_META_EXTTEXTOUT:
421cdf0e10cSrcweir 		{
422cdf0e10cSrcweir 			sal_Int16	nDx, nDxTmp;
423cdf0e10cSrcweir 			sal_uInt16	i, nLen, nOptions;
424cdf0e10cSrcweir 			sal_Int32	nRecordPos, nRecordSize, nOriginalTextLen, nNewTextLen;
425cdf0e10cSrcweir 			Point		aPosition;
426cdf0e10cSrcweir 			Rectangle	aRect;
427cdf0e10cSrcweir 			sal_Int32*	pDXAry = NULL;
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 			pWMF->SeekRel(-6);
430cdf0e10cSrcweir 			nRecordPos = pWMF->Tell();
431cdf0e10cSrcweir 			*pWMF >> nRecordSize;
432cdf0e10cSrcweir 			pWMF->SeekRel(2);
433cdf0e10cSrcweir 			aPosition = ReadYX();
434cdf0e10cSrcweir 			*pWMF >> nLen >> nOptions;
435cdf0e10cSrcweir 
436cdf0e10cSrcweir 			sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT;
437cdf0e10cSrcweir 			if ( nOptions & ETO_RTLREADING )
438cdf0e10cSrcweir 				nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
439cdf0e10cSrcweir 			pOut->SetTextLayoutMode( nTextLayoutMode );
440cdf0e10cSrcweir 			DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in WMF" );
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 			// Nur wenn der Text auch Zeichen enthaelt, macht die Ausgabe Sinn
443cdf0e10cSrcweir 			if( nLen )
444cdf0e10cSrcweir 			{
445cdf0e10cSrcweir 				nOriginalTextLen = nLen;
446cdf0e10cSrcweir 				if( nOptions & ETO_CLIPPED )
447cdf0e10cSrcweir 				{
448cdf0e10cSrcweir 					const Point aPt1( ReadPoint() );
449cdf0e10cSrcweir 					const Point aPt2( ReadPoint() );
450cdf0e10cSrcweir 					aRect = Rectangle( aPt1, aPt2 );
451cdf0e10cSrcweir 				}
452cdf0e10cSrcweir 				char* pChar = new char[ ( nOriginalTextLen + 1 ) &~ 1 ];
453cdf0e10cSrcweir 				pWMF->Read( pChar, ( nOriginalTextLen + 1 ) &~ 1 );
454cdf0e10cSrcweir 				String aText( pChar, (sal_uInt16)nOriginalTextLen, pOut->GetCharSet() );// after this conversion the text may contain
455cdf0e10cSrcweir 				nNewTextLen = aText.Len();										        // less character (japanese version), so the
456cdf0e10cSrcweir 				delete[] pChar;													        // dxAry will not fit
457cdf0e10cSrcweir 
458cdf0e10cSrcweir 				if ( nNewTextLen )
459cdf0e10cSrcweir 				{
460cdf0e10cSrcweir 					sal_uInt32	nMaxStreamPos = nRecordPos + ( nRecordSize << 1 );
461cdf0e10cSrcweir 					sal_Int32	nDxArySize =  nMaxStreamPos - pWMF->Tell();
462cdf0e10cSrcweir 					sal_Int32	nDxAryEntries = nDxArySize >> 1;
463cdf0e10cSrcweir 					sal_Bool	bUseDXAry = sal_False;
464cdf0e10cSrcweir 
465cdf0e10cSrcweir 					if ( ( ( nDxAryEntries % nOriginalTextLen ) == 0 ) && ( nNewTextLen <= nOriginalTextLen ) )
466cdf0e10cSrcweir 					{
467cdf0e10cSrcweir 						pDXAry = new sal_Int32[ nNewTextLen ];
468cdf0e10cSrcweir 						for ( i = 0; i < nNewTextLen; i++ )
469cdf0e10cSrcweir 						{
470cdf0e10cSrcweir 							if ( pWMF->Tell() >= nMaxStreamPos )
471cdf0e10cSrcweir 								break;
472cdf0e10cSrcweir 							*pWMF >> nDx;
473cdf0e10cSrcweir 							if ( nNewTextLen != nOriginalTextLen )
474cdf0e10cSrcweir 							{
475cdf0e10cSrcweir 								ByteString aTmp( aText.GetChar( i ), pOut->GetCharSet() );
476cdf0e10cSrcweir 								if ( aTmp.Len() > 1 )
477cdf0e10cSrcweir 								{
478cdf0e10cSrcweir 									sal_Int32 nDxCount = aTmp.Len() - 1;
479cdf0e10cSrcweir 									if ( ( ( nDxCount * 2 ) + pWMF->Tell() ) > nMaxStreamPos )
480cdf0e10cSrcweir 										break;
481cdf0e10cSrcweir 									while ( nDxCount-- )
482cdf0e10cSrcweir 									{
483cdf0e10cSrcweir 										*pWMF >> nDxTmp;
484cdf0e10cSrcweir 										nDx = nDx + nDxTmp;
485cdf0e10cSrcweir 									}
486cdf0e10cSrcweir 								}
487cdf0e10cSrcweir 							}
488cdf0e10cSrcweir 							pDXAry[ i ] = nDx;
489cdf0e10cSrcweir 						}
490cdf0e10cSrcweir 						if ( i == nNewTextLen )
491cdf0e10cSrcweir 							bUseDXAry = sal_True;
492cdf0e10cSrcweir 					}
493cdf0e10cSrcweir 					if ( pDXAry && bUseDXAry )
494cdf0e10cSrcweir 						pOut->DrawText( aPosition, aText, pDXAry );
495cdf0e10cSrcweir 					else
496cdf0e10cSrcweir 						pOut->DrawText( aPosition, aText );
497cdf0e10cSrcweir 				}
498cdf0e10cSrcweir 			}
499cdf0e10cSrcweir 			delete[] pDXAry;
500cdf0e10cSrcweir 
501cdf0e10cSrcweir 		}
502cdf0e10cSrcweir 		break;
503cdf0e10cSrcweir 
504cdf0e10cSrcweir 		case W_META_SELECTOBJECT:
505cdf0e10cSrcweir 		{
506cdf0e10cSrcweir 			sal_Int16	nObjIndex;
507cdf0e10cSrcweir 			*pWMF >> nObjIndex;
508cdf0e10cSrcweir 			pOut->SelectObject( nObjIndex );
509cdf0e10cSrcweir 		}
510cdf0e10cSrcweir 		break;
511cdf0e10cSrcweir 
512cdf0e10cSrcweir 		case W_META_SETTEXTALIGN:
513cdf0e10cSrcweir 		{
514cdf0e10cSrcweir 			sal_uInt16	nAlign;
515cdf0e10cSrcweir 			*pWMF >> nAlign;
516cdf0e10cSrcweir 			pOut->SetTextAlign( nAlign );
517cdf0e10cSrcweir 		}
518cdf0e10cSrcweir 		break;
519cdf0e10cSrcweir 
520cdf0e10cSrcweir 		case W_META_BITBLT:
521cdf0e10cSrcweir 		{
522cdf0e10cSrcweir 			// 0-3   : nWinROP						#93454#
523cdf0e10cSrcweir 			// 4-5   : y offset of source bitmap
524cdf0e10cSrcweir 			// 6-7   : x offset of source bitmap
525cdf0e10cSrcweir 			// 8-9   : used height of source bitmap
526cdf0e10cSrcweir 			// 10-11 : used width  of source bitmap
527cdf0e10cSrcweir 			// 12-13 : destination position y (in pixel)
528cdf0e10cSrcweir 			// 14-15 : destination position x (in pixel)
529cdf0e10cSrcweir 			// 16-17 : dont know
530cdf0e10cSrcweir 			// 18-19 : Width Bitmap in Pixel
531cdf0e10cSrcweir 			// 20-21 : Height Bitmap in Pixel
532cdf0e10cSrcweir 			// 22-23 : bytes per scanline
533cdf0e10cSrcweir 			// 24    : planes
534cdf0e10cSrcweir 			// 25	 : bitcount
535cdf0e10cSrcweir 
536cdf0e10cSrcweir 			sal_Int32	nWinROP;
537cdf0e10cSrcweir 			sal_uInt16	nSx, nSy, nSxe, nSye, nDontKnow, nWidth, nHeight, nBytesPerScan;
538cdf0e10cSrcweir 			sal_uInt8	nPlanes, nBitCount;
539cdf0e10cSrcweir 
540cdf0e10cSrcweir 			*pWMF >> nWinROP
541cdf0e10cSrcweir 				  >> nSy >> nSx >> nSye >> nSxe;
542cdf0e10cSrcweir 			Point aPoint( ReadYX() );
543cdf0e10cSrcweir 			*pWMF >> nDontKnow >> nWidth >> nHeight >> nBytesPerScan >> nPlanes >> nBitCount;
544cdf0e10cSrcweir 
545cdf0e10cSrcweir 			if ( nWidth && nHeight && ( nPlanes == 1 ) && ( nBitCount == 1 ) )
546cdf0e10cSrcweir 			{
547cdf0e10cSrcweir 				Bitmap aBmp( Size( nWidth, nHeight ), nBitCount );
548cdf0e10cSrcweir 				BitmapWriteAccess* pAcc;
549cdf0e10cSrcweir 				pAcc = aBmp.AcquireWriteAccess();
550cdf0e10cSrcweir 				if ( pAcc )
551cdf0e10cSrcweir 				{
552cdf0e10cSrcweir 					sal_uInt16 y, x, scan;
553cdf0e10cSrcweir 					sal_Int8 i, nEightPixels;
554cdf0e10cSrcweir 					for ( y = 0; y < nHeight; y++ )
555cdf0e10cSrcweir 					{
556cdf0e10cSrcweir 						x = 0;
557cdf0e10cSrcweir 						for ( scan = 0; scan < nBytesPerScan; scan++ )
558cdf0e10cSrcweir 						{
559cdf0e10cSrcweir 							*pWMF >> nEightPixels;
560cdf0e10cSrcweir 							for ( i = 7; i >= 0; i-- )
561cdf0e10cSrcweir 							{
562cdf0e10cSrcweir 								if ( x < nWidth )
563cdf0e10cSrcweir 								{
56487bc88d3SHerbert Dürr 									pAcc->SetPixelIndex( y, x, (nEightPixels>>i)&1 );
565cdf0e10cSrcweir 								}
566cdf0e10cSrcweir 								x++;
567cdf0e10cSrcweir 							}
568cdf0e10cSrcweir 						}
569cdf0e10cSrcweir 					}
570cdf0e10cSrcweir 					aBmp.ReleaseAccess( pAcc );
571cdf0e10cSrcweir                     if ( nSye && nSxe &&
572cdf0e10cSrcweir                         ( ( nSx + nSxe ) <= aBmp.GetSizePixel().Width() ) &&
573cdf0e10cSrcweir                             ( ( nSy + nSye <= aBmp.GetSizePixel().Height() ) ) )
574cdf0e10cSrcweir                     {
575cdf0e10cSrcweir                         Rectangle aCropRect( Point( nSx, nSy ), Size( nSxe, nSye ) );
576cdf0e10cSrcweir                         aBmp.Crop( aCropRect );
577cdf0e10cSrcweir                     }
578cdf0e10cSrcweir 					Rectangle aDestRect( aPoint, Size( nSxe, nSye ) );
579cdf0e10cSrcweir 				    aBmpSaveList.Insert( new BSaveStruct( aBmp, aDestRect, nWinROP ), LIST_APPEND );
580cdf0e10cSrcweir 				}
581cdf0e10cSrcweir 			}
582cdf0e10cSrcweir 		}
583cdf0e10cSrcweir 		break;
584cdf0e10cSrcweir 
585cdf0e10cSrcweir 		case W_META_STRETCHBLT:
586cdf0e10cSrcweir 		case W_META_DIBBITBLT:
587cdf0e10cSrcweir 		case W_META_DIBSTRETCHBLT:
588cdf0e10cSrcweir 		case W_META_STRETCHDIB:
589cdf0e10cSrcweir 		{
590cdf0e10cSrcweir 			sal_Int32   nWinROP;
591cdf0e10cSrcweir 			sal_uInt16  nSx, nSy, nSxe, nSye, nUsage;
592cdf0e10cSrcweir 			Bitmap		aBmp;
593cdf0e10cSrcweir 
594cdf0e10cSrcweir 			*pWMF >> nWinROP;
595cdf0e10cSrcweir 
596cdf0e10cSrcweir 			if( nFunc == W_META_STRETCHDIB )
597cdf0e10cSrcweir 				*pWMF >> nUsage;
598cdf0e10cSrcweir 
599cdf0e10cSrcweir             // nSye and nSxe is the number of pixels that has to been used
600cdf0e10cSrcweir 			if( nFunc == W_META_STRETCHDIB || nFunc == W_META_STRETCHBLT || nFunc == W_META_DIBSTRETCHBLT )
601cdf0e10cSrcweir 				*pWMF >> nSye >> nSxe;
602cdf0e10cSrcweir             else
603cdf0e10cSrcweir                 nSye = nSxe = 0;    // set this to zero as indicator not to scale the bitmap later
604cdf0e10cSrcweir 
605cdf0e10cSrcweir             // nSy and nx is the offset of the first pixel
606cdf0e10cSrcweir 			*pWMF >> nSy >> nSx;
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 			if( nFunc == W_META_STRETCHDIB || nFunc == W_META_DIBBITBLT || nFunc == W_META_DIBSTRETCHBLT )
609cdf0e10cSrcweir 			{
610cdf0e10cSrcweir 				if ( nWinROP == PATCOPY )
611cdf0e10cSrcweir 					*pWMF >> nUsage;	// i don't know anything of this parameter, so its called nUsage
612cdf0e10cSrcweir 										// pOut->DrawRect( Rectangle( ReadYX(), aDestSize ), sal_False );
613cdf0e10cSrcweir 
614cdf0e10cSrcweir 				Size aDestSize( ReadYXExt() );
615cdf0e10cSrcweir                 if ( aDestSize.Width() && aDestSize.Height() )  // #92623# do not try to read buggy bitmaps
616cdf0e10cSrcweir                 {
617cdf0e10cSrcweir 				    Rectangle aDestRect( ReadYX(), aDestSize );
618cdf0e10cSrcweir 				    if ( nWinROP != PATCOPY )
619*45fd3b9aSArmin Le Grand 					    ReadDIB(aBmp, *pWMF, false);
620cdf0e10cSrcweir 
621cdf0e10cSrcweir                     // test if it is sensible to crop
622cdf0e10cSrcweir                     if ( nSye && nSxe &&
623cdf0e10cSrcweir                         ( ( nSx + nSxe ) <= aBmp.GetSizePixel().Width() ) &&
624cdf0e10cSrcweir                             ( ( nSy + nSye <= aBmp.GetSizePixel().Height() ) ) )
625cdf0e10cSrcweir                     {
626cdf0e10cSrcweir                         Rectangle aCropRect( Point( nSx, nSy ), Size( nSxe, nSye ) );
627cdf0e10cSrcweir                         aBmp.Crop( aCropRect );
628cdf0e10cSrcweir                     }
629cdf0e10cSrcweir 				    aBmpSaveList.Insert( new BSaveStruct( aBmp, aDestRect, nWinROP ), LIST_APPEND );
630cdf0e10cSrcweir                 }
631cdf0e10cSrcweir 			}
632cdf0e10cSrcweir 		}
633cdf0e10cSrcweir 		break;
634cdf0e10cSrcweir 
635cdf0e10cSrcweir 		case W_META_DIBCREATEPATTERNBRUSH:
636cdf0e10cSrcweir 		{
637cdf0e10cSrcweir 			Bitmap	aBmp;
638cdf0e10cSrcweir 			BitmapReadAccess* pBmp;
639cdf0e10cSrcweir 			sal_uInt32	nRed = 0, nGreen = 0, nBlue = 0, nCount = 1;
640cdf0e10cSrcweir 			sal_uInt16	nFunction;
641cdf0e10cSrcweir 
642cdf0e10cSrcweir 			*pWMF >> nFunction >> nFunction;
643cdf0e10cSrcweir 
644*45fd3b9aSArmin Le Grand 			ReadDIB(aBmp, *pWMF, false);
645cdf0e10cSrcweir 			pBmp = aBmp.AcquireReadAccess();
646cdf0e10cSrcweir 			if ( pBmp )
647cdf0e10cSrcweir 			{
648cdf0e10cSrcweir 				for ( sal_Int32 y = 0; y < pBmp->Height(); y++ )
649cdf0e10cSrcweir 				{
650cdf0e10cSrcweir 					for ( sal_Int32 x = 0; x < pBmp->Width(); x++ )
651cdf0e10cSrcweir 					{
652cdf0e10cSrcweir 						const BitmapColor aColor( pBmp->GetColor( y, x ) );
653cdf0e10cSrcweir 
654cdf0e10cSrcweir 						nRed += aColor.GetRed();
655cdf0e10cSrcweir 						nGreen += aColor.GetGreen();
656cdf0e10cSrcweir 						nBlue += aColor.GetBlue();
657cdf0e10cSrcweir 					}
658cdf0e10cSrcweir 				}
659cdf0e10cSrcweir 				nCount = pBmp->Height() * pBmp->Width();
660cdf0e10cSrcweir 				if ( !nCount )
661cdf0e10cSrcweir 					nCount++;
662cdf0e10cSrcweir 				aBmp.ReleaseAccess( pBmp );
663cdf0e10cSrcweir 			}
664cdf0e10cSrcweir 			Color aColor( (sal_uInt8)( nRed / nCount ), (sal_uInt8)( nGreen / nCount ), (sal_uInt8)( nBlue / nCount ) );
665cdf0e10cSrcweir 			pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( aColor, sal_False ) );
666cdf0e10cSrcweir 		}
667cdf0e10cSrcweir 		break;
668cdf0e10cSrcweir 
669cdf0e10cSrcweir 		case W_META_DELETEOBJECT:
670cdf0e10cSrcweir 		{
671cdf0e10cSrcweir 			sal_Int16 nIndex;
672cdf0e10cSrcweir 			*pWMF >> nIndex;
673cdf0e10cSrcweir 			pOut->DeleteObject( nIndex );
674cdf0e10cSrcweir 		}
675cdf0e10cSrcweir 		break;
676cdf0e10cSrcweir 
677cdf0e10cSrcweir 		case W_META_CREATEPALETTE:
678cdf0e10cSrcweir 		{
679cdf0e10cSrcweir 			pOut->CreateObject( GDI_DUMMY );
680cdf0e10cSrcweir 		}
681cdf0e10cSrcweir 		break;
682cdf0e10cSrcweir 
683cdf0e10cSrcweir 		case W_META_CREATEBRUSH:
684cdf0e10cSrcweir 		{
685cdf0e10cSrcweir 			pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ), sal_False ) );
686cdf0e10cSrcweir 		}
687cdf0e10cSrcweir 		break;
688cdf0e10cSrcweir 
689cdf0e10cSrcweir 		case W_META_CREATEPATTERNBRUSH:
690cdf0e10cSrcweir 		{
691cdf0e10cSrcweir 			pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ), sal_False ) );
692cdf0e10cSrcweir 		}
693cdf0e10cSrcweir 		break;
694cdf0e10cSrcweir 
695cdf0e10cSrcweir 		case W_META_CREATEPENINDIRECT:
696cdf0e10cSrcweir 		{
697cdf0e10cSrcweir 			LineInfo	aLineInfo;
698cdf0e10cSrcweir 			sal_uInt16		nStyle, nWidth, nHeight;
699cdf0e10cSrcweir 
700cdf0e10cSrcweir 			*pWMF >> nStyle >> nWidth >> nHeight;
701cdf0e10cSrcweir 
702cdf0e10cSrcweir 			if ( nWidth )
703cdf0e10cSrcweir 				aLineInfo.SetWidth( nWidth );
704cdf0e10cSrcweir 
705cdf0e10cSrcweir 			sal_Bool bTransparent = sal_False;
706cdf0e10cSrcweir 			sal_uInt16 nDashCount = 0;
707cdf0e10cSrcweir 			sal_uInt16 nDotCount = 0;
708cdf0e10cSrcweir 			switch( nStyle )
709cdf0e10cSrcweir 			{
710cdf0e10cSrcweir 				case PS_DASHDOTDOT :
711cdf0e10cSrcweir 					nDotCount++;
712cdf0e10cSrcweir 				case PS_DASHDOT :
713cdf0e10cSrcweir 					nDashCount++;
714cdf0e10cSrcweir 				case PS_DOT :
715cdf0e10cSrcweir 					nDotCount++;
716cdf0e10cSrcweir 				break;
717cdf0e10cSrcweir 				case PS_DASH :
718cdf0e10cSrcweir 					nDashCount++;
719cdf0e10cSrcweir 				break;
720cdf0e10cSrcweir 				case PS_NULL :
721cdf0e10cSrcweir 					bTransparent = sal_True;
722cdf0e10cSrcweir 					aLineInfo.SetStyle( LINE_NONE );
723cdf0e10cSrcweir 				break;
724cdf0e10cSrcweir 				default :
725cdf0e10cSrcweir 				case PS_INSIDEFRAME :
726cdf0e10cSrcweir 				case PS_SOLID :
727cdf0e10cSrcweir 					aLineInfo.SetStyle( LINE_SOLID );
728cdf0e10cSrcweir 			}
729cdf0e10cSrcweir 			if ( nDashCount | nDotCount )
730cdf0e10cSrcweir 			{
731cdf0e10cSrcweir 				aLineInfo.SetStyle( LINE_DASH );
732cdf0e10cSrcweir 				aLineInfo.SetDashCount( nDashCount );
733cdf0e10cSrcweir 				aLineInfo.SetDotCount( nDotCount );
734cdf0e10cSrcweir 			}
735cdf0e10cSrcweir 			pOut->CreateObject( GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) );
736cdf0e10cSrcweir 		}
737cdf0e10cSrcweir 		break;
738cdf0e10cSrcweir 
739cdf0e10cSrcweir 		case W_META_CREATEBRUSHINDIRECT:
740cdf0e10cSrcweir 		{
741cdf0e10cSrcweir 			sal_uInt16	nStyle;
742cdf0e10cSrcweir 			*pWMF >> nStyle;
743cdf0e10cSrcweir 			pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? sal_True : sal_False ) );
744cdf0e10cSrcweir 		}
745cdf0e10cSrcweir 		break;
746cdf0e10cSrcweir 
747cdf0e10cSrcweir 		case W_META_CREATEFONTINDIRECT:
748cdf0e10cSrcweir 		{
749cdf0e10cSrcweir 			Size	aFontSize;
750cdf0e10cSrcweir 			char	lfFaceName[ LF_FACESIZE ];
751cdf0e10cSrcweir 			sal_Int16	lfEscapement, lfOrientation, lfWeight;	// ( ehemals sal_uInt16 )
752cdf0e10cSrcweir 
753cdf0e10cSrcweir 			LOGFONTW aLogFont;
754cdf0e10cSrcweir 			aFontSize = ReadYXExt();
755cdf0e10cSrcweir 			*pWMF >> lfEscapement >> lfOrientation >> lfWeight
756cdf0e10cSrcweir 					>> aLogFont.lfItalic >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision
757cdf0e10cSrcweir 						>> aLogFont.lfClipPrecision >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily;
758cdf0e10cSrcweir 			pWMF->Read( lfFaceName, LF_FACESIZE );
759cdf0e10cSrcweir 			aLogFont.lfWidth = aFontSize.Width();
760cdf0e10cSrcweir 			aLogFont.lfHeight = aFontSize.Height();
761cdf0e10cSrcweir 			aLogFont.lfEscapement = lfEscapement;
762cdf0e10cSrcweir 			aLogFont.lfOrientation = lfOrientation;
763cdf0e10cSrcweir 			aLogFont.lfWeight = lfWeight;
764cdf0e10cSrcweir 
765cdf0e10cSrcweir 			CharSet eCharSet;
766cdf0e10cSrcweir 			if ( ( aLogFont.lfCharSet == OEM_CHARSET ) || ( aLogFont.lfCharSet == DEFAULT_CHARSET ) )
767cdf0e10cSrcweir 				eCharSet = gsl_getSystemTextEncoding();
768cdf0e10cSrcweir 			else
769cdf0e10cSrcweir 				eCharSet = rtl_getTextEncodingFromWindowsCharset( aLogFont.lfCharSet );
770cdf0e10cSrcweir 			if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
771cdf0e10cSrcweir 				eCharSet = gsl_getSystemTextEncoding();
772cdf0e10cSrcweir 			if ( eCharSet == RTL_TEXTENCODING_SYMBOL )
773cdf0e10cSrcweir 				eCharSet = RTL_TEXTENCODING_MS_1252;
774cdf0e10cSrcweir 			aLogFont.alfFaceName = UniString( lfFaceName, eCharSet );
775cdf0e10cSrcweir 
776cdf0e10cSrcweir 			pOut->CreateObject( GDI_FONT, new WinMtfFontStyle( aLogFont ) );
777cdf0e10cSrcweir 		}
778cdf0e10cSrcweir 		break;
779cdf0e10cSrcweir 
780cdf0e10cSrcweir 		case W_META_CREATEBITMAPINDIRECT:
781cdf0e10cSrcweir 		{
782cdf0e10cSrcweir 			pOut->CreateObject( GDI_DUMMY );
783cdf0e10cSrcweir 		}
784cdf0e10cSrcweir 		break;
785cdf0e10cSrcweir 
786cdf0e10cSrcweir 		case W_META_CREATEBITMAP:
787cdf0e10cSrcweir 		{
788cdf0e10cSrcweir 			pOut->CreateObject( GDI_DUMMY );
789cdf0e10cSrcweir 		}
790cdf0e10cSrcweir 		break;
791cdf0e10cSrcweir 
792cdf0e10cSrcweir 		case W_META_CREATEREGION:
793cdf0e10cSrcweir 		{
794cdf0e10cSrcweir 			pOut->CreateObject( GDI_DUMMY );
795cdf0e10cSrcweir     	}
796cdf0e10cSrcweir 		break;
797cdf0e10cSrcweir 
798cdf0e10cSrcweir 		case W_META_EXCLUDECLIPRECT :
799cdf0e10cSrcweir 		{
800cdf0e10cSrcweir 			pOut->ExcludeClipRect( ReadRectangle() );
801cdf0e10cSrcweir 		}
802cdf0e10cSrcweir 		break;
803cdf0e10cSrcweir 
804cdf0e10cSrcweir 		case W_META_PATBLT:
805cdf0e10cSrcweir 		{
806cdf0e10cSrcweir 			sal_uInt32 nROP, nOldROP;
807cdf0e10cSrcweir 			*pWMF >> nROP;
808cdf0e10cSrcweir 			Size aSize = ReadYXExt();
809cdf0e10cSrcweir 			nOldROP = pOut->SetRasterOp( nROP );
810cdf0e10cSrcweir 			pOut->DrawRect( Rectangle( ReadYX(), aSize ), sal_False );
811cdf0e10cSrcweir 			pOut->SetRasterOp( nOldROP );
812cdf0e10cSrcweir 		}
813cdf0e10cSrcweir 		break;
814cdf0e10cSrcweir 
815cdf0e10cSrcweir 		case W_META_SELECTCLIPREGION:
816cdf0e10cSrcweir         {
817cdf0e10cSrcweir             sal_Int16 nObjIndex;
818cdf0e10cSrcweir             *pWMF >> nObjIndex;
819cdf0e10cSrcweir             if ( !nObjIndex )
820cdf0e10cSrcweir             {
821cdf0e10cSrcweir                 PolyPolygon aEmptyPolyPoly;
822cdf0e10cSrcweir                 pOut->SetClipPath( aEmptyPolyPoly, RGN_COPY, sal_True );
823cdf0e10cSrcweir             }
824cdf0e10cSrcweir         }
825cdf0e10cSrcweir         break;
826cdf0e10cSrcweir 
827cdf0e10cSrcweir 		case W_META_ESCAPE :
828cdf0e10cSrcweir 		{
829cdf0e10cSrcweir 			// nRecSize has been checked previously to be greater than 3
830cdf0e10cSrcweir 			sal_uInt64 nMetaRecSize = static_cast< sal_uInt64 >( nRecSize - 2 ) * 2;
831cdf0e10cSrcweir 			sal_uInt64 nMetaRecEndPos = pWMF->Tell() + nMetaRecSize;
832cdf0e10cSrcweir 
833cdf0e10cSrcweir 			// taking care that nRecSize does not exceed the maximal stream position
834cdf0e10cSrcweir 			if ( nMetaRecEndPos > nEndPos )
835cdf0e10cSrcweir 			{
836cdf0e10cSrcweir 				pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
837cdf0e10cSrcweir 				break;
838cdf0e10cSrcweir 			}
839cdf0e10cSrcweir 			if ( nRecSize >= 4 )	// minimal escape lenght
840cdf0e10cSrcweir 			{
841cdf0e10cSrcweir 				sal_uInt16	nMode, nLen;
842cdf0e10cSrcweir 				*pWMF >> nMode
843cdf0e10cSrcweir 					  >> nLen;
844cdf0e10cSrcweir                 if ( ( nMode == W_MFCOMMENT ) && ( nLen >= 4 ) )
845cdf0e10cSrcweir                 {
846cdf0e10cSrcweir                     sal_uInt32 nNewMagic; // we have to read int32 for
847cdf0e10cSrcweir                     *pWMF >> nNewMagic;   // META_ESCAPE_ENHANCED_METAFILE CommentIdentifier
848cdf0e10cSrcweir 
849cdf0e10cSrcweir                     if( nNewMagic == 0x2c2a4f4f &&  nLen >= 14 )
850cdf0e10cSrcweir                     {
851cdf0e10cSrcweir                         sal_uInt16 nMagic2;
852cdf0e10cSrcweir                         *pWMF >> nMagic2;
853cdf0e10cSrcweir                         if( nMagic2 == 0x0a ) // 2nd half of magic
854cdf0e10cSrcweir                         {                     // continue with private escape
855cdf0e10cSrcweir                             sal_uInt32 nCheck, nEsc;
856cdf0e10cSrcweir                             *pWMF >> nCheck
857cdf0e10cSrcweir                                   >> nEsc;
858cdf0e10cSrcweir 
859cdf0e10cSrcweir 					        sal_uInt32 nEscLen = nLen - 14;
860cdf0e10cSrcweir 					        if ( nEscLen <= ( nRecSize * 2 ) )
861cdf0e10cSrcweir 					        {
862cdf0e10cSrcweir #ifdef OSL_BIGENDIAN
863cdf0e10cSrcweir 						        sal_uInt32 nTmp = SWAPLONG( nEsc );
864cdf0e10cSrcweir 						        sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
865cdf0e10cSrcweir #else
866cdf0e10cSrcweir 						        sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
867cdf0e10cSrcweir #endif
868cdf0e10cSrcweir 						        sal_Int8* pData = NULL;
869cdf0e10cSrcweir 
870cdf0e10cSrcweir 						        if ( ( static_cast< sal_uInt64 >( nEscLen ) + pWMF->Tell() ) > nMetaRecEndPos )
871cdf0e10cSrcweir 						        {
872cdf0e10cSrcweir 							        pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
873cdf0e10cSrcweir 							        break;
874cdf0e10cSrcweir 						        }
875cdf0e10cSrcweir 						        if ( nEscLen > 0 )
876cdf0e10cSrcweir 						        {
877cdf0e10cSrcweir 							        pData = new sal_Int8[ nEscLen ];
878cdf0e10cSrcweir 							        pWMF->Read( pData, nEscLen );
879cdf0e10cSrcweir 							        nCheckSum = rtl_crc32( nCheckSum, pData, nEscLen );
880cdf0e10cSrcweir 						        }
881cdf0e10cSrcweir 						        if ( nCheck == nCheckSum )
882cdf0e10cSrcweir 						        {
883cdf0e10cSrcweir 							        switch( nEsc )
884cdf0e10cSrcweir 							        {
885cdf0e10cSrcweir 								        case PRIVATE_ESCAPE_UNICODE :
8861a11d300SArmin Le Grand 								        {
8871a11d300SArmin Le Grand                                             // we will use text instead of polygons only if we have the correct font
8881a11d300SArmin Le Grand 									        if ( Application::GetDefaultDevice()->IsFontAvailable( pOut->GetFont().GetName() ) )
889cdf0e10cSrcweir 									        {
890cdf0e10cSrcweir 										        Point  aPt;
891cdf0e10cSrcweir 										        String aString;
892cdf0e10cSrcweir 										        sal_uInt32	i, nStringLen, nDXCount;
893cdf0e10cSrcweir 										        sal_Int32* pDXAry = NULL;
894cdf0e10cSrcweir 										        SvMemoryStream aMemoryStream( nEscLen );
895cdf0e10cSrcweir 										        aMemoryStream.Write( pData, nEscLen );
896cdf0e10cSrcweir 										        aMemoryStream.Seek( STREAM_SEEK_TO_BEGIN );
897cdf0e10cSrcweir 										        aMemoryStream >> aPt.X()
898cdf0e10cSrcweir 													          >> aPt.Y()
899cdf0e10cSrcweir 													          >> nStringLen;
900cdf0e10cSrcweir 
901cdf0e10cSrcweir 										        if ( ( static_cast< sal_uInt64 >( nStringLen ) * sizeof( sal_Unicode ) ) < ( nEscLen - aMemoryStream.Tell() ) )
902cdf0e10cSrcweir 										        {
903cdf0e10cSrcweir 											        sal_Unicode* pBuf = aString.AllocBuffer( (xub_StrLen)nStringLen );
904cdf0e10cSrcweir 											        for ( i = 0; i < nStringLen; i++ )
905cdf0e10cSrcweir 												        aMemoryStream >> pBuf[ i ];
906cdf0e10cSrcweir 											        aMemoryStream >> nDXCount;
907cdf0e10cSrcweir 											        if ( ( static_cast< sal_uInt64 >( nDXCount ) * sizeof( sal_Int32 ) ) >= ( nEscLen - aMemoryStream.Tell() ) )
908cdf0e10cSrcweir 												        nDXCount = 0;
909cdf0e10cSrcweir 											        if ( nDXCount )
910cdf0e10cSrcweir 												        pDXAry = new sal_Int32[ nDXCount ];
911cdf0e10cSrcweir 											        for  ( i = 0; i < nDXCount; i++ )
912cdf0e10cSrcweir 												        aMemoryStream >> pDXAry[ i ];
913cdf0e10cSrcweir 											        aMemoryStream >> nSkipActions;
914cdf0e10cSrcweir 											        pOut->DrawText( aPt, aString, pDXAry );
915cdf0e10cSrcweir 											        delete[] pDXAry;
916cdf0e10cSrcweir 										        }
917cdf0e10cSrcweir 									        }
918cdf0e10cSrcweir 								        }
919cdf0e10cSrcweir 								        break;
920cdf0e10cSrcweir 							        }
921cdf0e10cSrcweir 						        }
922cdf0e10cSrcweir 						        delete[] pData;
923cdf0e10cSrcweir 					        }
924cdf0e10cSrcweir                         }
925cdf0e10cSrcweir                     }
926cdf0e10cSrcweir                     else if ( (nNewMagic == static_cast< sal_uInt32 >(0x43464D57)) && (nLen >= 34) && ( (sal_Int32)(nLen + 10) <= (sal_Int32)(nRecSize * 2) ))
927cdf0e10cSrcweir                     {
928cdf0e10cSrcweir                         sal_uInt32 nComType, nVersion, nFlags, nComRecCount,
929cdf0e10cSrcweir                                    nCurRecSize, nRemainingSize, nEMFTotalSize;
930cdf0e10cSrcweir                         sal_uInt16 nCheck;
931cdf0e10cSrcweir 
932cdf0e10cSrcweir                         *pWMF >> nComType >> nVersion >> nCheck >> nFlags
933cdf0e10cSrcweir                               >> nComRecCount >> nCurRecSize
934cdf0e10cSrcweir                               >> nRemainingSize >> nEMFTotalSize; // the nRemainingSize is not mentioned in MSDN documentation
935cdf0e10cSrcweir                                                                   // but it seems to be required to read in data produced by OLE
936cdf0e10cSrcweir 
937cdf0e10cSrcweir                         if( nComType == 0x01 && nVersion == 0x10000 && nComRecCount )
938cdf0e10cSrcweir                         {
939cdf0e10cSrcweir                             if( !nEMFRec )
940cdf0e10cSrcweir                             {   // first EMF comment
941cdf0e10cSrcweir                                 nEMFRecCount    = nComRecCount;
942cdf0e10cSrcweir                                 nEMFSize        = nEMFTotalSize;
943cdf0e10cSrcweir                                 pEMFStream = new SvMemoryStream( nEMFSize );
944cdf0e10cSrcweir                             }
945cdf0e10cSrcweir                             else if( ( nEMFRecCount != nComRecCount ) || ( nEMFSize != nEMFTotalSize ) ) // add additional checks here
946cdf0e10cSrcweir                             {
947cdf0e10cSrcweir                                 // total records should be the same as in previous comments
948cdf0e10cSrcweir                                 nEMFRecCount = 0xFFFFFFFF;
949cdf0e10cSrcweir                                 delete pEMFStream;
950cdf0e10cSrcweir                                 pEMFStream = NULL;
951cdf0e10cSrcweir                             }
952cdf0e10cSrcweir                             nEMFRec++;
953cdf0e10cSrcweir 
954cdf0e10cSrcweir                             if( pEMFStream && nCurRecSize + 34 > nLen )
955cdf0e10cSrcweir                             {
956cdf0e10cSrcweir                                 nEMFRecCount = 0xFFFFFFFF;
957cdf0e10cSrcweir                                 delete pEMFStream;
958cdf0e10cSrcweir                                 pEMFStream = NULL;
959cdf0e10cSrcweir                             }
960cdf0e10cSrcweir 
961cdf0e10cSrcweir                             if( pEMFStream )
962cdf0e10cSrcweir                             {
963cdf0e10cSrcweir                                 sal_Int8* pBuf = new sal_Int8[ nCurRecSize ];
964cdf0e10cSrcweir                                 sal_uInt32 nCount = pWMF->Read( pBuf, nCurRecSize );
965cdf0e10cSrcweir                                 if( nCount == nCurRecSize )
966cdf0e10cSrcweir                                     pEMFStream->Write( pBuf, nCount );
967cdf0e10cSrcweir                                 delete[] pBuf;
968cdf0e10cSrcweir                             }
969cdf0e10cSrcweir                         }
970cdf0e10cSrcweir                     }
971cdf0e10cSrcweir 				}
972cdf0e10cSrcweir 			}
973cdf0e10cSrcweir 		}
974cdf0e10cSrcweir 		break;
975cdf0e10cSrcweir 
976cdf0e10cSrcweir 		case W_META_SETRELABS:
977cdf0e10cSrcweir 		case W_META_SETPOLYFILLMODE:
978cdf0e10cSrcweir 		case W_META_SETSTRETCHBLTMODE:
979cdf0e10cSrcweir 		case W_META_SETTEXTCHAREXTRA:
980cdf0e10cSrcweir 		case W_META_SETTEXTJUSTIFICATION:
981cdf0e10cSrcweir 		case W_META_FLOODFILL :
982cdf0e10cSrcweir 		case W_META_FILLREGION:
983cdf0e10cSrcweir 		case W_META_FRAMEREGION:
984cdf0e10cSrcweir 		case W_META_INVERTREGION:
985cdf0e10cSrcweir 		case W_META_PAINTREGION:
986cdf0e10cSrcweir 		case W_META_DRAWTEXT:
987cdf0e10cSrcweir 		case W_META_SETMAPPERFLAGS:
988cdf0e10cSrcweir 		case W_META_SETDIBTODEV:
989cdf0e10cSrcweir 		case W_META_SELECTPALETTE:
990cdf0e10cSrcweir 		case W_META_REALIZEPALETTE:
991cdf0e10cSrcweir 		case W_META_ANIMATEPALETTE:
992cdf0e10cSrcweir 		case W_META_SETPALENTRIES:
993cdf0e10cSrcweir 		case W_META_RESIZEPALETTE:
994cdf0e10cSrcweir 		case W_META_EXTFLOODFILL:
995cdf0e10cSrcweir 		case W_META_RESETDC:
996cdf0e10cSrcweir 		case W_META_STARTDOC:
997cdf0e10cSrcweir 		case W_META_STARTPAGE:
998cdf0e10cSrcweir 		case W_META_ENDPAGE:
999cdf0e10cSrcweir 		case W_META_ABORTDOC:
1000cdf0e10cSrcweir 		case W_META_ENDDOC:
1001cdf0e10cSrcweir 		break;
1002cdf0e10cSrcweir 	}
1003cdf0e10cSrcweir }
1004cdf0e10cSrcweir 
1005cdf0e10cSrcweir // ------------------------------------------------------------------------
1006cdf0e10cSrcweir 
ReadHeader()1007cdf0e10cSrcweir sal_Bool WMFReader::ReadHeader()
1008cdf0e10cSrcweir {
1009cdf0e10cSrcweir 	Rectangle	aPlaceableBound;
1010cdf0e10cSrcweir 	sal_uInt32  nl, nStrmPos = pWMF->Tell();
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir 	// Einlesen des METAFILEHEADER, falls vorhanden
1013cdf0e10cSrcweir 	*pWMF >> nl;
1014cdf0e10cSrcweir 
1015cdf0e10cSrcweir     Size aWMFSize;
1016cdf0e10cSrcweir 	if ( nl == 0x9ac6cdd7L )
1017cdf0e10cSrcweir 	{
1018cdf0e10cSrcweir 		sal_Int16 nVal;
1019cdf0e10cSrcweir 
1020cdf0e10cSrcweir 		// hmf (Unused) ueberlesen wir
1021cdf0e10cSrcweir 		pWMF->SeekRel(2);
1022cdf0e10cSrcweir 
1023cdf0e10cSrcweir 		// BoundRect
1024cdf0e10cSrcweir 		*pWMF >> nVal; aPlaceableBound.Left() = nVal;
1025cdf0e10cSrcweir 		*pWMF >> nVal; aPlaceableBound.Top() = nVal;
1026cdf0e10cSrcweir 		*pWMF >> nVal; aPlaceableBound.Right() = nVal;
1027cdf0e10cSrcweir 		*pWMF >> nVal; aPlaceableBound.Bottom() = nVal;
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir 		// inch
1030cdf0e10cSrcweir 		*pWMF >> nUnitsPerInch;
1031cdf0e10cSrcweir 
1032cdf0e10cSrcweir 		// reserved
1033cdf0e10cSrcweir 		pWMF->SeekRel( 4 );
1034cdf0e10cSrcweir 
1035cdf0e10cSrcweir 		// checksum  pruefen wir lieber nicht
1036cdf0e10cSrcweir 		pWMF->SeekRel( 2 );
1037cdf0e10cSrcweir     }
1038cdf0e10cSrcweir 	else
1039cdf0e10cSrcweir 	{
1040cdf0e10cSrcweir 		nUnitsPerInch = 96;
1041cdf0e10cSrcweir         pWMF->Seek( nStrmPos + 18 );    // set the streampos to the start of the the metaactions
1042cdf0e10cSrcweir         GetPlaceableBound( aPlaceableBound, pWMF );
1043cdf0e10cSrcweir         pWMF->Seek( nStrmPos );
1044cdf0e10cSrcweir 	}
1045cdf0e10cSrcweir 
1046cdf0e10cSrcweir     pOut->SetWinOrg( aPlaceableBound.TopLeft() );
1047cdf0e10cSrcweir     aWMFSize = Size( labs( aPlaceableBound.GetWidth() ), labs( aPlaceableBound.GetHeight() ) );
1048cdf0e10cSrcweir 	pOut->SetWinExt( aWMFSize );
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir 	Size aDevExt( 10000, 10000 );
1051cdf0e10cSrcweir 	if( ( labs( aWMFSize.Width() ) > 1 ) && ( labs( aWMFSize.Height() ) > 1 ) )
1052cdf0e10cSrcweir 	{
1053cdf0e10cSrcweir 		const Fraction	aFrac( 1, nUnitsPerInch );
1054cdf0e10cSrcweir 		MapMode			aWMFMap( MAP_INCH, Point(), aFrac, aFrac );
1055cdf0e10cSrcweir 		Size			aSize100( OutputDevice::LogicToLogic( aWMFSize, aWMFMap, MAP_100TH_MM ) );
1056cdf0e10cSrcweir 		aDevExt = Size( labs( aSize100.Width() ), labs( aSize100.Height() ) );
1057cdf0e10cSrcweir     }
1058cdf0e10cSrcweir 	pOut->SetDevExt( aDevExt );
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir 	// Einlesen des METAHEADER
1061cdf0e10cSrcweir 	*pWMF >> nl; // Typ und Headergroesse
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir 	if( nl != 0x00090001 )
1064cdf0e10cSrcweir 	{
1065cdf0e10cSrcweir 		pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
1066cdf0e10cSrcweir 		return sal_False;
1067cdf0e10cSrcweir 	}
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir 	pWMF->SeekRel( 2 ); // Version (von Windows)
1070cdf0e10cSrcweir 	pWMF->SeekRel( 4 ); // Size (der Datei in Words)
1071cdf0e10cSrcweir 	pWMF->SeekRel( 2 ); // NoObjects (Maximale Anzahl der gleichzeitigen Objekte)
1072cdf0e10cSrcweir 	pWMF->SeekRel( 4 ); // MaxRecord (Groesse des groessten Records in Words)
1073cdf0e10cSrcweir 	pWMF->SeekRel( 2 ); // NoParameters (Unused
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir 	return sal_True;
1076cdf0e10cSrcweir }
1077cdf0e10cSrcweir 
ReadWMF()1078cdf0e10cSrcweir void WMFReader::ReadWMF()
1079cdf0e10cSrcweir {
1080cdf0e10cSrcweir 	sal_uInt16	nFunction;
1081cdf0e10cSrcweir 	sal_uLong	nPos, nPercent, nLastPercent;
1082cdf0e10cSrcweir 
1083cdf0e10cSrcweir 	nSkipActions = 0;
1084cdf0e10cSrcweir 	nCurrentAction = 0;
1085cdf0e10cSrcweir 	nUnicodeEscapeAction = 0;
1086cdf0e10cSrcweir 
1087cdf0e10cSrcweir     pEMFStream      = NULL;
1088cdf0e10cSrcweir     nEMFRecCount    = 0;
1089cdf0e10cSrcweir     nEMFRec         = 0;
1090cdf0e10cSrcweir     nEMFSize        = 0;
1091cdf0e10cSrcweir 
1092cdf0e10cSrcweir 	sal_Bool bEMFAvailable = sal_False;
1093cdf0e10cSrcweir 
1094cdf0e10cSrcweir 	pOut->SetMapMode( MM_ANISOTROPIC );
1095cdf0e10cSrcweir 	pOut->SetWinOrg( Point() );
1096cdf0e10cSrcweir 	pOut->SetWinExt( Size( 1, 1 ) );
1097cdf0e10cSrcweir 	pOut->SetDevExt( Size( 10000, 10000 ) );
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir 	nEndPos=pWMF->Seek( STREAM_SEEK_TO_END );
1100cdf0e10cSrcweir 	pWMF->Seek( nStartPos );
1101cdf0e10cSrcweir 	Callback( (sal_uInt16) ( nLastPercent = 0 ) );
1102cdf0e10cSrcweir 
1103cdf0e10cSrcweir 	if ( ReadHeader() )
1104cdf0e10cSrcweir 	{
1105cdf0e10cSrcweir 
1106cdf0e10cSrcweir 		nPos = pWMF->Tell();
1107cdf0e10cSrcweir 
1108cdf0e10cSrcweir 		if( nEndPos - nStartPos )
1109cdf0e10cSrcweir 		{
1110cdf0e10cSrcweir 			while( sal_True )
1111cdf0e10cSrcweir 			{
1112cdf0e10cSrcweir 				nCurrentAction++;
1113cdf0e10cSrcweir 				nPercent = ( nPos - nStartPos ) * 100 / ( nEndPos - nStartPos );
1114cdf0e10cSrcweir 
1115cdf0e10cSrcweir 				if( nLastPercent + 4 <= nPercent )
1116cdf0e10cSrcweir 				{
1117cdf0e10cSrcweir 					Callback( (sal_uInt16) nPercent );
1118cdf0e10cSrcweir 					nLastPercent = nPercent;
1119cdf0e10cSrcweir 				}
1120cdf0e10cSrcweir 				*pWMF >> nRecSize >> nFunction;
1121cdf0e10cSrcweir 
1122cdf0e10cSrcweir 				if( pWMF->GetError() || ( nRecSize < 3 ) || ( nRecSize==3 && nFunction==0 ) || pWMF->IsEof() )
1123cdf0e10cSrcweir 				{
1124cdf0e10cSrcweir 
1125cdf0e10cSrcweir 					if( pWMF->IsEof() )
1126cdf0e10cSrcweir 						pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir 					break;
1129cdf0e10cSrcweir 				}
1130cdf0e10cSrcweir 				if ( !bEMFAvailable )
1131cdf0e10cSrcweir 				{
1132cdf0e10cSrcweir 					if( aBmpSaveList.Count() &&
1133cdf0e10cSrcweir 						( nFunction != W_META_STRETCHDIB ) &&
1134cdf0e10cSrcweir 						( nFunction != W_META_DIBBITBLT ) &&
1135cdf0e10cSrcweir 						( nFunction != W_META_DIBSTRETCHBLT ) )
1136cdf0e10cSrcweir 					{
1137cdf0e10cSrcweir 						pOut->ResolveBitmapActions( aBmpSaveList );
1138cdf0e10cSrcweir 					}
1139cdf0e10cSrcweir 					if ( !nSkipActions )
1140cdf0e10cSrcweir 						ReadRecordParams( nFunction );
1141cdf0e10cSrcweir 					else
1142cdf0e10cSrcweir 						nSkipActions--;
1143cdf0e10cSrcweir 
1144cdf0e10cSrcweir 					if( pEMFStream && nEMFRecCount == nEMFRec )
1145cdf0e10cSrcweir 					{
1146cdf0e10cSrcweir 						GDIMetaFile aMeta;
1147cdf0e10cSrcweir 						pEMFStream->Seek( 0 );
1148cdf0e10cSrcweir 						EnhWMFReader* pEMFReader = new EnhWMFReader ( *pEMFStream, aMeta );
1149cdf0e10cSrcweir 						bEMFAvailable = pEMFReader->ReadEnhWMF();
1150cdf0e10cSrcweir 						delete pEMFReader; // destroy first!!!
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir 						if( bEMFAvailable )
1153cdf0e10cSrcweir 						{
1154cdf0e10cSrcweir 							pOut->AddFromGDIMetaFile( aMeta );
1155cdf0e10cSrcweir 							pOut->SetrclFrame( Rectangle(0, 0, aMeta.GetPrefSize().Width(), aMeta.GetPrefSize().Height() ));
1156cdf0e10cSrcweir 
1157cdf0e10cSrcweir 							// the stream needs to be set to the wmf end position,
1158cdf0e10cSrcweir 							// otherwise the GfxLink that is created will be incorrect
1159cdf0e10cSrcweir 							// (leading to graphic loss after swapout/swapin).
1160cdf0e10cSrcweir 							// so we will proceed normally, but are ignoring further wmf
1161cdf0e10cSrcweir 							// records
1162cdf0e10cSrcweir 						}
1163cdf0e10cSrcweir 						else
1164cdf0e10cSrcweir 						{
1165cdf0e10cSrcweir 							// something went wrong
1166cdf0e10cSrcweir 							// continue with WMF, don't try this again
1167cdf0e10cSrcweir 							delete pEMFStream;
1168cdf0e10cSrcweir 							pEMFStream = NULL;
1169cdf0e10cSrcweir 						}
1170cdf0e10cSrcweir 					}
1171cdf0e10cSrcweir 				}
1172cdf0e10cSrcweir                 nPos += nRecSize * 2;
1173cdf0e10cSrcweir                 if ( nPos <= nEndPos )
1174cdf0e10cSrcweir                     pWMF->Seek( nPos  );
1175cdf0e10cSrcweir                 else
1176cdf0e10cSrcweir                     pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
1177cdf0e10cSrcweir 			}
1178cdf0e10cSrcweir 		}
1179cdf0e10cSrcweir 		else
1180cdf0e10cSrcweir 			pWMF->SetError( SVSTREAM_GENERALERROR );
1181cdf0e10cSrcweir 
1182cdf0e10cSrcweir 		if( !pWMF->GetError() && aBmpSaveList.Count() )
1183cdf0e10cSrcweir 			pOut->ResolveBitmapActions( aBmpSaveList );
1184cdf0e10cSrcweir 	}
1185cdf0e10cSrcweir 	if ( pWMF->GetError() )
1186cdf0e10cSrcweir 		pWMF->Seek( nStartPos );
1187cdf0e10cSrcweir }
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir // ------------------------------------------------------------------------
1190cdf0e10cSrcweir 
GetWinExtMax(const Point & rSource,Rectangle & rPlaceableBound,const sal_Int16 nMapMode)1191cdf0e10cSrcweir static void GetWinExtMax( const Point& rSource, Rectangle& rPlaceableBound, const sal_Int16 nMapMode )
1192cdf0e10cSrcweir {
1193cdf0e10cSrcweir 	Point aSource( rSource );
1194cdf0e10cSrcweir 	if ( nMapMode == MM_HIMETRIC )
1195cdf0e10cSrcweir 		aSource.Y() = -rSource.Y();
1196cdf0e10cSrcweir     if ( aSource.X() < rPlaceableBound.Left() )
1197cdf0e10cSrcweir         rPlaceableBound.Left() = aSource.X();
1198cdf0e10cSrcweir     if ( aSource.X() > rPlaceableBound.Right() )
1199cdf0e10cSrcweir         rPlaceableBound.Right() = aSource.X();
1200cdf0e10cSrcweir     if ( aSource.Y() < rPlaceableBound.Top() )
1201cdf0e10cSrcweir         rPlaceableBound.Top() = aSource.Y();
1202cdf0e10cSrcweir     if ( aSource.Y() > rPlaceableBound.Bottom() )
1203cdf0e10cSrcweir         rPlaceableBound.Bottom() = aSource.Y();
1204cdf0e10cSrcweir }
1205cdf0e10cSrcweir 
GetWinExtMax(const Rectangle & rSource,Rectangle & rPlaceableBound,const sal_Int16 nMapMode)1206cdf0e10cSrcweir static void GetWinExtMax( const Rectangle& rSource, Rectangle& rPlaceableBound, const sal_Int16 nMapMode )
1207cdf0e10cSrcweir {
1208cdf0e10cSrcweir     GetWinExtMax( rSource.TopLeft(), rPlaceableBound, nMapMode );
1209cdf0e10cSrcweir     GetWinExtMax( rSource.BottomRight(), rPlaceableBound, nMapMode );
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir 
GetPlaceableBound(Rectangle & rPlaceableBound,SvStream * pStm)1212cdf0e10cSrcweir sal_Bool WMFReader::GetPlaceableBound( Rectangle& rPlaceableBound, SvStream* pStm )
1213cdf0e10cSrcweir {
1214cdf0e10cSrcweir     sal_Bool bRet = sal_True;
1215cdf0e10cSrcweir 
1216cdf0e10cSrcweir     rPlaceableBound.Left()   = (sal_Int32)0x7fffffff;
1217cdf0e10cSrcweir     rPlaceableBound.Top()    = (sal_Int32)0x7fffffff;
1218cdf0e10cSrcweir     rPlaceableBound.Right()  = (sal_Int32)0x80000000;
1219cdf0e10cSrcweir     rPlaceableBound.Bottom() = (sal_Int32)0x80000000;
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir 	sal_Int16 nMapMode = MM_ANISOTROPIC;
1222cdf0e10cSrcweir 
1223cdf0e10cSrcweir     sal_uInt16 nFunction;
1224cdf0e10cSrcweir     sal_uInt32 nRSize;
1225cdf0e10cSrcweir 	sal_uInt32 nPos = pStm->Tell();
1226cdf0e10cSrcweir 	sal_uInt32 nEnd = pStm->Seek( STREAM_SEEK_TO_END );
1227cdf0e10cSrcweir 
1228cdf0e10cSrcweir     pStm->Seek( nPos );
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir     if( nEnd - nPos )
1231cdf0e10cSrcweir 	{
1232cdf0e10cSrcweir 		while( bRet )
1233cdf0e10cSrcweir 		{
1234cdf0e10cSrcweir 			*pStm >> nRSize >> nFunction;
1235cdf0e10cSrcweir 
1236cdf0e10cSrcweir 			if( pStm->GetError() || ( nRSize < 3 ) || ( nRSize==3 && nFunction==0 ) || pStm->IsEof() )
1237cdf0e10cSrcweir 			{
1238cdf0e10cSrcweir 				if( pStm->IsEof() )
1239cdf0e10cSrcweir                 {
1240cdf0e10cSrcweir 					pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
1241cdf0e10cSrcweir                     bRet = sal_False;
1242cdf0e10cSrcweir                 }
1243cdf0e10cSrcweir 				break;
1244cdf0e10cSrcweir 			}
1245cdf0e10cSrcweir 	        switch( nFunction )
1246cdf0e10cSrcweir 	        {
1247cdf0e10cSrcweir 				case W_META_SETWINDOWORG:
1248cdf0e10cSrcweir 				{
1249cdf0e10cSrcweir 					Point aWinOrg;
1250cdf0e10cSrcweir 					aWinOrg = ReadYX();
1251cdf0e10cSrcweir 					rPlaceableBound.SetPos( aWinOrg );
1252cdf0e10cSrcweir 				}
1253cdf0e10cSrcweir 				break;
1254cdf0e10cSrcweir 
1255cdf0e10cSrcweir 				case W_META_SETWINDOWEXT:
1256cdf0e10cSrcweir 				{
1257cdf0e10cSrcweir 					Point aPos0( 0, 0 );
1258cdf0e10cSrcweir 					sal_Int16 nWidth, nHeight;
1259cdf0e10cSrcweir 					*pStm >> nHeight >> nWidth;
1260cdf0e10cSrcweir 					rPlaceableBound.SetSize( Size( nWidth, nHeight ) );
1261cdf0e10cSrcweir 				}
1262cdf0e10cSrcweir 				break;
1263cdf0e10cSrcweir 
1264cdf0e10cSrcweir 				case W_META_SETMAPMODE :
1265cdf0e10cSrcweir 					*pStm >> nMapMode;
1266cdf0e10cSrcweir 				break;
1267cdf0e10cSrcweir 
1268cdf0e10cSrcweir 				case W_META_MOVETO:
1269cdf0e10cSrcweir 		        case W_META_LINETO:
1270cdf0e10cSrcweir 			        GetWinExtMax( ReadYX(), rPlaceableBound, nMapMode );
1271cdf0e10cSrcweir 		        break;
1272cdf0e10cSrcweir 
1273cdf0e10cSrcweir 		        case W_META_RECTANGLE:
1274cdf0e10cSrcweir 		        case W_META_INTERSECTCLIPRECT:
1275cdf0e10cSrcweir 		        case W_META_EXCLUDECLIPRECT :
1276cdf0e10cSrcweir 		        case W_META_ELLIPSE:
1277cdf0e10cSrcweir                     GetWinExtMax( ReadRectangle(), rPlaceableBound, nMapMode );
1278cdf0e10cSrcweir 		        break;
1279cdf0e10cSrcweir 
1280cdf0e10cSrcweir 		        case W_META_ROUNDRECT:
1281cdf0e10cSrcweir 		        {
1282cdf0e10cSrcweir 			        Size aSize( ReadYXExt() );
1283cdf0e10cSrcweir                     GetWinExtMax( ReadRectangle(), rPlaceableBound, nMapMode );
1284cdf0e10cSrcweir 		        }
1285cdf0e10cSrcweir 		        break;
1286cdf0e10cSrcweir 
1287cdf0e10cSrcweir 		        case W_META_ARC:
1288cdf0e10cSrcweir 		        case W_META_PIE:
1289cdf0e10cSrcweir 		        case W_META_CHORD:
1290cdf0e10cSrcweir 		        {
1291cdf0e10cSrcweir 			        Point aEnd( ReadYX() );
1292cdf0e10cSrcweir 			        Point aStart( ReadYX() );
1293cdf0e10cSrcweir                     GetWinExtMax( ReadRectangle(), rPlaceableBound, nMapMode );
1294cdf0e10cSrcweir 		        }
1295cdf0e10cSrcweir 		        break;
1296cdf0e10cSrcweir 
1297cdf0e10cSrcweir 		        case W_META_POLYGON:
1298cdf0e10cSrcweir 		        {
1299cdf0e10cSrcweir 			        sal_uInt16 i,nPoints;
1300cdf0e10cSrcweir 			        *pStm >> nPoints;
1301cdf0e10cSrcweir 			        for( i = 0; i < nPoints; i++ )
1302cdf0e10cSrcweir 				        GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode );
1303cdf0e10cSrcweir 		        }
1304cdf0e10cSrcweir 		        break;
1305cdf0e10cSrcweir 
1306cdf0e10cSrcweir 		        case W_META_POLYPOLYGON:
1307cdf0e10cSrcweir 		        {
1308cdf0e10cSrcweir 			        sal_uInt16	i, nPoly, nPoints = 0;
1309cdf0e10cSrcweir 			        *pStm >> nPoly;
1310cdf0e10cSrcweir 			        for( i = 0; i < nPoly; i++ )
1311cdf0e10cSrcweir 			        {
1312cdf0e10cSrcweir                         sal_uInt16 nP;
1313cdf0e10cSrcweir 				        *pStm >> nP;
1314cdf0e10cSrcweir 				        nPoints = nPoints + nP;
1315cdf0e10cSrcweir 			        }
1316cdf0e10cSrcweir 			        for ( i = 0; i < nPoints; i++ )
1317cdf0e10cSrcweir 				        GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode );
1318cdf0e10cSrcweir 		        }
1319cdf0e10cSrcweir 		        break;
1320cdf0e10cSrcweir 
1321cdf0e10cSrcweir 		        case W_META_POLYLINE:
1322cdf0e10cSrcweir 		        {
1323cdf0e10cSrcweir 			        sal_uInt16 i,nPoints;
1324cdf0e10cSrcweir 			        *pStm >> nPoints;
1325cdf0e10cSrcweir 			        for( i = 0; i < nPoints; i++ )
1326cdf0e10cSrcweir 				        GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode );
1327cdf0e10cSrcweir 		        }
1328cdf0e10cSrcweir 		        break;
1329cdf0e10cSrcweir 
1330cdf0e10cSrcweir 		        case W_META_SETPIXEL:
1331cdf0e10cSrcweir 		        {
1332cdf0e10cSrcweir 			        const Color aColor = ReadColor();
1333cdf0e10cSrcweir 			        GetWinExtMax( ReadYX(), rPlaceableBound, nMapMode );
1334cdf0e10cSrcweir 		        }
1335cdf0e10cSrcweir 		        break;
1336cdf0e10cSrcweir 
1337cdf0e10cSrcweir 		        case W_META_TEXTOUT:
1338cdf0e10cSrcweir 		        {
1339cdf0e10cSrcweir 			        sal_uInt16 nLength;
1340cdf0e10cSrcweir 			        *pStm >> nLength;
1341cdf0e10cSrcweir 					// todo: we also have to take care of the text width
1342cdf0e10cSrcweir 			        if ( nLength )
1343cdf0e10cSrcweir 					{
1344cdf0e10cSrcweir 						pStm->SeekRel( ( nLength + 1 ) &~ 1 );
1345cdf0e10cSrcweir 			            GetWinExtMax( ReadYX(), rPlaceableBound, nMapMode );
1346cdf0e10cSrcweir 					}
1347cdf0e10cSrcweir 		        }
1348cdf0e10cSrcweir 		        break;
1349cdf0e10cSrcweir 
1350cdf0e10cSrcweir 		        case W_META_EXTTEXTOUT:
1351cdf0e10cSrcweir 		        {
1352cdf0e10cSrcweir 			        sal_uInt16	nLen, nOptions;
1353cdf0e10cSrcweir 			        sal_Int32	nRecordPos, nRecordSize;
1354cdf0e10cSrcweir 			        Point		aPosition;
1355cdf0e10cSrcweir 			        Rectangle	aRect;
1356cdf0e10cSrcweir 
1357cdf0e10cSrcweir 			        pStm->SeekRel(-6);
1358cdf0e10cSrcweir 			        nRecordPos = pStm->Tell();
1359cdf0e10cSrcweir 			        *pStm >> nRecordSize;
1360cdf0e10cSrcweir 			        pStm->SeekRel(2);
1361cdf0e10cSrcweir 			        aPosition = ReadYX();
1362cdf0e10cSrcweir 					*pStm >> nLen >> nOptions;
1363cdf0e10cSrcweir 					// todo: we also have to take care of the text width
1364cdf0e10cSrcweir 					if( nLen )
1365cdf0e10cSrcweir 						GetWinExtMax( aPosition, rPlaceableBound, nMapMode );
1366cdf0e10cSrcweir 		        }
1367cdf0e10cSrcweir 		        break;
1368cdf0e10cSrcweir 		        case W_META_BITBLT:
1369cdf0e10cSrcweir 		        case W_META_STRETCHBLT:
1370cdf0e10cSrcweir 		        case W_META_DIBBITBLT:
1371cdf0e10cSrcweir 		        case W_META_DIBSTRETCHBLT:
1372cdf0e10cSrcweir 		        case W_META_STRETCHDIB:
1373cdf0e10cSrcweir 		        {
1374cdf0e10cSrcweir 			        sal_Int32   nWinROP;
1375cdf0e10cSrcweir 			        sal_uInt16  nSx, nSy, nSxe, nSye, nUsage;
1376cdf0e10cSrcweir 			        *pStm >> nWinROP;
1377cdf0e10cSrcweir 
1378cdf0e10cSrcweir 			        if( nFunction == W_META_STRETCHDIB )
1379cdf0e10cSrcweir 				        *pStm >> nUsage;
1380cdf0e10cSrcweir 
1381cdf0e10cSrcweir                     // nSye and nSxe is the number of pixels that has to been used
1382cdf0e10cSrcweir 			        if( nFunction == W_META_STRETCHDIB || nFunction == W_META_STRETCHBLT || nFunction == W_META_DIBSTRETCHBLT )
1383cdf0e10cSrcweir 				        *pStm >> nSye >> nSxe;
1384cdf0e10cSrcweir                     else
1385cdf0e10cSrcweir                         nSye = nSxe = 0;    // set this to zero as indicator not to scale the bitmap later
1386cdf0e10cSrcweir 
1387cdf0e10cSrcweir                     // nSy and nx is the offset of the first pixel
1388cdf0e10cSrcweir 			        *pStm >> nSy >> nSx;
1389cdf0e10cSrcweir 
1390cdf0e10cSrcweir 			        if( nFunction == W_META_STRETCHDIB || nFunction == W_META_DIBBITBLT || nFunction == W_META_DIBSTRETCHBLT )
1391cdf0e10cSrcweir 			        {
1392cdf0e10cSrcweir 				        if ( nWinROP == PATCOPY )
1393cdf0e10cSrcweir 					        *pStm >> nUsage;	// i don't know anything of this parameter, so its called nUsage
1394cdf0e10cSrcweir 										        // pOut->DrawRect( Rectangle( ReadYX(), aDestSize ), sal_False );
1395cdf0e10cSrcweir 
1396cdf0e10cSrcweir 				        Size aDestSize( ReadYXExt() );
1397cdf0e10cSrcweir                         if ( aDestSize.Width() && aDestSize.Height() )  // #92623# do not try to read buggy bitmaps
1398cdf0e10cSrcweir                         {
1399cdf0e10cSrcweir 				            Rectangle aDestRect( ReadYX(), aDestSize );
1400cdf0e10cSrcweir                             GetWinExtMax( aDestRect, rPlaceableBound, nMapMode );
1401cdf0e10cSrcweir                         }
1402cdf0e10cSrcweir 			        }
1403cdf0e10cSrcweir 		        }
1404cdf0e10cSrcweir 		        break;
1405cdf0e10cSrcweir 
1406cdf0e10cSrcweir 		        case W_META_PATBLT:
1407cdf0e10cSrcweir 		        {
1408cdf0e10cSrcweir 			        sal_uInt32 nROP;
1409cdf0e10cSrcweir 			        *pStm >> nROP;
1410cdf0e10cSrcweir 			        Size aSize = ReadYXExt();
1411cdf0e10cSrcweir                     GetWinExtMax( Rectangle( ReadYX(), aSize ), rPlaceableBound, nMapMode );
1412cdf0e10cSrcweir 		        }
1413cdf0e10cSrcweir 		        break;
1414cdf0e10cSrcweir             }
1415cdf0e10cSrcweir             nPos += nRSize * 2;
1416cdf0e10cSrcweir  			if ( nPos <= nEnd )
1417cdf0e10cSrcweir  				pStm->Seek( nPos );
1418cdf0e10cSrcweir  			else
1419cdf0e10cSrcweir  			{
1420cdf0e10cSrcweir  				pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
1421cdf0e10cSrcweir  				bRet = sal_False;
1422cdf0e10cSrcweir  			}
1423cdf0e10cSrcweir 
1424cdf0e10cSrcweir 		}
1425cdf0e10cSrcweir 	}
1426cdf0e10cSrcweir 	else
1427cdf0e10cSrcweir     {
1428cdf0e10cSrcweir 		pStm->SetError( SVSTREAM_GENERALERROR );
1429cdf0e10cSrcweir         bRet = sal_False;
1430cdf0e10cSrcweir     }
1431cdf0e10cSrcweir     return bRet;
1432cdf0e10cSrcweir }
1433cdf0e10cSrcweir 
~WMFReader()1434cdf0e10cSrcweir WMFReader::~WMFReader()
1435cdf0e10cSrcweir {
1436cdf0e10cSrcweir     if( pEMFStream )
1437cdf0e10cSrcweir         delete pEMFStream;
1438cdf0e10cSrcweir }
1439