1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: emfwr.cxx,v $
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"
35 #include <vcl/salbtype.hxx>
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
161 #define TA_BASELINE 24
162 #define TA_RTLREADING 256
163 #define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING)
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
;
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
) );
188 rOStm
.SeekRel( 100 );
190 // write initial values
191 ImplBeginRecord( WIN_EMR_SETWINDOWORGEX
);
192 (*mpStm
) << (INT32
) 0 << (INT32
) 0;
195 ImplBeginRecord( WIN_EMR_SETWINDOWEXTEX
);
196 (*mpStm
) << (INT32
) aMtfSizePix
.Width() << (INT32
) aMtfSizePix
.Height();
199 ImplWriteRasterOp( ROP_OVERPAINT
);
201 ImplBeginRecord( WIN_EMR_SETBKMODE
);
202 (*mpStm
) << (UINT32
) 1; // TRANSPARENT
208 ImplBeginRecord( WIN_EMR_EOF
);
209 (*mpStm
)<< (sal_uInt32
)0 // nPalEntries
210 << (sal_uInt32
)0x16 // offPalEntries
211 << (sal_uInt32
)0x14; // nSizeLast
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
)
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!" );
271 mnRecordPos
= mpStm
->Tell();
278 // -----------------------------------------------------------------------------
280 void EMFWriter::ImplEndRecord()
282 DBG_ASSERT( mbRecordOpen
, "Record was not opened!" );
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
292 *mpStm
<< (sal_uInt32
)( ( nActPos
- mnRecordPos
) + nFillBytes
);
293 mpStm
->Seek( nActPos
);
294 while( nFillBytes
-- )
295 *mpStm
<< (sal_uInt8
)0;
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
;
321 // destroy handle of created object
322 ImplBeginRecord( WIN_EMR_DELETEOBJECT
);
323 ( *mpStm
) << rHandle
;
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() );
349 ImplBeginRecord( WIN_EMR_SELECTOBJECT
);
350 (*mpStm
) << mnLineHandle
;
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
;
370 ImplBeginRecord( WIN_EMR_SELECTOBJECT
);
371 (*mpStm
) << mnFillHandle
;
376 // -----------------------------------------------------------------------------
378 void EMFWriter::ImplCheckTextAttr()
380 if( mbTextChanged
&& ImplPrepareHandleSelect( mnTextHandle
, TEXT_SELECT
) )
382 const Font
& rFont
= maVDev
.GetFont();
383 String
aFontName( rFont
.GetName() );
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;
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;
433 (*mpStm
) << nPitchAndFamily
;
435 for( i
= 0; i
< 32; i
++ )
436 (*mpStm
) << (sal_Unicode
) ( ( i
< aFontName
.Len() ) ? aFontName
.GetChar( i
) : 0 );
439 for( i
= 0; i
< 64; i
++ )
440 (*mpStm
) << (sal_Unicode
) 0;
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 ;
450 (*mpStm
) << (UINT32
) 0;
453 (*mpStm
) << (UINT32
) 0;
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;
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
;
479 ImplBeginRecord( WIN_EMR_SETTEXTCOLOR
);
480 ImplWriteColor( maVDev
.GetTextColor() );
483 ImplBeginRecord( WIN_EMR_SELECTOBJECT
);
484 (*mpStm
) << mnTextHandle
;
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;
501 // -----------------------------------------------------------------------------
503 void EMFWriter::ImplWriteRasterOp( RasterOp 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
);
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
);
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
] );
581 // -----------------------------------------------------------------------------
583 void EMFWriter::ImplWritePolyPolygonRecord( const PolyPolygon
& rPolyPoly
)
585 sal_uInt16 n
, i
, nPolyCount
= rPolyPoly
.Count();
589 if( 1 == nPolyCount
)
590 ImplWritePolygonRecord( rPolyPoly
[ 0 ], TRUE
);
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
;
605 ImplWritePath( rPolyPoly
, sal_True
);
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
] );
632 // -----------------------------------------------------------------------------
634 void EMFWriter::ImplWritePath( const PolyPolygon
& rPolyPoly
, sal_Bool bClosed
)
640 ImplBeginRecord( WIN_EMR_BEGINPATH
);
643 sal_uInt16 i
, n
, o
, nPolyCount
= rPolyPoly
.Count();
644 for ( i
= 0; i
< nPolyCount
; i
++ )
647 const Polygon
& rPoly
= rPolyPoly
[ i
];
648 while ( n
< rPoly
.GetSize() )
650 sal_uInt16 nBezPoints
= 0;
653 while ( ( ( nBezPoints
+ n
+ 2 ) < rPoly
.GetSize() ) && ( rPoly
.GetFlags( nBezPoints
+ n
) == POLY_CONTROL
) )
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
] );
672 sal_uInt16 nPoints
= 1;
673 while( ( nPoints
+ n
) < rPoly
.GetSize() && ( rPoly
.GetFlags( nPoints
+ n
) != POLY_CONTROL
) )
675 ImplBeginRecord( WIN_EMR_MOVETOEX
);
676 ImplWritePoint( rPoly
[ n
] );
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
] );
693 if ( bClosed
&& ( n
== rPoly
.GetSize() ) )
695 ImplBeginRecord( WIN_EMR_CLOSEFIGURE
);
700 ImplBeginRecord( WIN_EMR_ENDPATH
);
702 ImplBeginRecord( bClosed
? WIN_EMR_FILLPATH
: WIN_EMR_STROKEPATH
);
706 // -----------------------------------------------------------------------------
708 void EMFWriter::ImplWriteBmpRecord( const Bitmap
& rBmp
, const Point
& rPt
,
709 const Size
& rSz
, UINT32 nROP
)
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
;
733 // get DIB parameters
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
);
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
;
764 sal_uInt32 nNormWidth
;
765 sal_Int32
* pOwnArray
;
772 nNormWidth
= maVDev
.GetTextWidth( rText
);
773 pDX
= (sal_Int32
*) pDXArray
;
777 pOwnArray
= new sal_Int32
[ nLen
];
778 nNormWidth
= maVDev
.GetTextArray( rText
, pOwnArray
);
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
);
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 ) );
807 for( i
= 0; i
< nLen
; i
++ )
808 (*mpStm
) << (sal_Unicode
)rText
.GetChar( i
);
812 (*mpStm
) << (UINT16
) 0;
815 ImplWriteExtent( pDX
[ 0 ] );
819 for( i
= 1; i
< ( nLen
- 1 ); i
++ )
820 ImplWriteExtent( pDX
[ i
] - pDX
[ i
- 1 ] );
822 ImplWriteExtent( pDX
[ nLen
- 2 ] / ( nLen
- 1 ) );
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();
841 case( META_PIXEL_ACTION
):
843 const MetaPixelAction
* pA
= (const MetaPixelAction
*) pAction
;
846 ImplBeginRecord( WIN_EMR_SETPIXELV
);
847 ImplWritePoint( pA
->GetPoint() );
848 ImplWriteColor( pA
->GetColor() );
853 case( META_POINT_ACTION
):
855 if( maVDev
.IsLineColor() )
857 const MetaPointAction
* pA
= (const MetaPointAction
*) pAction
;
860 ImplBeginRecord( WIN_EMR_SETPIXELV
);
861 ImplWritePoint( pA
->GetPoint() );
862 ImplWriteColor( maVDev
.GetLineColor() );
868 case( META_LINE_ACTION
):
870 if( maVDev
.IsLineColor() )
872 const MetaLineAction
* pA
= (const MetaLineAction
*) pAction
;
876 ImplBeginRecord( WIN_EMR_MOVETOEX
);
877 ImplWritePoint( pA
->GetStartPoint() );
880 ImplBeginRecord( WIN_EMR_LINETO
);
881 ImplWritePoint( pA
->GetEndPoint() );
884 ImplBeginRecord( WIN_EMR_SETPIXELV
);
885 ImplWritePoint( pA
->GetEndPoint() );
886 ImplWriteColor( maVDev
.GetLineColor() );
892 case( META_RECT_ACTION
):
894 if( maVDev
.IsLineColor() || maVDev
.IsFillColor() )
896 const MetaRectAction
* pA
= (const MetaRectAction
*) pAction
;
901 ImplBeginRecord( WIN_EMR_RECTANGLE
);
902 ImplWriteRect( pA
->GetRect() );
908 case( META_ROUNDRECT_ACTION
):
910 if( maVDev
.IsLineColor() || maVDev
.IsFillColor() )
912 const MetaRoundRectAction
* pA
= (const MetaRoundRectAction
*) pAction
;
917 ImplBeginRecord( WIN_EMR_ROUNDRECT
);
918 ImplWriteRect( pA
->GetRect() );
919 ImplWriteSize( Size( pA
->GetHorzRound(), pA
->GetVertRound() ) );
925 case( META_ELLIPSE_ACTION
):
927 if( maVDev
.IsLineColor() || maVDev
.IsFillColor() )
929 const MetaEllipseAction
* pA
= (const MetaEllipseAction
*) pAction
;
934 ImplBeginRecord( WIN_EMR_ELLIPSE
);
935 ImplWriteRect( pA
->GetRect() );
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() )
952 case( META_ARC_ACTION
):
954 const MetaArcAction
* pA
= (const MetaArcAction
*) pAction
;
955 aPoly
= Polygon( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint(), POLY_ARC
);
959 case( META_PIE_ACTION
):
961 const MetaPieAction
* pA
= (const MetaPieAction
*) pAction
;
962 aPoly
= Polygon( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint(), POLY_PIE
);
966 case( META_CHORD_ACTION
):
968 const MetaChordAction
* pA
= (const MetaChordAction
*) pAction
;
969 aPoly
= Polygon( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint(), POLY_CHORD
);
973 case( META_POLYGON_ACTION
):
974 aPoly
= ( (const MetaPolygonAction
*) pAction
)->GetPolygon();
978 ImplWritePolygonRecord( aPoly
, nType
!= META_ARC_ACTION
);
983 case( META_POLYLINE_ACTION
):
985 if( maVDev
.IsLineColor() )
986 ImplWritePolygonRecord( ( (const MetaPolyLineAction
*) pAction
)->GetPolygon(), FALSE
);
990 case( META_POLYPOLYGON_ACTION
):
992 if( maVDev
.IsLineColor() || maVDev
.IsFillColor() )
993 ImplWritePolyPolygonRecord( ( (const MetaPolyPolygonAction
*) pAction
)->GetPolyPolygon() );
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
);
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
);
1017 case META_TRANSPARENT_ACTION
:
1019 ImplCheckFillAttr();
1020 ImplCheckLineAttr();
1021 ImplWritePolyPolygonRecord( ( (MetaTransparentAction
*) pAction
)->GetPolyPolygon() );
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
);
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
);
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
);
1079 ImplBeginRecord( WIN_EMR_RESTOREDC
);
1080 (*mpStm
) << (INT32
) -1;
1088 case META_BMP_ACTION
:
1090 const MetaBmpAction
* pA
= (const MetaBmpAction
*) pAction
;
1091 ImplWriteBmpRecord( pA
->GetBitmap(), pA
->GetPoint(), pA
->GetBitmap().GetSizePixel(), WIN_SRCCOPY
);
1095 case META_BMPSCALE_ACTION
:
1097 const MetaBmpScaleAction
* pA
= (const MetaBmpScaleAction
*) pAction
;
1098 ImplWriteBmpRecord( pA
->GetBitmap(), pA
->GetPoint(), pA
->GetSize(), WIN_SRCCOPY
);
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
);
1112 case META_BMPEX_ACTION
:
1114 const MetaBmpExAction
* pA
= (const MetaBmpExAction
*) pAction
;
1115 Bitmap
aBmp( pA
->GetBitmapEx().GetBitmap() );
1116 Bitmap
aMsk( pA
->GetBitmapEx().GetMask() );
1120 aBmp
.Replace( aMsk
, COL_WHITE
);
1122 ImplWriteBmpRecord( aMsk
, pA
->GetPoint(), aMsk
.GetSizePixel(), WIN_SRCPAINT
);
1123 ImplWriteBmpRecord( aBmp
, pA
->GetPoint(), aBmp
.GetSizePixel(), WIN_SRCAND
);
1126 ImplWriteBmpRecord( aBmp
, pA
->GetPoint(), aBmp
.GetSizePixel(), WIN_SRCCOPY
);
1130 case META_BMPEXSCALE_ACTION
:
1132 const MetaBmpExScaleAction
* pA
= (const MetaBmpExScaleAction
*) pAction
;
1133 Bitmap
aBmp( pA
->GetBitmapEx().GetBitmap() );
1134 Bitmap
aMsk( pA
->GetBitmapEx().GetMask() );
1138 aBmp
.Replace( aMsk
, COL_WHITE
);
1140 ImplWriteBmpRecord( aMsk
, pA
->GetPoint(), pA
->GetSize(), WIN_SRCPAINT
);
1141 ImplWriteBmpRecord( aBmp
, pA
->GetPoint(), pA
->GetSize(), WIN_SRCAND
);
1144 ImplWriteBmpRecord( aBmp
, pA
->GetPoint(), pA
->GetSize(), WIN_SRCCOPY
);
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() );
1158 aBmp
.Replace( aMsk
, COL_WHITE
);
1160 ImplWriteBmpRecord( aMsk
, pA
->GetDestPoint(), pA
->GetDestSize(), WIN_SRCPAINT
);
1161 ImplWriteBmpRecord( aBmp
, pA
->GetDestPoint(), pA
->GetDestSize(), WIN_SRCAND
);
1164 ImplWriteBmpRecord( aBmp
, pA
->GetDestPoint(), pA
->GetDestSize(), WIN_SRCCOPY
);
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 );
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 );
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 );
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() );
1208 case( META_LINECOLOR_ACTION
):
1210 ( (MetaAction
*) pAction
)->Execute( &maVDev
);
1211 mbLineChanged
= TRUE
;
1215 case( META_FILLCOLOR_ACTION
):
1217 ( (MetaAction
*) pAction
)->Execute( &maVDev
);
1218 mbFillChanged
= TRUE
;
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
;
1233 case( META_ISECTRECTCLIPREGION_ACTION
):
1235 ( (MetaAction
*) pAction
)->Execute( &maVDev
);
1237 ImplBeginRecord( WIN_EMR_INTERSECTCLIPRECT
);
1238 ImplWriteRect( ( (MetaISectRectClipRegionAction
*) pAction
)->GetRect() );
1243 case( META_CLIPREGION_ACTION
):
1244 case( META_ISECTREGIONCLIPREGION_ACTION
):
1245 case( META_MOVECLIPREGION_ACTION
):
1247 ( (MetaAction
*) pAction
)->Execute( &maVDev
);
1251 case( META_REFPOINT_ACTION
):
1252 case( META_MAPMODE_ACTION
):
1253 ( (MetaAction
*) pAction
)->Execute( &maVDev
);
1256 case( META_PUSH_ACTION
):
1258 ( (MetaAction
*) pAction
)->Execute( &maVDev
);
1260 ImplBeginRecord( WIN_EMR_SAVEDC
);
1265 case( META_POP_ACTION
):
1267 ( (MetaAction
*) pAction
)->Execute( &maVDev
);
1269 ImplBeginRecord( WIN_EMR_RESTOREDC
);
1270 (*mpStm
) << (INT32
) -1;
1273 ImplWriteRasterOp( maVDev
.GetRasterOp() );
1274 mbLineChanged
= mbFillChanged
= mbTextChanged
= TRUE
;
1278 case( META_RASTEROP_ACTION
):
1280 ( (MetaAction
*) pAction
)->Execute( &maVDev
);
1281 ImplWriteRasterOp( ( (MetaRasterOpAction
*) pAction
)->GetRasterOp() );
1285 case( META_LAYOUTMODE_ACTION
):
1287 sal_uInt32 nLayoutMode
= ( (MetaLayoutModeAction
*) pAction
)->GetLayoutMode();
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
;
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
1313 DBG_ERROR( ( ByteString( "EMFWriter::ImplWriteActions: unsupported MetaAction #" ) += ByteString::CreateFromInt32( nType
) ).GetBuffer() );