update dev300-m58
[ooovba.git] / svtools / source / filter.vcl / wmf / enhwmf.cxx
blob0abce365f81ff7e06d426e50db700883f427c254
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: enhwmf.cxx,v $
10 * $Revision: 1.39 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #include "winmtf.hxx"
35 #include <osl/endian.h>
37 //=========================== GDI-Array ===================================
39 #define EMR_HEADER 1
40 #define EMR_POLYBEZIER 2
41 #define EMR_POLYGON 3
42 #define EMR_POLYLINE 4
43 #define EMR_POLYBEZIERTO 5
44 #define EMR_POLYLINETO 6
45 #define EMR_POLYPOLYLINE 7
46 #define EMR_POLYPOLYGON 8
47 #define EMR_SETWINDOWEXTEX 9
48 #define EMR_SETWINDOWORGEX 10
49 #define EMR_SETVIEWPORTEXTEX 11
50 #define EMR_SETVIEWPORTORGEX 12
51 #define EMR_SETBRUSHORGEX 13
52 #define EMR_EOF 14
53 #define EMR_SETPIXELV 15
54 #define EMR_SETMAPPERFLAGS 16
55 #define EMR_SETMAPMODE 17
56 #define EMR_SETBKMODE 18
57 #define EMR_SETPOLYFILLMODE 19
58 #define EMR_SETROP2 20
59 #define EMR_SETSTRETCHBLTMODE 21
60 #define EMR_SETTEXTALIGN 22
61 #define EMR_SETCOLORADJUSTMENT 23
62 #define EMR_SETTEXTCOLOR 24
63 #define EMR_SETBKCOLOR 25
64 #define EMR_OFFSETCLIPRGN 26
65 #define EMR_MOVETOEX 27
66 #define EMR_SETMETARGN 28
67 #define EMR_EXCLUDECLIPRECT 29
68 #define EMR_INTERSECTCLIPRECT 30
69 #define EMR_SCALEVIEWPORTEXTEX 31
70 #define EMR_SCALEWINDOWEXTEX 32
71 #define EMR_SAVEDC 33
72 #define EMR_RESTOREDC 34
73 #define EMR_SETWORLDTRANSFORM 35
74 #define EMR_MODIFYWORLDTRANSFORM 36
75 #define EMR_SELECTOBJECT 37
76 #define EMR_CREATEPEN 38
77 #define EMR_CREATEBRUSHINDIRECT 39
78 #define EMR_DELETEOBJECT 40
79 #define EMR_ANGLEARC 41
80 #define EMR_ELLIPSE 42
81 #define EMR_RECTANGLE 43
82 #define EMR_ROUNDRECT 44
83 #define EMR_ARC 45
84 #define EMR_CHORD 46
85 #define EMR_PIE 47
86 #define EMR_SELECTPALETTE 48
87 #define EMR_CREATEPALETTE 49
88 #define EMR_SETPALETTEENTRIES 50
89 #define EMR_RESIZEPALETTE 51
90 #define EMR_REALIZEPALETTE 52
91 #define EMR_EXTFLOODFILL 53
92 #define EMR_LINETO 54
93 #define EMR_ARCTO 55
94 #define EMR_POLYDRAW 56
95 #define EMR_SETARCDIRECTION 57
96 #define EMR_SETMITERLIMIT 58
97 #define EMR_BEGINPATH 59
98 #define EMR_ENDPATH 60
99 #define EMR_CLOSEFIGURE 61
100 #define EMR_FILLPATH 62
101 #define EMR_STROKEANDFILLPATH 63
102 #define EMR_STROKEPATH 64
103 #define EMR_FLATTENPATH 65
104 #define EMR_WIDENPATH 66
105 #define EMR_SELECTCLIPPATH 67
106 #define EMR_ABORTPATH 68
108 #define EMR_GDICOMMENT 70
109 #define EMR_FILLRGN 71
110 #define EMR_FRAMERGN 72
111 #define EMR_INVERTRGN 73
112 #define EMR_PAINTRGN 74
113 #define EMR_EXTSELECTCLIPRGN 75
114 #define EMR_BITBLT 76
115 #define EMR_STRETCHBLT 77
116 #define EMR_MASKBLT 78
117 #define EMR_PLGBLT 79
118 #define EMR_SETDIBITSTODEVICE 80
119 #define EMR_STRETCHDIBITS 81
120 #define EMR_EXTCREATEFONTINDIRECTW 82
121 #define EMR_EXTTEXTOUTA 83
122 #define EMR_EXTTEXTOUTW 84
123 #define EMR_POLYBEZIER16 85
124 #define EMR_POLYGON16 86
125 #define EMR_POLYLINE16 87
126 #define EMR_POLYBEZIERTO16 88
127 #define EMR_POLYLINETO16 89
128 #define EMR_POLYPOLYLINE16 90
129 #define EMR_POLYPOLYGON16 91
130 #define EMR_POLYDRAW16 92
131 #define EMR_CREATEMONOBRUSH 93
132 #define EMR_CREATEDIBPATTERNBRUSHPT 94
133 #define EMR_EXTCREATEPEN 95
134 #define EMR_POLYTEXTOUTA 96
135 #define EMR_POLYTEXTOUTW 97
137 // WINDOWS VERSION >= 0x400
138 #define EMR_SETICMMODE 98
139 #define EMR_CREATECOLORSPACE 99
140 #define EMR_SETCOLORSPACE 100
141 #define EMR_DELETECOLORSPACE 101
142 #define EMR_GLSRECORD 102
143 #define EMR_GLSBOUNDEDRECORD 103
144 #define EMR_PIXELFORMAT 104
146 // WINDOWS VERSION >= 0x500
147 #define EMR_DRAWESCAPE 105
148 #define EMR_EXTESCAPE 106
149 #define EMR_STARTDOC 107
150 #define EMR_SMALLTEXTOUT 108
151 #define EMR_FORCEUFIMAPPING 109
152 #define EMR_NAMEDESCAPE 110
153 #define EMR_COLORCORRECTPALETTE 111
154 #define EMR_SETICMPROFILEA 112
155 #define EMR_SETICMPROFILEW 113
156 #define EMR_ALPHABLEND 114
157 #define EMR_ALPHADIBBLEND 115
158 #define EMR_TRANSPARENTBLT 116
159 #define EMR_TRANSPARENTDIB 117
160 #define EMR_GRADIENTFILL 118
161 #define EMR_SETLINKEDUFIS 119
162 #define EMR_SETTEXTJUSTIFICATION 120
164 #define EMFP_DEBUG(x)
165 //#define EMFP_DEBUG(x) x
167 //-----------------------------------------------------------------------------------
169 #ifdef OSL_BIGENDIAN
170 // currently unused
171 static float GetSwapFloat( SvStream& rSt )
173 float fTmp;
174 sal_Int8* pPtr = (sal_Int8*)&fTmp;
175 rSt >> pPtr[3] >> pPtr[2] >> pPtr[1] >> pPtr[0]; // Little Endian <-> Big Endian switch
176 return fTmp;
178 #endif
180 SvStream& operator>>( SvStream& rIn, XForm& rXForm )
182 if ( sizeof( float ) != 4 )
184 DBG_ERROR( "EnhWMFReader::sizeof( float ) != 4" );
185 rXForm = XForm();
187 else
189 #ifdef OSL_BIGENDIAN
190 rXForm.eM11 = GetSwapFloat( rIn );
191 rXForm.eM12 = GetSwapFloat( rIn );
192 rXForm.eM21 = GetSwapFloat( rIn );
193 rXForm.eM22 = GetSwapFloat( rIn );
194 rXForm.eDx = GetSwapFloat( rIn );
195 rXForm.eDy = GetSwapFloat( rIn );
196 #else
197 rIn >> rXForm.eM11 >> rXForm.eM12 >> rXForm.eM21 >> rXForm.eM22
198 >> rXForm.eDx >> rXForm.eDy;
199 #endif
201 return rIn;
204 static sal_Bool ImplReadRegion( PolyPolygon& rPolyPoly, SvStream& rSt, sal_uInt32 nLen )
206 sal_Bool bOk = sal_False;
207 if ( nLen )
209 sal_uInt32 nHdSize, nType, nCount, nRgnSize, i;
210 rSt >> nHdSize
211 >> nType
212 >> nCount
213 >> nRgnSize;
215 if ( nCount && ( nType == RDH_RECTANGLES ) &&
216 ( nLen >= ( ( nCount << 4 ) + ( nHdSize - 16 ) ) ) )
218 sal_Int32 nx1, ny1, nx2, ny2;
220 for ( i = 0; i < nCount; i++ )
222 rSt >> nx1 >> ny1 >> nx2 >> ny2;
224 Rectangle aRect( Point( nx1, ny1 ), Point( nx2, ny2 ) );
225 Polygon aPolygon( aRect );
226 PolyPolygon aPolyPolyOr1( aPolygon );
227 PolyPolygon aPolyPolyOr2( rPolyPoly );
228 rPolyPoly.GetUnion( aPolyPolyOr1, aPolyPolyOr2 );
229 rPolyPoly = aPolyPolyOr2;
231 bOk = sal_True;
234 return bOk;
237 EMFP_DEBUG(void dumpWords( SvStream& s, int i )
239 sal_uInt32 pos = s.Tell();
240 INT16 data;
241 for( ; i > 0; i -- ) {
242 s >> data;
243 EMFP_DEBUG(printf ("\t\t\tdata: %04hx\n", data));
245 s.Seek (pos);
248 void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, sal_Bool& bHaveDC)
250 if (!bEMFPlus) {
251 pOut->PassEMFPlusHeaderInfo();
253 // debug code - write the stream to debug file /tmp/emf-stream.emf
254 EMFP_DEBUG(int pos = pWMF->Tell();
255 pWMF->Seek(0);
256 SvFileStream file( UniString::CreateFromAscii( "/tmp/emf-stream.emf" ), STREAM_WRITE | STREAM_TRUNC );
258 *pWMF >> file;
259 file.Flush();
260 file.Close();
262 pWMF->Seek( pos );)
264 bEMFPlus = true;
266 void *buffer = malloc( length );
268 int count = 0, next, pos = pWMF->Tell();
269 pOut->PassEMFPlus( buffer, pWMF->Read( buffer, length ) );
270 pWMF->Seek( pos );
272 bHaveDC = false;
274 length -= 4;
276 while (length > 0) {
277 UINT16 type, flags;
278 UINT32 size, dataSize;
279 sal_uInt32 next;
281 *pWMF >> type >> flags >> size >> dataSize;
283 EMFP_DEBUG(printf ("\t\tEMF+ record type: %d\n", type));
285 // GetDC
286 if( type == 16388 ) {
287 bHaveDC = true;
288 EMFP_DEBUG(printf ("\t\tEMF+ lock DC (device context)\n", type));
291 next = pWMF->Tell() + ( size - 12 );
293 length -= size;
295 pWMF->Seek( next );
298 free( buffer );
301 void EnhWMFReader::ReadGDIComment()
303 sal_uInt32 type;
305 *pWMF >> type;
307 switch( type ) {
308 case 2: {
309 sal_Int32 x, y, r, b;
311 EMFP_DEBUG(printf ("\t\tBEGINGROUP\n"));
313 *pWMF >> x >> y >> r >> b;
314 EMFP_DEBUG(printf ("\t\tbounding rectangle: %d,%d x %d,%d\n", x, y, r, b));
316 sal_uInt32 l;
318 *pWMF >> l;
319 EMFP_DEBUG(printf ("\t\tdescription length: %d\n", l));
321 break;
323 case 3: {
324 sal_uInt32 x, y, w, h;
326 EMFP_DEBUG(printf ("\t\tENDGROUP\n"));
327 break;
329 case 0x40000004: {
330 sal_uInt32 x, y, w, h;
332 EMFP_DEBUG(printf ("\t\tMULTIFORMATS\n"));
333 break;
335 default:
336 EMFP_DEBUG(printf ("\t\tunknown GDIComment\n"));
337 EMFP_DEBUG(dumpWords (*pWMF, 16));
341 BOOL EnhWMFReader::ReadEnhWMF()
343 sal_uInt32 nStretchBltMode = 0;
344 sal_uInt32 nRecType, nRecSize, nNextPos,
345 nW, nH, nPoints, nColor, nIndex,
346 nDat32, nNom1, nDen1, nNom2, nDen2;
347 sal_Int32 nX32, nY32, nx32, ny32;
348 sal_Int16 nX16, nY16;
350 sal_Bool bFlag, bStatus = ReadHeader();
351 sal_Bool bHaveDC = false;
353 #ifdef UNX
354 static sal_Bool bEnableEMFPlus = ( getenv( "EMF_PLUS_DISABLE" ) == NULL );
355 #else
356 // TODO: make it possible to disable emf+ on windows
357 static sal_Bool bEnableEMFPlus = sal_True;
358 #endif
360 while( bStatus && nRecordCount-- )
362 *pWMF >> nRecType >> nRecSize;
364 if ( ( nRecSize < 8 ) || ( nRecSize & 3 ) ) // Parameter sind immer durch 4 teilbar
366 bStatus = FALSE;
367 break;
370 nNextPos = pWMF->Tell() + ( nRecSize - 8 );
372 if ( nNextPos > nEndPos )
374 bStatus = FALSE;
375 break;
378 if( aBmpSaveList.Count() && ( nRecType != EMR_STRETCHBLT ) && ( nRecType != EMR_STRETCHDIBITS ) )
379 pOut->ResolveBitmapActions( aBmpSaveList );
381 bFlag = sal_False;
383 EMFP_DEBUG(printf ("0x%04x-0x%04x record type: %d size: %d\n", nNextPos - nRecSize, nNextPos, nRecType, nRecSize));
385 if( bEnableEMFPlus && nRecType == EMR_GDICOMMENT ) {
386 sal_uInt32 length;
388 *pWMF >> length;
390 EMFP_DEBUG(printf ("\tGDI comment\n\t\tlength: %d\n", length));
392 if( length >= 4 ) {
393 UINT32 id;
395 *pWMF >> id;
397 EMFP_DEBUG(printf ("\t\tbegin %c%c%c%c id: 0x%x\n", (char)(id & 0xff), (char)((id & 0xff00) >> 8), (char)((id & 0xff0000) >> 16), (char)((id & 0xff000000) >> 24), id));
399 // EMF+ comment (fixme: BE?)
400 if( id == 0x2B464D45 && nRecSize >= 12 )
401 ReadEMFPlusComment( length, bHaveDC );
402 // GDIC comment, doesn't do anything useful yet => enabled only for debug
403 else if( id == 0x43494447 && nRecSize >= 12 )
404 EMFP_DEBUG(ReadGDIComment());
405 else
406 EMFP_DEBUG(printf ("\t\tunknown id: 0x%x\n", id));
408 } else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
410 switch( nRecType )
412 case EMR_POLYBEZIERTO :
413 bFlag = sal_True;
414 case EMR_POLYBEZIER :
416 pWMF->SeekRel( 16 );
417 *pWMF >> nPoints;
418 sal_uInt16 i = 0;
419 if ( bFlag )
421 i++;
422 nPoints++;
424 Polygon aPoly( (sal_uInt16)nPoints );
425 for( ; i < (sal_uInt16)nPoints; i++ )
427 *pWMF >> nX32 >> nY32;
428 aPoly[ i ] = Point( nX32, nY32 );
430 pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath );
432 break;
434 case EMR_POLYGON :
436 pWMF->SeekRel( 16 );
437 *pWMF >> nPoints;
438 Polygon aPoly( (UINT16)nPoints );
439 for( UINT16 k = 0; k < (UINT16)nPoints; k++ )
441 *pWMF >> nX32 >> nY32;
442 aPoly[ k ] = Point( nX32, nY32 );
444 pOut->DrawPolygon( aPoly, bRecordPath );
446 break;
448 case EMR_POLYLINETO :
449 bFlag = sal_True;
450 case EMR_POLYLINE :
452 pWMF->SeekRel( 0x10 );
453 *pWMF >> nPoints;
454 UINT16 i = 0;
455 if ( bFlag )
457 i++;
458 nPoints++;
460 Polygon aPolygon( (UINT16)nPoints );
461 for ( ; i < (UINT16)nPoints; i++ )
463 *pWMF >> nX32 >> nY32;
464 aPolygon[ i ] = Point( nX32, nY32 );
466 pOut->DrawPolyLine( aPolygon, bFlag, bRecordPath );
468 break;
470 case EMR_POLYPOLYLINE :
472 UINT16* pnPoints;
474 INT32 i, nPoly;
475 pWMF->SeekRel( 0x10 );
477 // Anzahl der Polygone:
478 *pWMF >> nPoly >> i;
480 // taking the amount of points of each polygon, retrieving the total number of points
481 if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(UINT16) )
483 if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(UINT16) ) <= ( nEndPos - pWMF->Tell() ) )
485 pnPoints = new UINT16[ nPoly ];
487 for ( i = 0; i < nPoly; i++ )
489 *pWMF >> nPoints;
490 pnPoints[ i ] = (UINT16)nPoints;
493 // Polygonpunkte holen:
495 for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ )
497 Polygon aPoly( pnPoints[ i ] );
498 for( UINT16 k = 0; k < pnPoints[ i ]; k++ )
500 *pWMF >> nX32 >> nY32;
501 aPoly[ k ] = Point( nX32, nY32 );
503 pOut->DrawPolyLine( aPoly, sal_False, bRecordPath );
505 delete[] pnPoints;
509 break;
511 case EMR_POLYPOLYGON :
513 UINT16* pnPoints;
514 Point* pPtAry;
516 UINT32 i, nPoly, nGesPoints;
517 pWMF->SeekRel( 0x10 );
519 // Anzahl der Polygone:
520 *pWMF >> nPoly >> nGesPoints;
522 if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(UINT16) ) )
524 if ( ( nPoly * sizeof(UINT16) ) <= ( nEndPos - pWMF->Tell() ) )
526 pnPoints = new UINT16[ nPoly ];
528 for ( i = 0; i < nPoly; i++ )
530 *pWMF >> nPoints;
531 pnPoints[ i ] = (UINT16)nPoints;
534 if ( ( nGesPoints * (sizeof(sal_uInt32)+sizeof(sal_uInt32)) ) <= ( nEndPos - pWMF->Tell() ) )
536 // Polygonpunkte holen:
537 pPtAry = new Point[ nGesPoints ];
539 for ( i = 0; i < nGesPoints; i++ )
541 *pWMF >> nX32 >> nY32;
542 pPtAry[ i ] = Point( nX32, nY32 );
544 // PolyPolygon Actions erzeugen
545 PolyPolygon aPolyPoly( (UINT16)nPoly, pnPoints, pPtAry );
546 pOut->DrawPolyPolygon( aPolyPoly, bRecordPath );
547 delete[] pPtAry;
549 delete[] pnPoints;
553 break;
555 case EMR_SETWINDOWEXTEX :
556 { // #75383#
557 *pWMF >> nW >> nH;
558 pOut->SetWinExt( Size( nW, nH ) );
560 break;
562 case EMR_SETWINDOWORGEX :
564 *pWMF >> nX32 >> nY32;
565 pOut->SetWinOrg( Point( nX32, nY32 ) );
567 break;
569 case EMR_SCALEWINDOWEXTEX :
571 *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2;
572 pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
574 break;
576 case EMR_SETVIEWPORTORGEX :
578 *pWMF >> nX32 >> nY32;
579 pOut->SetDevOrg( Point( nX32, nY32 ) );
581 break;
583 case EMR_SCALEVIEWPORTEXTEX :
585 *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2;
586 pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
588 break;
590 case EMR_SETVIEWPORTEXTEX :
592 *pWMF >> nW >> nH;
593 pOut->SetDevExt( Size( nW, nH ) );
595 break;
597 case EMR_EOF :
598 nRecordCount = 0; // #76846#
599 break;
601 case EMR_SETPIXELV :
603 *pWMF >> nX32 >> nY32;
604 pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() );
606 break;
608 case EMR_SETMAPMODE :
610 sal_uInt32 nMapMode;
611 *pWMF >> nMapMode;
612 pOut->SetMapMode( nMapMode );
614 break;
616 case EMR_SETBKMODE :
618 *pWMF >> nDat32;
619 pOut->SetBkMode( nDat32 );
621 break;
623 case EMR_SETPOLYFILLMODE :
624 break;
626 case EMR_SETROP2 :
628 *pWMF >> nDat32;
629 pOut->SetRasterOp( nDat32 );
631 break;
633 case EMR_SETSTRETCHBLTMODE :
635 *pWMF >> nStretchBltMode;
637 break;
639 case EMR_SETTEXTALIGN :
641 *pWMF >> nDat32;
642 pOut->SetTextAlign( nDat32 );
644 break;
646 case EMR_SETTEXTCOLOR :
648 pOut->SetTextColor( ReadColor() );
650 break;
652 case EMR_SETBKCOLOR :
654 pOut->SetBkColor( ReadColor() );
656 break;
658 case EMR_OFFSETCLIPRGN :
660 *pWMF >> nX32 >> nY32;
661 pOut->MoveClipRegion( Size( nX32, nY32 ) );
663 break;
665 case EMR_MOVETOEX :
667 *pWMF >> nX32 >> nY32;
668 pOut->MoveTo( Point( nX32, nY32 ), bRecordPath );
670 break;
672 case EMR_INTERSECTCLIPRECT :
674 *pWMF >> nX32 >> nY32 >> nx32 >> ny32;
675 pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
677 break;
679 case EMR_SAVEDC :
681 pOut->Push();
683 break;
685 case EMR_RESTOREDC :
687 pOut->Pop();
689 break;
691 case EMR_SETWORLDTRANSFORM :
693 XForm aTempXForm;
694 *pWMF >> aTempXForm;
695 pOut->SetWorldTransform( aTempXForm );
697 break;
699 case EMR_MODIFYWORLDTRANSFORM :
701 UINT32 nMode;
702 XForm aTempXForm;
703 *pWMF >> aTempXForm >> nMode;
704 pOut->ModifyWorldTransform( aTempXForm, nMode );
706 break;
708 case EMR_SELECTOBJECT :
710 *pWMF >> nIndex;
711 pOut->SelectObject( nIndex );
713 break;
715 case EMR_CREATEPEN :
717 *pWMF >> nIndex;
718 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
721 LineInfo aLineInfo;
722 UINT32 nStyle;
723 Size aSize;
725 *pWMF >> nStyle >> aSize.Width() >> aSize.Height();
727 if ( aSize.Width() )
728 aLineInfo.SetWidth( aSize.Width() );
730 BOOL bTransparent = FALSE;
731 UINT16 nDashCount = 0;
732 UINT16 nDotCount = 0;
733 switch( nStyle )
735 case PS_DASHDOTDOT :
736 nDotCount++;
737 case PS_DASHDOT :
738 nDashCount++;
739 case PS_DOT :
740 nDotCount++;
741 break;
742 case PS_DASH :
743 nDashCount++;
744 break;
745 case PS_NULL :
746 bTransparent = TRUE;
747 aLineInfo.SetStyle( LINE_NONE );
748 break;
749 default :
750 case PS_INSIDEFRAME :
751 case PS_SOLID :
752 aLineInfo.SetStyle( LINE_SOLID );
754 if ( nDashCount | nDotCount )
756 aLineInfo.SetStyle( LINE_DASH );
757 aLineInfo.SetDashCount( nDashCount );
758 aLineInfo.SetDotCount( nDotCount );
760 pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) );
763 break;
765 case EMR_EXTCREATEPEN :
767 sal_Int32 elpHatch;
768 sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries;
769 Color aColorRef;
771 *pWMF >> nIndex;
772 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
774 *pWMF >> offBmi >> cbBmi >> offBits >> cbBits >> nStyle >> nWidth >> nBrushStyle;
775 aColorRef = ReadColor();
776 *pWMF >> elpHatch >> elpNumEntries;
778 LineInfo aLineInfo;
779 if ( nWidth )
780 aLineInfo.SetWidth( nWidth );
782 sal_Bool bTransparent = sal_False;
783 sal_uInt16 nDashCount = 0;
784 sal_uInt16 nDotCount = 0;
786 switch( nStyle & PS_STYLE_MASK )
788 case PS_DASHDOTDOT :
789 nDotCount++;
790 case PS_DASHDOT :
791 nDashCount++;
792 case PS_DOT :
793 nDotCount++;
794 break;
795 case PS_DASH :
796 nDashCount++;
797 break;
798 case PS_NULL :
799 bTransparent = sal_True;
800 aLineInfo.SetStyle( LINE_NONE );
801 break;
803 default :
804 case PS_INSIDEFRAME :
805 case PS_SOLID :
806 aLineInfo.SetStyle( LINE_SOLID );
808 if ( nDashCount | nDotCount )
810 aLineInfo.SetStyle( LINE_DASH );
811 aLineInfo.SetDashCount( nDashCount );
812 aLineInfo.SetDotCount( nDotCount );
814 pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( aColorRef, aLineInfo, bTransparent ) );
817 break;
819 case EMR_CREATEBRUSHINDIRECT :
821 UINT32 nStyle;
822 *pWMF >> nIndex;
823 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
825 *pWMF >> nStyle;
826 pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? TRUE : FALSE ) );
829 break;
831 case EMR_DELETEOBJECT :
833 *pWMF >> nIndex;
834 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
835 pOut->DeleteObject( nIndex );
837 break;
839 case EMR_ELLIPSE :
841 *pWMF >> nX32 >> nY32 >> nx32 >> ny32;
842 pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) );
844 break;
846 case EMR_RECTANGLE :
848 *pWMF >> nX32 >> nY32 >> nx32 >> ny32;
849 pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
851 break;
853 case EMR_ROUNDRECT :
855 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nW >> nH;
856 Size aSize( Size( nW, nH ) );
857 pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize );
859 break;
861 case EMR_ARC :
863 UINT32 nStartX, nStartY, nEndX, nEndY;
864 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
865 pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
867 break;
869 case EMR_CHORD :
871 UINT32 nStartX, nStartY, nEndX, nEndY;
872 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
873 pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
875 break;
877 case EMR_PIE :
879 UINT32 nStartX, nStartY, nEndX, nEndY;
880 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
881 const Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 ));
883 // #i73608# OutputDevice deviates from WMF
884 // semantics. start==end means full ellipse here.
885 if( nStartX == nEndX && nStartY == nEndY )
886 pOut->DrawEllipse( aRect );
887 else
888 pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
890 break;
892 case EMR_LINETO :
894 *pWMF >> nX32 >> nY32;
895 pOut->LineTo( Point( nX32, nY32 ), bRecordPath );
897 break;
899 case EMR_ARCTO :
901 UINT32 nStartX, nStartY, nEndX, nEndY;
902 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
903 pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), TRUE );
905 break;
907 case EMR_BEGINPATH :
909 pOut->ClearPath();
910 bRecordPath = sal_True;
912 break;
914 case EMR_ABORTPATH :
915 pOut->ClearPath();
916 case EMR_ENDPATH :
917 bRecordPath = sal_False;
918 break;
920 case EMR_CLOSEFIGURE :
921 pOut->ClosePath();
922 break;
924 case EMR_FILLPATH :
925 pOut->StrokeAndFillPath( sal_False, sal_True );
926 break;
928 case EMR_STROKEANDFILLPATH :
929 pOut->StrokeAndFillPath( sal_True, sal_True );
930 break;
932 case EMR_STROKEPATH :
933 pOut->StrokeAndFillPath( sal_True, sal_False );
934 break;
936 case EMR_SELECTCLIPPATH :
938 sal_Int32 nClippingMode;
939 *pWMF >> nClippingMode;
940 pOut->SetClipPath( pOut->GetPathObj(), nClippingMode, sal_True );
942 break;
944 case EMR_EXTSELECTCLIPRGN :
946 sal_Int32 iMode, cbRgnData;
947 *pWMF >> cbRgnData
948 >> iMode;
950 PolyPolygon aPolyPoly;
951 if ( cbRgnData )
952 ImplReadRegion( aPolyPoly, *pWMF, nRecSize );
953 pOut->SetClipPath( aPolyPoly, iMode, sal_False );
955 break;
957 case EMR_BITBLT : // PASSTHROUGH INTENDED
958 case EMR_STRETCHBLT :
960 INT32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc;
961 UINT32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc;
962 XForm xformSrc;
964 UINT32 nStart = pWMF->Tell() - 8;
966 pWMF->SeekRel( 0x10 );
967 *pWMF >> xDest >> yDest >> cxDest >> cyDest >> dwRop >> xSrc >> ySrc
968 >> xformSrc >> nColor >> iUsageSrc >> offBmiSrc >> cbBmiSrc
969 >> offBitsSrc >> cbBitsSrc;
971 if ( nRecType == EMR_STRETCHBLT )
972 *pWMF >> cxSrc >> cySrc;
973 else
974 cxSrc = cySrc = 0;
976 Bitmap aBitmap;
977 Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
979 cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative
980 cyDest = abs( (int)cyDest ); // and also 122889
982 if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
983 bStatus = FALSE;
984 else
986 UINT32 nSize = cbBmiSrc + cbBitsSrc + 14;
987 if ( nSize <= ( nEndPos - nStartPos ) )
989 char* pBuf = new char[ nSize ];
990 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
991 aTmp.ObjectOwnsMemory( TRUE );
992 aTmp << (BYTE)'B'
993 << (BYTE)'M'
994 << (UINT32)cbBitsSrc
995 << (UINT16)0
996 << (UINT16)0
997 << (UINT32)cbBmiSrc + 14;
998 pWMF->Seek( nStart + offBmiSrc );
999 pWMF->Read( pBuf + 14, cbBmiSrc );
1000 pWMF->Seek( nStart + offBitsSrc );
1001 pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
1002 aTmp.Seek( 0 );
1003 aBitmap.Read( aTmp, TRUE );
1005 // test if it is sensible to crop
1006 if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
1007 ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
1008 ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
1009 ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
1011 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
1012 aBitmap.Crop( aCropRect );
1014 /* Pseudocomment to add more context so that make patch.unapply
1015 * works better. Ha!
1017 aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ), LIST_APPEND );
1021 break;
1023 case EMR_STRETCHDIBITS :
1025 INT32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest;
1026 UINT32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop;
1027 UINT32 nStart = pWMF->Tell() - 8;
1029 pWMF->SeekRel( 0x10 );
1030 *pWMF >> xDest >> yDest >> xSrc >> ySrc >> cxSrc >> cySrc >> offBmiSrc >> cbBmiSrc >> offBitsSrc
1031 >> cbBitsSrc >> iUsageSrc >> dwRop >> cxDest >> cyDest;
1033 Bitmap aBitmap;
1034 Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
1036 cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative
1037 cyDest = abs( (int)cyDest ); // and also 122889
1039 if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
1040 bStatus = FALSE;
1041 else
1043 UINT32 nSize = cbBmiSrc + cbBitsSrc + 14;
1044 if ( nSize <= ( nEndPos - nStartPos ) )
1046 char* pBuf = new char[ nSize ];
1047 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
1048 aTmp.ObjectOwnsMemory( TRUE );
1049 aTmp << (BYTE)'B'
1050 << (BYTE)'M'
1051 << (UINT32)cbBitsSrc
1052 << (UINT16)0
1053 << (UINT16)0
1054 << (UINT32)cbBmiSrc + 14;
1055 pWMF->Seek( nStart + offBmiSrc );
1056 pWMF->Read( pBuf + 14, cbBmiSrc );
1057 pWMF->Seek( nStart + offBitsSrc );
1058 pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
1059 aTmp.Seek( 0 );
1060 aBitmap.Read( aTmp, TRUE );
1062 // test if it is sensible to crop
1063 if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
1064 ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
1065 ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
1066 ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
1068 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
1069 aBitmap.Crop( aCropRect );
1071 /* Another pseudocomment to make make patch.unapply work better */
1072 aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ), LIST_APPEND );
1076 break;
1078 case EMR_EXTCREATEFONTINDIRECTW :
1080 *pWMF >> nIndex;
1081 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
1083 LOGFONTW aLogFont;
1084 *pWMF >> aLogFont.lfHeight >> aLogFont.lfWidth >> aLogFont.lfEscapement >> aLogFont.lfOrientation >> aLogFont.lfWeight >> aLogFont.lfItalic
1085 >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision >> aLogFont.lfClipPrecision
1086 >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily;
1088 sal_Unicode lfFaceName[ LF_FACESIZE ];
1090 for ( int i = 0; i < LF_FACESIZE; i++ )
1092 UINT16 nChar;
1093 *pWMF >> nChar;
1094 lfFaceName[ i ] = nChar;
1096 aLogFont.alfFaceName = UniString( lfFaceName );
1097 pOut->CreateObject( nIndex, GDI_FONT, new WinMtfFontStyle( aLogFont ) );
1100 break;
1102 case EMR_EXTTEXTOUTA :
1103 bFlag = sal_True;
1104 case EMR_EXTTEXTOUTW :
1106 sal_Int32 nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale;
1107 sal_uInt32 nCurPos, nLen, nOffString, nOptions, offDx;
1108 sal_Int32* pDX = NULL;
1110 nCurPos = pWMF->Tell() - 8;
1112 *pWMF >> nLeft >> nTop >> nRight >> nBottom >> nGfxMode >> nXScale >> nYScale
1113 >> ptlReferenceX >> ptlReferenceY >> nLen >> nOffString >> nOptions;
1115 pWMF->SeekRel( 0x10 );
1116 *pWMF >> offDx;
1118 sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT;
1119 if ( nOptions & ETO_RTLREADING )
1120 nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
1121 pOut->SetTextLayoutMode( nTextLayoutMode );
1122 DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in EMF" );
1124 Point aPos( ptlReferenceX, ptlReferenceY );
1125 if ( nLen && ( nLen < SAL_MAX_UINT32 / sizeof(sal_Int32) ) )
1127 if ( offDx && (( nCurPos + offDx + nLen * 4 ) <= nNextPos ) )
1129 pWMF->Seek( nCurPos + offDx );
1130 if ( ( nLen * sizeof(sal_uInt32) ) <= ( nEndPos - pWMF->Tell() ) )
1132 pDX = new sal_Int32[ nLen ];
1133 sal_uInt32 i;
1134 for ( i = 0; i < nLen; i++ )
1135 *pWMF >> pDX[ i ];
1138 pWMF->Seek( nCurPos + nOffString );
1139 String aText;
1140 if ( bFlag )
1142 if ( nLen <= ( nEndPos - pWMF->Tell() ) )
1144 sal_Char* pBuf = new sal_Char[ nLen ];
1145 pWMF->Read( pBuf, nLen );
1146 aText = String( pBuf, (sal_uInt16)nLen, pOut->GetCharSet() );
1147 delete[] pBuf;
1149 if ( aText.Len() != nLen )
1151 sal_uInt16 i, j, k;
1152 sal_Int32* pOldDx = pDX;
1153 pDX = new sal_Int32[ aText.Len() ];
1154 for ( i = 0, j = 0; i < aText.Len(); i++ )
1156 ByteString aCharacter( aText.GetChar( i ), pOut->GetCharSet() );
1157 pDX[ i ] = 0;
1158 for ( k = 0; ( k < aCharacter.Len() ) && ( j < nLen ) && ( i < aText.Len() ); k++ )
1159 pDX[ i ] += pOldDx[ j++ ];
1161 delete[] pOldDx;
1165 else
1167 if ( ( nLen * sizeof(sal_Unicode) ) <= ( nEndPos - pWMF->Tell() ) )
1169 sal_Unicode* pBuf = new sal_Unicode[ nLen ];
1170 pWMF->Read( pBuf, nLen << 1 );
1171 #ifdef OSL_BIGENDIAN
1172 sal_Char nTmp, *pTmp = (sal_Char*)( pBuf + nLen );
1173 while ( pTmp-- != (sal_Char*)pBuf )
1175 nTmp = *pTmp--;
1176 pTmp[ 1 ] = *pTmp;
1177 *pTmp = nTmp;
1179 #endif
1180 aText = String( pBuf, (xub_StrLen)nLen );
1181 delete[] pBuf;
1184 pOut->DrawText( aPos, aText, pDX, bRecordPath, nGfxMode );
1186 delete[] pDX;
1188 break;
1190 case EMR_POLYBEZIERTO16 :
1191 bFlag = sal_True;
1192 case EMR_POLYBEZIER16 :
1194 pWMF->SeekRel( 16 );
1195 *pWMF >> nPoints;
1196 UINT16 i = 0;
1197 if ( bFlag )
1199 i++;
1200 nPoints++;
1202 Polygon aPoly( (UINT16)nPoints );
1203 for( ; i < (UINT16)nPoints; i++ )
1205 *pWMF >> nX16 >> nY16;
1206 aPoly[ i ] = Point( nX16, nY16 );
1208 pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); // Line( aPoly, bFlag );
1210 break;
1212 case EMR_POLYGON16 :
1214 pWMF->SeekRel( 16 );
1215 *pWMF >> nPoints;
1216 Polygon aPoly( (UINT16)nPoints );
1217 for( UINT16 k = 0; k < (UINT16)nPoints; k++ )
1219 *pWMF >> nX16 >> nY16;
1220 aPoly[ k ] = Point( nX16, nY16 );
1222 pOut->DrawPolygon( aPoly, bRecordPath );
1224 break;
1226 case EMR_POLYLINETO16 :
1227 bFlag = sal_True;
1228 case EMR_POLYLINE16 :
1230 pWMF->SeekRel( 16 );
1231 *pWMF >> nPoints;
1232 UINT16 i = 0;
1233 if ( bFlag )
1235 i++;
1236 nPoints++;
1239 Polygon aPoly( (UINT16)nPoints );
1240 for( ; i < (UINT16)nPoints; i++ )
1242 *pWMF >> nX16 >> nY16;
1243 aPoly[ i ] = Point( nX16, nY16 );
1245 pOut->DrawPolyLine( aPoly, bFlag, bRecordPath );
1247 break;
1249 case EMR_POLYPOLYLINE16 :
1251 UINT16* pnPoints;
1253 INT32 i, nPoly, nGesPoints;
1254 pWMF->SeekRel( 0x10 );
1255 // Anzahl der Polygone:
1256 *pWMF >> nPoly >> nGesPoints;
1258 // taking the amount of points of each polygon, retrieving the total number of points
1259 if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(UINT16) )
1261 if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(UINT16) ) <= ( nEndPos - pWMF->Tell() ) )
1263 pnPoints = new UINT16[ nPoly ];
1264 for ( i = 0; i < nPoly; i++ )
1266 *pWMF >> nPoints;
1267 pnPoints[ i ] = (UINT16)nPoints;
1269 // Polygonpunkte holen:
1270 for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ )
1272 Polygon aPolygon( pnPoints[ i ] );
1273 for ( UINT16 k = 0; k < pnPoints[ i ]; k++ )
1275 *pWMF >> nX16 >> nY16;
1276 aPolygon[ k ] = Point( nX16, nY16 );
1278 pOut->DrawPolyLine( aPolygon, sal_False, bRecordPath );
1280 delete[] pnPoints;
1284 break;
1286 case EMR_POLYPOLYGON16 :
1288 UINT16* pnPoints;
1289 Point* pPtAry;
1291 UINT32 i, nPoly, nGesPoints;
1292 pWMF->SeekRel( 0x10 );
1293 // Anzahl der Polygone:
1294 *pWMF >> nPoly >> nGesPoints;
1295 if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(UINT16) ) )
1297 if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof( UINT16 ) ) <= ( nEndPos - pWMF->Tell() ) )
1299 pnPoints = new UINT16[ nPoly ];
1300 for ( i = 0; i < nPoly; i++ )
1302 *pWMF >> nPoints;
1303 pnPoints[ i ] = (UINT16)nPoints;
1305 if ( ( nGesPoints * (sizeof(sal_uInt16)+sizeof(sal_uInt16)) ) <= ( nEndPos - pWMF->Tell() ) )
1307 // Polygonpunkte holen:
1308 pPtAry = new Point[ nGesPoints ];
1309 for ( i = 0; i < nGesPoints; i++ )
1311 *pWMF >> nX16 >> nY16;
1312 pPtAry[ i ] = Point( nX16, nY16 );
1315 // PolyPolygon Actions erzeugen
1316 PolyPolygon aPolyPoly( (UINT16)nPoly, pnPoints, pPtAry );
1317 pOut->DrawPolyPolygon( aPolyPoly, bRecordPath );
1318 delete[] pPtAry;
1320 delete[] pnPoints;
1324 break;
1326 case EMR_FILLRGN :
1328 sal_uInt32 nLen;
1329 PolyPolygon aPolyPoly;
1330 pWMF->SeekRel( 0x10 );
1331 *pWMF >> nLen >> nIndex;
1333 if ( ImplReadRegion( aPolyPoly, *pWMF, nRecSize ) )
1335 pOut->Push();
1336 pOut->SelectObject( nIndex );
1337 pOut->DrawPolyPolygon( aPolyPoly, sal_False );
1338 pOut->Pop();
1341 break;
1343 case EMR_CREATEDIBPATTERNBRUSHPT :
1345 static int count = 0;
1346 UINT32 nStart = pWMF->Tell() - 8;
1347 Bitmap aBitmap;
1349 *pWMF >> nIndex;
1351 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
1353 UINT32 usage, offBmi, cbBmi, offBits, cbBits;
1355 *pWMF >> usage;
1356 *pWMF >> offBmi;
1357 *pWMF >> cbBmi;
1358 *pWMF >> offBits;
1359 *pWMF >> cbBits;
1361 if ( (cbBits > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBits < cbBmi) )
1362 bStatus = FALSE;
1363 else if ( offBmi )
1365 UINT32 nSize = cbBmi + cbBits + 14;
1366 if ( nSize <= ( nEndPos - nStartPos ) )
1368 char* pBuf = new char[ nSize ];
1370 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
1371 aTmp.ObjectOwnsMemory( TRUE );
1372 aTmp << (BYTE)'B'
1373 << (BYTE)'M'
1374 << (UINT32)cbBits
1375 << (UINT16)0
1376 << (UINT16)0
1377 << (UINT32)cbBmi + 14;
1378 pWMF->Seek( nStart + offBmi );
1379 pWMF->Read( pBuf + 14, cbBmi );
1380 pWMF->Seek( nStart + offBits );
1381 pWMF->Read( pBuf + 14 + cbBmi, cbBits );
1382 aTmp.Seek( 0 );
1383 aBitmap.Read( aTmp, TRUE );
1388 pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( aBitmap ) );
1390 break;
1392 #ifdef WIN_MTF_ASSERT
1393 default : WinMtfAssertHandler( "Unknown Meta Action" ); break;
1394 case EMR_MASKBLT : WinMtfAssertHandler( "MaskBlt" ); break;
1395 case EMR_PLGBLT : WinMtfAssertHandler( "PlgBlt" ); break;
1396 case EMR_SETDIBITSTODEVICE : WinMtfAssertHandler( "SetDIBitsToDevice" ); break;
1397 case EMR_FRAMERGN : WinMtfAssertHandler( "FrameRgn" ); break;
1398 case EMR_INVERTRGN : WinMtfAssertHandler( "InvertRgn" ); break;
1399 case EMR_PAINTRGN : WinMtfAssertHandler( "PaintRgn" ); break;
1400 case EMR_FLATTENPATH : WinMtfAssertHandler( "FlattenPath" ); break;
1401 case EMR_WIDENPATH : WinMtfAssertHandler( "WidenPath" ); break;
1402 case EMR_POLYDRAW : WinMtfAssertHandler( "Polydraw" ); break;
1403 case EMR_SETARCDIRECTION : WinMtfAssertHandler( "SetArcDirection" ); break;
1404 case EMR_SETPALETTEENTRIES : WinMtfAssertHandler( "SetPaletteEntries" ); break;
1405 case EMR_RESIZEPALETTE : WinMtfAssertHandler( "ResizePalette" ); break;
1406 case EMR_EXTFLOODFILL : WinMtfAssertHandler( "ExtFloodFill" ); break;
1407 case EMR_ANGLEARC : WinMtfAssertHandler( "AngleArc" ); break;
1408 case EMR_SETCOLORADJUSTMENT : WinMtfAssertHandler( "SetColorAdjustment" ); break;
1409 case EMR_POLYDRAW16 : WinMtfAssertHandler( "PolyDraw16" ); break;
1410 case EMR_POLYTEXTOUTA : WinMtfAssertHandler( "PolyTextOutA" ); break;
1411 case EMR_POLYTEXTOUTW : WinMtfAssertHandler( "PolyTextOutW" ); break;
1412 case EMR_CREATECOLORSPACE : WinMtfAssertHandler( "CreateColorSpace" ); break;
1413 case EMR_SETCOLORSPACE : WinMtfAssertHandler( "SetColorSpace" ); break;
1414 case EMR_DELETECOLORSPACE : WinMtfAssertHandler( "DeleteColorSpace" ); break;
1415 case EMR_GLSRECORD : WinMtfAssertHandler( "GlsRecord" ); break;
1416 case EMR_GLSBOUNDEDRECORD : WinMtfAssertHandler( "GlsBoundRecord" ); break;
1417 case EMR_PIXELFORMAT : WinMtfAssertHandler( "PixelFormat" ); break;
1418 case EMR_DRAWESCAPE : WinMtfAssertHandler( "DrawEscape" ); break;
1419 case EMR_EXTESCAPE : WinMtfAssertHandler( "ExtEscape" ); break;
1420 case EMR_STARTDOC : WinMtfAssertHandler( "StartDoc" ); break;
1421 case EMR_SMALLTEXTOUT : WinMtfAssertHandler( "SmallTextOut" ); break;
1422 case EMR_FORCEUFIMAPPING : WinMtfAssertHandler( "ForceUFIMapping" ); break;
1423 case EMR_NAMEDESCAPE : WinMtfAssertHandler( "NamedEscape" ); break;
1424 case EMR_COLORCORRECTPALETTE : WinMtfAssertHandler( "ColorCorrectPalette" ); break;
1425 case EMR_SETICMPROFILEA : WinMtfAssertHandler( "SetICMProfileA" ); break;
1426 case EMR_SETICMPROFILEW : WinMtfAssertHandler( "SetICMProfileW" ); break;
1427 case EMR_ALPHABLEND : WinMtfAssertHandler( "Alphablend" ); break;
1428 case EMR_TRANSPARENTBLT : WinMtfAssertHandler( "TransparenBlt" ); break;
1429 case EMR_TRANSPARENTDIB : WinMtfAssertHandler( "TransparenDib" ); break;
1430 case EMR_GRADIENTFILL : WinMtfAssertHandler( "GradientFill" ); break;
1431 case EMR_SETLINKEDUFIS : WinMtfAssertHandler( "SetLinkedUFIS" ); break;
1433 case EMR_SETMAPPERFLAGS : WinMtfAssertHandler( "SetMapperFlags", 0 ); break;
1434 case EMR_SETICMMODE : WinMtfAssertHandler( "SetICMMode", 0 ); break;
1435 case EMR_CREATEMONOBRUSH : WinMtfAssertHandler( "CreateMonoBrush", 0 ); break;
1436 case EMR_SETBRUSHORGEX : WinMtfAssertHandler( "SetBrushOrgEx", 0 ); break;
1437 case EMR_SETMETARGN : WinMtfAssertHandler( "SetMetArgn", 0 ); break;
1438 case EMR_SETMITERLIMIT : WinMtfAssertHandler( "SetMiterLimit", 0 ); break;
1439 case EMR_EXCLUDECLIPRECT : WinMtfAssertHandler( "ExcludeClipRect", 0 ); break;
1440 case EMR_REALIZEPALETTE : WinMtfAssertHandler( "RealizePalette", 0 ); break;
1441 case EMR_SELECTPALETTE : WinMtfAssertHandler( "SelectPalette", 0 ); break;
1442 case EMR_CREATEPALETTE : WinMtfAssertHandler( "CreatePalette", 0 ); break;
1443 case EMR_ALPHADIBBLEND : WinMtfAssertHandler( "AlphaDibBlend", 0 ); break;
1444 case EMR_SETTEXTJUSTIFICATION : WinMtfAssertHandler( "SetTextJustification", 0 ); break;
1446 case EMR_GDICOMMENT :
1447 case EMR_HEADER : // has already been read at ReadHeader()
1448 break;
1449 #endif
1451 pWMF->Seek( nNextPos );
1453 if( aBmpSaveList.Count() )
1454 pOut->ResolveBitmapActions( aBmpSaveList );
1456 if ( bStatus )
1457 pWMF->Seek(nEndPos);
1459 return bStatus;
1462 //-----------------------------------------------------------------------------------
1464 BOOL EnhWMFReader::ReadHeader()
1466 UINT32 nUINT32, nHeaderSize, nPalEntries;
1467 INT32 nLeft, nTop, nRight, nBottom;
1469 // METAFILEHEADER SPARE ICH MIR HIER
1470 // Einlesen des METAHEADER
1471 *pWMF >> nUINT32 >> nHeaderSize;
1472 if ( nUINT32 != 1 ) // Typ
1473 return FALSE;
1475 // bound size
1476 Rectangle rclBounds; // rectangle in logical units 1/100th mm
1477 *pWMF >> nLeft >> nTop >> nRight >> nBottom;
1478 rclBounds.Left() = nLeft;
1479 rclBounds.Top() = nTop;
1480 rclBounds.Right() = nRight;
1481 rclBounds.Bottom() = nBottom;
1483 // picture frame size
1484 Rectangle rclFrame; // rectangle in device units
1485 *pWMF >> nLeft >> nTop >> nRight >> nBottom;
1486 rclFrame.Left() = nLeft;
1487 rclFrame.Top() = nTop;
1488 rclFrame.Right() = nRight;
1489 rclFrame.Bottom() = nBottom;
1491 *pWMF >> nUINT32; // signature
1493 if ( nUINT32 != 0x464d4520 )
1494 return FALSE;
1496 *pWMF >> nUINT32; // nVersion
1497 *pWMF >> nEndPos; // size of metafile
1498 nEndPos += nStartPos;
1500 sal_uInt32 nStrmPos = pWMF->Tell(); // checking if nEndPos is valid
1501 pWMF->Seek( STREAM_SEEK_TO_END );
1502 if ( pWMF->Tell() < nEndPos )
1503 nEndPos = pWMF->Tell();
1504 pWMF->Seek( nStrmPos );
1506 *pWMF >> nRecordCount;
1508 if ( !nRecordCount )
1509 return FALSE;
1511 pWMF->SeekRel( 0xc );
1513 sal_Int32 nPixX, nPixY, nMillX, nMillY;
1514 *pWMF >> nPalEntries >> nPixX >> nPixY >> nMillX >> nMillY;
1516 pOut->SetrclFrame( rclFrame );
1517 pOut->SetrclBounds( rclBounds );
1518 pOut->SetRefPix( Size( nPixX, nPixY ) );
1519 pOut->SetRefMill( Size( nMillX, nMillY ) );
1521 pWMF->Seek( nStartPos + nHeaderSize );
1522 return TRUE;
1525 //-----------------------------------------------------------------------------------
1527 Rectangle EnhWMFReader::ReadRectangle( INT32 x1, INT32 y1, INT32 x2, INT32 y2 )
1529 Point aTL ( Point( x1, y1 ) );
1530 Point aBR( Point( --x2, --y2 ) );
1531 return Rectangle( aTL, aBR );
1534 EnhWMFReader::~EnhWMFReader()