update dev300-m58
[ooovba.git] / svtools / source / filter.vcl / wmf / emfwr.cxx
blob2d36a21f7425bd5b0e8cf931d3e842b886aeaff6
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: emfwr.cxx,v $
10 * $Revision: 1.21 $
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 "emfwr.hxx"
35 #include <vcl/salbtype.hxx>
37 // -----------
38 // - Defines -
39 // -----------
41 #define WIN_EMR_HEADER 1
42 #define WIN_EMR_POLYBEZIER 2
43 #define WIN_EMR_POLYGON 3
44 #define WIN_EMR_POLYLINE 4
45 #define WIN_EMR_POLYBEZIERTO 5
46 #define WIN_EMR_POLYLINETO 6
47 #define WIN_EMR_POLYPOLYLINE 7
48 #define WIN_EMR_POLYPOLYGON 8
49 #define WIN_EMR_SETWINDOWEXTEX 9
50 #define WIN_EMR_SETWINDOWORGEX 10
51 #define WIN_EMR_SETVIEWPORTEXTEX 11
52 #define WIN_EMR_SETVIEWPORTORGEX 12
53 #define WIN_EMR_SETBRUSHORGEX 13
54 #define WIN_EMR_EOF 14
55 #define WIN_EMR_SETPIXELV 15
56 #define WIN_EMR_SETMAPPERFLAGS 16
57 #define WIN_EMR_SETMAPMODE 17
58 #define WIN_EMR_SETBKMODE 18
59 #define WIN_EMR_SETPOLYFILLMODE 19
60 #define WIN_EMR_SETROP2 20
61 #define WIN_EMR_SETSTRETCHBLTMODE 21
62 #define WIN_EMR_SETTEXTALIGN 22
63 #define WIN_EMR_SETCOLORADJUSTMENT 23
64 #define WIN_EMR_SETTEXTCOLOR 24
65 #define WIN_EMR_SETBKCOLOR 25
66 #define WIN_EMR_OFFSETCLIPRGN 26
67 #define WIN_EMR_MOVETOEX 27
68 #define WIN_EMR_SETMETARGN 28
69 #define WIN_EMR_EXCLUDECLIPRECT 29
70 #define WIN_EMR_INTERSECTCLIPRECT 30
71 #define WIN_EMR_SCALEVIEWPORTEXTEX 31
72 #define WIN_EMR_SCALEWINDOWEXTEX 32
73 #define WIN_EMR_SAVEDC 33
74 #define WIN_EMR_RESTOREDC 34
75 #define WIN_EMR_SETWORLDTRANSFORM 35
76 #define WIN_EMR_MODIFYWORLDTRANSFORM 36
77 #define WIN_EMR_SELECTOBJECT 37
78 #define WIN_EMR_CREATEPEN 38
79 #define WIN_EMR_CREATEBRUSHINDIRECT 39
80 #define WIN_EMR_DELETEOBJECT 40
81 #define WIN_EMR_ANGLEARC 41
82 #define WIN_EMR_ELLIPSE 42
83 #define WIN_EMR_RECTANGLE 43
84 #define WIN_EMR_ROUNDRECT 44
85 #define WIN_EMR_ARC 45
86 #define WIN_EMR_CHORD 46
87 #define WIN_EMR_PIE 47
88 #define WIN_EMR_SELECTPALETTE 48
89 #define WIN_EMR_CREATEPALETTE 49
90 #define WIN_EMR_SETPALETTEENTRIES 50
91 #define WIN_EMR_RESIZEPALETTE 51
92 #define WIN_EMR_REALIZEPALETTE 52
93 #define WIN_EMR_EXTFLOODFILL 53
94 #define WIN_EMR_LINETO 54
95 #define WIN_EMR_ARCTO 55
96 #define WIN_EMR_POLYDRAW 56
97 #define WIN_EMR_SETARCDIRECTION 57
98 #define WIN_EMR_SETMITERLIMIT 58
99 #define WIN_EMR_BEGINPATH 59
100 #define WIN_EMR_ENDPATH 60
101 #define WIN_EMR_CLOSEFIGURE 61
102 #define WIN_EMR_FILLPATH 62
103 #define WIN_EMR_STROKEANDFILLPATH 63
104 #define WIN_EMR_STROKEPATH 64
105 #define WIN_EMR_FLATTENPATH 65
106 #define WIN_EMR_WIDENPATH 66
107 #define WIN_EMR_SELECTCLIPPATH 67
108 #define WIN_EMR_ABORTPATH 68
110 #define WIN_EMR_GDICOMMENT 70
111 #define WIN_EMR_FILLRGN 71
112 #define WIN_EMR_FRAMERGN 72
113 #define WIN_EMR_INVERTRGN 73
114 #define WIN_EMR_PAINTRGN 74
115 #define WIN_EMR_EXTSELECTCLIPRGN 75
116 #define WIN_EMR_BITBLT 76
117 #define WIN_EMR_STRETCHBLT 77
118 #define WIN_EMR_MASKBLT 78
119 #define WIN_EMR_PLGBLT 79
120 #define WIN_EMR_SETDIBITSTODEVICE 80
121 #define WIN_EMR_STRETCHDIBITS 81
122 #define WIN_EMR_EXTCREATEFONTINDIRECTW 82
123 #define WIN_EMR_EXTTEXTOUTA 83
124 #define WIN_EMR_EXTTEXTOUTW 84
125 #define WIN_EMR_POLYBEZIER16 85
126 #define WIN_EMR_POLYGON16 86
127 #define WIN_EMR_POLYLINE16 87
128 #define WIN_EMR_POLYBEZIERTO16 88
129 #define WIN_EMR_POLYLINETO16 89
130 #define WIN_EMR_POLYPOLYLINE16 90
131 #define WIN_EMR_POLYPOLYGON16 91
132 #define WIN_EMR_POLYDRAW16 92
133 #define WIN_EMR_CREATEMONOBRUSH 93
134 #define WIN_EMR_CREATEDIBPATTERNBRUSHPT 94
135 #define WIN_EMR_EXTCREATEPEN 95
136 #define WIN_EMR_POLYTEXTOUTA 96
137 #define WIN_EMR_POLYTEXTOUTW 97
139 #define WIN_SRCCOPY 0x00CC0020L
140 #define WIN_SRCPAINT 0x00EE0086L
141 #define WIN_SRCAND 0x008800C6L
142 #define WIN_SRCINVERT 0x00660046L
144 #define HANDLE_INVALID 0xffffffff
145 #define MAXHANDLES 65000
147 #define LINE_SELECT 0x00000001
148 #define FILL_SELECT 0x00000002
149 #define TEXT_SELECT 0x00000004
151 /* Text Alignment Options */
152 #define TA_NOUPDATECP 0
153 #define TA_UPDATECP 1
155 #define TA_LEFT 0
156 #define TA_RIGHT 2
157 #define TA_CENTER 6
159 #define TA_TOP 0
160 #define TA_BOTTOM 8
161 #define TA_BASELINE 24
162 #define TA_RTLREADING 256
163 #define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING)
165 // -------------
166 // - EMFWriter -
167 // -------------
169 BOOL EMFWriter::WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfigItem* pFilterConfigItem )
171 const ULONG nHeaderPos = rOStm.Tell();
173 mpHandlesUsed = new BOOL[ MAXHANDLES ];
174 memset( mpHandlesUsed, 0, MAXHANDLES * sizeof( BOOL ) );
175 mnHorTextAlign = mnHandleCount = mnLastPercent = mnRecordPos = mnRecordCount = 0;
176 mnLineHandle = mnFillHandle = mnTextHandle = HANDLE_INVALID;
177 mbRecordOpen = FALSE;
179 mpStm = &rOStm;
180 maVDev.EnableOutput( FALSE );
181 maVDev.SetMapMode( rMtf.GetPrefMapMode() );
182 mpFilterConfigItem = pFilterConfigItem;
184 const Size aMtfSizePix( maVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
185 const Size aMtfSizeLog( maVDev.LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_100TH_MM ) );
187 // seek over header
188 rOStm.SeekRel( 100 );
190 // write initial values
191 ImplBeginRecord( WIN_EMR_SETWINDOWORGEX );
192 (*mpStm) << (INT32) 0 << (INT32) 0;
193 ImplEndRecord();
195 ImplBeginRecord( WIN_EMR_SETWINDOWEXTEX );
196 (*mpStm) << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height();
197 ImplEndRecord();
199 ImplWriteRasterOp( ROP_OVERPAINT );
201 ImplBeginRecord( WIN_EMR_SETBKMODE );
202 (*mpStm) << (UINT32) 1; // TRANSPARENT
203 ImplEndRecord();
205 // write emf data
206 ImplWrite( rMtf );
208 ImplBeginRecord( WIN_EMR_EOF );
209 (*mpStm)<< (sal_uInt32)0 // nPalEntries
210 << (sal_uInt32)0x16 // offPalEntries
211 << (sal_uInt32)0x14; // nSizeLast
212 ImplEndRecord();
215 // write header
216 const ULONG nEndPos = mpStm->Tell(); mpStm->Seek( nHeaderPos );
218 (*mpStm) << (UINT32) 0x00000001 << (UINT32) 100;
219 (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizePix.Width() - 1 ) << (INT32) ( aMtfSizePix.Height() - 1 );
220 (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizeLog.Width() - 1 ) << (INT32) ( aMtfSizeLog.Height() - 1 );
221 (*mpStm) << (UINT32) 0x464d4520 << (UINT32) 0x10000 << (UINT32) ( nEndPos - nHeaderPos );
222 (*mpStm) << (UINT32) mnRecordCount << (UINT16) ( mnHandleCount + 1 ) << (UINT16) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0;
223 (*mpStm) << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height();
224 (*mpStm) << (INT32) ( aMtfSizeLog.Width() / 100 ) << (INT32) ( aMtfSizeLog.Height() / 100 );
225 (*mpStm) << (UINT32) 0 << (UINT32) 0 << (UINT32) 0;
227 mpStm->Seek( nEndPos );
228 delete[] mpHandlesUsed;
230 return( mpStm->GetError() == ERRCODE_NONE );
233 // -----------------------------------------------------------------------------
235 ULONG EMFWriter::ImplAcquireHandle()
237 ULONG nHandle = HANDLE_INVALID;
239 for( ULONG i = 0; i < MAXHANDLES && ( HANDLE_INVALID == nHandle ); i++ )
241 if( !mpHandlesUsed[ i ] )
243 mpHandlesUsed[ i ] = TRUE;
245 if( ( nHandle = i ) == mnHandleCount )
246 mnHandleCount++;
250 DBG_ASSERT( nHandle != HANDLE_INVALID, "No more handles available" );
251 return( nHandle != HANDLE_INVALID ? nHandle + 1 : HANDLE_INVALID );
254 // -----------------------------------------------------------------------------
256 void EMFWriter::ImplReleaseHandle( ULONG nHandle )
258 DBG_ASSERT( nHandle && ( nHandle < MAXHANDLES ), "Handle out of range" );
259 mpHandlesUsed[ nHandle - 1 ] = FALSE;
262 // -----------------------------------------------------------------------------
264 void EMFWriter::ImplBeginRecord( sal_uInt32 nType )
266 DBG_ASSERT( !mbRecordOpen, "Another record is already opened!" );
268 if( !mbRecordOpen )
270 mbRecordOpen = TRUE;
271 mnRecordPos = mpStm->Tell();
273 (*mpStm) << nType;
274 mpStm->SeekRel( 4 );
278 // -----------------------------------------------------------------------------
280 void EMFWriter::ImplEndRecord()
282 DBG_ASSERT( mbRecordOpen, "Record was not opened!" );
284 if( mbRecordOpen )
286 sal_Int32 nFillBytes, nActPos = mpStm->Tell();
287 mpStm->Seek( mnRecordPos + 4 );
288 nFillBytes = nActPos - mnRecordPos;
289 nFillBytes += 3; // each record has to be dword aligned
290 nFillBytes ^= 3;
291 nFillBytes &= 3;
292 *mpStm << (sal_uInt32)( ( nActPos - mnRecordPos ) + nFillBytes );
293 mpStm->Seek( nActPos );
294 while( nFillBytes-- )
295 *mpStm << (sal_uInt8)0;
296 mnRecordCount++;
297 mbRecordOpen = FALSE;
301 // -----------------------------------------------------------------------------
303 BOOL EMFWriter::ImplPrepareHandleSelect( sal_uInt32& rHandle, ULONG nSelectType )
305 if( rHandle != HANDLE_INVALID )
307 UINT32 nStockObject = 0x80000000;
309 if( LINE_SELECT == nSelectType )
310 nStockObject |= 0x00000007;
311 else if( FILL_SELECT == nSelectType )
312 nStockObject |= 0x00000001;
313 else if( TEXT_SELECT == nSelectType )
314 nStockObject |= 0x0000000a;
316 // select stock object first
317 ImplBeginRecord( WIN_EMR_SELECTOBJECT );
318 ( *mpStm ) << nStockObject;
319 ImplEndRecord();
321 // destroy handle of created object
322 ImplBeginRecord( WIN_EMR_DELETEOBJECT );
323 ( *mpStm ) << rHandle;
324 ImplEndRecord();
326 // mark handle as free
327 ImplReleaseHandle( rHandle );
330 rHandle = ImplAcquireHandle();
332 return( HANDLE_INVALID != rHandle );
335 // -----------------------------------------------------------------------------
337 void EMFWriter::ImplCheckLineAttr()
339 if( mbLineChanged && ImplPrepareHandleSelect( mnLineHandle, LINE_SELECT ) )
341 sal_uInt32 nStyle = maVDev.IsLineColor() ? 0 : 5;
342 sal_uInt32 nWidth = 0, nHeight = 0;
344 ImplBeginRecord( WIN_EMR_CREATEPEN );
345 (*mpStm) << mnLineHandle << nStyle << nWidth << nHeight;
346 ImplWriteColor( maVDev.GetLineColor() );
347 ImplEndRecord();
349 ImplBeginRecord( WIN_EMR_SELECTOBJECT );
350 (*mpStm) << mnLineHandle;
351 ImplEndRecord();
355 // -----------------------------------------------------------------------------
357 void EMFWriter::ImplCheckFillAttr()
359 if( mbFillChanged && ImplPrepareHandleSelect( mnFillHandle, FILL_SELECT ) )
361 sal_uInt32 nStyle = maVDev.IsFillColor() ? 0 : 1;
362 sal_uInt32 nPatternStyle = 0;
364 ImplBeginRecord( WIN_EMR_CREATEBRUSHINDIRECT );
365 (*mpStm) << mnFillHandle << nStyle;
366 ImplWriteColor( maVDev.GetFillColor() );
367 (*mpStm) << nPatternStyle;
368 ImplEndRecord();
370 ImplBeginRecord( WIN_EMR_SELECTOBJECT );
371 (*mpStm) << mnFillHandle;
372 ImplEndRecord();
376 // -----------------------------------------------------------------------------
378 void EMFWriter::ImplCheckTextAttr()
380 if( mbTextChanged && ImplPrepareHandleSelect( mnTextHandle, TEXT_SELECT ) )
382 const Font& rFont = maVDev.GetFont();
383 String aFontName( rFont.GetName() );
384 sal_Int32 nWeight;
385 sal_uInt16 i;
386 sal_uInt8 nPitchAndFamily;
388 ImplBeginRecord( WIN_EMR_EXTCREATEFONTINDIRECTW );
389 (*mpStm) << mnTextHandle;
390 ImplWriteExtent( -rFont.GetSize().Height() );
391 ImplWriteExtent( rFont.GetSize().Width() );
392 (*mpStm) << (INT32) rFont.GetOrientation() << (INT32) rFont.GetOrientation();
394 switch( rFont.GetWeight() )
396 case WEIGHT_THIN: nWeight = 100; break;
397 case WEIGHT_ULTRALIGHT: nWeight = 200; break;
398 case WEIGHT_LIGHT: nWeight = 300; break;
399 case WEIGHT_SEMILIGHT: nWeight = 300; break;
400 case WEIGHT_NORMAL: nWeight = 400; break;
401 case WEIGHT_MEDIUM: nWeight = 500; break;
402 case WEIGHT_SEMIBOLD: nWeight = 600; break;
403 case WEIGHT_BOLD: nWeight = 700; break;
404 case WEIGHT_ULTRABOLD: nWeight = 800; break;
405 case WEIGHT_BLACK: nWeight = 900; break;
406 default: nWeight = 0; break;
409 (*mpStm) << nWeight;
410 (*mpStm) << (BYTE) ( ( ITALIC_NONE == rFont.GetItalic() ) ? 0 : 1 );
411 (*mpStm) << (BYTE) ( ( UNDERLINE_NONE == rFont.GetUnderline() ) ? 0 : 1 );
412 (*mpStm) << (BYTE) ( ( STRIKEOUT_NONE == rFont.GetStrikeout() ) ? 0 : 1 );
413 (*mpStm) << (BYTE) ( ( RTL_TEXTENCODING_SYMBOL == rFont.GetCharSet() ) ? 2 : 0 );
414 (*mpStm) << (BYTE) 0 << (BYTE) 0 << (BYTE) 0;
416 switch( rFont.GetPitch() )
418 case PITCH_FIXED: nPitchAndFamily = 0x01; break;
419 case PITCH_VARIABLE: nPitchAndFamily = 0x02; break;
420 default: nPitchAndFamily = 0x00; break;
423 switch( rFont.GetFamily() )
425 case FAMILY_DECORATIVE: nPitchAndFamily |= 0x50; break;
426 case FAMILY_MODERN: nPitchAndFamily |= 0x30; break;
427 case FAMILY_ROMAN: nPitchAndFamily |= 0x10; break;
428 case FAMILY_SCRIPT: nPitchAndFamily |= 0x40; break;
429 case FAMILY_SWISS: nPitchAndFamily |= 0x20; break;
430 default: break;
433 (*mpStm) << nPitchAndFamily;
435 for( i = 0; i < 32; i++ )
436 (*mpStm) << (sal_Unicode) ( ( i < aFontName.Len() ) ? aFontName.GetChar( i ) : 0 );
438 // dummy elfFullName
439 for( i = 0; i < 64; i++ )
440 (*mpStm) << (sal_Unicode) 0;
442 // dummy elfStyle
443 for( i = 0; i < 32; i++ )
444 (*mpStm) << (sal_Unicode) 0;
446 // dummy elfVersion, elfStyleSize, elfMatch, elfReserved
447 (*mpStm) << (UINT32) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0 ;
449 // dummy elfVendorId
450 (*mpStm) << (UINT32) 0;
452 // dummy elfCulture
453 (*mpStm) << (UINT32) 0;
455 // dummy elfPanose
456 (*mpStm) << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0;
458 // fill record to get a record size divideable by 4
459 (*mpStm) << (UINT16) 0;
461 ImplEndRecord();
463 // TextAlign
464 UINT32 nTextAlign;
466 switch( rFont.GetAlign() )
468 case ALIGN_TOP: nTextAlign = TA_TOP; break;
469 case ALIGN_BOTTOM: nTextAlign = TA_BOTTOM; break;
470 default: nTextAlign = TA_BASELINE; break;
472 nTextAlign |= mnHorTextAlign;
474 ImplBeginRecord( WIN_EMR_SETTEXTALIGN );
475 (*mpStm) << nTextAlign;
476 ImplEndRecord();
478 // Text color
479 ImplBeginRecord( WIN_EMR_SETTEXTCOLOR );
480 ImplWriteColor( maVDev.GetTextColor() );
481 ImplEndRecord();
483 ImplBeginRecord( WIN_EMR_SELECTOBJECT );
484 (*mpStm) << mnTextHandle;
485 ImplEndRecord();
489 // -----------------------------------------------------------------------------
491 void EMFWriter::ImplWriteColor( const Color& rColor )
493 UINT32 nCol = rColor.GetRed();
495 nCol |= ( (UINT32) rColor.GetGreen() ) << 8;
496 nCol |= ( (UINT32) rColor.GetBlue() ) << 16;
498 (*mpStm) << nCol;
501 // -----------------------------------------------------------------------------
503 void EMFWriter::ImplWriteRasterOp( RasterOp eRop )
505 UINT32 nROP2;
507 switch( eRop )
509 case ROP_INVERT: nROP2 = 6; break;
510 case ROP_XOR: nROP2 = 7; break;
511 default: nROP2 = 13;break;
514 ImplBeginRecord( WIN_EMR_SETROP2 );
515 (*mpStm) << nROP2;
516 ImplEndRecord();
519 // -----------------------------------------------------------------------------
521 void EMFWriter::ImplWriteExtent( long nExtent )
523 const Size aSize( maVDev.LogicToPixel( Size( nExtent, nExtent ) ) );
524 (*mpStm) << (INT32) aSize.Width();
527 // -----------------------------------------------------------------------------
529 void EMFWriter::ImplWritePoint( const Point& rPoint )
531 const Point aPoint( maVDev.LogicToPixel( rPoint ) );
533 (*mpStm) << (INT32) aPoint.X() << (INT32) aPoint.Y();
536 // -----------------------------------------------------------------------------
538 void EMFWriter::ImplWriteSize( const Size& rSize)
540 const Size aSize( maVDev.LogicToPixel( rSize ) );
542 (*mpStm) << (INT32) aSize.Width() << (INT32) aSize.Height();
545 // -----------------------------------------------------------------------------
547 void EMFWriter::ImplWriteRect( const Rectangle& rRect )
549 const Rectangle aRect( maVDev.LogicToPixel( rRect ) );
551 (*mpStm) << aRect.Left() << aRect.Top() << aRect.Right() << aRect.Bottom();
554 // -----------------------------------------------------------------------------
556 void EMFWriter::ImplWritePolygonRecord( const Polygon& rPoly, BOOL bClose )
558 if( rPoly.GetSize() )
560 if( rPoly.HasFlags() )
561 ImplWritePath( rPoly, bClose );
562 else
564 if( bClose )
565 ImplCheckFillAttr();
567 ImplCheckLineAttr();
569 ImplBeginRecord( bClose ? WIN_EMR_POLYGON : WIN_EMR_POLYLINE );
570 ImplWriteRect( rPoly.GetBoundRect() );
571 (*mpStm) << (UINT32) rPoly.GetSize();
573 for( USHORT i = 0; i < rPoly.GetSize(); i++ )
574 ImplWritePoint( rPoly[ i ] );
576 ImplEndRecord();
581 // -----------------------------------------------------------------------------
583 void EMFWriter::ImplWritePolyPolygonRecord( const PolyPolygon& rPolyPoly )
585 sal_uInt16 n, i, nPolyCount = rPolyPoly.Count();
587 if( nPolyCount )
589 if( 1 == nPolyCount )
590 ImplWritePolygonRecord( rPolyPoly[ 0 ], TRUE );
591 else
593 sal_Bool bHasFlags = sal_False;
594 sal_uInt32 nTotalPoints = 0;
596 for( i = 0; i < nPolyCount; i++ )
598 nTotalPoints += rPolyPoly[ i ].GetSize();
599 if ( rPolyPoly[ i ].HasFlags() )
600 bHasFlags = sal_True;
602 if( nTotalPoints )
604 if ( bHasFlags )
605 ImplWritePath( rPolyPoly, sal_True );
606 else
608 ImplCheckFillAttr();
609 ImplCheckLineAttr();
611 ImplBeginRecord( WIN_EMR_POLYPOLYGON );
612 ImplWriteRect( rPolyPoly.GetBoundRect() );
613 (*mpStm) << (sal_uInt32)nPolyCount << nTotalPoints;
615 for( i = 0; i < nPolyCount; i++ )
616 (*mpStm) << (sal_uInt32)rPolyPoly[ i ].GetSize();
618 for( i = 0; i < nPolyCount; i++ )
620 const Polygon& rPoly = rPolyPoly[ i ];
622 for( n = 0; n < rPoly.GetSize(); n++ )
623 ImplWritePoint( rPoly[ n ] );
625 ImplEndRecord();
632 // -----------------------------------------------------------------------------
634 void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed )
636 if ( bClosed )
637 ImplCheckFillAttr();
638 ImplCheckLineAttr();
640 ImplBeginRecord( WIN_EMR_BEGINPATH );
641 ImplEndRecord();
643 sal_uInt16 i, n, o, nPolyCount = rPolyPoly.Count();
644 for ( i = 0; i < nPolyCount; i++ )
646 n = 0;
647 const Polygon& rPoly = rPolyPoly[ i ];
648 while ( n < rPoly.GetSize() )
650 sal_uInt16 nBezPoints = 0;
651 if ( n )
653 while ( ( ( nBezPoints + n + 2 ) < rPoly.GetSize() ) && ( rPoly.GetFlags( nBezPoints + n ) == POLY_CONTROL ) )
654 nBezPoints += 3;
656 if ( nBezPoints )
658 ImplBeginRecord( WIN_EMR_POLYBEZIERTO );
659 Polygon aNewPoly( nBezPoints + 1 );
660 aNewPoly[ 0 ] = rPoly[ n - 1 ];
661 for ( o = 0; o < nBezPoints; o++ )
662 aNewPoly[ o + 1 ] = rPoly[ n + o ];
663 ImplWriteRect( aNewPoly.GetBoundRect() );
664 (*mpStm) << (sal_uInt32)nBezPoints;
665 for( o = 1; o < aNewPoly.GetSize(); o++ )
666 ImplWritePoint( aNewPoly[ o ] );
667 ImplEndRecord();
668 n = n + nBezPoints;
670 else
672 sal_uInt16 nPoints = 1;
673 while( ( nPoints + n ) < rPoly.GetSize() && ( rPoly.GetFlags( nPoints + n ) != POLY_CONTROL ) )
674 nPoints++;
675 ImplBeginRecord( WIN_EMR_MOVETOEX );
676 ImplWritePoint( rPoly[ n ] );
677 ImplEndRecord();
678 if ( nPoints > 1 )
680 ImplBeginRecord( WIN_EMR_POLYLINETO );
681 Polygon aNewPoly( nPoints );
682 aNewPoly[ 0 ] = rPoly[ n ];
683 for ( o = 1; o < nPoints; o++ )
684 aNewPoly[ o ] = rPoly[ n + o ];
685 ImplWriteRect( aNewPoly.GetBoundRect() );
686 (*mpStm) << (sal_uInt32)( nPoints - 1 );
687 for( o = 1; o < aNewPoly.GetSize(); o++ )
688 ImplWritePoint( aNewPoly[ o ] );
689 ImplEndRecord();
691 n = n + nPoints;
693 if ( bClosed && ( n == rPoly.GetSize() ) )
695 ImplBeginRecord( WIN_EMR_CLOSEFIGURE );
696 ImplEndRecord();
700 ImplBeginRecord( WIN_EMR_ENDPATH );
701 ImplEndRecord();
702 ImplBeginRecord( bClosed ? WIN_EMR_FILLPATH : WIN_EMR_STROKEPATH );
703 ImplEndRecord();
706 // -----------------------------------------------------------------------------
708 void EMFWriter::ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt,
709 const Size& rSz, UINT32 nROP )
711 if( !!rBmp )
713 SvMemoryStream aMemStm( 65535, 65535 );
714 const Size aBmpSizePixel( rBmp.GetSizePixel() );
716 ImplBeginRecord( WIN_EMR_STRETCHDIBITS );
717 ImplWriteRect( Rectangle( rPt, rSz ) );
718 ImplWritePoint( rPt );
719 (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) aBmpSizePixel.Width() << (INT32) aBmpSizePixel.Height();
721 // write offset positions and sizes later
722 const ULONG nOffPos = mpStm->Tell();
723 mpStm->SeekRel( 16 );
725 (*mpStm) << (UINT32) 0 << ( ( ROP_XOR == maVDev.GetRasterOp() && WIN_SRCCOPY == nROP ) ? WIN_SRCINVERT : nROP );
726 ImplWriteSize( rSz );
728 rBmp.Write( aMemStm, TRUE, FALSE );
730 UINT32 nDIBSize = aMemStm.Tell(), nHeaderSize, nCompression, nColsUsed, nPalCount, nImageSize;
731 UINT16 nBitCount;
733 // get DIB parameters
734 aMemStm.Seek( 0 );
735 aMemStm >> nHeaderSize;
736 aMemStm.SeekRel( 10 );
737 aMemStm >> nBitCount >> nCompression >> nImageSize;
738 aMemStm.SeekRel( 8 );
739 aMemStm >> nColsUsed;
741 nPalCount = ( nBitCount <= 8 ) ? ( nColsUsed ? nColsUsed : ( 1 << (UINT32) nBitCount ) ) :
742 ( ( 3 == nCompression ) ? 12 : 0 );
744 mpStm->Write( aMemStm.GetData(), nDIBSize );
746 const ULONG nEndPos = mpStm->Tell();
747 mpStm->Seek( nOffPos );
748 (*mpStm) << (UINT32) 80 << (UINT32)( nHeaderSize + ( nPalCount << 2 ) );
749 (*mpStm) << (UINT32)( 80 + ( nHeaderSize + ( nPalCount << 2 ) ) ) << nImageSize;
750 mpStm->Seek( nEndPos );
752 ImplEndRecord();
756 // -----------------------------------------------------------------------------
758 void EMFWriter::ImplWriteTextRecord( const Point& rPos, const String rText, const sal_Int32* pDXArray, sal_uInt32 nWidth )
760 xub_StrLen nLen = rText.Len(), i;
762 if( nLen )
764 sal_uInt32 nNormWidth;
765 sal_Int32* pOwnArray;
766 sal_Int32* pDX;
768 // get text sizes
769 if( pDXArray )
771 pOwnArray = NULL;
772 nNormWidth = maVDev.GetTextWidth( rText );
773 pDX = (sal_Int32*) pDXArray;
775 else
777 pOwnArray = new sal_Int32[ nLen ];
778 nNormWidth = maVDev.GetTextArray( rText, pOwnArray );
779 pDX = pOwnArray;
782 if( nLen > 1 )
784 nNormWidth = pDX[ nLen - 2 ] + maVDev.GetTextWidth( rText.GetChar( nLen - 1 ) );
786 if( nWidth && nNormWidth && ( nWidth != nNormWidth ) )
788 const double fFactor = (double) nWidth / nNormWidth;
790 for( i = 0; i < ( nLen - 1 ); i++ )
791 pDX[ i ] = FRound( pDX[ i ] * fFactor );
795 // write text record
796 ImplBeginRecord( WIN_EMR_EXTTEXTOUTW );
798 ImplWriteRect( Rectangle( rPos, Size( nNormWidth, maVDev.GetTextHeight() ) ) );
799 (*mpStm) << (UINT32)1;
800 (*mpStm) << (INT32) 0 << (INT32) 0;
801 ImplWritePoint( rPos );
802 (*mpStm) << (UINT32) nLen << (UINT32) 76 << (UINT32) 2;
803 (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) 0 << (INT32) 0;
804 (*mpStm) << (UINT32) ( 76 + ( nLen << 1 ) + ( (nLen & 1 ) ? 2 : 0 ) );
806 // write text
807 for( i = 0; i < nLen; i++ )
808 (*mpStm) << (sal_Unicode)rText.GetChar( i );
810 // padding word
811 if( nLen & 1 )
812 (*mpStm) << (UINT16) 0;
814 // write DX array
815 ImplWriteExtent( pDX[ 0 ] );
817 if( nLen > 1 )
819 for( i = 1; i < ( nLen - 1 ); i++ )
820 ImplWriteExtent( pDX[ i ] - pDX[ i - 1 ] );
822 ImplWriteExtent( pDX[ nLen - 2 ] / ( nLen - 1 ) );
825 ImplEndRecord();
826 delete[] pOwnArray;
830 // -----------------------------------------------------------------------------
832 void EMFWriter::ImplWrite( const GDIMetaFile& rMtf )
834 for( ULONG j = 0, nActionCount = rMtf.GetActionCount(); j < nActionCount; j++ )
836 const MetaAction* pAction = rMtf.GetAction( j );
837 const USHORT nType = pAction->GetType();
839 switch( nType )
841 case( META_PIXEL_ACTION ):
843 const MetaPixelAction* pA = (const MetaPixelAction*) pAction;
845 ImplCheckLineAttr();
846 ImplBeginRecord( WIN_EMR_SETPIXELV );
847 ImplWritePoint( pA->GetPoint() );
848 ImplWriteColor( pA->GetColor() );
849 ImplEndRecord();
851 break;
853 case( META_POINT_ACTION ):
855 if( maVDev.IsLineColor() )
857 const MetaPointAction* pA = (const MetaPointAction*) pAction;
859 ImplCheckLineAttr();
860 ImplBeginRecord( WIN_EMR_SETPIXELV );
861 ImplWritePoint( pA->GetPoint() );
862 ImplWriteColor( maVDev.GetLineColor() );
863 ImplEndRecord();
866 break;
868 case( META_LINE_ACTION ):
870 if( maVDev.IsLineColor() )
872 const MetaLineAction* pA = (const MetaLineAction*) pAction;
874 ImplCheckLineAttr();
876 ImplBeginRecord( WIN_EMR_MOVETOEX );
877 ImplWritePoint( pA->GetStartPoint() );
878 ImplEndRecord();
880 ImplBeginRecord( WIN_EMR_LINETO );
881 ImplWritePoint( pA->GetEndPoint() );
882 ImplEndRecord();
884 ImplBeginRecord( WIN_EMR_SETPIXELV );
885 ImplWritePoint( pA->GetEndPoint() );
886 ImplWriteColor( maVDev.GetLineColor() );
887 ImplEndRecord();
890 break;
892 case( META_RECT_ACTION ):
894 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
896 const MetaRectAction* pA = (const MetaRectAction*) pAction;
898 ImplCheckFillAttr();
899 ImplCheckLineAttr();
901 ImplBeginRecord( WIN_EMR_RECTANGLE );
902 ImplWriteRect( pA->GetRect() );
903 ImplEndRecord();
906 break;
908 case( META_ROUNDRECT_ACTION ):
910 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
912 const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pAction;
914 ImplCheckFillAttr();
915 ImplCheckLineAttr();
917 ImplBeginRecord( WIN_EMR_ROUNDRECT );
918 ImplWriteRect( pA->GetRect() );
919 ImplWriteSize( Size( pA->GetHorzRound(), pA->GetVertRound() ) );
920 ImplEndRecord();
923 break;
925 case( META_ELLIPSE_ACTION ):
927 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
929 const MetaEllipseAction* pA = (const MetaEllipseAction*) pAction;
931 ImplCheckFillAttr();
932 ImplCheckLineAttr();
934 ImplBeginRecord( WIN_EMR_ELLIPSE );
935 ImplWriteRect( pA->GetRect() );
936 ImplEndRecord();
939 break;
941 case( META_ARC_ACTION ):
942 case( META_PIE_ACTION ):
943 case( META_CHORD_ACTION ):
944 case( META_POLYGON_ACTION ):
946 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
948 Polygon aPoly;
950 switch( nType )
952 case( META_ARC_ACTION ):
954 const MetaArcAction* pA = (const MetaArcAction*) pAction;
955 aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_ARC );
957 break;
959 case( META_PIE_ACTION ):
961 const MetaPieAction* pA = (const MetaPieAction*) pAction;
962 aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_PIE );
964 break;
966 case( META_CHORD_ACTION ):
968 const MetaChordAction* pA = (const MetaChordAction*) pAction;
969 aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_CHORD );
971 break;
973 case( META_POLYGON_ACTION ):
974 aPoly = ( (const MetaPolygonAction*) pAction )->GetPolygon();
975 break;
978 ImplWritePolygonRecord( aPoly, nType != META_ARC_ACTION );
981 break;
983 case( META_POLYLINE_ACTION ):
985 if( maVDev.IsLineColor() )
986 ImplWritePolygonRecord( ( (const MetaPolyLineAction*) pAction )->GetPolygon(), FALSE );
988 break;
990 case( META_POLYPOLYGON_ACTION ):
992 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
993 ImplWritePolyPolygonRecord( ( (const MetaPolyPolygonAction*) pAction )->GetPolyPolygon() );
995 break;
997 case( META_GRADIENT_ACTION ):
999 const MetaGradientAction* pA = (const MetaGradientAction*) pAction;
1000 GDIMetaFile aTmpMtf;
1002 maVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
1003 ImplWrite( aTmpMtf );
1005 break;
1007 case META_HATCH_ACTION:
1009 const MetaHatchAction* pA = (const MetaHatchAction*) pAction;
1010 GDIMetaFile aTmpMtf;
1012 maVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
1013 ImplWrite( aTmpMtf );
1015 break;
1017 case META_TRANSPARENT_ACTION:
1019 ImplCheckFillAttr();
1020 ImplCheckLineAttr();
1021 ImplWritePolyPolygonRecord( ( (MetaTransparentAction*) pAction )->GetPolyPolygon() );
1023 break;
1025 case META_FLOATTRANSPARENT_ACTION:
1027 const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pAction;
1029 GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
1030 Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
1031 const Size aSrcSize( aTmpMtf.GetPrefSize() );
1032 const Point aDestPt( pA->GetPoint() );
1033 const Size aDestSize( pA->GetSize() );
1034 const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
1035 const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
1036 long nMoveX, nMoveY;
1038 if( fScaleX != 1.0 || fScaleY != 1.0 )
1040 aTmpMtf.Scale( fScaleX, fScaleY );
1041 aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
1044 nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
1046 if( nMoveX || nMoveY )
1047 aTmpMtf.Move( nMoveX, nMoveY );
1049 ImplCheckFillAttr();
1050 ImplCheckLineAttr();
1051 ImplCheckTextAttr();
1052 ImplWrite( aTmpMtf );
1054 break;
1056 case( META_EPS_ACTION ):
1058 const MetaEPSAction* pA = (const MetaEPSAction*) pAction;
1059 const GDIMetaFile aSubstitute( pA->GetSubstitute() );
1061 for( ULONG i = 0, nCount = aSubstitute.GetActionCount(); i < nCount; i++ )
1063 const MetaAction* pSubstAct = aSubstitute.GetAction( i );
1064 if( pSubstAct->GetType() == META_BMPSCALE_ACTION )
1066 maVDev.Push( PUSH_ALL );
1067 ImplBeginRecord( WIN_EMR_SAVEDC );
1068 ImplEndRecord();
1070 MapMode aMapMode( aSubstitute.GetPrefMapMode() );
1071 Size aOutSize( maVDev.LogicToLogic( pA->GetSize(), maVDev.GetMapMode(), aMapMode ) );
1072 aMapMode.SetScaleX( Fraction( aOutSize.Width(), aSubstitute.GetPrefSize().Width() ) );
1073 aMapMode.SetScaleY( Fraction( aOutSize.Height(), aSubstitute.GetPrefSize().Height() ) );
1074 aMapMode.SetOrigin( maVDev.LogicToLogic( pA->GetPoint(), maVDev.GetMapMode(), aMapMode ) );
1075 maVDev.SetMapMode( aMapMode );
1076 ImplWrite( aSubstitute );
1078 maVDev.Pop();
1079 ImplBeginRecord( WIN_EMR_RESTOREDC );
1080 (*mpStm) << (INT32) -1;
1081 ImplEndRecord();
1082 break;
1086 break;
1088 case META_BMP_ACTION:
1090 const MetaBmpAction* pA = (const MetaBmpAction *) pAction;
1091 ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), pA->GetBitmap().GetSizePixel(), WIN_SRCCOPY );
1093 break;
1095 case META_BMPSCALE_ACTION:
1097 const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction;
1098 ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
1100 break;
1102 case META_BMPSCALEPART_ACTION:
1104 const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pAction;
1105 Bitmap aTmp( pA->GetBitmap() );
1107 if( aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
1108 ImplWriteBmpRecord( aTmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
1110 break;
1112 case META_BMPEX_ACTION:
1114 const MetaBmpExAction* pA = (const MetaBmpExAction *) pAction;
1115 Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
1116 Bitmap aMsk( pA->GetBitmapEx().GetMask() );
1118 if( !!aMsk )
1120 aBmp.Replace( aMsk, COL_WHITE );
1121 aMsk.Invert();
1122 ImplWriteBmpRecord( aMsk, pA->GetPoint(), aMsk.GetSizePixel(), WIN_SRCPAINT );
1123 ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCAND );
1125 else
1126 ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCCOPY );
1128 break;
1130 case META_BMPEXSCALE_ACTION:
1132 const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction;
1133 Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
1134 Bitmap aMsk( pA->GetBitmapEx().GetMask() );
1136 if( !!aMsk )
1138 aBmp.Replace( aMsk, COL_WHITE );
1139 aMsk.Invert();
1140 ImplWriteBmpRecord( aMsk, pA->GetPoint(), pA->GetSize(), WIN_SRCPAINT );
1141 ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCAND );
1143 else
1144 ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
1146 break;
1148 case META_BMPEXSCALEPART_ACTION:
1150 const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pAction;
1151 BitmapEx aBmpEx( pA->GetBitmapEx() );
1152 aBmpEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
1153 Bitmap aBmp( aBmpEx.GetBitmap() );
1154 Bitmap aMsk( aBmpEx.GetMask() );
1156 if( !!aMsk )
1158 aBmp.Replace( aMsk, COL_WHITE );
1159 aMsk.Invert();
1160 ImplWriteBmpRecord( aMsk, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCPAINT );
1161 ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCAND );
1163 else
1164 ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
1166 break;
1168 case META_TEXT_ACTION:
1170 const MetaTextAction* pA = (const MetaTextAction*) pAction;
1171 const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
1173 ImplCheckTextAttr();
1174 ImplWriteTextRecord( pA->GetPoint(), aText, NULL, 0 );
1176 break;
1178 case META_TEXTRECT_ACTION:
1180 const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction;
1181 const String aText( pA->GetText() );
1183 ImplCheckTextAttr();
1184 ImplWriteTextRecord( pA->GetRect().TopLeft(), aText, NULL, 0 );
1186 break;
1188 case META_TEXTARRAY_ACTION:
1190 const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pAction;
1191 const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
1193 ImplCheckTextAttr();
1194 ImplWriteTextRecord( pA->GetPoint(), aText, pA->GetDXArray(), 0 );
1196 break;
1198 case META_STRETCHTEXT_ACTION:
1200 const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction;
1201 const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
1203 ImplCheckTextAttr();
1204 ImplWriteTextRecord( pA->GetPoint(), aText, NULL, pA->GetWidth() );
1206 break;
1208 case( META_LINECOLOR_ACTION ):
1210 ( (MetaAction*) pAction )->Execute( &maVDev );
1211 mbLineChanged = TRUE;
1213 break;
1215 case( META_FILLCOLOR_ACTION ):
1217 ( (MetaAction*) pAction )->Execute( &maVDev );
1218 mbFillChanged = TRUE;
1220 break;
1222 case( META_TEXTCOLOR_ACTION ):
1223 case( META_TEXTLINECOLOR_ACTION ):
1224 case( META_TEXTFILLCOLOR_ACTION ):
1225 case( META_TEXTALIGN_ACTION ):
1226 case( META_FONT_ACTION ):
1228 ( (MetaAction*) pAction )->Execute( &maVDev );
1229 mbTextChanged = TRUE;
1231 break;
1233 case( META_ISECTRECTCLIPREGION_ACTION ):
1235 ( (MetaAction*) pAction )->Execute( &maVDev );
1237 ImplBeginRecord( WIN_EMR_INTERSECTCLIPRECT );
1238 ImplWriteRect( ( (MetaISectRectClipRegionAction*) pAction )->GetRect() );
1239 ImplEndRecord();
1241 break;
1243 case( META_CLIPREGION_ACTION ):
1244 case( META_ISECTREGIONCLIPREGION_ACTION ):
1245 case( META_MOVECLIPREGION_ACTION ):
1247 ( (MetaAction*) pAction )->Execute( &maVDev );
1249 break;
1251 case( META_REFPOINT_ACTION ):
1252 case( META_MAPMODE_ACTION ):
1253 ( (MetaAction*) pAction )->Execute( &maVDev );
1254 break;
1256 case( META_PUSH_ACTION ):
1258 ( (MetaAction*) pAction )->Execute( &maVDev );
1260 ImplBeginRecord( WIN_EMR_SAVEDC );
1261 ImplEndRecord();
1263 break;
1265 case( META_POP_ACTION ):
1267 ( (MetaAction*) pAction )->Execute( &maVDev );
1269 ImplBeginRecord( WIN_EMR_RESTOREDC );
1270 (*mpStm) << (INT32) -1;
1271 ImplEndRecord();
1273 ImplWriteRasterOp( maVDev.GetRasterOp() );
1274 mbLineChanged = mbFillChanged = mbTextChanged = TRUE;
1276 break;
1278 case( META_RASTEROP_ACTION ):
1280 ( (MetaAction*) pAction )->Execute( &maVDev );
1281 ImplWriteRasterOp( ( (MetaRasterOpAction*) pAction )->GetRasterOp() );
1283 break;
1285 case( META_LAYOUTMODE_ACTION ):
1287 sal_uInt32 nLayoutMode = ( (MetaLayoutModeAction*) pAction )->GetLayoutMode();
1288 mnHorTextAlign = 0;
1289 if (nLayoutMode & TEXT_LAYOUT_BIDI_RTL)
1291 mnHorTextAlign = TA_RIGHT | TA_RTLREADING;
1293 if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_RIGHT)
1294 mnHorTextAlign |= TA_RIGHT;
1295 else if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_LEFT)
1296 mnHorTextAlign &= ~TA_RIGHT;
1297 break;
1300 case( META_MASK_ACTION ):
1301 case( META_MASKSCALE_ACTION ):
1302 case( META_MASKSCALEPART_ACTION ):
1303 case( META_WALLPAPER_ACTION ):
1304 case( META_TEXTLINE_ACTION ):
1305 case( META_COMMENT_ACTION ):
1306 case( META_GRADIENTEX_ACTION ):
1308 // !!! >>> we don't want to support these actions
1310 break;
1312 default:
1313 DBG_ERROR( ( ByteString( "EMFWriter::ImplWriteActions: unsupported MetaAction #" ) += ByteString::CreateFromInt32( nType ) ).GetBuffer() );
1314 break;