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