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: wmfwr.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"
34 #include <vcl/salbtype.hxx>
36 #include <vcl/fontcvt.hxx>
38 #include <rtl/tencinfo.h>
39 #include <tools/tenccvt.hxx>
40 #include <osl/endian.h>
41 #ifndef INCLUDED_I18NUTIL_UNICODE_HXX
42 #include <i18nutil/unicode.hxx> //unicode::getUnicodeScriptType
46 #include <vcl/metric.hxx>
48 //====================== MS-Windows-defines ===============================
50 #define W_META_SETBKCOLOR 0x0201
51 #define W_META_SETBKMODE 0x0102
52 #define W_META_SETMAPMODE 0x0103
53 #define W_META_SETROP2 0x0104
54 #define W_META_SETRELABS 0x0105
55 #define W_META_SETPOLYFILLMODE 0x0106
56 #define W_META_SETSTRETCHBLTMODE 0x0107
57 #define W_META_SETTEXTCHAREXTRA 0x0108
58 #define W_META_SETTEXTCOLOR 0x0209
59 #define W_META_SETTEXTJUSTIFICATION 0x020A
60 #define W_META_SETWINDOWORG 0x020B
61 #define W_META_SETWINDOWEXT 0x020C
62 #define W_META_SETVIEWPORTORG 0x020D
63 #define W_META_SETVIEWPORTEXT 0x020E
64 #define W_META_OFFSETWINDOWORG 0x020F
65 #define W_META_SCALEWINDOWEXT 0x0410
66 #define W_META_OFFSETVIEWPORTORG 0x0211
67 #define W_META_SCALEVIEWPORTEXT 0x0412
68 #define W_META_LINETO 0x0213
69 #define W_META_MOVETO 0x0214
70 #define W_META_EXCLUDECLIPRECT 0x0415
71 #define W_META_INTERSECTCLIPRECT 0x0416
72 #define W_META_ARC 0x0817
73 #define W_META_ELLIPSE 0x0418
74 #define W_META_FLOODFILL 0x0419
75 #define W_META_PIE 0x081A
76 #define W_META_RECTANGLE 0x041B
77 #define W_META_ROUNDRECT 0x061C
78 #define W_META_PATBLT 0x061D
79 #define W_META_SAVEDC 0x001E
80 #define W_META_SETPIXEL 0x041F
81 #define W_META_OFFSETCLIPRGN 0x0220
82 #define W_META_TEXTOUT 0x0521
83 #define W_META_BITBLT 0x0922
84 #define W_META_STRETCHBLT 0x0B23
85 #define W_META_POLYGON 0x0324
86 #define W_META_POLYLINE 0x0325
87 #define W_META_ESCAPE 0x0626
88 #define W_META_RESTOREDC 0x0127
89 #define W_META_FILLREGION 0x0228
90 #define W_META_FRAMEREGION 0x0429
91 #define W_META_INVERTREGION 0x012A
92 #define W_META_PAINTREGION 0x012B
93 #define W_META_SELECTCLIPREGION 0x012C
94 #define W_META_SELECTOBJECT 0x012D
95 #define W_META_SETTEXTALIGN 0x012E
96 #define W_META_DRAWTEXT 0x062F
97 #define W_META_CHORD 0x0830
98 #define W_META_SETMAPPERFLAGS 0x0231
99 #define W_META_EXTTEXTOUT 0x0a32
100 #define W_META_SETDIBTODEV 0x0d33
101 #define W_META_SELECTPALETTE 0x0234
102 #define W_META_REALIZEPALETTE 0x0035
103 #define W_META_ANIMATEPALETTE 0x0436
104 #define W_META_SETPALENTRIES 0x0037
105 #define W_META_POLYPOLYGON 0x0538
106 #define W_META_RESIZEPALETTE 0x0139
107 #define W_META_DIBBITBLT 0x0940
108 #define W_META_DIBSTRETCHBLT 0x0b41
109 #define W_META_DIBCREATEPATTERNBRUSH 0x0142
110 #define W_META_STRETCHDIB 0x0f43
111 #define W_META_EXTFLOODFILL 0x0548
112 #define W_META_RESETDC 0x014C
113 #define W_META_STARTDOC 0x014D
114 #define W_META_STARTPAGE 0x004F
115 #define W_META_ENDPAGE 0x0050
116 #define W_META_ABORTDOC 0x0052
117 #define W_META_ENDDOC 0x005E
118 #define W_META_DELETEOBJECT 0x01f0
119 #define W_META_CREATEPALETTE 0x00f7
120 #define W_META_CREATEBRUSH 0x00F8
121 #define W_META_CREATEPATTERNBRUSH 0x01F9
122 #define W_META_CREATEPENINDIRECT 0x02FA
123 #define W_META_CREATEFONTINDIRECT 0x02FB
124 #define W_META_CREATEBRUSHINDIRECT 0x02FC
125 #define W_META_CREATEBITMAPINDIRECT 0x02FD
126 #define W_META_CREATEBITMAP 0x06FE
127 #define W_META_CREATEREGION 0x06FF
129 #define W_TRANSPARENT 1
133 #define W_R2_NOTMERGEPEN 2
134 #define W_R2_MASKNOTPEN 3
135 #define W_R2_NOTCOPYPEN 4
136 #define W_R2_MASKPENNOT 5
138 #define W_R2_XORPEN 7
139 #define W_R2_NOTMASKPEN 8
140 #define W_R2_MASKPEN 9
141 #define W_R2_NOTXORPEN 10
143 #define W_R2_MERGENOTPEN 12
144 #define W_R2_COPYPEN 13
145 #define W_R2_MERGEPENNOT 14
146 #define W_R2_MERGEPEN 15
147 #define W_R2_WHITE 16
149 #define W_TA_NOUPDATECP 0x0000
150 #define W_TA_UPDATECP 0x0001
151 #define W_TA_LEFT 0x0000
152 #define W_TA_RIGHT 0x0002
153 #define W_TA_CENTER 0x0006
154 #define W_TA_TOP 0x0000
155 #define W_TA_BOTTOM 0x0008
156 #define W_TA_BASELINE 0x0018
157 #define W_TA_RTLREADING 0x0100
159 #define W_SRCCOPY 0x00CC0020L
160 #define W_SRCPAINT 0x00EE0086L
161 #define W_SRCAND 0x008800C6L
162 #define W_SRCINVERT 0x00660046L
163 #define W_SRCERASE 0x00440328L
164 #define W_NOTSRCCOPY 0x00330008L
165 #define W_NOTSRCERASE 0x001100A6L
166 #define W_MERGECOPY 0x00C000CAL
167 #define W_MERGEPAINT 0x00BB0226L
168 #define W_PATCOPY 0x00F00021L
169 #define W_PATPAINT 0x00FB0A09L
170 #define W_PATINVERT 0x005A0049L
171 #define W_DSTINVERT 0x00550009L
172 #define W_BLACKNESS 0x00000042L
173 #define W_WHITENESS 0x00FF0062L
178 #define W_PS_DASHDOT 3
179 #define W_PS_DASHDOTDOT 4
181 #define W_PS_INSIDEFRAME 6
183 #define W_LF_FACESIZE 32
185 #define W_ANSI_CHARSET 0
186 #define W_DEFAULT_CHARSET 1
187 #define W_SYMBOL_CHARSET 2
188 #define W_SHIFTJIS_CHARSET 128
189 #define W_HANGEUL_CHARSET 129
190 #define W_GB2312_CHARSET 134
191 #define W_CHINESEBIG5_CHARSET 136
192 #define W_OEM_CHARSET 255
194 #define W_JOHAB_CHARSET 130
195 #define W_HEBREW_CHARSET 177
196 #define W_ARABIC_CHARSET 178
197 #define W_GREEK_CHARSET 161
198 #define W_TURKISH_CHARSET 162
199 #define W_VIETNAMESE_CHARSET 163
200 #define W_THAI_CHARSET 222
201 #define W_EASTEUROPE_CHARSET 238
202 #define W_RUSSIAN_CHARSET 204
203 #define W_MAC_CHARSET 77
204 #define W_BALTIC_CHARSET 186
206 #define W_DEFAULT_PITCH 0x00
207 #define W_FIXED_PITCH 0x01
208 #define W_VARIABLE_PITCH 0x02
210 #define W_FF_DONTCARE 0x00
211 #define W_FF_ROMAN 0x10
212 #define W_FF_SWISS 0x20
213 #define W_FF_MODERN 0x30
214 #define W_FF_SCRIPT 0x40
215 #define W_FF_DECORATIVE 0x50
217 #define W_FW_DONTCARE 0
218 #define W_FW_THIN 100
219 #define W_FW_EXTRALIGHT 200
220 #define W_FW_LIGHT 300
221 #define W_FW_NORMAL 400
222 #define W_FW_MEDIUM 500
223 #define W_FW_SEMIBOLD 600
224 #define W_FW_BOLD 700
225 #define W_FW_EXTRABOLD 800
226 #define W_FW_HEAVY 900
227 #define W_FW_ULTRALIGHT 200
228 #define W_FW_REGULAR 400
229 #define W_FW_DEMIBOLD 600
230 #define W_FW_ULTRABOLD 800
231 #define W_FW_BLACK 900
234 #define W_BS_HOLLOW 1
235 #define W_BS_HATCHED 2
236 #define W_BS_PATTERN 3
237 #define W_BS_INDEXED 4
238 #define W_BS_DIBPATTERN 5
240 #define W_HS_HORIZONTAL 0
241 #define W_HS_VERTICAL 1
242 #define W_HS_FDIAGONAL 2
243 #define W_HS_BDIAGONAL 3
245 #define W_HS_DIAGCROSS 5
247 #define W_MFCOMMENT 15
249 #define PRIVATE_ESCAPE_UNICODE 2
251 /// copied from writerwordglue.cxx
254 Utility to categorize unicode characters into the best fit windows charset
255 range for exporting to ww6, or as a hint to non \u unicode token aware rtf
258 rtl_TextEncoding
getScriptClass(sal_Unicode cChar
)
260 using namespace com::sun::star::i18n
;
262 static ScriptTypeList aScripts
[] =
264 { UnicodeScript_kBasicLatin
, UnicodeScript_kBasicLatin
, RTL_TEXTENCODING_MS_1252
},
265 { UnicodeScript_kLatin1Supplement
, UnicodeScript_kLatin1Supplement
, RTL_TEXTENCODING_MS_1252
},
266 { UnicodeScript_kLatinExtendedA
, UnicodeScript_kLatinExtendedA
, RTL_TEXTENCODING_MS_1250
},
267 { UnicodeScript_kLatinExtendedB
, UnicodeScript_kLatinExtendedB
, RTL_TEXTENCODING_MS_1257
},
268 { UnicodeScript_kGreek
, UnicodeScript_kGreek
, RTL_TEXTENCODING_MS_1253
},
269 { UnicodeScript_kCyrillic
, UnicodeScript_kCyrillic
, RTL_TEXTENCODING_MS_1251
},
270 { UnicodeScript_kHebrew
, UnicodeScript_kHebrew
, RTL_TEXTENCODING_MS_1255
},
271 { UnicodeScript_kArabic
, UnicodeScript_kArabic
, RTL_TEXTENCODING_MS_1256
},
272 { UnicodeScript_kThai
, UnicodeScript_kThai
, RTL_TEXTENCODING_MS_1258
},
273 { UnicodeScript_kScriptCount
, UnicodeScript_kScriptCount
, RTL_TEXTENCODING_MS_1252
}
275 return unicode::getUnicodeScriptType(cChar
, aScripts
,
276 RTL_TEXTENCODING_MS_1252
);
279 //========================== Methoden von WMFWriter ==========================
281 void WMFWriter::MayCallback()
283 if ( xStatusIndicator
.is() )
287 // Wir gehen mal einfach so davon aus, dass 16386 Actions einer Bitmap entsprechen
288 // (in der Regel wird ein Metafile entweder nur Actions oder einige Bitmaps und fast
289 // keine Actions enthalten. Dann ist das Verhaeltnis ziemlich unwichtig)
291 nPercent
=((nWrittenBitmaps
<<14)+(nActBitmapPercent
<<14)/100+nWrittenActions
)
293 /((nNumberOfBitmaps
<<14)+nNumberOfActions
);
295 if ( nPercent
>= nLastPercent
+ 3 )
297 nLastPercent
= nPercent
;
298 if( nPercent
<= 100 )
299 xStatusIndicator
->setValue( nPercent
);
304 void WMFWriter::CountActionsAndBitmaps( const GDIMetaFile
& rMTF
)
306 ULONG nAction
, nActionCount
;
308 nActionCount
= rMTF
.GetActionCount();
310 for ( nAction
=0; nAction
<nActionCount
; nAction
++ )
312 MetaAction
* pMA
= rMTF
.GetAction( nAction
);
314 switch( pMA
->GetType() )
316 case META_BMP_ACTION
:
317 case META_BMPSCALE_ACTION
:
318 case META_BMPSCALEPART_ACTION
:
319 case META_BMPEX_ACTION
:
320 case META_BMPEXSCALE_ACTION
:
321 case META_BMPEXSCALEPART_ACTION
:
330 void WMFWriter::WritePointXY(const Point
& rPoint
)
332 Point
aPt( pVirDev
->LogicToLogic(rPoint
,aSrcMapMode
,aTargetMapMode
) );
333 *pWMF
<< ((short)aPt
.X()) << ((short)aPt
.Y());
337 void WMFWriter::WritePointYX(const Point
& rPoint
)
339 Point
aPt( pVirDev
->LogicToLogic(rPoint
,aSrcMapMode
,aTargetMapMode
) );
340 *pWMF
<< ((short)aPt
.Y()) << ((short)aPt
.X());
344 sal_Int32
WMFWriter::ScaleWidth( sal_Int32 nDX
)
346 Size
aSz( pVirDev
->LogicToLogic(Size(nDX
,0),aSrcMapMode
,aTargetMapMode
) );
351 void WMFWriter::WriteSize(const Size
& rSize
)
353 Size
aSz( pVirDev
->LogicToLogic(rSize
,aSrcMapMode
,aTargetMapMode
) );
354 *pWMF
<< ((short)aSz
.Width()) << ((short)aSz
.Height());
358 void WMFWriter::WriteHeightWidth(const Size
& rSize
)
360 Size
aSz( pVirDev
->LogicToLogic(rSize
,aSrcMapMode
,aTargetMapMode
) );
361 *pWMF
<< ((short)aSz
.Height()) << ((short)aSz
.Width());
365 void WMFWriter::WriteRectangle(const Rectangle
& rRect
)
367 WritePointYX(Point(rRect
.Right()+1,rRect
.Bottom()+1));
368 WritePointYX(rRect
.TopLeft());
372 void WMFWriter::WriteColor(const Color
& rColor
)
374 *pWMF
<< (BYTE
) rColor
.GetRed() << (BYTE
) rColor
.GetGreen() << (BYTE
) rColor
.GetBlue() << (BYTE
) 0;
378 void WMFWriter::WriteRecordHeader(sal_uInt32 nSizeWords
, sal_uInt16 nType
)
380 nActRecordPos
=pWMF
->Tell();
381 if (nSizeWords
>nMaxRecordSize
) nMaxRecordSize
=nSizeWords
;
382 *pWMF
<< nSizeWords
<< nType
;
386 void WMFWriter::UpdateRecordHeader()
391 nPos
=pWMF
->Tell(); nSize
=nPos
-nActRecordPos
;
392 if ((nSize
& 1)!=0) {
397 if (nSize
>nMaxRecordSize
) nMaxRecordSize
=nSize
;
398 pWMF
->Seek(nActRecordPos
);
404 void WMFWriter::WMFRecord_Arc(const Rectangle
& rRect
, const Point
& rStartPt
, const Point
& rEndPt
)
406 WriteRecordHeader(0x0000000b,W_META_ARC
);
407 WritePointYX(rEndPt
);
408 WritePointYX(rStartPt
);
409 WriteRectangle(rRect
);
412 void WMFWriter::WMFRecord_Chord(const Rectangle
& rRect
, const Point
& rStartPt
, const Point
& rEndPt
)
414 WriteRecordHeader(0x0000000b,W_META_CHORD
);
415 WritePointYX(rEndPt
);
416 WritePointYX(rStartPt
);
417 WriteRectangle(rRect
);
421 void WMFWriter::WMFRecord_CreateBrushIndirect(const Color
& rColor
)
423 WriteRecordHeader(0x00000007,W_META_CREATEBRUSHINDIRECT
);
425 if( rColor
==Color(COL_TRANSPARENT
) )
426 *pWMF
<< (UINT16
) W_BS_HOLLOW
;
428 *pWMF
<< (UINT16
) W_BS_SOLID
;
430 WriteColor( rColor
);
435 void WMFWriter::WMFRecord_CreateFontIndirect(const Font
& rFont
)
440 WriteRecordHeader(0x00000000,W_META_CREATEFONTINDIRECT
);
441 WriteHeightWidth(Size(rFont
.GetSize().Width(),-rFont
.GetSize().Height()));
442 *pWMF
<< (short)rFont
.GetOrientation() << (short)rFont
.GetOrientation();
444 switch (rFont
.GetWeight()) {
445 case WEIGHT_THIN
: nWeight
=W_FW_THIN
; break;
446 case WEIGHT_ULTRALIGHT
: nWeight
=W_FW_ULTRALIGHT
; break;
447 case WEIGHT_LIGHT
: nWeight
=W_FW_LIGHT
; break;
448 case WEIGHT_SEMILIGHT
: nWeight
=W_FW_LIGHT
; break;
449 case WEIGHT_NORMAL
: nWeight
=W_FW_NORMAL
; break;
450 case WEIGHT_MEDIUM
: nWeight
=W_FW_MEDIUM
; break;
451 case WEIGHT_SEMIBOLD
: nWeight
=W_FW_SEMIBOLD
; break;
452 case WEIGHT_BOLD
: nWeight
=W_FW_BOLD
; break;
453 case WEIGHT_ULTRABOLD
: nWeight
=W_FW_ULTRABOLD
; break;
454 case WEIGHT_BLACK
: nWeight
=W_FW_BLACK
; break;
455 default: nWeight
=W_FW_DONTCARE
;
459 if (rFont
.GetItalic()==ITALIC_NONE
) *pWMF
<< (BYTE
)0; else *pWMF
<< (BYTE
)1;
460 if (rFont
.GetUnderline()==UNDERLINE_NONE
) *pWMF
<< (BYTE
)0; else *pWMF
<< (BYTE
)1;
461 if (rFont
.GetStrikeout()==STRIKEOUT_NONE
) *pWMF
<< (BYTE
)0; else *pWMF
<< (BYTE
)1;
463 CharSet eFontNameEncoding
= rFont
.GetCharSet();
464 sal_uInt8 nCharSet
= rtl_getBestWindowsCharsetFromTextEncoding( eFontNameEncoding
);
465 if ( eFontNameEncoding
== RTL_TEXTENCODING_SYMBOL
)
466 eFontNameEncoding
= RTL_TEXTENCODING_MS_1252
;
468 nCharSet
= W_ANSI_CHARSET
;
471 *pWMF
<< (BYTE
)0 << (BYTE
)0 << (BYTE
)0;
473 switch (rFont
.GetPitch()) {
474 case PITCH_FIXED
: nPitchFamily
=W_FIXED_PITCH
; break;
475 case PITCH_VARIABLE
: nPitchFamily
=W_VARIABLE_PITCH
; break;
476 default: nPitchFamily
=W_DEFAULT_PITCH
;
478 switch (rFont
.GetFamily()) {
479 case FAMILY_DECORATIVE
: nPitchFamily
|=W_FF_DECORATIVE
; break;
480 case FAMILY_MODERN
: nPitchFamily
|=W_FF_MODERN
; break;
481 case FAMILY_ROMAN
: nPitchFamily
|=W_FF_ROMAN
; break;
482 case FAMILY_SCRIPT
: nPitchFamily
|=W_FF_SCRIPT
; break;
483 case FAMILY_SWISS
: nPitchFamily
|=W_FF_SWISS
; break;
484 default: nPitchFamily
|=W_FF_DONTCARE
;
486 *pWMF
<< nPitchFamily
;
488 ByteString
aFontName( rFont
.GetName(), eFontNameEncoding
);
489 for ( i
= 0; i
< W_LF_FACESIZE
; i
++ )
491 sal_Char nChar
= ( i
< aFontName
.Len() ) ? aFontName
.GetChar( i
) : 0;
494 UpdateRecordHeader();
497 void WMFWriter::WMFRecord_CreatePenIndirect(const Color
& rColor
, const LineInfo
& rLineInfo
)
499 WriteRecordHeader(0x00000008,W_META_CREATEPENINDIRECT
);
500 USHORT nStyle
= rColor
== Color( COL_TRANSPARENT
) ? W_PS_NULL
: W_PS_SOLID
;
501 switch( rLineInfo
.GetStyle() )
505 if ( rLineInfo
.GetDotCount() )
507 if ( !rLineInfo
.GetDashCount() )
511 if ( !rLineInfo
.GetDotCount() == 1 )
512 nStyle
= W_PS_DASHDOT
;
514 nStyle
= W_PS_DASHDOTDOT
;
529 WriteSize( Size( rLineInfo
.GetWidth(), 0 ) );
530 WriteColor( rColor
);
533 void WMFWriter::WMFRecord_DeleteObject(USHORT nObjectHandle
)
535 WriteRecordHeader(0x00000004,W_META_DELETEOBJECT
);
536 *pWMF
<< nObjectHandle
;
540 void WMFWriter::WMFRecord_Ellipse(const Rectangle
& rRect
)
542 WriteRecordHeader(0x00000007,W_META_ELLIPSE
);
543 WriteRectangle(rRect
);
546 bool IsStarSymbol(const String
&rStr
)
548 return rStr
.EqualsIgnoreCaseAscii("starsymbol") ||
549 rStr
.EqualsIgnoreCaseAscii("opensymbol");
552 void WMFWriter::WMFRecord_Escape( sal_uInt32 nEsc
, sal_uInt32 nLen
, const sal_Int8
* pData
)
555 sal_uInt32 nTmp
= SWAPLONG( nEsc
);
556 sal_uInt32 nCheckSum
= rtl_crc32( 0, &nTmp
, 4 );
558 sal_uInt32 nCheckSum
= rtl_crc32( 0, &nEsc
, 4 );
561 nCheckSum
= rtl_crc32( nCheckSum
, pData
, nLen
);
563 WriteRecordHeader( 3 + 9 + ( ( nLen
+ 1 ) >> 1 ), W_META_ESCAPE
);
564 *pWMF
<< (sal_uInt16
)W_MFCOMMENT
565 << (sal_uInt16
)( nLen
+ 14 ) // we will always have a fourteen byte escape header:
566 << (sal_uInt16
)0x4f4f // OO
567 << (sal_uInt32
)0xa2c2a // evil magic number
568 << (sal_uInt32
)nCheckSum
// crc32 checksum about nEsc & pData
569 << (sal_uInt32
)nEsc
; // escape number
570 pWMF
->Write( pData
, nLen
);
572 *pWMF
<< (sal_uInt8
)0; // pad byte
575 /* if return value is true, then a complete unicode string and also a polygon replacement has been written,
576 so there is no more action necessary
578 sal_Bool
WMFWriter::WMFRecord_Escape_Unicode( const Point
& rPoint
, const String
& rUniStr
, const sal_Int32
* pDXAry
)
580 sal_Bool bEscapeUsed
= sal_False
;
582 sal_uInt32 i
, nStringLen
= rUniStr
.Len();
585 // first we will check if a comment is necessary
586 if ( aSrcFont
.GetCharSet() != RTL_TEXTENCODING_SYMBOL
) // symbol is always byte character, so there is no unicode loss
588 const sal_Unicode
* pBuf
= rUniStr
.GetBuffer();
589 const rtl_TextEncoding aTextEncodingOrg
= aSrcFont
.GetCharSet();
590 ByteString
aByteStr( rUniStr
, aTextEncodingOrg
);
591 String
aUniStr2( aByteStr
, aTextEncodingOrg
);
592 const sal_Unicode
* pConversion
= aUniStr2
.GetBuffer(); // this is the unicode array after bytestring <-> unistring conversion
593 for ( i
= 0; i
< nStringLen
; i
++ )
595 if ( *pBuf
++ != *pConversion
++ )
599 if ( i
!= nStringLen
) // after conversion the characters are not original,
600 { // try again, with determining a better charset from unicode char
601 pBuf
= rUniStr
.GetBuffer();
602 const sal_Unicode
* pCheckChar
= pBuf
;
603 rtl_TextEncoding aTextEncoding
= getScriptClass (*pCheckChar
); // try the first character
604 for ( i
= 1; i
< nStringLen
; i
++)
606 if (aTextEncoding
!= aTextEncodingOrg
) // found something
609 aTextEncoding
= getScriptClass (*pCheckChar
); // try the next character
612 aByteStr
= ByteString ( rUniStr
, aTextEncoding
);
613 aUniStr2
= String ( aByteStr
, aTextEncoding
);
614 pConversion
= aUniStr2
.GetBuffer(); // this is the unicode array after bytestring <-> unistring conversion
615 for ( i
= 0; i
< nStringLen
; i
++ )
617 if ( *pBuf
++ != *pConversion
++ )
622 aSrcFont
.SetCharSet (aTextEncoding
);
627 if ( ( i
!= nStringLen
) || IsStarSymbol( aSrcFont
.GetName() ) ) // after conversion the characters are not original, so we
628 { // will store the unicode string and a polypoly replacement
629 Color
aOldFillColor( aSrcFillColor
);
630 Color
aOldLineColor( aSrcLineColor
);
631 aSrcLineInfo
= LineInfo();
632 aSrcFillColor
= aSrcTextColor
;
633 aSrcLineColor
= Color( COL_TRANSPARENT
);
634 SetLineAndFillAttr();
635 pVirDev
->SetFont( aSrcFont
);
636 std::vector
<PolyPolygon
> aPolyPolyVec
;
637 if ( pVirDev
->GetTextOutlines( aPolyPolyVec
, rUniStr
) )
639 sal_uInt32 nDXCount
= pDXAry
? nStringLen
: 0;
640 sal_uInt32 nSkipActions
= aPolyPolyVec
.size();
641 sal_Int32 nStrmLen
= 8 +
642 + sizeof( nStringLen
) + ( nStringLen
* 2 )
643 + sizeof( nDXCount
) + ( nDXCount
* 4 )
644 + sizeof( nSkipActions
);
646 SvMemoryStream
aMemoryStream( nStrmLen
);
647 Point
aPt( pVirDev
->LogicToLogic( rPoint
, aSrcMapMode
, aTargetMapMode
) );
648 aMemoryStream
<< aPt
.X()
651 for ( i
= 0; i
< nStringLen
; i
++ )
652 aMemoryStream
<< rUniStr
.GetChar( (sal_uInt16
)i
);
653 aMemoryStream
<< nDXCount
;
654 for ( i
= 0; i
< nDXCount
; i
++ )
655 aMemoryStream
<< pDXAry
[ i
];
656 aMemoryStream
<< nSkipActions
;
657 WMFRecord_Escape( PRIVATE_ESCAPE_UNICODE
, nStrmLen
, (const sal_Int8
*)aMemoryStream
.GetData() );
659 std::vector
<PolyPolygon
>::iterator
aIter( aPolyPolyVec
.begin() );
660 while ( aIter
!= aPolyPolyVec
.end() )
662 PolyPolygon
aPolyPoly( *aIter
++ );
663 aPolyPoly
.Move( rPoint
.X(), rPoint
.Y() );
664 WMFRecord_PolyPolygon( aPolyPoly
);
666 aSrcFillColor
= aOldFillColor
;
667 aSrcLineColor
= aOldLineColor
;
668 bEscapeUsed
= sal_True
;
676 void WMFWriter::WMFRecord_ExtTextOut( const Point
& rPoint
,
677 const String
& rString
, const sal_Int32
* pDXAry
)
679 sal_uInt16 nOriginalTextLen
= rString
.Len();
681 if ( (nOriginalTextLen
<= 1) || (pDXAry
== NULL
) )
683 WMFRecord_TextOut(rPoint
, rString
);
686 rtl_TextEncoding eChrSet
= aSrcFont
.GetCharSet();
687 ByteString
aByteString(rString
, eChrSet
);
688 TrueExtTextOut(rPoint
,rString
,aByteString
,pDXAry
);
691 void WMFWriter::TrueExtTextOut( const Point
& rPoint
, const String
& rString
,
692 const ByteString
& rByteString
, const sal_Int32
* pDXAry
)
694 WriteRecordHeader( 0, W_META_EXTTEXTOUT
);
695 WritePointYX( rPoint
);
696 sal_uInt16 nNewTextLen
= rByteString
.Len();
697 *pWMF
<< nNewTextLen
<< (sal_uInt16
)0;
700 for ( i
= 0; i
< nNewTextLen
; i
++ )
701 *pWMF
<< (sal_uInt8
)rByteString
.GetChar( i
);
702 if ( nNewTextLen
& 1 )
703 *pWMF
<< (sal_uInt8
)0;
705 sal_uInt16 nOriginalTextLen
= rString
.Len();
706 sal_Int16
* pConvertedDXAry
= new sal_Int16
[ nOriginalTextLen
];
708 pConvertedDXAry
[ j
++ ] = (sal_Int16
)ScaleWidth( pDXAry
[ 0 ] );
709 for ( i
= 1; i
< ( nOriginalTextLen
- 1 ); i
++ )
710 pConvertedDXAry
[ j
++ ] = (sal_Int16
)ScaleWidth( pDXAry
[ i
] - pDXAry
[ i
- 1 ] );
711 pConvertedDXAry
[ j
] = (sal_Int16
)ScaleWidth( pDXAry
[ nOriginalTextLen
- 2 ] / ( nOriginalTextLen
- 1 ) );
713 for ( i
= 0; i
< nOriginalTextLen
; i
++ )
715 sal_Int16 nDx
= pConvertedDXAry
[ i
];
717 if ( nOriginalTextLen
< nNewTextLen
)
719 ByteString
aTemp( rString
.GetChar( i
), aSrcFont
.GetCharSet());
722 *pWMF
<< (sal_uInt16
)0;
725 delete[] pConvertedDXAry
;
726 UpdateRecordHeader();
729 void WMFWriter::WMFRecord_LineTo(const Point
& rPoint
)
731 WriteRecordHeader(0x00000005,W_META_LINETO
);
732 WritePointYX(rPoint
);
736 void WMFWriter::WMFRecord_MoveTo(const Point
& rPoint
)
738 WriteRecordHeader(0x00000005,W_META_MOVETO
);
739 WritePointYX(rPoint
);
743 void WMFWriter::WMFRecord_Pie(const Rectangle
& rRect
, const Point
& rStartPt
, const Point
& rEndPt
)
745 WriteRecordHeader(0x0000000b,W_META_PIE
);
746 WritePointYX(rEndPt
);
747 WritePointYX(rStartPt
);
748 WriteRectangle(rRect
);
752 void WMFWriter::WMFRecord_Polygon(const Polygon
& rPoly
)
757 if ( rPoly
.HasFlags() )
758 rPoly
.GetSimple( aSimplePoly
);
761 nSize
= aSimplePoly
.GetSize();
762 WriteRecordHeader(((ULONG
)nSize
)*2+4,W_META_POLYGON
);
764 for (i
=0; i
<nSize
; i
++) WritePointXY(aSimplePoly
.GetPoint(i
));
768 void WMFWriter::WMFRecord_PolyLine(const Polygon
& rPoly
)
772 if ( rPoly
.HasFlags() )
773 rPoly
.GetSimple( aSimplePoly
);
776 nSize
=aSimplePoly
.GetSize();
777 WriteRecordHeader(((ULONG
)nSize
)*2+4,W_META_POLYLINE
);
779 for (i
=0; i
<nSize
; i
++) WritePointXY(aSimplePoly
.GetPoint(i
));
783 void WMFWriter::WMFRecord_PolyPolygon(const PolyPolygon
& rPolyPoly
)
785 const Polygon
* pPoly
;
786 USHORT nCount
,nSize
,i
,j
;
788 nCount
=rPolyPoly
.Count();
789 PolyPolygon
aSimplePolyPoly( rPolyPoly
);
790 for ( i
= 0; i
< nCount
; i
++ )
792 if ( aSimplePolyPoly
[ i
].HasFlags() )
795 aSimplePolyPoly
[ i
].GetSimple( aSimplePoly
);
796 aSimplePolyPoly
[ i
] = aSimplePoly
;
799 WriteRecordHeader(0,W_META_POLYPOLYGON
);
801 for (i
=0; i
<nCount
; i
++) *pWMF
<< ((USHORT
)(aSimplePolyPoly
.GetObject(i
).GetSize()));
802 for (i
=0; i
<nCount
; i
++) {
803 pPoly
=&(aSimplePolyPoly
.GetObject(i
));
804 nSize
=pPoly
->GetSize();
805 for (j
=0; j
<nSize
; j
++) WritePointXY(pPoly
->GetPoint(j
));
807 UpdateRecordHeader();
811 void WMFWriter::WMFRecord_Rectangle(const Rectangle
& rRect
)
813 WriteRecordHeader( 0x00000007,W_META_RECTANGLE
);
814 WriteRectangle( rRect
);
818 void WMFWriter::WMFRecord_RestoreDC()
820 WriteRecordHeader(0x00000004,W_META_RESTOREDC
);
825 void WMFWriter::WMFRecord_RoundRect(const Rectangle
& rRect
, long nHorzRound
, long nVertRound
)
827 WriteRecordHeader(0x00000009,W_META_ROUNDRECT
);
828 WriteHeightWidth(Size(nHorzRound
,nVertRound
));
829 WriteRectangle(rRect
);
833 void WMFWriter::WMFRecord_SaveDC()
835 WriteRecordHeader(0x00000003,W_META_SAVEDC
);
839 void WMFWriter::WMFRecord_SelectObject(USHORT nObjectHandle
)
841 WriteRecordHeader(0x00000004,W_META_SELECTOBJECT
);
842 *pWMF
<< nObjectHandle
;
846 void WMFWriter::WMFRecord_SetBkColor(const Color
& rColor
)
848 WriteRecordHeader(0x00000005,W_META_SETBKCOLOR
);
853 void WMFWriter::WMFRecord_SetBkMode(BOOL bTransparent
)
855 WriteRecordHeader(0x00000004,W_META_SETBKMODE
);
856 if (bTransparent
==TRUE
) *pWMF
<< (USHORT
)W_TRANSPARENT
;
857 else *pWMF
<< (USHORT
)W_OPAQUE
;
860 void WMFWriter::WMFRecord_SetStretchBltMode()
862 WriteRecordHeader( 0x00000004, W_META_SETSTRETCHBLTMODE
);
863 *pWMF
<< (USHORT
) 3; // STRETCH_DELETESCANS
866 void WMFWriter::WMFRecord_SetPixel(const Point
& rPoint
, const Color
& rColor
)
868 WriteRecordHeader(0x00000007,W_META_SETPIXEL
);
870 WritePointYX(rPoint
);
874 void WMFWriter::WMFRecord_SetROP2(RasterOp eROP
)
879 case ROP_INVERT
: nROP2
=W_R2_NOT
; break;
880 case ROP_XOR
: nROP2
=W_R2_XORPEN
; break;
881 default: nROP2
=W_R2_COPYPEN
;
883 WriteRecordHeader(0x00000004,W_META_SETROP2
);
888 void WMFWriter::WMFRecord_SetTextAlign(FontAlign eFontAlign
, UINT32 eHorTextAlign
)
892 switch (eFontAlign
) {
893 case ALIGN_TOP
: nAlign
=W_TA_TOP
; break;
894 case ALIGN_BOTTOM
: nAlign
=W_TA_BOTTOM
; break;
895 default: nAlign
=W_TA_BASELINE
;
897 nAlign
|=eHorTextAlign
;
898 nAlign
|=W_TA_NOUPDATECP
;
900 WriteRecordHeader(0x00000004,W_META_SETTEXTALIGN
);
905 void WMFWriter::WMFRecord_SetTextColor(const Color
& rColor
)
907 WriteRecordHeader(0x00000005,W_META_SETTEXTCOLOR
);
912 void WMFWriter::WMFRecord_SetWindowExt(const Size
& rSize
)
914 WriteRecordHeader(0x00000005,W_META_SETWINDOWEXT
);
915 WriteHeightWidth(rSize
);
919 void WMFWriter::WMFRecord_SetWindowOrg(const Point
& rPoint
)
921 WriteRecordHeader(0x00000005,W_META_SETWINDOWORG
);
922 WritePointYX(rPoint
);
926 void WMFWriter::WMFRecord_StretchDIB( const Point
& rPoint
, const Size
& rSize
,
927 const Bitmap
& rBitmap
, sal_uInt32 nROP
)
929 ULONG nPosAnf
,nPosEnd
;
931 nActBitmapPercent
=50;
934 WriteRecordHeader(0x00000000,W_META_STRETCHDIB
);
936 // Die Reihenfolge im Metafile soll jetzt sein:
937 // einige Parameter (laenge 22), dann die Bitmap ohne FILEHEADER.
938 // Da aber *pWMF << rBitmap einen FILEHEADER der Laenge 14
939 // erzeugt, schreiben wir zuerst die Bitmap an die richtige Position
940 // Und ueberschreiben hinterher den FILEHEADER mit den Parametern.
941 nPosAnf
=pWMF
->Tell(); // Position merken, wo Parameter hin sollen
942 *pWMF
<< (long)0 << (long)0; // 8 bytes auffuellen (diese 8 bytes +
943 // 14 bytes ueberfluessigen FILEHEADER
944 // = 22 bytes Parameter)
945 *pWMF
<< rBitmap
; // Bitmap schreiben
947 // Parameter schreiben:
948 nPosEnd
=pWMF
->Tell();
951 // Raster-Op bestimmen, falls nichts uebergeben wurde
954 switch( eSrcRasterOp
)
956 case ROP_INVERT
: nROP
= W_DSTINVERT
; break;
957 case ROP_XOR
: nROP
= W_SRCINVERT
; break;
958 default: nROP
= W_SRCCOPY
;
964 (short) rBitmap
.GetSizePixel().Height() <<
965 (short) rBitmap
.GetSizePixel().Width() <<
969 WriteHeightWidth(rSize
);
970 WritePointYX(rPoint
);
973 UpdateRecordHeader();
980 void WMFWriter::WMFRecord_TextOut(const Point
& rPoint
, const String
& rStr
)
982 rtl_TextEncoding eChrSet
= aSrcFont
.GetCharSet();
983 ByteString
aString( rStr
, eChrSet
);
984 TrueTextOut(rPoint
, aString
);
987 void WMFWriter::TrueTextOut(const Point
& rPoint
, const ByteString
& rString
)
991 WriteRecordHeader(0,W_META_TEXTOUT
);
994 for ( i
= 0; i
< nLen
; i
++ )
995 *pWMF
<< (BYTE
)rString
.GetChar( i
);
996 if ((nLen
&1)!=0) *pWMF
<< (BYTE
)0;
997 WritePointYX(rPoint
);
998 UpdateRecordHeader();
1001 void WMFWriter::WMFRecord_EndOfFile()
1003 WriteRecordHeader(0x00000003,0x0000);
1007 void WMFWriter::WMFRecord_IntersectClipRect( const Rectangle
& rRect
)
1009 WriteRecordHeader( 0x00000007, W_META_INTERSECTCLIPRECT
);
1010 WriteRectangle(rRect
);
1014 USHORT
WMFWriter::AllocHandle()
1018 for (i
=0; i
<MAXOBJECTHANDLES
; i
++) {
1019 if (bHandleAllocated
[i
]==FALSE
) {
1020 bHandleAllocated
[i
]=TRUE
;
1029 void WMFWriter::FreeHandle(USHORT nObjectHandle
)
1031 if (nObjectHandle
<MAXOBJECTHANDLES
) bHandleAllocated
[nObjectHandle
]=FALSE
;
1035 void WMFWriter::CreateSelectDeletePen( const Color
& rColor
, const LineInfo
& rLineInfo
)
1039 nOldHandle
=nDstPenHandle
;
1040 nDstPenHandle
=AllocHandle();
1041 WMFRecord_CreatePenIndirect( rColor
, rLineInfo
);
1042 WMFRecord_SelectObject(nDstPenHandle
);
1043 if (nOldHandle
<MAXOBJECTHANDLES
) {
1044 WMFRecord_DeleteObject(nOldHandle
);
1045 FreeHandle(nOldHandle
);
1050 void WMFWriter::CreateSelectDeleteFont(const Font
& rFont
)
1054 nOldHandle
=nDstFontHandle
;
1055 nDstFontHandle
=AllocHandle();
1056 WMFRecord_CreateFontIndirect(rFont
);
1057 WMFRecord_SelectObject(nDstFontHandle
);
1058 if (nOldHandle
<MAXOBJECTHANDLES
) {
1059 WMFRecord_DeleteObject(nOldHandle
);
1060 FreeHandle(nOldHandle
);
1065 void WMFWriter::CreateSelectDeleteBrush(const Color
& rColor
)
1069 nOldHandle
=nDstBrushHandle
;
1070 nDstBrushHandle
=AllocHandle();
1071 WMFRecord_CreateBrushIndirect(rColor
);
1072 WMFRecord_SelectObject(nDstBrushHandle
);
1073 if (nOldHandle
<MAXOBJECTHANDLES
) {
1074 WMFRecord_DeleteObject(nOldHandle
);
1075 FreeHandle(nOldHandle
);
1080 void WMFWriter::SetLineAndFillAttr()
1082 if ( eDstROP2
!= eSrcRasterOp
)
1084 eDstROP2
=eSrcRasterOp
;
1085 WMFRecord_SetROP2(eDstROP2
);
1087 if ( ( aDstLineColor
!= aSrcLineColor
) || ( aDstLineInfo
!= aSrcLineInfo
) )
1089 aDstLineColor
= aSrcLineColor
;
1090 aDstLineInfo
= aSrcLineInfo
;
1091 CreateSelectDeletePen( aDstLineColor
, aDstLineInfo
);
1093 if ( aDstFillColor
!= aSrcFillColor
)
1095 aDstFillColor
= aSrcFillColor
;
1096 CreateSelectDeleteBrush( aDstFillColor
);
1098 if ( bDstIsClipping
!= bSrcIsClipping
||
1099 (bSrcIsClipping
==TRUE
&& aDstClipRegion
!=aSrcClipRegion
)) {
1100 bDstIsClipping
=bSrcIsClipping
;
1101 aDstClipRegion
=aSrcClipRegion
;
1105 void WMFWriter::SetAllAttr()
1107 SetLineAndFillAttr();
1108 if ( aDstTextColor
!= aSrcTextColor
)
1110 aDstTextColor
= aSrcTextColor
;
1111 WMFRecord_SetTextColor(aDstTextColor
);
1113 if ( eDstTextAlign
!= eSrcTextAlign
|| eDstHorTextAlign
!= eSrcHorTextAlign
)
1115 eDstTextAlign
= eSrcTextAlign
;
1116 eDstHorTextAlign
= eSrcHorTextAlign
;
1117 WMFRecord_SetTextAlign( eDstTextAlign
, eDstHorTextAlign
);
1119 if ( aDstFont
!= aSrcFont
)
1121 pVirDev
->SetFont(aSrcFont
);
1122 if ( aDstFont
.GetName() != aSrcFont
.GetName() )
1124 FontCharMap aFontCharMap
;
1125 if ( pVirDev
->GetFontCharMap( aFontCharMap
) )
1127 if ( ( aFontCharMap
.GetFirstChar() & 0xff00 ) == 0xf000 )
1128 aSrcFont
.SetCharSet( RTL_TEXTENCODING_SYMBOL
);
1129 else if ( aSrcFont
.GetCharSet() == RTL_TEXTENCODING_SYMBOL
)
1130 aSrcFont
.SetCharSet( RTL_TEXTENCODING_MS_1252
);
1133 aDstFont
= aSrcFont
;
1134 CreateSelectDeleteFont(aDstFont
);
1139 void WMFWriter::WriteRecords( const GDIMetaFile
& rMTF
)
1146 nACount
= rMTF
.GetActionCount();
1148 WMFRecord_SetStretchBltMode();
1150 for( nA
=0; nA
<nACount
; nA
++ )
1152 pMA
= rMTF
.GetAction( nA
);
1154 switch( pMA
->GetType() )
1156 case META_PIXEL_ACTION
:
1158 const MetaPixelAction
* pA
= (const MetaPixelAction
*) pMA
;
1159 aSrcLineInfo
= LineInfo();
1160 SetLineAndFillAttr();
1161 WMFRecord_SetPixel( pA
->GetPoint(), pA
->GetColor() );
1165 case META_POINT_ACTION
:
1167 const MetaPointAction
* pA
= (const MetaPointAction
*) pMA
;
1168 const Point
& rPt
= pA
->GetPoint();
1169 aSrcLineInfo
= LineInfo();
1170 SetLineAndFillAttr();
1171 WMFRecord_MoveTo( rPt
);
1172 WMFRecord_LineTo( rPt
);
1176 case META_LINE_ACTION
:
1178 const MetaLineAction
* pA
= (const MetaLineAction
*) pMA
;
1179 aSrcLineInfo
= pA
->GetLineInfo();
1180 SetLineAndFillAttr();
1181 WMFRecord_MoveTo( pA
->GetStartPoint() );
1182 WMFRecord_LineTo( pA
->GetEndPoint() );
1186 case META_RECT_ACTION
:
1188 const MetaRectAction
* pA
= (const MetaRectAction
*) pMA
;
1189 aSrcLineInfo
= LineInfo();
1190 SetLineAndFillAttr();
1191 WMFRecord_Rectangle( pA
->GetRect() );
1195 case META_ROUNDRECT_ACTION
:
1197 const MetaRoundRectAction
* pA
= (const MetaRoundRectAction
*) pMA
;
1198 aSrcLineInfo
= LineInfo();
1199 SetLineAndFillAttr();
1200 WMFRecord_RoundRect( pA
->GetRect(), pA
->GetHorzRound(), pA
->GetVertRound() );
1204 case META_ELLIPSE_ACTION
:
1206 const MetaEllipseAction
* pA
= (const MetaEllipseAction
*) pMA
;
1207 aSrcLineInfo
= LineInfo();
1208 SetLineAndFillAttr();
1209 WMFRecord_Ellipse( pA
->GetRect() );
1213 case META_ARC_ACTION
:
1215 const MetaArcAction
* pA
= (const MetaArcAction
*) pMA
;
1216 aSrcLineInfo
= LineInfo();
1217 SetLineAndFillAttr();
1218 WMFRecord_Arc( pA
->GetRect(),pA
->GetStartPoint(),pA
->GetEndPoint() );
1222 case META_PIE_ACTION
:
1224 const MetaPieAction
* pA
= (const MetaPieAction
*) pMA
;
1225 aSrcLineInfo
= LineInfo();
1226 SetLineAndFillAttr();
1227 WMFRecord_Pie( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint() );
1232 case META_CHORD_ACTION
:
1234 const MetaChordAction
* pA
= (const MetaChordAction
*) pMA
;
1235 aSrcLineInfo
= LineInfo();
1236 SetLineAndFillAttr();
1237 WMFRecord_Chord( pA
->GetRect(), pA
->GetStartPoint(), pA
->GetEndPoint() );
1241 case META_POLYLINE_ACTION
:
1243 const MetaPolyLineAction
* pA
= (const MetaPolyLineAction
*) pMA
;
1244 aSrcLineInfo
= pA
->GetLineInfo();
1245 SetLineAndFillAttr();
1246 WMFRecord_PolyLine( pA
->GetPolygon() );
1250 case META_POLYGON_ACTION
:
1252 const MetaPolygonAction
* pA
= (const MetaPolygonAction
*) pMA
;
1253 aSrcLineInfo
= LineInfo();
1254 SetLineAndFillAttr();
1255 WMFRecord_Polygon( pA
->GetPolygon() );
1259 case META_POLYPOLYGON_ACTION
:
1261 const MetaPolyPolygonAction
* pA
= (const MetaPolyPolygonAction
*) pMA
;
1262 aSrcLineInfo
= LineInfo();
1263 SetLineAndFillAttr();
1264 WMFRecord_PolyPolygon( pA
->GetPolyPolygon() );
1268 case META_TEXTRECT_ACTION
:
1270 const MetaTextRectAction
* pA
= (const MetaTextRectAction
*)pMA
;
1271 String
aTemp( pA
->GetText() );
1272 aSrcLineInfo
= LineInfo();
1275 Point
aPos( pA
->GetRect().TopLeft() );
1276 if ( !WMFRecord_Escape_Unicode( aPos
, aTemp
, NULL
) )
1277 WMFRecord_TextOut( aPos
, aTemp
);
1281 case META_TEXT_ACTION
:
1283 const MetaTextAction
* pA
= (const MetaTextAction
*) pMA
;
1284 String
aTemp( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() );
1285 aSrcLineInfo
= LineInfo();
1287 if ( !WMFRecord_Escape_Unicode( pA
->GetPoint(), aTemp
, NULL
) )
1288 WMFRecord_TextOut( pA
->GetPoint(), aTemp
);
1292 case META_TEXTARRAY_ACTION
:
1294 const MetaTextArrayAction
* pA
= (const MetaTextArrayAction
*) pMA
;
1296 String
aTemp( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() );
1297 aSrcLineInfo
= LineInfo();
1299 if ( !WMFRecord_Escape_Unicode( pA
->GetPoint(), aTemp
, pA
->GetDXArray() ) )
1300 WMFRecord_ExtTextOut( pA
->GetPoint(), aTemp
, pA
->GetDXArray() );
1304 case META_STRETCHTEXT_ACTION
:
1306 const MetaStretchTextAction
* pA
= (const MetaStretchTextAction
*) pMA
;
1307 String
aTemp( pA
->GetText(), pA
->GetIndex(), pA
->GetLen() );
1310 sal_Int32 nNormSize
;
1312 pVirDev
->SetFont( aSrcFont
);
1314 sal_Int32
* pDXAry
= nLen
? new sal_Int32
[ nLen
] : NULL
;
1315 nNormSize
= pVirDev
->GetTextArray( aTemp
, pDXAry
);
1316 for ( i
= 0; i
< ( nLen
- 1 ); i
++ )
1317 pDXAry
[ i
] = pDXAry
[ i
] * (sal_Int32
)pA
->GetWidth() / nNormSize
;
1318 if ( ( nLen
<= 1 ) || ( (sal_Int32
)pA
->GetWidth() == nNormSize
) )
1319 delete[] pDXAry
, pDXAry
= NULL
;
1320 aSrcLineInfo
= LineInfo();
1322 if ( !WMFRecord_Escape_Unicode( pA
->GetPoint(), aTemp
, pDXAry
) )
1323 WMFRecord_ExtTextOut( pA
->GetPoint(), aTemp
, pDXAry
);
1328 case META_BMP_ACTION
:
1330 const MetaBmpAction
* pA
= (const MetaBmpAction
*) pMA
;
1331 WMFRecord_StretchDIB( pA
->GetPoint(), pA
->GetBitmap().GetSizePixel(), pA
->GetBitmap() );
1335 case META_BMPSCALE_ACTION
:
1337 const MetaBmpScaleAction
* pA
= (const MetaBmpScaleAction
*) pMA
;
1338 WMFRecord_StretchDIB( pA
->GetPoint(), pA
->GetSize(), pA
->GetBitmap() );
1342 case META_BMPSCALEPART_ACTION
:
1344 const MetaBmpScalePartAction
* pA
= (const MetaBmpScalePartAction
*) pMA
;
1345 Bitmap
aTmp( pA
->GetBitmap() );
1347 if( aTmp
.Crop( Rectangle( pA
->GetSrcPoint(), pA
->GetSrcSize() ) ) )
1348 WMFRecord_StretchDIB( pA
->GetDestPoint(), pA
->GetDestSize(), aTmp
);
1352 case META_BMPEX_ACTION
:
1354 const MetaBmpExAction
* pA
= (const MetaBmpExAction
*) pMA
;
1355 Bitmap
aBmp( pA
->GetBitmapEx().GetBitmap() );
1356 Bitmap
aMsk( pA
->GetBitmapEx().GetMask() );
1360 aBmp
.Replace( aMsk
, COL_WHITE
);
1362 WMFRecord_StretchDIB( pA
->GetPoint(), aMsk
.GetSizePixel(), aBmp
, W_SRCPAINT
);
1363 WMFRecord_StretchDIB( pA
->GetPoint(), aBmp
.GetSizePixel(), aBmp
, W_SRCAND
);
1366 WMFRecord_StretchDIB( pA
->GetPoint(), aBmp
.GetSizePixel(), aBmp
);
1370 case META_BMPEXSCALE_ACTION
:
1372 const MetaBmpExScaleAction
* pA
= (const MetaBmpExScaleAction
*) pMA
;
1373 Bitmap
aBmp( pA
->GetBitmapEx().GetBitmap() );
1374 Bitmap
aMsk( pA
->GetBitmapEx().GetMask() );
1378 aBmp
.Replace( aMsk
, COL_WHITE
);
1380 WMFRecord_StretchDIB( pA
->GetPoint(), pA
->GetSize(), aMsk
, W_SRCPAINT
);
1381 WMFRecord_StretchDIB( pA
->GetPoint(), pA
->GetSize(), aBmp
, W_SRCAND
);
1384 WMFRecord_StretchDIB( pA
->GetPoint(), pA
->GetSize(), aBmp
);
1388 case META_BMPEXSCALEPART_ACTION
:
1390 const MetaBmpExScalePartAction
* pA
= (const MetaBmpExScalePartAction
*) pMA
;
1391 BitmapEx
aBmpEx( pA
->GetBitmapEx() );
1392 aBmpEx
.Crop( Rectangle( pA
->GetSrcPoint(), pA
->GetSrcSize() ) );
1393 Bitmap
aBmp( aBmpEx
.GetBitmap() );
1394 Bitmap
aMsk( aBmpEx
.GetMask() );
1398 aBmp
.Replace( aMsk
, COL_WHITE
);
1400 WMFRecord_StretchDIB( pA
->GetDestPoint(), pA
->GetDestSize(), aMsk
, W_SRCPAINT
);
1401 WMFRecord_StretchDIB( pA
->GetDestPoint(), pA
->GetDestSize(), aBmp
, W_SRCAND
);
1404 WMFRecord_StretchDIB( pA
->GetDestPoint(), pA
->GetDestSize(), aBmp
);
1408 case META_GRADIENT_ACTION
:
1410 const MetaGradientAction
* pA
= (const MetaGradientAction
*) pMA
;
1411 GDIMetaFile aTmpMtf
;
1413 pVirDev
->AddGradientActions( pA
->GetRect(), pA
->GetGradient(), aTmpMtf
);
1414 WriteRecords( aTmpMtf
);
1418 case META_HATCH_ACTION
:
1420 const MetaHatchAction
* pA
= (const MetaHatchAction
*) pMA
;
1421 GDIMetaFile aTmpMtf
;
1423 pVirDev
->AddHatchActions( pA
->GetPolyPolygon(), pA
->GetHatch(), aTmpMtf
);
1424 WriteRecords( aTmpMtf
);
1428 case META_WALLPAPER_ACTION
:
1430 const MetaWallpaperAction
* pA
= (const MetaWallpaperAction
*) pMA
;
1431 const Color
& rColor
= pA
->GetWallpaper().GetColor();
1432 const Color
aOldLineColor( aSrcLineColor
);
1433 const Color
aOldFillColor( aSrcFillColor
);
1435 aSrcLineColor
= rColor
;
1436 aSrcFillColor
= rColor
;
1437 aSrcLineInfo
= LineInfo();
1438 SetLineAndFillAttr();
1439 WMFRecord_Rectangle( pA
->GetRect() );
1440 aSrcLineColor
= aOldLineColor
;
1441 aSrcFillColor
= aOldFillColor
;
1445 case META_ISECTRECTCLIPREGION_ACTION
:
1447 const MetaISectRectClipRegionAction
* pA
= (const MetaISectRectClipRegionAction
*) pMA
;
1448 WMFRecord_IntersectClipRect( pA
->GetRect() );
1452 case META_LINECOLOR_ACTION
:
1454 const MetaLineColorAction
* pA
= (const MetaLineColorAction
*) pMA
;
1456 if( pA
->IsSetting() )
1457 aSrcLineColor
= pA
->GetColor();
1459 aSrcLineColor
= Color( COL_TRANSPARENT
);
1463 case META_FILLCOLOR_ACTION
:
1465 const MetaFillColorAction
* pA
= (const MetaFillColorAction
*) pMA
;
1467 if( pA
->IsSetting() )
1468 aSrcFillColor
= pA
->GetColor();
1470 aSrcFillColor
= Color( COL_TRANSPARENT
);
1474 case META_TEXTCOLOR_ACTION
:
1476 const MetaTextColorAction
* pA
= (const MetaTextColorAction
*) pMA
;
1477 aSrcTextColor
= pA
->GetColor();
1481 case META_TEXTFILLCOLOR_ACTION
:
1483 const MetaTextFillColorAction
* pA
= (const MetaTextFillColorAction
*) pMA
;
1484 if( pA
->IsSetting() )
1485 aSrcFont
.SetFillColor( pA
->GetColor() );
1487 aSrcFont
.SetFillColor( Color( COL_TRANSPARENT
) );
1491 case META_TEXTALIGN_ACTION
:
1493 const MetaTextAlignAction
* pA
= (const MetaTextAlignAction
*) pMA
;
1494 eSrcTextAlign
= pA
->GetTextAlign();
1498 case META_MAPMODE_ACTION
:
1500 const MetaMapModeAction
* pA
= (const MetaMapModeAction
*) pMA
;
1502 if (aSrcMapMode
!=pA
->GetMapMode())
1504 if( pA
->GetMapMode().GetMapUnit() == MAP_RELATIVE
)
1506 MapMode aMM
= pA
->GetMapMode();
1507 Fraction aScaleX
= aMM
.GetScaleX();
1508 Fraction aScaleY
= aMM
.GetScaleY();
1510 Point aOrigin
= aSrcMapMode
.GetOrigin();
1511 BigInt
aX( aOrigin
.X() );
1512 aX
*= BigInt( aScaleX
.GetDenominator() );
1513 if( aOrigin
.X() >= 0 )
1514 if( aScaleX
.GetNumerator() >= 0 )
1515 aX
+= BigInt( aScaleX
.GetNumerator()/2 );
1517 aX
-= BigInt( (aScaleX
.GetNumerator()+1)/2 );
1519 if( aScaleX
.GetNumerator() >= 0 )
1520 aX
-= BigInt( (aScaleX
.GetNumerator()-1)/2 );
1522 aX
+= BigInt( aScaleX
.GetNumerator()/2 );
1523 aX
/= BigInt( aScaleX
.GetNumerator() );
1524 aOrigin
.X() = (long)aX
+ aMM
.GetOrigin().X();
1525 BigInt
aY( aOrigin
.Y() );
1526 aY
*= BigInt( aScaleY
.GetDenominator() );
1527 if( aOrigin
.Y() >= 0 )
1528 if( aScaleY
.GetNumerator() >= 0 )
1529 aY
+= BigInt( aScaleY
.GetNumerator()/2 );
1531 aY
-= BigInt( (aScaleY
.GetNumerator()+1)/2 );
1533 if( aScaleY
.GetNumerator() >= 0 )
1534 aY
-= BigInt( (aScaleY
.GetNumerator()-1)/2 );
1536 aY
+= BigInt( aScaleY
.GetNumerator()/2 );
1537 aY
/= BigInt( aScaleY
.GetNumerator() );
1538 aOrigin
.Y() = (long)aY
+ aMM
.GetOrigin().Y();
1539 aSrcMapMode
.SetOrigin( aOrigin
);
1541 aScaleX
*= aSrcMapMode
.GetScaleX();
1542 aScaleY
*= aSrcMapMode
.GetScaleY();
1543 aSrcMapMode
.SetScaleX( aScaleX
);
1544 aSrcMapMode
.SetScaleY( aScaleY
);
1547 aSrcMapMode
=pA
->GetMapMode();
1552 case META_FONT_ACTION
:
1554 const MetaFontAction
* pA
= (const MetaFontAction
*) pMA
;
1555 aSrcFont
= pA
->GetFont();
1557 if ( aSrcFont
.GetCharSet() == RTL_TEXTENCODING_DONTKNOW
)
1558 aSrcFont
.SetCharSet( GetExtendedTextEncoding( gsl_getSystemTextEncoding() ) );
1559 if ( aSrcFont
.GetCharSet() == RTL_TEXTENCODING_UNICODE
)
1560 aSrcFont
.SetCharSet( RTL_TEXTENCODING_MS_1252
);
1561 eSrcTextAlign
= aSrcFont
.GetAlign();
1562 aSrcTextColor
= aSrcFont
.GetColor();
1563 aSrcFont
.SetAlign( ALIGN_BASELINE
);
1564 aSrcFont
.SetColor( COL_WHITE
);
1568 case META_PUSH_ACTION
:
1570 const MetaPushAction
* pA
= (const MetaPushAction
*)pMA
;
1572 WMFWriterAttrStackMember
* pAt
= new WMFWriterAttrStackMember
;
1573 pAt
->nFlags
= pA
->GetFlags();
1574 pAt
->aClipRegion
= aSrcClipRegion
;
1575 pAt
->aLineColor
=aSrcLineColor
;
1576 pAt
->aFillColor
=aSrcFillColor
;
1577 pAt
->eRasterOp
=eSrcRasterOp
;
1578 pAt
->aFont
=aSrcFont
;
1579 pAt
->eTextAlign
=eSrcTextAlign
;
1580 pAt
->aTextColor
=aSrcTextColor
;
1581 pAt
->aMapMode
=aSrcMapMode
;
1582 pAt
->aLineInfo
=aDstLineInfo
;
1583 pAt
->pSucc
=pAttrStack
;
1586 SetAllAttr(); // update ( now all source attributes are equal to the destination attributes )
1592 case META_POP_ACTION
:
1594 WMFWriterAttrStackMember
* pAt
=pAttrStack
;
1598 aDstLineInfo
= pAt
->aLineInfo
;
1599 aDstLineColor
= pAt
->aLineColor
;
1600 if ( pAt
->nFlags
& PUSH_LINECOLOR
)
1601 aSrcLineColor
= pAt
->aLineColor
;
1602 aDstFillColor
= pAt
->aFillColor
;
1603 if ( pAt
->nFlags
& PUSH_FILLCOLOR
)
1604 aSrcFillColor
= pAt
->aFillColor
;
1605 eDstROP2
= pAt
->eRasterOp
;
1606 if ( pAt
->nFlags
& PUSH_RASTEROP
)
1607 eSrcRasterOp
= pAt
->eRasterOp
;
1608 aDstFont
= pAt
->aFont
;
1609 if ( pAt
->nFlags
& PUSH_FONT
)
1610 aSrcFont
= pAt
->aFont
;
1611 eDstTextAlign
= pAt
->eTextAlign
;
1612 if ( pAt
->nFlags
& ( PUSH_FONT
| PUSH_TEXTALIGN
) )
1613 eSrcTextAlign
= pAt
->eTextAlign
;
1614 aDstTextColor
= pAt
->aTextColor
;
1615 if ( pAt
->nFlags
& ( PUSH_FONT
| PUSH_TEXTCOLOR
) )
1616 aSrcTextColor
= pAt
->aTextColor
;
1617 if ( pAt
->nFlags
& PUSH_MAPMODE
)
1618 aSrcMapMode
= pAt
->aMapMode
;
1619 aDstClipRegion
= pAt
->aClipRegion
;
1620 if ( pAt
->nFlags
& PUSH_CLIPREGION
)
1621 aSrcClipRegion
= pAt
->aClipRegion
;
1623 WMFRecord_RestoreDC();
1624 pAttrStack
= pAt
->pSucc
;
1630 case META_EPS_ACTION
:
1632 const MetaEPSAction
* pA
= (const MetaEPSAction
*)pMA
;
1633 const GDIMetaFile
aGDIMetaFile( pA
->GetSubstitute() );
1635 INT32 nCount
= aGDIMetaFile
.GetActionCount();
1636 for ( INT32 i
= 0; i
< nCount
; i
++ )
1638 const MetaAction
* pMetaAct
= aGDIMetaFile
.GetAction( i
);
1639 if ( pMetaAct
->GetType() == META_BMPSCALE_ACTION
)
1641 const MetaBmpScaleAction
* pBmpScaleAction
= (const MetaBmpScaleAction
*)pMetaAct
;
1642 WMFRecord_StretchDIB( pA
->GetPoint(), pA
->GetSize(), pBmpScaleAction
->GetBitmap() );
1649 case META_RASTEROP_ACTION
:
1651 const MetaRasterOpAction
* pA
= (const MetaRasterOpAction
*) pMA
;
1652 eSrcRasterOp
=pA
->GetRasterOp();
1656 case META_TRANSPARENT_ACTION
:
1658 aSrcLineInfo
= LineInfo();
1659 SetLineAndFillAttr();
1660 WMFRecord_PolyPolygon( ( (MetaTransparentAction
*) pMA
)->GetPolyPolygon() );
1664 case META_FLOATTRANSPARENT_ACTION
:
1666 const MetaFloatTransparentAction
* pA
= (const MetaFloatTransparentAction
*) pMA
;
1668 GDIMetaFile
aTmpMtf( pA
->GetGDIMetaFile() );
1669 Point
aSrcPt( aTmpMtf
.GetPrefMapMode().GetOrigin() );
1670 const Size
aSrcSize( aTmpMtf
.GetPrefSize() );
1671 const Point
aDestPt( pA
->GetPoint() );
1672 const Size
aDestSize( pA
->GetSize() );
1673 const double fScaleX
= aSrcSize
.Width() ? (double) aDestSize
.Width() / aSrcSize
.Width() : 1.0;
1674 const double fScaleY
= aSrcSize
.Height() ? (double) aDestSize
.Height() / aSrcSize
.Height() : 1.0;
1675 long nMoveX
, nMoveY
;
1677 aSrcLineInfo
= LineInfo();
1680 if( fScaleX
!= 1.0 || fScaleY
!= 1.0 )
1682 aTmpMtf
.Scale( fScaleX
, fScaleY
);
1683 aSrcPt
.X() = FRound( aSrcPt
.X() * fScaleX
), aSrcPt
.Y() = FRound( aSrcPt
.Y() * fScaleY
);
1686 nMoveX
= aDestPt
.X() - aSrcPt
.X(), nMoveY
= aDestPt
.Y() - aSrcPt
.Y();
1688 if( nMoveX
|| nMoveY
)
1689 aTmpMtf
.Move( nMoveX
, nMoveY
);
1691 WriteRecords( aTmpMtf
);
1695 case( META_LAYOUTMODE_ACTION
):
1697 sal_uInt32 nLayoutMode
= ( (MetaLayoutModeAction
*) pMA
)->GetLayoutMode();
1698 eSrcHorTextAlign
= 0; // TA_LEFT
1699 if (nLayoutMode
& TEXT_LAYOUT_BIDI_RTL
)
1701 eSrcHorTextAlign
= W_TA_RIGHT
| W_TA_RTLREADING
;
1703 if (nLayoutMode
& TEXT_LAYOUT_TEXTORIGIN_RIGHT
)
1704 eSrcHorTextAlign
|= W_TA_RIGHT
;
1705 else if (nLayoutMode
& TEXT_LAYOUT_TEXTORIGIN_LEFT
)
1706 eSrcHorTextAlign
&= ~W_TA_RIGHT
;
1710 // Unsupported Actions
1711 case META_MASK_ACTION
:
1712 case META_MASKSCALE_ACTION
:
1713 case META_MASKSCALEPART_ACTION
:
1715 DBG_ERROR( "Unsupported action: MetaMask...Action!" );
1719 case META_CLIPREGION_ACTION
:
1722 case META_ISECTREGIONCLIPREGION_ACTION
:
1724 DBG_ERROR( "Unsupported action: MetaISectRegionClipRegionAction!" );
1728 case META_MOVECLIPREGION_ACTION
:
1730 DBG_ERROR( "Unsupported action: MetaMoveClipRegionAction!" );
1738 if (pWMF
->GetError())
1747 // ------------------------------------------------------------------------
1749 void WMFWriter::WriteHeader( const GDIMetaFile
&, BOOL bPlaceable
)
1753 USHORT nCheckSum
, nValue
;
1754 Size
aSize( pVirDev
->LogicToLogic(Size(1,1),MapMode(MAP_INCH
), aTargetMapMode
) );
1755 USHORT nUnitsPerInch
= (USHORT
) ( ( aSize
.Width() + aSize
.Height() ) >> 1 );
1758 nValue
=0xcdd7; nCheckSum
^=nValue
; *pWMF
<< nValue
;
1759 nValue
=0x9ac6; nCheckSum
^=nValue
; *pWMF
<< nValue
;
1760 nValue
=0x0000; nCheckSum
^=nValue
; *pWMF
<< nValue
;
1761 nValue
=0x0000; nCheckSum
^=nValue
; *pWMF
<< nValue
;
1762 nValue
=0x0000; nCheckSum
^=nValue
; *pWMF
<< nValue
;
1763 nValue
=(USHORT
) aTargetSize
.Width(); nCheckSum
^=nValue
; *pWMF
<< nValue
;
1764 nValue
=(USHORT
) aTargetSize
.Height(); nCheckSum
^=nValue
; *pWMF
<< nValue
;
1765 nValue
=nUnitsPerInch
; nCheckSum
^=nValue
; *pWMF
<< nValue
;
1766 nValue
=0x0000; nCheckSum
^=nValue
; *pWMF
<< nValue
;
1767 nValue
=0x0000; nCheckSum
^=nValue
; *pWMF
<< nValue
;
1771 nMetafileHeaderPos
=pWMF
->Tell();
1772 *pWMF
<< (sal_uInt16
)0x0001 // Typ: Datei
1773 << (sal_uInt16
)0x0009 // Headerlaenge in Worten
1774 << (sal_uInt16
)0x0300 // Version als BCD-Zahl
1775 << (sal_uInt32
) 0x00000000 // Dateilaenge (ohne 1. Header), wird spaeter durch UpdateHeader() berichtigt
1776 << (sal_uInt16
)MAXOBJECTHANDLES
// Maximalezahl der gleichzeitigen Objekte
1777 << (sal_uInt32
) 0x00000000 // Maximale Record-laenge, wird spaeter durch UpdateHeader() berichtigt
1778 << (sal_uInt16
)0x0000; // Reserved
1781 // ------------------------------------------------------------------------
1783 void WMFWriter::UpdateHeader()
1786 sal_uInt32 nFileSize
;
1788 nPos
=pWMF
->Tell(); // Endposition = Gesammtgroesse der Datei
1789 nFileSize
=nPos
-nMetafileHeaderPos
; // Groesse des 1. Headers abziehen
1790 if ((nFileSize
&1)!=0) { // ggf. auf ganze Worte aufrunden
1795 nFileSize
>>=1; // In Anzahl Worte umrechnen
1796 pWMF
->Seek(nMetafileHeaderPos
+6); // Zum Dateigroessen-Eintrag im zweiten Header
1797 *pWMF
<< nFileSize
; // Dateigroesse berichtigen
1798 pWMF
->SeekRel(2); // Zum Max-Record-Laenge-Eintrag im zweiten Header
1799 *pWMF
<< nMaxRecordSize
; // und berichtigen
1803 // ------------------------------------------------------------------------
1805 BOOL
WMFWriter::WriteWMF( const GDIMetaFile
& rMTF
, SvStream
& rTargetStream
,
1806 FilterConfigItem
* pFConfigItem
, BOOL bPlaceable
)
1808 WMFWriterAttrStackMember
* pAt
;
1812 pVirDev
= new VirtualDevice
;
1814 pFilterConfigItem
= pFConfigItem
;
1815 if ( pFilterConfigItem
)
1817 xStatusIndicator
= pFilterConfigItem
->GetStatusIndicator();
1818 if ( xStatusIndicator
.is() )
1821 xStatusIndicator
->start( aMsg
, 100 );
1826 pWMF
=&rTargetStream
;
1827 pWMF
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
1831 aSrcMapMode
=rMTF
.GetPrefMapMode();
1835 aTargetMapMode
= aSrcMapMode
;
1836 aTargetSize
= rMTF
.GetPrefSize();
1837 nTargetDivisor
= CalcSaveTargetMapMode(aTargetMapMode
, aTargetSize
);
1838 aTargetSize
.Width() /= nTargetDivisor
;
1839 aTargetSize
.Height() /= nTargetDivisor
;
1843 aTargetMapMode
= MapMode( MAP_INCH
);
1845 const long nUnit
= pVirDev
->LogicToPixel( Size( 1, 1 ), aTargetMapMode
).Width();
1846 const Fraction
aFrac( 1, nUnit
);
1848 aTargetMapMode
.SetScaleX( aFrac
);
1849 aTargetMapMode
.SetScaleY( aFrac
);
1850 aTargetSize
= pVirDev
->LogicToLogic( rMTF
.GetPrefSize(), aSrcMapMode
, aTargetMapMode
);
1853 pVirDev
->SetMapMode( aTargetMapMode
);
1857 for (USHORT i
=0; i
<MAXOBJECTHANDLES
; i
++)
1858 bHandleAllocated
[i
]=FALSE
;
1860 nDstPenHandle
=0xffff;
1861 nDstFontHandle
=0xffff;
1862 nDstBrushHandle
=0xffff;
1868 nActBitmapPercent
=0;
1870 CountActionsAndBitmaps(rMTF
);
1872 WriteHeader(rMTF
,bPlaceable
);
1873 WMFRecord_SetWindowOrg(Point(0,0));
1874 WMFRecord_SetWindowExt(rMTF
.GetPrefSize());
1875 WMFRecord_SetBkMode( TRUE
);
1877 eDstROP2
= eSrcRasterOp
= ROP_OVERPAINT
;
1878 WMFRecord_SetROP2(eDstROP2
);
1880 aDstLineInfo
= LineInfo();
1881 aDstLineColor
= aSrcLineColor
= Color( COL_BLACK
);
1882 CreateSelectDeletePen( aDstLineColor
, aDstLineInfo
);
1884 aDstFillColor
= aSrcFillColor
= Color( COL_WHITE
);
1885 CreateSelectDeleteBrush( aDstFillColor
);
1887 aDstClipRegion
= aSrcClipRegion
= Region();
1888 bDstIsClipping
= bSrcIsClipping
= FALSE
;
1891 aFont
.SetCharSet( GetExtendedTextEncoding( gsl_getSystemTextEncoding() ) );
1892 aFont
.SetColor( Color( COL_WHITE
) );
1893 aFont
.SetAlign( ALIGN_BASELINE
);
1894 aDstFont
= aSrcFont
= aFont
;
1895 CreateSelectDeleteFont(aDstFont
);
1897 eDstTextAlign
= eSrcTextAlign
= ALIGN_BASELINE
;
1898 eDstHorTextAlign
= eSrcHorTextAlign
= W_TA_LEFT
;
1899 WMFRecord_SetTextAlign( eDstTextAlign
, eDstHorTextAlign
);
1901 aDstTextColor
= aSrcTextColor
= Color( COL_WHITE
);
1902 WMFRecord_SetTextColor(aDstTextColor
);
1907 WMFRecord_EndOfFile();
1913 pAttrStack
=pAt
->pSucc
;
1920 if ( xStatusIndicator
.is() )
1921 xStatusIndicator
->end();
1926 // ------------------------------------------------------------------------
1928 USHORT
WMFWriter::CalcSaveTargetMapMode(MapMode
& rMapMode
,
1929 const Size
& rPrefSize
)
1931 Fraction
aDivFrac(2, 1);
1932 USHORT nDivisor
= 1;
1934 Size aSize
= pVirDev
->LogicToLogic( rPrefSize
, aSrcMapMode
, rMapMode
);
1936 while( nDivisor
<= 64 && (aSize
.Width() > 32767 || aSize
.Height() > 32767) )
1938 Fraction aFrac
= rMapMode
.GetScaleX();
1941 rMapMode
.SetScaleX(aFrac
);
1942 aFrac
= rMapMode
.GetScaleY();
1944 rMapMode
.SetScaleY(aFrac
);
1946 aSize
= pVirDev
->LogicToLogic( rPrefSize
, aSrcMapMode
, rMapMode
);