Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/rendergraphicrasterizer.hxx>
31 : : #include "wmfwr.hxx"
32 : : #include <unotools/fontcvt.hxx>
33 : : #include "emfwr.hxx"
34 : : #include <rtl/crc.h>
35 : : #include <rtl/tencinfo.h>
36 : : #include <tools/bigint.hxx>
37 : : #include <tools/helpers.hxx>
38 : : #include <tools/tenccvt.hxx>
39 : : #include <osl/endian.h>
40 : : #include <i18nutil/unicode.hxx> //unicode::getUnicodeScriptType
41 : :
42 : : #include <vcl/metric.hxx>
43 : : #include <basegfx/polygon/b2dpolygon.hxx>
44 : : #include <basegfx/polygon/b2dpolypolygon.hxx>
45 : :
46 : : //====================== MS-Windows-defines ===============================
47 : :
48 : : #define W_META_SETBKCOLOR 0x0201
49 : : #define W_META_SETBKMODE 0x0102
50 : : #define W_META_SETMAPMODE 0x0103
51 : : #define W_META_SETROP2 0x0104
52 : : #define W_META_SETRELABS 0x0105
53 : : #define W_META_SETPOLYFILLMODE 0x0106
54 : : #define W_META_SETSTRETCHBLTMODE 0x0107
55 : : #define W_META_SETTEXTCHAREXTRA 0x0108
56 : : #define W_META_SETTEXTCOLOR 0x0209
57 : : #define W_META_SETTEXTJUSTIFICATION 0x020A
58 : : #define W_META_SETWINDOWORG 0x020B
59 : : #define W_META_SETWINDOWEXT 0x020C
60 : : #define W_META_SETVIEWPORTORG 0x020D
61 : : #define W_META_SETVIEWPORTEXT 0x020E
62 : : #define W_META_OFFSETWINDOWORG 0x020F
63 : : #define W_META_SCALEWINDOWEXT 0x0410
64 : : #define W_META_OFFSETVIEWPORTORG 0x0211
65 : : #define W_META_SCALEVIEWPORTEXT 0x0412
66 : : #define W_META_LINETO 0x0213
67 : : #define W_META_MOVETO 0x0214
68 : : #define W_META_EXCLUDECLIPRECT 0x0415
69 : : #define W_META_INTERSECTCLIPRECT 0x0416
70 : : #define W_META_ARC 0x0817
71 : : #define W_META_ELLIPSE 0x0418
72 : : #define W_META_FLOODFILL 0x0419
73 : : #define W_META_PIE 0x081A
74 : : #define W_META_RECTANGLE 0x041B
75 : : #define W_META_ROUNDRECT 0x061C
76 : : #define W_META_PATBLT 0x061D
77 : : #define W_META_SAVEDC 0x001E
78 : : #define W_META_SETPIXEL 0x041F
79 : : #define W_META_OFFSETCLIPRGN 0x0220
80 : : #define W_META_TEXTOUT 0x0521
81 : : #define W_META_BITBLT 0x0922
82 : : #define W_META_STRETCHBLT 0x0B23
83 : : #define W_META_POLYGON 0x0324
84 : : #define W_META_POLYLINE 0x0325
85 : : #define W_META_ESCAPE 0x0626
86 : : #define W_META_RESTOREDC 0x0127
87 : : #define W_META_FILLREGION 0x0228
88 : : #define W_META_FRAMEREGION 0x0429
89 : : #define W_META_INVERTREGION 0x012A
90 : : #define W_META_PAINTREGION 0x012B
91 : : #define W_META_SELECTCLIPREGION 0x012C
92 : : #define W_META_SELECTOBJECT 0x012D
93 : : #define W_META_SETTEXTALIGN 0x012E
94 : : #define W_META_DRAWTEXT 0x062F
95 : : #define W_META_CHORD 0x0830
96 : : #define W_META_SETMAPPERFLAGS 0x0231
97 : : #define W_META_EXTTEXTOUT 0x0a32
98 : : #define W_META_SETDIBTODEV 0x0d33
99 : : #define W_META_SELECTPALETTE 0x0234
100 : : #define W_META_REALIZEPALETTE 0x0035
101 : : #define W_META_ANIMATEPALETTE 0x0436
102 : : #define W_META_SETPALENTRIES 0x0037
103 : : #define W_META_POLYPOLYGON 0x0538
104 : : #define W_META_RESIZEPALETTE 0x0139
105 : : #define W_META_DIBBITBLT 0x0940
106 : : #define W_META_DIBSTRETCHBLT 0x0b41
107 : : #define W_META_DIBCREATEPATTERNBRUSH 0x0142
108 : : #define W_META_STRETCHDIB 0x0f43
109 : : #define W_META_EXTFLOODFILL 0x0548
110 : : #define W_META_RESETDC 0x014C
111 : : #define W_META_STARTDOC 0x014D
112 : : #define W_META_STARTPAGE 0x004F
113 : : #define W_META_ENDPAGE 0x0050
114 : : #define W_META_ABORTDOC 0x0052
115 : : #define W_META_ENDDOC 0x005E
116 : : #define W_META_DELETEOBJECT 0x01f0
117 : : #define W_META_CREATEPALETTE 0x00f7
118 : : #define W_META_CREATEBRUSH 0x00F8
119 : : #define W_META_CREATEPATTERNBRUSH 0x01F9
120 : : #define W_META_CREATEPENINDIRECT 0x02FA
121 : : #define W_META_CREATEFONTINDIRECT 0x02FB
122 : : #define W_META_CREATEBRUSHINDIRECT 0x02FC
123 : : #define W_META_CREATEBITMAPINDIRECT 0x02FD
124 : : #define W_META_CREATEBITMAP 0x06FE
125 : : #define W_META_CREATEREGION 0x06FF
126 : :
127 : : #define W_TRANSPARENT 1
128 : : #define W_OPAQUE 2
129 : :
130 : : #define W_R2_BLACK 1
131 : : #define W_R2_NOTMERGEPEN 2
132 : : #define W_R2_MASKNOTPEN 3
133 : : #define W_R2_NOTCOPYPEN 4
134 : : #define W_R2_MASKPENNOT 5
135 : : #define W_R2_NOT 6
136 : : #define W_R2_XORPEN 7
137 : : #define W_R2_NOTMASKPEN 8
138 : : #define W_R2_MASKPEN 9
139 : : #define W_R2_NOTXORPEN 10
140 : : #define W_R2_NOP 11
141 : : #define W_R2_MERGENOTPEN 12
142 : : #define W_R2_COPYPEN 13
143 : : #define W_R2_MERGEPENNOT 14
144 : : #define W_R2_MERGEPEN 15
145 : : #define W_R2_WHITE 16
146 : :
147 : : #define W_TA_NOUPDATECP 0x0000
148 : : #define W_TA_UPDATECP 0x0001
149 : : #define W_TA_LEFT 0x0000
150 : : #define W_TA_RIGHT 0x0002
151 : : #define W_TA_CENTER 0x0006
152 : : #define W_TA_TOP 0x0000
153 : : #define W_TA_BOTTOM 0x0008
154 : : #define W_TA_BASELINE 0x0018
155 : : #define W_TA_RTLREADING 0x0100
156 : :
157 : : #define W_SRCCOPY 0x00CC0020L
158 : : #define W_SRCPAINT 0x00EE0086L
159 : : #define W_SRCAND 0x008800C6L
160 : : #define W_SRCINVERT 0x00660046L
161 : : #define W_SRCERASE 0x00440328L
162 : : #define W_NOTSRCCOPY 0x00330008L
163 : : #define W_NOTSRCERASE 0x001100A6L
164 : : #define W_MERGECOPY 0x00C000CAL
165 : : #define W_MERGEPAINT 0x00BB0226L
166 : : #define W_PATCOPY 0x00F00021L
167 : : #define W_PATPAINT 0x00FB0A09L
168 : : #define W_PATINVERT 0x005A0049L
169 : : #define W_DSTINVERT 0x00550009L
170 : : #define W_BLACKNESS 0x00000042L
171 : : #define W_WHITENESS 0x00FF0062L
172 : :
173 : : #define W_PS_SOLID 0
174 : : #define W_PS_DASH 1
175 : : #define W_PS_DOT 2
176 : : #define W_PS_DASHDOT 3
177 : : #define W_PS_DASHDOTDOT 4
178 : : #define W_PS_NULL 5
179 : : #define W_PS_INSIDEFRAME 6
180 : :
181 : : #define W_LF_FACESIZE 32
182 : :
183 : : #define W_ANSI_CHARSET 0
184 : : #define W_DEFAULT_CHARSET 1
185 : : #define W_SYMBOL_CHARSET 2
186 : : #define W_SHIFTJIS_CHARSET 128
187 : : #define W_HANGEUL_CHARSET 129
188 : : #define W_GB2312_CHARSET 134
189 : : #define W_CHINESEBIG5_CHARSET 136
190 : : #define W_OEM_CHARSET 255
191 : : /*WINVER >= 0x0400*/
192 : : #define W_JOHAB_CHARSET 130
193 : : #define W_HEBREW_CHARSET 177
194 : : #define W_ARABIC_CHARSET 178
195 : : #define W_GREEK_CHARSET 161
196 : : #define W_TURKISH_CHARSET 162
197 : : #define W_VIETNAMESE_CHARSET 163
198 : : #define W_THAI_CHARSET 222
199 : : #define W_EASTEUROPE_CHARSET 238
200 : : #define W_RUSSIAN_CHARSET 204
201 : : #define W_MAC_CHARSET 77
202 : : #define W_BALTIC_CHARSET 186
203 : :
204 : : #define W_DEFAULT_PITCH 0x00
205 : : #define W_FIXED_PITCH 0x01
206 : : #define W_VARIABLE_PITCH 0x02
207 : :
208 : : #define W_FF_DONTCARE 0x00
209 : : #define W_FF_ROMAN 0x10
210 : : #define W_FF_SWISS 0x20
211 : : #define W_FF_MODERN 0x30
212 : : #define W_FF_SCRIPT 0x40
213 : : #define W_FF_DECORATIVE 0x50
214 : :
215 : : #define W_FW_DONTCARE 0
216 : : #define W_FW_THIN 100
217 : : #define W_FW_EXTRALIGHT 200
218 : : #define W_FW_LIGHT 300
219 : : #define W_FW_NORMAL 400
220 : : #define W_FW_MEDIUM 500
221 : : #define W_FW_SEMIBOLD 600
222 : : #define W_FW_BOLD 700
223 : : #define W_FW_EXTRABOLD 800
224 : : #define W_FW_HEAVY 900
225 : : #define W_FW_ULTRALIGHT 200
226 : : #define W_FW_REGULAR 400
227 : : #define W_FW_DEMIBOLD 600
228 : : #define W_FW_ULTRABOLD 800
229 : : #define W_FW_BLACK 900
230 : :
231 : : #define W_BS_SOLID 0
232 : : #define W_BS_HOLLOW 1
233 : : #define W_BS_HATCHED 2
234 : : #define W_BS_PATTERN 3
235 : : #define W_BS_INDEXED 4
236 : : #define W_BS_DIBPATTERN 5
237 : :
238 : : #define W_HS_HORIZONTAL 0
239 : : #define W_HS_VERTICAL 1
240 : : #define W_HS_FDIAGONAL 2
241 : : #define W_HS_BDIAGONAL 3
242 : : #define W_HS_CROSS 4
243 : : #define W_HS_DIAGCROSS 5
244 : :
245 : : #define W_MFCOMMENT 15
246 : :
247 : : #define PRIVATE_ESCAPE_UNICODE 2
248 : :
249 : : //========================== Methoden von WMFWriter ==========================
250 : :
251 : 8169 : void WMFWriter::MayCallback()
252 : : {
253 [ - + ]: 8169 : if ( xStatusIndicator.is() )
254 : : {
255 : : sal_uLong nPercent;
256 : :
257 : : // Wir gehen mal einfach so davon aus, dass 16386 Actions einer Bitmap entsprechen
258 : : // (in der Regel wird ein Metafile entweder nur Actions oder einige Bitmaps und fast
259 : : // keine Actions enthalten. Dann ist das Verhaeltnis ziemlich unwichtig)
260 : :
261 : : nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
262 : : *100
263 : 0 : /((nNumberOfBitmaps<<14)+nNumberOfActions);
264 : :
265 [ # # ]: 0 : if ( nPercent >= nLastPercent + 3 )
266 : : {
267 : 0 : nLastPercent = nPercent;
268 [ # # ]: 0 : if( nPercent <= 100 )
269 : 0 : xStatusIndicator->setValue( nPercent );
270 : : }
271 : : }
272 : 8169 : }
273 : :
274 : 87 : void WMFWriter::CountActionsAndBitmaps( const GDIMetaFile & rMTF )
275 : : {
276 : : size_t nAction, nActionCount;
277 : :
278 : 87 : nActionCount = rMTF.GetActionSize();
279 : :
280 [ + + ]: 8256 : for ( nAction=0; nAction < nActionCount; nAction++ )
281 : : {
282 : 8169 : MetaAction* pMA = rMTF.GetAction( nAction );
283 : :
284 [ - + ]: 8169 : switch( pMA->GetType() )
285 : : {
286 : : case META_BMP_ACTION:
287 : : case META_BMPSCALE_ACTION:
288 : : case META_BMPSCALEPART_ACTION:
289 : : case META_BMPEX_ACTION:
290 : : case META_BMPEXSCALE_ACTION:
291 : : case META_BMPEXSCALEPART_ACTION:
292 : : case META_RENDERGRAPHIC_ACTION:
293 : 0 : nNumberOfBitmaps++;
294 : 0 : break;
295 : : }
296 : 8169 : nNumberOfActions++;
297 : : }
298 : 87 : }
299 : :
300 : :
301 : 25494 : void WMFWriter::WritePointXY(const Point & rPoint)
302 : : {
303 [ + - ]: 25494 : Point aPt( pVirDev->LogicToLogic(rPoint,aSrcMapMode,aTargetMapMode) );
304 [ + - ][ + - ]: 25494 : *pWMF << ((short)aPt.X()) << ((short)aPt.Y());
305 : 25494 : }
306 : :
307 : :
308 : 1011 : void WMFWriter::WritePointYX(const Point & rPoint)
309 : : {
310 [ + - ]: 1011 : Point aPt( pVirDev->LogicToLogic(rPoint,aSrcMapMode,aTargetMapMode) );
311 [ + - ][ + - ]: 1011 : *pWMF << ((short)aPt.Y()) << ((short)aPt.X());
312 : 1011 : }
313 : :
314 : :
315 : 183 : sal_Int32 WMFWriter::ScaleWidth( sal_Int32 nDX )
316 : : {
317 [ + - ]: 183 : Size aSz( pVirDev->LogicToLogic(Size(nDX,0),aSrcMapMode,aTargetMapMode) );
318 : 183 : return aSz.Width();
319 : : }
320 : :
321 : :
322 : 501 : void WMFWriter::WriteSize(const Size & rSize)
323 : : {
324 [ + - ]: 501 : Size aSz( pVirDev->LogicToLogic(rSize,aSrcMapMode,aTargetMapMode) );
325 [ + - ][ + - ]: 501 : *pWMF << ((short)aSz.Width()) << ((short)aSz.Height());
326 : 501 : }
327 : :
328 : :
329 : 1284 : void WMFWriter::WriteHeightWidth(const Size & rSize)
330 : : {
331 [ + - ]: 1284 : Size aSz( pVirDev->LogicToLogic(rSize,aSrcMapMode,aTargetMapMode) );
332 [ + - ][ + - ]: 1284 : *pWMF << ((short)aSz.Height()) << ((short)aSz.Width());
333 : 1284 : }
334 : :
335 : :
336 : 144 : void WMFWriter::WriteRectangle(const Rectangle & rRect)
337 : : {
338 [ + - ]: 144 : WritePointYX(Point(rRect.Right()+1,rRect.Bottom()+1));
339 [ + - ]: 144 : WritePointYX(rRect.TopLeft());
340 : 144 : }
341 : :
342 : :
343 : 2082 : void WMFWriter::WriteColor(const Color & rColor)
344 : : {
345 : 2082 : *pWMF << (sal_uInt8) rColor.GetRed() << (sal_uInt8) rColor.GetGreen() << (sal_uInt8) rColor.GetBlue() << (sal_uInt8) 0;
346 : 2082 : }
347 : :
348 : :
349 : 11775 : void WMFWriter::WriteRecordHeader(sal_uInt32 nSizeWords, sal_uInt16 nType)
350 : : {
351 : 11775 : nActRecordPos=pWMF->Tell();
352 [ - + ]: 11775 : if (nSizeWords>nMaxRecordSize) nMaxRecordSize=nSizeWords;
353 : 11775 : *pWMF << nSizeWords << nType;
354 : 11775 : }
355 : :
356 : :
357 : 2172 : void WMFWriter::UpdateRecordHeader()
358 : : {
359 : : sal_uLong nPos;
360 : : sal_uInt32 nSize;
361 : :
362 : 2172 : nPos=pWMF->Tell(); nSize=nPos-nActRecordPos;
363 [ - + ]: 2172 : if ((nSize & 1)!=0) {
364 : 0 : *pWMF << (sal_uInt8)0;
365 : 0 : nPos++; nSize++;
366 : : }
367 : 2172 : nSize/=2;
368 [ + + ]: 2172 : if (nSize>nMaxRecordSize) nMaxRecordSize=nSize;
369 : 2172 : pWMF->Seek(nActRecordPos);
370 : 2172 : *pWMF << nSize;
371 : 2172 : pWMF->Seek(nPos);
372 : 2172 : }
373 : :
374 : :
375 : 0 : void WMFWriter::WMFRecord_Arc(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
376 : : {
377 : 0 : WriteRecordHeader(0x0000000b,W_META_ARC);
378 : 0 : WritePointYX(rEndPt);
379 : 0 : WritePointYX(rStartPt);
380 : 0 : WriteRectangle(rRect);
381 : 0 : }
382 : :
383 : 0 : void WMFWriter::WMFRecord_Chord(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
384 : : {
385 : 0 : WriteRecordHeader(0x0000000b,W_META_CHORD);
386 : 0 : WritePointYX(rEndPt);
387 : 0 : WritePointYX(rStartPt);
388 : 0 : WriteRectangle(rRect);
389 : 0 : }
390 : :
391 : :
392 : 501 : void WMFWriter::WMFRecord_CreateBrushIndirect(const Color& rColor)
393 : : {
394 : 501 : WriteRecordHeader(0x00000007,W_META_CREATEBRUSHINDIRECT);
395 : :
396 [ - + ]: 501 : if( rColor==Color(COL_TRANSPARENT) )
397 : 0 : *pWMF << (sal_uInt16) W_BS_HOLLOW;
398 : : else
399 : 501 : *pWMF << (sal_uInt16) W_BS_SOLID;
400 : :
401 : 501 : WriteColor( rColor );
402 : 501 : *pWMF << (sal_uInt16) 0;
403 : 501 : }
404 : :
405 : :
406 : 1197 : void WMFWriter::WMFRecord_CreateFontIndirect(const Font & rFont)
407 : : {
408 : : sal_uInt16 nWeight,i;
409 : : sal_uInt8 nPitchFamily;
410 : :
411 [ + - ]: 1197 : WriteRecordHeader(0x00000000,W_META_CREATEFONTINDIRECT);
412 [ + - ][ + - ]: 1197 : WriteHeightWidth(Size(rFont.GetSize().Width(),-rFont.GetSize().Height()));
[ + - ]
413 [ + - ][ + - ]: 1197 : *pWMF << (short)rFont.GetOrientation() << (short)rFont.GetOrientation();
[ + - ][ + - ]
414 : :
415 [ + - ][ - - : 1197 : switch (rFont.GetWeight()) {
- - + - -
- - - + ]
416 : 0 : case WEIGHT_THIN: nWeight=W_FW_THIN; break;
417 : 0 : case WEIGHT_ULTRALIGHT: nWeight=W_FW_ULTRALIGHT; break;
418 : 0 : case WEIGHT_LIGHT: nWeight=W_FW_LIGHT; break;
419 : 0 : case WEIGHT_SEMILIGHT: nWeight=W_FW_LIGHT; break;
420 : 1110 : case WEIGHT_NORMAL: nWeight=W_FW_NORMAL; break;
421 : 0 : case WEIGHT_MEDIUM: nWeight=W_FW_MEDIUM; break;
422 : 0 : case WEIGHT_SEMIBOLD: nWeight=W_FW_SEMIBOLD; break;
423 : 0 : case WEIGHT_BOLD: nWeight=W_FW_BOLD; break;
424 : 0 : case WEIGHT_ULTRABOLD: nWeight=W_FW_ULTRABOLD; break;
425 : 0 : case WEIGHT_BLACK: nWeight=W_FW_BLACK; break;
426 : 87 : default: nWeight=W_FW_DONTCARE;
427 : : }
428 [ + - ]: 1197 : *pWMF << nWeight;
429 : :
430 [ + - ][ + + ]: 1197 : if (rFont.GetItalic()==ITALIC_NONE) *pWMF << (sal_uInt8)0; else *pWMF << (sal_uInt8)1;
[ + - ][ + - ]
431 [ + - ][ + - ]: 1197 : if (rFont.GetUnderline()==UNDERLINE_NONE) *pWMF << (sal_uInt8)0; else *pWMF << (sal_uInt8)1;
[ + - ][ # # ]
432 [ + - ][ + - ]: 1197 : if (rFont.GetStrikeout()==STRIKEOUT_NONE) *pWMF << (sal_uInt8)0; else *pWMF << (sal_uInt8)1;
[ + - ][ # # ]
433 : :
434 [ + - ]: 1197 : CharSet eFontNameEncoding = rFont.GetCharSet();
435 [ + - ]: 1197 : sal_uInt8 nCharSet = rtl_getBestWindowsCharsetFromTextEncoding( eFontNameEncoding );
436 [ - + ]: 1197 : if ( eFontNameEncoding == RTL_TEXTENCODING_SYMBOL )
437 : 0 : eFontNameEncoding = RTL_TEXTENCODING_MS_1252;
438 [ - + ]: 1197 : if ( nCharSet == 1 )
439 : 0 : nCharSet = W_ANSI_CHARSET;
440 [ + - ]: 1197 : *pWMF << nCharSet;
441 : :
442 [ + - ][ + - ]: 1197 : *pWMF << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0;
[ + - ]
443 : :
444 [ + - ]: 1197 : switch (rFont.GetPitch()) {
[ - - + ]
445 : 0 : case PITCH_FIXED: nPitchFamily=W_FIXED_PITCH; break;
446 : 0 : case PITCH_VARIABLE: nPitchFamily=W_VARIABLE_PITCH; break;
447 : 1197 : default: nPitchFamily=W_DEFAULT_PITCH;
448 : : }
449 [ + - ][ - - : 1197 : switch (rFont.GetFamily()) {
+ - - + ]
450 : 0 : case FAMILY_DECORATIVE: nPitchFamily|=W_FF_DECORATIVE; break;
451 : 0 : case FAMILY_MODERN: nPitchFamily|=W_FF_MODERN; break;
452 : 696 : case FAMILY_ROMAN: nPitchFamily|=W_FF_ROMAN; break;
453 : 0 : case FAMILY_SCRIPT: nPitchFamily|=W_FF_SCRIPT; break;
454 : 0 : case FAMILY_SWISS: nPitchFamily|=W_FF_SWISS; break;
455 : 501 : default: nPitchFamily|=W_FF_DONTCARE;
456 : : }
457 [ + - ]: 1197 : *pWMF << nPitchFamily;
458 : :
459 [ + - ][ + - ]: 1197 : rtl::OString aFontName(rtl::OUStringToOString(rFont.GetName(), eFontNameEncoding));
[ + - ]
460 [ + + ]: 39501 : for ( i = 0; i < W_LF_FACESIZE; i++ )
461 : : {
462 [ + + ]: 38304 : sal_Char nChar = ( i < aFontName.getLength() ) ? aFontName[i] : 0;
463 [ + - ]: 38304 : *pWMF << nChar;
464 : : }
465 [ + - ]: 1197 : UpdateRecordHeader();
466 : 1197 : }
467 : :
468 : 501 : void WMFWriter::WMFRecord_CreatePenIndirect(const Color& rColor, const LineInfo& rLineInfo )
469 : : {
470 : 501 : WriteRecordHeader(0x00000008,W_META_CREATEPENINDIRECT);
471 [ + + ]: 501 : sal_uInt16 nStyle = rColor == Color( COL_TRANSPARENT ) ? W_PS_NULL : W_PS_SOLID;
472 [ - - + ]: 501 : switch( rLineInfo.GetStyle() )
473 : : {
474 : : case LINE_DASH :
475 : : {
476 [ # # ]: 0 : if ( rLineInfo.GetDotCount() )
477 : : {
478 [ # # ]: 0 : if ( !rLineInfo.GetDashCount() )
479 : 0 : nStyle = W_PS_DOT;
480 : : else
481 : : {
482 [ # # ][ # # ]: 0 : if ( !rLineInfo.GetDotCount() == 1 )
483 : 0 : nStyle = W_PS_DASHDOT;
484 : : else
485 : 0 : nStyle = W_PS_DASHDOTDOT;
486 : : }
487 : : }
488 : : else
489 : 0 : nStyle = W_PS_DASH;
490 : : }
491 : 0 : break;
492 : : case LINE_NONE :
493 : 0 : nStyle = W_PS_NULL;
494 : 0 : break;
495 : : default:
496 : 501 : break;
497 : : }
498 : 501 : *pWMF << nStyle;
499 : :
500 [ + - ]: 501 : WriteSize( Size( rLineInfo.GetWidth(), 0 ) );
501 : 501 : WriteColor( rColor );
502 : 501 : }
503 : :
504 : 1938 : void WMFWriter::WMFRecord_DeleteObject(sal_uInt16 nObjectHandle)
505 : : {
506 : 1938 : WriteRecordHeader(0x00000004,W_META_DELETEOBJECT);
507 : 1938 : *pWMF << nObjectHandle;
508 : 1938 : }
509 : :
510 : :
511 : 0 : void WMFWriter::WMFRecord_Ellipse(const Rectangle & rRect)
512 : : {
513 : 0 : WriteRecordHeader(0x00000007,W_META_ELLIPSE);
514 : 0 : WriteRectangle(rRect);
515 : 0 : }
516 : :
517 : 915 : bool IsStarSymbol(const String &rStr)
518 : : {
519 : 915 : return rStr.EqualsIgnoreCaseAscii("starsymbol") ||
520 [ + + ][ + - ]: 915 : rStr.EqualsIgnoreCaseAscii("opensymbol");
521 : : }
522 : :
523 : 357 : void WMFWriter::WMFRecord_Escape( sal_uInt32 nEsc, sal_uInt32 nLen, const sal_Int8* pData )
524 : : {
525 : : #ifdef OSL_BIGENDIAN
526 : : sal_uInt32 nTmp = OSL_SWAPDWORD( nEsc );
527 : : sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
528 : : #else
529 : 357 : sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
530 : : #endif
531 [ + - ]: 357 : if ( nLen )
532 : 357 : nCheckSum = rtl_crc32( nCheckSum, pData, nLen );
533 : :
534 : 357 : WriteRecordHeader( 3 + 9 + ( ( nLen + 1 ) >> 1 ), W_META_ESCAPE );
535 : 357 : *pWMF << (sal_uInt16)W_MFCOMMENT
536 : 357 : << (sal_uInt16)( nLen + 14 ) // we will always have a fourteen byte escape header:
537 : 357 : << (sal_uInt16)0x4f4f // OO
538 : 357 : << (sal_uInt32)0xa2c2a // evil magic number
539 : 357 : << (sal_uInt32)nCheckSum // crc32 checksum about nEsc & pData
540 : 357 : << (sal_uInt32)nEsc; // escape number
541 : 357 : pWMF->Write( pData, nLen );
542 [ - + ]: 357 : if ( nLen & 1 )
543 : 0 : *pWMF << (sal_uInt8)0; // pad byte
544 : 357 : }
545 : :
546 : : /* if return value is true, then a complete unicode string and also a polygon replacement has been written,
547 : : so there is no more action necessary
548 : : */
549 : 993 : sal_Bool WMFWriter::WMFRecord_Escape_Unicode( const Point& rPoint, const String& rUniStr, const sal_Int32* pDXAry )
550 : : {
551 : 993 : sal_Bool bEscapeUsed = sal_False;
552 : :
553 : 993 : sal_uInt32 i, nStringLen = rUniStr.Len();
554 [ + - ]: 993 : if ( nStringLen )
555 : : {
556 : : // first we will check if a comment is necessary
557 [ + - ]: 993 : if ( aSrcFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) // symbol is always byte character, so there is no unicode loss
558 : : {
559 : 993 : const sal_Unicode* pBuf = rUniStr.GetBuffer();
560 [ + - ]: 993 : const rtl_TextEncoding aTextEncodingOrg = aSrcFont.GetCharSet();
561 [ + - ][ + - ]: 993 : rtl::OString aByteStr(rtl::OUStringToOString(rUniStr, aTextEncodingOrg));
562 [ + - ]: 993 : rtl::OUString aUniStr2(rtl::OStringToOUString(aByteStr, aTextEncodingOrg));
563 : 993 : const sal_Unicode* pConversion = aUniStr2.getStr(); // this is the unicode array after bytestring <-> unistring conversion
564 [ + + ]: 1914 : for ( i = 0; i < nStringLen; i++ )
565 : : {
566 [ + + ]: 1116 : if ( *pBuf++ != *pConversion++ )
567 : 195 : break;
568 : : }
569 : :
570 [ + + ]: 993 : if ( i != nStringLen ) // after conversion the characters are not original,
571 : : { // try again, with determining a better charset from unicode char
572 : 195 : pBuf = rUniStr.GetBuffer();
573 : 195 : const sal_Unicode* pCheckChar = pBuf;
574 [ + - ]: 195 : rtl_TextEncoding aTextEncoding = getBestMSEncodingByChar(*pCheckChar); // try the first character
575 [ + + ]: 201 : for ( i = 1; i < nStringLen; i++)
576 : : {
577 [ + + ]: 12 : if (aTextEncoding != aTextEncodingOrg) // found something
578 : 6 : break;
579 : 6 : pCheckChar++;
580 [ + - ]: 6 : aTextEncoding = getBestMSEncodingByChar(*pCheckChar); // try the next character
581 : : }
582 : :
583 [ + - ][ + - ]: 195 : aByteStr = rtl::OUStringToOString(rUniStr, aTextEncoding);
584 [ + - ]: 195 : aUniStr2 = rtl::OStringToOUString(aByteStr, aTextEncoding);
585 : 195 : pConversion = aUniStr2.getStr(); // this is the unicode array after bytestring <-> unistring conversion
586 [ + + ]: 324 : for ( i = 0; i < nStringLen; i++ )
587 : : {
588 [ + + ]: 207 : if ( *pBuf++ != *pConversion++ )
589 : 78 : break;
590 : : }
591 [ + + ]: 195 : if (i == nStringLen)
592 : : {
593 [ + - ]: 117 : aSrcFont.SetCharSet (aTextEncoding);
594 [ + - ]: 117 : SetAllAttr();
595 : : }
596 : : }
597 : :
598 [ + + ][ + - ]: 993 : if ( ( i != nStringLen ) || IsStarSymbol( aSrcFont.GetName() ) ) // after conversion the characters are not original, so we
[ + - ][ + + ]
[ + + ]
599 : : { // will store the unicode string and a polypoly replacement
600 : 357 : Color aOldFillColor( aSrcFillColor );
601 : 357 : Color aOldLineColor( aSrcLineColor );
602 [ + - ][ + - ]: 357 : aSrcLineInfo = LineInfo();
[ + - ]
603 : 357 : aSrcFillColor = aSrcTextColor;
604 : 357 : aSrcLineColor = Color( COL_TRANSPARENT );
605 [ + - ]: 357 : SetLineAndFillAttr();
606 [ + - ]: 357 : pVirDev->SetFont( aSrcFont );
607 [ + - ]: 357 : std::vector<PolyPolygon> aPolyPolyVec;
608 [ + - ][ + - ]: 357 : if ( pVirDev->GetTextOutlines( aPolyPolyVec, rUniStr ) )
609 : : {
610 [ - + ]: 357 : sal_uInt32 nDXCount = pDXAry ? nStringLen : 0;
611 : 357 : sal_uInt32 nSkipActions = aPolyPolyVec.size();
612 : : sal_Int32 nStrmLen = 8 +
613 : : + sizeof( nStringLen ) + ( nStringLen * 2 )
614 : : + sizeof( nDXCount ) + ( nDXCount * 4 )
615 : 357 : + sizeof( nSkipActions );
616 : :
617 [ + - ]: 357 : SvMemoryStream aMemoryStream( nStrmLen );
618 [ + - ]: 357 : Point aPt( pVirDev->LogicToLogic( rPoint, aSrcMapMode, aTargetMapMode ) );
619 [ + - ]: 357 : aMemoryStream << static_cast<sal_Int32>(aPt.X())
620 [ + - ]: 714 : << static_cast<sal_Int32>(aPt.Y())
621 [ + - ]: 357 : << nStringLen;
622 [ + + ]: 714 : for ( i = 0; i < nStringLen; i++ )
623 [ + - ]: 357 : aMemoryStream << rUniStr.GetChar( (sal_uInt16)i );
624 [ + - ]: 357 : aMemoryStream << nDXCount;
625 [ - + ]: 357 : for ( i = 0; i < nDXCount; i++ )
626 [ # # ]: 0 : aMemoryStream << pDXAry[ i ];
627 [ + - ]: 357 : aMemoryStream << nSkipActions;
628 [ + - ][ + - ]: 357 : WMFRecord_Escape( PRIVATE_ESCAPE_UNICODE, nStrmLen, (const sal_Int8*)aMemoryStream.GetData() );
629 : :
630 : 357 : std::vector<PolyPolygon>::iterator aIter( aPolyPolyVec.begin() );
631 [ + - ][ + + ]: 576 : while ( aIter != aPolyPolyVec.end() )
632 : : {
633 [ + - ][ + - ]: 219 : PolyPolygon aPolyPoly( *aIter++ );
[ + - ]
634 [ + - ]: 219 : aPolyPoly.Move( rPoint.X(), rPoint.Y() );
635 [ + - ]: 219 : WMFRecord_PolyPolygon( aPolyPoly );
636 [ + - ]: 219 : }
637 : 357 : aSrcFillColor = aOldFillColor;
638 : 357 : aSrcLineColor = aOldLineColor;
639 [ + - ]: 357 : bEscapeUsed = sal_True;
640 : 357 : }
641 : 993 : }
642 : : }
643 : : }
644 : 993 : return bEscapeUsed;
645 : : }
646 : :
647 : 636 : void WMFWriter::WMFRecord_ExtTextOut( const Point & rPoint,
648 : : const String & rString, const sal_Int32 * pDXAry )
649 : : {
650 : 636 : sal_uInt16 nOriginalTextLen = rString.Len();
651 : :
652 [ + + ][ + + ]: 636 : if ( (nOriginalTextLen <= 1) || (pDXAry == NULL) )
653 : : {
654 [ + - ]: 576 : WMFRecord_TextOut(rPoint, rString);
655 : 636 : return;
656 : : }
657 [ + - ]: 60 : rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
658 [ + - ][ + - ]: 60 : rtl::OString aByteString(rtl::OUStringToOString(rString, eChrSet));
659 [ + - ]: 636 : TrueExtTextOut(rPoint,rString,aByteString,pDXAry);
660 : : }
661 : :
662 : 60 : void WMFWriter::TrueExtTextOut( const Point & rPoint, const String & rString,
663 : : const rtl::OString& rByteString, const sal_Int32 * pDXAry )
664 : : {
665 : 60 : WriteRecordHeader( 0, W_META_EXTTEXTOUT );
666 : 60 : WritePointYX( rPoint );
667 : 60 : sal_uInt16 nNewTextLen = static_cast<sal_uInt16>(rByteString.getLength());
668 : 60 : *pWMF << nNewTextLen << (sal_uInt16)0;
669 : 60 : write_uInt8s_FromOString(*pWMF, rByteString, nNewTextLen);
670 [ + + ]: 60 : if ( nNewTextLen & 1 )
671 : 45 : *pWMF << (sal_uInt8)0;
672 : :
673 : 60 : sal_uInt16 nOriginalTextLen = rString.Len();
674 : 60 : sal_Int16* pConvertedDXAry = new sal_Int16[ nOriginalTextLen ];
675 : 60 : sal_Int32 j = 0;
676 : 60 : pConvertedDXAry[ j++ ] = (sal_Int16)ScaleWidth( pDXAry[ 0 ] );
677 [ + + ]: 123 : for (sal_uInt16 i = 1; i < ( nOriginalTextLen - 1 ); ++i)
678 : 63 : pConvertedDXAry[ j++ ] = (sal_Int16)ScaleWidth( pDXAry[ i ] - pDXAry[ i - 1 ] );
679 : 60 : pConvertedDXAry[ j ] = (sal_Int16)ScaleWidth( pDXAry[ nOriginalTextLen - 2 ] / ( nOriginalTextLen - 1 ) );
680 : :
681 [ + + ]: 243 : for (sal_uInt16 i = 0; i < nOriginalTextLen; ++i)
682 : : {
683 : 183 : sal_Int16 nDx = pConvertedDXAry[ i ];
684 : 183 : *pWMF << nDx;
685 [ - + ]: 183 : if ( nOriginalTextLen < nNewTextLen )
686 : : {
687 : 0 : sal_Unicode nUniChar = rString.GetChar(i);
688 [ # # ][ # # ]: 0 : rtl::OString aTemp(&nUniChar, 1, aSrcFont.GetCharSet());
689 : 0 : j = aTemp.getLength();
690 [ # # ]: 0 : while ( --j > 0 )
691 [ # # ]: 0 : *pWMF << (sal_uInt16)0;
692 : : }
693 : : }
694 [ + - ]: 60 : delete[] pConvertedDXAry;
695 : 60 : UpdateRecordHeader();
696 : 60 : }
697 : :
698 : 0 : void WMFWriter::WMFRecord_LineTo(const Point & rPoint)
699 : : {
700 : 0 : WriteRecordHeader(0x00000005,W_META_LINETO);
701 : 0 : WritePointYX(rPoint);
702 : 0 : }
703 : :
704 : :
705 : 0 : void WMFWriter::WMFRecord_MoveTo(const Point & rPoint)
706 : : {
707 : 0 : WriteRecordHeader(0x00000005,W_META_MOVETO);
708 : 0 : WritePointYX(rPoint);
709 : 0 : }
710 : :
711 : :
712 : 0 : void WMFWriter::WMFRecord_Pie(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
713 : : {
714 : 0 : WriteRecordHeader(0x0000000b,W_META_PIE);
715 : 0 : WritePointYX(rEndPt);
716 : 0 : WritePointYX(rStartPt);
717 : 0 : WriteRectangle(rRect);
718 : 0 : }
719 : :
720 : :
721 : 0 : void WMFWriter::WMFRecord_Polygon(const Polygon & rPoly)
722 : : {
723 : : sal_uInt16 nSize,i;
724 : :
725 [ # # ]: 0 : Polygon aSimplePoly;
726 [ # # ][ # # ]: 0 : if ( rPoly.HasFlags() )
727 [ # # ]: 0 : rPoly.AdaptiveSubdivide( aSimplePoly );
728 : : else
729 [ # # ]: 0 : aSimplePoly = rPoly;
730 [ # # ]: 0 : nSize = aSimplePoly.GetSize();
731 [ # # ]: 0 : WriteRecordHeader(((sal_uLong)nSize)*2+4,W_META_POLYGON);
732 [ # # ]: 0 : *pWMF << nSize;
733 [ # # ][ # # ]: 0 : for (i=0; i<nSize; i++) WritePointXY(aSimplePoly.GetPoint(i));
[ # # ][ # # ]
734 : 0 : }
735 : :
736 : :
737 : 0 : void WMFWriter::WMFRecord_PolyLine(const Polygon & rPoly)
738 : : {
739 : : sal_uInt16 nSize,i;
740 [ # # ]: 0 : Polygon aSimplePoly;
741 [ # # ][ # # ]: 0 : if ( rPoly.HasFlags() )
742 [ # # ]: 0 : rPoly.AdaptiveSubdivide( aSimplePoly );
743 : : else
744 [ # # ]: 0 : aSimplePoly = rPoly;
745 [ # # ]: 0 : nSize=aSimplePoly.GetSize();
746 [ # # ]: 0 : WriteRecordHeader(((sal_uLong)nSize)*2+4,W_META_POLYLINE);
747 [ # # ]: 0 : *pWMF << nSize;
748 [ # # ][ # # ]: 0 : for (i=0; i<nSize; i++) WritePointXY(aSimplePoly.GetPoint(i));
[ # # ][ # # ]
749 : 0 : }
750 : :
751 : :
752 : 219 : void WMFWriter::WMFRecord_PolyPolygon(const PolyPolygon & rPolyPoly)
753 : : {
754 : : const Polygon * pPoly;
755 : : sal_uInt16 nCount,nSize,i,j;
756 : :
757 [ + - ]: 219 : nCount=rPolyPoly.Count();
758 [ + - ]: 219 : PolyPolygon aSimplePolyPoly( rPolyPoly );
759 [ + + ]: 1014 : for ( i = 0; i < nCount; i++ )
760 : : {
761 [ + - ][ + - ]: 795 : if ( aSimplePolyPoly[ i ].HasFlags() )
[ + + ]
762 : : {
763 [ + - ]: 534 : Polygon aSimplePoly;
764 [ + - ][ + - ]: 534 : aSimplePolyPoly[ i ].AdaptiveSubdivide( aSimplePoly );
765 [ + - ][ + - ]: 534 : aSimplePolyPoly[ i ] = aSimplePoly;
[ + - ]
766 : : }
767 : : }
768 [ + - ]: 219 : WriteRecordHeader(0,W_META_POLYPOLYGON);
769 [ + - ]: 219 : *pWMF << nCount;
770 [ + - ][ + - ]: 1014 : for (i=0; i<nCount; i++) *pWMF << ((sal_uInt16)(aSimplePolyPoly.GetObject(i).GetSize()));
[ + - ][ + + ]
771 [ + + ]: 1014 : for (i=0; i<nCount; i++) {
772 [ + - ]: 795 : pPoly=&(aSimplePolyPoly.GetObject(i));
773 [ + - ]: 795 : nSize=pPoly->GetSize();
774 [ + - ][ + - ]: 26289 : for (j=0; j<nSize; j++) WritePointXY(pPoly->GetPoint(j));
[ + + ]
775 : : }
776 [ + - ][ + - ]: 219 : UpdateRecordHeader();
777 : 219 : }
778 : :
779 : :
780 : 57 : void WMFWriter::WMFRecord_Rectangle(const Rectangle & rRect)
781 : : {
782 : 57 : WriteRecordHeader( 0x00000007,W_META_RECTANGLE );
783 : 57 : WriteRectangle( rRect );
784 : 57 : }
785 : :
786 : :
787 : 1137 : void WMFWriter::WMFRecord_RestoreDC()
788 : : {
789 : 1137 : WriteRecordHeader(0x00000004,W_META_RESTOREDC);
790 : 1137 : *pWMF << (short)-1;
791 : 1137 : }
792 : :
793 : :
794 : 0 : void WMFWriter::WMFRecord_RoundRect(const Rectangle & rRect, long nHorzRound, long nVertRound)
795 : : {
796 : 0 : WriteRecordHeader(0x00000009,W_META_ROUNDRECT);
797 [ # # ]: 0 : WriteHeightWidth(Size(nHorzRound,nVertRound));
798 : 0 : WriteRectangle(rRect);
799 : 0 : }
800 : :
801 : :
802 : 1137 : void WMFWriter::WMFRecord_SaveDC()
803 : : {
804 : 1137 : WriteRecordHeader(0x00000003,W_META_SAVEDC);
805 : 1137 : }
806 : :
807 : :
808 : 2199 : void WMFWriter::WMFRecord_SelectObject(sal_uInt16 nObjectHandle)
809 : : {
810 : 2199 : WriteRecordHeader(0x00000004,W_META_SELECTOBJECT);
811 : 2199 : *pWMF << nObjectHandle;
812 : 2199 : }
813 : :
814 : :
815 : 87 : void WMFWriter::WMFRecord_SetBkMode(sal_Bool bTransparent)
816 : : {
817 : 87 : WriteRecordHeader(0x00000004,W_META_SETBKMODE);
818 [ + - ]: 87 : if (bTransparent==sal_True) *pWMF << (sal_uInt16)W_TRANSPARENT;
819 : 0 : else *pWMF << (sal_uInt16)W_OPAQUE;
820 : 87 : }
821 : :
822 : 87 : void WMFWriter::WMFRecord_SetStretchBltMode()
823 : : {
824 : 87 : WriteRecordHeader( 0x00000004, W_META_SETSTRETCHBLTMODE );
825 : 87 : *pWMF << (sal_uInt16) 3; // STRETCH_DELETESCANS
826 : 87 : }
827 : :
828 : 0 : void WMFWriter::WMFRecord_SetPixel(const Point & rPoint, const Color & rColor)
829 : : {
830 : 0 : WriteRecordHeader(0x00000007,W_META_SETPIXEL);
831 : 0 : WriteColor(rColor);
832 : 0 : WritePointYX(rPoint);
833 : 0 : }
834 : :
835 : :
836 : 87 : void WMFWriter::WMFRecord_SetROP2(RasterOp eROP)
837 : : {
838 : : sal_uInt16 nROP2;
839 : :
840 [ - - + ]: 87 : switch (eROP) {
841 : 0 : case ROP_INVERT: nROP2=W_R2_NOT; break;
842 : 0 : case ROP_XOR: nROP2=W_R2_XORPEN; break;
843 : 87 : default: nROP2=W_R2_COPYPEN;
844 : : }
845 : 87 : WriteRecordHeader(0x00000004,W_META_SETROP2);
846 : 87 : *pWMF << nROP2;
847 : 87 : }
848 : :
849 : :
850 : 87 : void WMFWriter::WMFRecord_SetTextAlign(FontAlign eFontAlign, sal_uInt32 eHorTextAlign)
851 : : {
852 : : sal_uInt16 nAlign;
853 : :
854 [ - - + ]: 87 : switch (eFontAlign) {
855 : 0 : case ALIGN_TOP: nAlign=W_TA_TOP; break;
856 : 0 : case ALIGN_BOTTOM: nAlign=W_TA_BOTTOM; break;
857 : 87 : default: nAlign=W_TA_BASELINE;
858 : : }
859 : 87 : nAlign|=eHorTextAlign;
860 : 87 : nAlign|=W_TA_NOUPDATECP;
861 : :
862 : 87 : WriteRecordHeader(0x00000004,W_META_SETTEXTALIGN);
863 : 87 : *pWMF << nAlign;
864 : 87 : }
865 : :
866 : :
867 : 1080 : void WMFWriter::WMFRecord_SetTextColor(const Color & rColor)
868 : : {
869 : 1080 : WriteRecordHeader(0x00000005,W_META_SETTEXTCOLOR);
870 : 1080 : WriteColor(rColor);
871 : 1080 : }
872 : :
873 : :
874 : 87 : void WMFWriter::WMFRecord_SetWindowExt(const Size & rSize)
875 : : {
876 : 87 : WriteRecordHeader(0x00000005,W_META_SETWINDOWEXT);
877 : 87 : WriteHeightWidth(rSize);
878 : 87 : }
879 : :
880 : :
881 : 87 : void WMFWriter::WMFRecord_SetWindowOrg(const Point & rPoint)
882 : : {
883 : 87 : WriteRecordHeader(0x00000005,W_META_SETWINDOWORG);
884 : 87 : WritePointYX(rPoint);
885 : 87 : }
886 : :
887 : :
888 : 0 : void WMFWriter::WMFRecord_StretchDIB( const Point & rPoint, const Size & rSize,
889 : : const Bitmap & rBitmap, sal_uInt32 nROP )
890 : : {
891 : : sal_uLong nPosAnf,nPosEnd;
892 : :
893 : 0 : nActBitmapPercent=50;
894 : 0 : MayCallback();
895 : :
896 : 0 : WriteRecordHeader(0x00000000,W_META_STRETCHDIB);
897 : :
898 : : // Die Reihenfolge im Metafile soll jetzt sein:
899 : : // einige Parameter (laenge 22), dann die Bitmap ohne FILEHEADER.
900 : : // Da aber *pWMF << rBitmap einen FILEHEADER der Laenge 14
901 : : // erzeugt, schreiben wir zuerst die Bitmap an die richtige Position
902 : : // Und ueberschreiben hinterher den FILEHEADER mit den Parametern.
903 : 0 : nPosAnf=pWMF->Tell(); // Position merken, wo Parameter hin sollen
904 : 0 : *pWMF << (sal_Int32)0 << (sal_Int32)0; // 8 bytes auffuellen (diese 8 bytes +
905 : : // 14 bytes ueberfluessigen FILEHEADER
906 : : // = 22 bytes Parameter)
907 : 0 : *pWMF << rBitmap; // Bitmap schreiben
908 : :
909 : : // Parameter schreiben:
910 : 0 : nPosEnd=pWMF->Tell();
911 : 0 : pWMF->Seek(nPosAnf);
912 : :
913 : : // Raster-Op bestimmen, falls nichts uebergeben wurde
914 [ # # ]: 0 : if( !nROP )
915 : : {
916 [ # # # ]: 0 : switch( eSrcRasterOp )
917 : : {
918 : 0 : case ROP_INVERT: nROP = W_DSTINVERT; break;
919 : 0 : case ROP_XOR: nROP = W_SRCINVERT; break;
920 : 0 : default: nROP = W_SRCCOPY;
921 : : }
922 : : }
923 : :
924 [ # # ]: 0 : *pWMF << nROP <<
925 [ # # ]: 0 : (short) 0 <<
926 [ # # ][ # # ]: 0 : (short) rBitmap.GetSizePixel().Height() <<
927 [ # # ]: 0 : (short) rBitmap.GetSizePixel().Width() <<
928 [ # # ]: 0 : (short) 0 <<
929 [ # # ]: 0 : (short) 0;
930 : :
931 : 0 : WriteHeightWidth(rSize);
932 : 0 : WritePointYX(rPoint);
933 : 0 : pWMF->Seek(nPosEnd);
934 : :
935 : 0 : UpdateRecordHeader();
936 : :
937 : 0 : nWrittenBitmaps++;
938 : 0 : nActBitmapPercent=0;
939 : 0 : }
940 : :
941 : :
942 : 576 : void WMFWriter::WMFRecord_TextOut(const Point & rPoint, const String & rStr)
943 : : {
944 [ + - ]: 576 : rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
945 [ + - ][ + - ]: 576 : rtl::OString aString(rtl::OUStringToOString(rStr, eChrSet));
946 [ + - ]: 576 : TrueTextOut(rPoint, aString);
947 : 576 : }
948 : :
949 : 576 : void WMFWriter::TrueTextOut(const Point & rPoint, const rtl::OString& rString)
950 : : {
951 : 576 : WriteRecordHeader(0,W_META_TEXTOUT);
952 : :
953 : 576 : write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(*pWMF, rString);
954 : 576 : sal_Int32 nLen = rString.getLength();
955 [ + + ]: 576 : if ((nLen&1)!=0) *pWMF << (sal_uInt8)0;
956 : 576 : WritePointYX(rPoint);
957 : 576 : UpdateRecordHeader();
958 : 576 : }
959 : :
960 : 87 : void WMFWriter::WMFRecord_EndOfFile()
961 : : {
962 : 87 : WriteRecordHeader(0x00000003,0x0000);
963 : 87 : }
964 : :
965 : :
966 : 87 : void WMFWriter::WMFRecord_IntersectClipRect( const Rectangle& rRect )
967 : : {
968 : 87 : WriteRecordHeader( 0x00000007, W_META_INTERSECTCLIPRECT );
969 : 87 : WriteRectangle(rRect);
970 : 87 : }
971 : :
972 : :
973 : 2199 : sal_uInt16 WMFWriter::AllocHandle()
974 : : {
975 : : sal_uInt16 i;
976 : :
977 [ + - ]: 5559 : for (i=0; i<MAXOBJECTHANDLES; i++) {
978 [ + + ]: 5559 : if (bHandleAllocated[i]==sal_False) {
979 : 2199 : bHandleAllocated[i]=sal_True;
980 : 2199 : return i;
981 : : }
982 : : }
983 : 0 : bStatus=sal_False;
984 : 2199 : return 0xffff;
985 : : }
986 : :
987 : :
988 : 1938 : void WMFWriter::FreeHandle(sal_uInt16 nObjectHandle)
989 : : {
990 [ + - ]: 1938 : if (nObjectHandle<MAXOBJECTHANDLES) bHandleAllocated[nObjectHandle]=sal_False;
991 : 1938 : }
992 : :
993 : :
994 : 501 : void WMFWriter::CreateSelectDeletePen( const Color& rColor, const LineInfo& rLineInfo )
995 : : {
996 : : sal_uInt16 nOldHandle;
997 : :
998 : 501 : nOldHandle=nDstPenHandle;
999 : 501 : nDstPenHandle=AllocHandle();
1000 : 501 : WMFRecord_CreatePenIndirect( rColor, rLineInfo );
1001 : 501 : WMFRecord_SelectObject(nDstPenHandle);
1002 [ + + ]: 501 : if (nOldHandle<MAXOBJECTHANDLES) {
1003 : 414 : WMFRecord_DeleteObject(nOldHandle);
1004 : 414 : FreeHandle(nOldHandle);
1005 : : }
1006 : 501 : }
1007 : :
1008 : :
1009 : 1197 : void WMFWriter::CreateSelectDeleteFont(const Font & rFont)
1010 : : {
1011 : : sal_uInt16 nOldHandle;
1012 : :
1013 : 1197 : nOldHandle=nDstFontHandle;
1014 : 1197 : nDstFontHandle=AllocHandle();
1015 : 1197 : WMFRecord_CreateFontIndirect(rFont);
1016 : 1197 : WMFRecord_SelectObject(nDstFontHandle);
1017 [ + + ]: 1197 : if (nOldHandle<MAXOBJECTHANDLES) {
1018 : 1110 : WMFRecord_DeleteObject(nOldHandle);
1019 : 1110 : FreeHandle(nOldHandle);
1020 : : }
1021 : 1197 : }
1022 : :
1023 : :
1024 : 501 : void WMFWriter::CreateSelectDeleteBrush(const Color& rColor)
1025 : : {
1026 : : sal_uInt16 nOldHandle;
1027 : :
1028 : 501 : nOldHandle=nDstBrushHandle;
1029 : 501 : nDstBrushHandle=AllocHandle();
1030 : 501 : WMFRecord_CreateBrushIndirect(rColor);
1031 : 501 : WMFRecord_SelectObject(nDstBrushHandle);
1032 [ + + ]: 501 : if (nOldHandle<MAXOBJECTHANDLES) {
1033 : 414 : WMFRecord_DeleteObject(nOldHandle);
1034 : 414 : FreeHandle(nOldHandle);
1035 : : }
1036 : 501 : }
1037 : :
1038 : :
1039 : 2661 : void WMFWriter::SetLineAndFillAttr()
1040 : : {
1041 [ - + ]: 2661 : if ( eDstROP2 != eSrcRasterOp )
1042 : : {
1043 : 0 : eDstROP2=eSrcRasterOp;
1044 : 0 : WMFRecord_SetROP2(eDstROP2);
1045 : : }
1046 [ + + ][ - + ]: 2661 : if ( ( aDstLineColor != aSrcLineColor ) || ( aDstLineInfo != aSrcLineInfo ) )
[ + + ]
1047 : : {
1048 : 414 : aDstLineColor = aSrcLineColor;
1049 : 414 : aDstLineInfo = aSrcLineInfo;
1050 : 414 : CreateSelectDeletePen( aDstLineColor, aDstLineInfo );
1051 : : }
1052 [ + + ]: 2661 : if ( aDstFillColor != aSrcFillColor )
1053 : : {
1054 : 414 : aDstFillColor = aSrcFillColor;
1055 : 414 : CreateSelectDeleteBrush( aDstFillColor );
1056 : : }
1057 [ + - ]: 2661 : if ( bDstIsClipping != bSrcIsClipping ||
[ - + # # ]
[ - + ]
1058 : 0 : (bSrcIsClipping==sal_True && aDstClipRegion!=aSrcClipRegion)) {
1059 : 0 : bDstIsClipping=bSrcIsClipping;
1060 : 0 : aDstClipRegion=aSrcClipRegion;
1061 : : }
1062 : 2661 : }
1063 : :
1064 : 2247 : void WMFWriter::SetAllAttr()
1065 : : {
1066 : 2247 : SetLineAndFillAttr();
1067 [ + + ]: 2247 : if ( aDstTextColor != aSrcTextColor )
1068 : : {
1069 : 993 : aDstTextColor = aSrcTextColor;
1070 : 993 : WMFRecord_SetTextColor(aDstTextColor);
1071 : : }
1072 [ + - ][ - + ]: 2247 : if ( eDstTextAlign != eSrcTextAlign || eDstHorTextAlign != eSrcHorTextAlign )
1073 : : {
1074 : 0 : eDstTextAlign = eSrcTextAlign;
1075 : 0 : eDstHorTextAlign = eSrcHorTextAlign;
1076 : 0 : WMFRecord_SetTextAlign( eDstTextAlign, eDstHorTextAlign );
1077 : : }
1078 [ + + ]: 2247 : if ( aDstFont != aSrcFont )
1079 : : {
1080 : 1110 : pVirDev->SetFont(aSrcFont);
1081 [ + + ]: 1110 : if ( aDstFont.GetName() != aSrcFont.GetName() )
1082 : : {
1083 [ + - ]: 993 : FontCharMap aFontCharMap;
1084 [ + - ][ + - ]: 993 : if ( pVirDev->GetFontCharMap( aFontCharMap ) )
1085 : : {
1086 [ + - ][ - + ]: 993 : if ( ( aFontCharMap.GetFirstChar() & 0xff00 ) == 0xf000 )
1087 [ # # ]: 0 : aSrcFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
1088 [ + - ][ - + ]: 993 : else if ( aSrcFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
1089 [ # # ]: 0 : aSrcFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );
1090 [ + - ]: 993 : }
1091 : : }
1092 : 1110 : aDstFont = aSrcFont;
1093 : 1110 : CreateSelectDeleteFont(aDstFont);
1094 : : }
1095 : 2247 : }
1096 : :
1097 : :
1098 : 0 : void WMFWriter::HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
1099 : : {
1100 [ # # ]: 0 : if(rLinePolygon.count())
1101 : : {
1102 [ # # ]: 0 : basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
1103 [ # # ]: 0 : basegfx::B2DPolyPolygon aFillPolyPolygon;
1104 : :
1105 [ # # ]: 0 : rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
1106 : :
1107 [ # # ][ # # ]: 0 : if(aLinePolyPolygon.count())
1108 : : {
1109 [ # # ]: 0 : aSrcLineInfo = rInfo;
1110 [ # # ]: 0 : SetLineAndFillAttr();
1111 : :
1112 [ # # ][ # # ]: 0 : for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
1113 : : {
1114 [ # # ]: 0 : const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
1115 [ # # ][ # # ]: 0 : WMFRecord_PolyLine(Polygon(aCandidate));
[ # # ]
1116 [ # # ]: 0 : }
1117 : : }
1118 : :
1119 [ # # ][ # # ]: 0 : if(aFillPolyPolygon.count())
1120 : : {
1121 : 0 : const Color aOldLineColor(aSrcLineColor);
1122 : 0 : const Color aOldFillColor(aSrcFillColor);
1123 : :
1124 : 0 : aSrcLineColor = Color( COL_TRANSPARENT );
1125 : 0 : aSrcFillColor = aOldLineColor;
1126 [ # # ]: 0 : SetLineAndFillAttr();
1127 : :
1128 [ # # ][ # # ]: 0 : for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
1129 : : {
1130 [ # # ][ # # ]: 0 : const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
[ # # ]
1131 [ # # ][ # # ]: 0 : WMFRecord_Polygon(Polygon(aPolygon));
[ # # ]
1132 [ # # ]: 0 : }
1133 : :
1134 : 0 : aSrcLineColor = aOldLineColor;
1135 : 0 : aSrcFillColor = aOldFillColor;
1136 [ # # ]: 0 : SetLineAndFillAttr();
1137 [ # # ][ # # ]: 0 : }
1138 : : }
1139 : 0 : }
1140 : :
1141 : 87 : void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
1142 : : {
1143 : : MetaAction* pMA;
1144 : :
1145 [ + - ]: 87 : if( bStatus )
1146 : : {
1147 : 87 : size_t nACount = rMTF.GetActionSize();
1148 : :
1149 : 87 : WMFRecord_SetStretchBltMode();
1150 : :
1151 [ + + ]: 8256 : for( size_t nA = 0; nA < nACount; nA++ )
1152 : : {
1153 : 8169 : pMA = rMTF.GetAction( nA );
1154 : :
1155 [ - - - + : 8169 : switch( pMA->GetType() )
- - - - -
- - - - -
- + - - -
- - - - -
- + + + +
+ + - + +
+ - - - -
+ - - - -
- + ]
1156 : : {
1157 : : case META_PIXEL_ACTION:
1158 : : {
1159 : 0 : const MetaPixelAction* pA = (const MetaPixelAction *) pMA;
1160 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1161 : 0 : SetLineAndFillAttr();
1162 : 0 : WMFRecord_SetPixel( pA->GetPoint(), pA->GetColor() );
1163 : : }
1164 : 0 : break;
1165 : :
1166 : : case META_POINT_ACTION:
1167 : : {
1168 : 0 : const MetaPointAction* pA = (const MetaPointAction*) pMA;
1169 : 0 : const Point& rPt = pA->GetPoint();
1170 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1171 : 0 : SetLineAndFillAttr();
1172 : 0 : WMFRecord_MoveTo( rPt);
1173 : 0 : WMFRecord_LineTo( rPt );
1174 : : }
1175 : 0 : break;
1176 : :
1177 : : case META_LINE_ACTION:
1178 : : {
1179 : 0 : const MetaLineAction* pA = (const MetaLineAction *) pMA;
1180 [ # # ]: 0 : if(pA->GetLineInfo().IsDefault())
1181 : : {
1182 : 0 : aSrcLineInfo = pA->GetLineInfo();
1183 : 0 : SetLineAndFillAttr();
1184 : 0 : WMFRecord_MoveTo( pA->GetStartPoint() );
1185 : 0 : WMFRecord_LineTo( pA->GetEndPoint() );
1186 : : }
1187 : : else
1188 : : {
1189 : : // LineInfo used; handle Dash/Dot and fat lines
1190 [ # # ]: 0 : basegfx::B2DPolygon aPolygon;
1191 [ # # ]: 0 : aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
1192 [ # # ]: 0 : aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
1193 [ # # ][ # # ]: 0 : HandleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
1194 : : }
1195 : : }
1196 : 0 : break;
1197 : :
1198 : : case META_RECT_ACTION:
1199 : : {
1200 : 57 : const MetaRectAction* pA = (const MetaRectAction*) pMA;
1201 [ + - ]: 57 : aSrcLineInfo = LineInfo();
1202 : 57 : SetLineAndFillAttr();
1203 : 57 : WMFRecord_Rectangle( pA->GetRect() );
1204 : : }
1205 : 57 : break;
1206 : :
1207 : : case META_ROUNDRECT_ACTION:
1208 : : {
1209 : 0 : const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pMA;
1210 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1211 : 0 : SetLineAndFillAttr();
1212 : 0 : WMFRecord_RoundRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
1213 : : }
1214 : 0 : break;
1215 : :
1216 : : case META_ELLIPSE_ACTION:
1217 : : {
1218 : 0 : const MetaEllipseAction* pA = (const MetaEllipseAction*) pMA;
1219 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1220 : 0 : SetLineAndFillAttr();
1221 : 0 : WMFRecord_Ellipse( pA->GetRect() );
1222 : : }
1223 : 0 : break;
1224 : :
1225 : : case META_ARC_ACTION:
1226 : : {
1227 : 0 : const MetaArcAction* pA = (const MetaArcAction*) pMA;
1228 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1229 : 0 : SetLineAndFillAttr();
1230 : 0 : WMFRecord_Arc( pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint() );
1231 : : }
1232 : 0 : break;
1233 : :
1234 : : case META_PIE_ACTION:
1235 : : {
1236 : 0 : const MetaPieAction* pA = (const MetaPieAction*) pMA;
1237 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1238 : 0 : SetLineAndFillAttr();
1239 : 0 : WMFRecord_Pie( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
1240 : : }
1241 : 0 : break;
1242 : :
1243 : :
1244 : : case META_CHORD_ACTION:
1245 : : {
1246 : 0 : const MetaChordAction* pA = (const MetaChordAction*) pMA;
1247 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1248 : 0 : SetLineAndFillAttr();
1249 : 0 : WMFRecord_Chord( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
1250 : : }
1251 : 0 : break;
1252 : :
1253 : : case META_POLYLINE_ACTION:
1254 : : {
1255 : 0 : const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pMA;
1256 : 0 : const Polygon& rPoly = pA->GetPolygon();
1257 : :
1258 [ # # ]: 0 : if( rPoly.GetSize() )
1259 : : {
1260 [ # # ]: 0 : if(pA->GetLineInfo().IsDefault())
1261 : : {
1262 : 0 : aSrcLineInfo = pA->GetLineInfo();
1263 : 0 : SetLineAndFillAttr();
1264 : 0 : WMFRecord_PolyLine( rPoly );
1265 : : }
1266 : : else
1267 : : {
1268 : : // LineInfo used; handle Dash/Dot and fat lines
1269 [ # # ]: 0 : HandleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
1270 : : }
1271 : : }
1272 : : }
1273 : 0 : break;
1274 : :
1275 : : case META_POLYGON_ACTION:
1276 : : {
1277 : 0 : const MetaPolygonAction* pA = (const MetaPolygonAction*) pMA;
1278 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1279 : 0 : SetLineAndFillAttr();
1280 : 0 : WMFRecord_Polygon( pA->GetPolygon() );
1281 : : }
1282 : 0 : break;
1283 : :
1284 : : case META_POLYPOLYGON_ACTION:
1285 : : {
1286 : 0 : const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pMA;
1287 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1288 : 0 : SetLineAndFillAttr();
1289 : 0 : WMFRecord_PolyPolygon( pA->GetPolyPolygon() );
1290 : : }
1291 : 0 : break;
1292 : :
1293 : : case META_TEXTRECT_ACTION:
1294 : : {
1295 : 0 : const MetaTextRectAction * pA = (const MetaTextRectAction*)pMA;
1296 [ # # ]: 0 : String aTemp( pA->GetText() );
1297 [ # # ][ # # ]: 0 : aSrcLineInfo = LineInfo();
[ # # ]
1298 [ # # ]: 0 : SetAllAttr();
1299 : :
1300 : 0 : Point aPos( pA->GetRect().TopLeft() );
1301 [ # # ][ # # ]: 0 : if ( !WMFRecord_Escape_Unicode( aPos, aTemp, NULL ) )
1302 [ # # ][ # # ]: 0 : WMFRecord_TextOut( aPos, aTemp );
1303 : : }
1304 : 0 : break;
1305 : :
1306 : : case META_TEXT_ACTION:
1307 : : {
1308 : 0 : const MetaTextAction * pA = (const MetaTextAction*) pMA;
1309 [ # # ][ # # ]: 0 : String aTemp( pA->GetText(), pA->GetIndex(), pA->GetLen() );
[ # # ]
1310 [ # # ][ # # ]: 0 : aSrcLineInfo = LineInfo();
[ # # ]
1311 [ # # ]: 0 : SetAllAttr();
1312 [ # # ][ # # ]: 0 : if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, NULL ) )
1313 [ # # ][ # # ]: 0 : WMFRecord_TextOut( pA->GetPoint(), aTemp );
1314 : : }
1315 : 0 : break;
1316 : :
1317 : : case META_TEXTARRAY_ACTION:
1318 : : {
1319 : 0 : const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pMA;
1320 : :
1321 [ # # ][ # # ]: 0 : String aTemp( pA->GetText(), pA->GetIndex(), pA->GetLen() );
[ # # ]
1322 [ # # ][ # # ]: 0 : aSrcLineInfo = LineInfo();
[ # # ]
1323 [ # # ]: 0 : SetAllAttr();
1324 [ # # ][ # # ]: 0 : if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, pA->GetDXArray() ) )
1325 [ # # ][ # # ]: 0 : WMFRecord_ExtTextOut( pA->GetPoint(), aTemp, pA->GetDXArray() );
1326 : : }
1327 : 0 : break;
1328 : :
1329 : : case META_STRETCHTEXT_ACTION:
1330 : : {
1331 : 993 : const MetaStretchTextAction* pA = (const MetaStretchTextAction *) pMA;
1332 [ + - ][ + - ]: 993 : String aTemp( pA->GetText(), pA->GetIndex(), pA->GetLen() );
[ + - ]
1333 : :
1334 : : sal_uInt16 nLen,i;
1335 : : sal_Int32 nNormSize;
1336 : :
1337 [ + - ]: 993 : pVirDev->SetFont( aSrcFont );
1338 : 993 : nLen = aTemp.Len();
1339 [ + - ][ + - ]: 993 : sal_Int32* pDXAry = nLen ? new sal_Int32[ nLen ] : NULL;
1340 [ + - ]: 993 : nNormSize = pVirDev->GetTextArray( aTemp, pDXAry );
1341 [ + + ]: 1122 : for ( i = 0; i < ( nLen - 1 ); i++ )
1342 : 129 : pDXAry[ i ] = pDXAry[ i ] * (sal_Int32)pA->GetWidth() / nNormSize;
1343 [ + + ][ + + ]: 993 : if ( ( nLen <= 1 ) || ( (sal_Int32)pA->GetWidth() == nNormSize ) )
[ + + ]
1344 [ + - ]: 933 : delete[] pDXAry, pDXAry = NULL;
1345 [ + - ][ + - ]: 993 : aSrcLineInfo = LineInfo();
[ + - ]
1346 [ + - ]: 993 : SetAllAttr();
1347 [ + - ][ + + ]: 993 : if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, pDXAry ) )
1348 [ + - ]: 636 : WMFRecord_ExtTextOut( pA->GetPoint(), aTemp, pDXAry );
1349 [ + + ][ + - ]: 993 : delete[] pDXAry;
1350 : : }
1351 : 993 : break;
1352 : :
1353 : : case META_BMP_ACTION:
1354 : : {
1355 : 0 : const MetaBmpAction* pA = (const MetaBmpAction *) pMA;
1356 [ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), pA->GetBitmap().GetSizePixel(), pA->GetBitmap() );
1357 : : }
1358 : 0 : break;
1359 : :
1360 : : case META_BMPSCALE_ACTION:
1361 : : {
1362 : 0 : const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pMA;
1363 : 0 : WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pA->GetBitmap() );
1364 : : }
1365 : 0 : break;
1366 : :
1367 : : case META_BMPSCALEPART_ACTION:
1368 : : {
1369 : 0 : const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pMA;
1370 [ # # ]: 0 : Bitmap aTmp( pA->GetBitmap() );
1371 : :
1372 [ # # ][ # # ]: 0 : if( aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
[ # # ]
1373 [ # # ][ # # ]: 0 : WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aTmp );
1374 : : }
1375 : 0 : break;
1376 : :
1377 : : case META_BMPEX_ACTION:
1378 : : {
1379 : 0 : const MetaBmpExAction* pA = (const MetaBmpExAction *) pMA;
1380 [ # # ]: 0 : Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
1381 [ # # ]: 0 : Bitmap aMsk( pA->GetBitmapEx().GetMask() );
1382 : :
1383 [ # # ]: 0 : if( !!aMsk )
1384 : : {
1385 [ # # ]: 0 : aBmp.Replace( aMsk, COL_WHITE );
1386 [ # # ]: 0 : aMsk.Invert();
1387 [ # # ][ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), aMsk.GetSizePixel(), aBmp, W_SRCPAINT );
1388 [ # # ][ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp, W_SRCAND );
1389 : : }
1390 : : else
1391 [ # # ][ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp );
[ # # ][ # # ]
1392 : : }
1393 : 0 : break;
1394 : :
1395 : : case META_BMPEXSCALE_ACTION:
1396 : : {
1397 : 0 : const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pMA;
1398 [ # # ]: 0 : Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
1399 [ # # ]: 0 : Bitmap aMsk( pA->GetBitmapEx().GetMask() );
1400 : :
1401 [ # # ]: 0 : if( !!aMsk )
1402 : : {
1403 [ # # ]: 0 : aBmp.Replace( aMsk, COL_WHITE );
1404 [ # # ]: 0 : aMsk.Invert();
1405 [ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aMsk, W_SRCPAINT );
1406 [ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp, W_SRCAND );
1407 : : }
1408 : : else
1409 [ # # ][ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp );
[ # # ]
1410 : : }
1411 : 0 : break;
1412 : :
1413 : : case META_BMPEXSCALEPART_ACTION:
1414 : : {
1415 : 0 : const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pMA;
1416 [ # # ]: 0 : BitmapEx aBmpEx( pA->GetBitmapEx() );
1417 [ # # ][ # # ]: 0 : aBmpEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
1418 [ # # ]: 0 : Bitmap aBmp( aBmpEx.GetBitmap() );
1419 [ # # ]: 0 : Bitmap aMsk( aBmpEx.GetMask() );
1420 : :
1421 [ # # ]: 0 : if( !!aMsk )
1422 : : {
1423 [ # # ]: 0 : aBmp.Replace( aMsk, COL_WHITE );
1424 [ # # ]: 0 : aMsk.Invert();
1425 [ # # ]: 0 : WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aMsk, W_SRCPAINT );
1426 [ # # ]: 0 : WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp, W_SRCAND );
1427 : : }
1428 : : else
1429 [ # # ][ # # ]: 0 : WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp );
[ # # ][ # # ]
1430 : : }
1431 : 0 : break;
1432 : :
1433 : : case META_GRADIENT_ACTION:
1434 : : {
1435 : 0 : const MetaGradientAction* pA = (const MetaGradientAction*) pMA;
1436 [ # # ]: 0 : GDIMetaFile aTmpMtf;
1437 : :
1438 [ # # ]: 0 : pVirDev->AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
1439 [ # # ][ # # ]: 0 : WriteRecords( aTmpMtf );
1440 : : }
1441 : 0 : break;
1442 : :
1443 : : case META_HATCH_ACTION:
1444 : : {
1445 : 0 : const MetaHatchAction* pA = (const MetaHatchAction*) pMA;
1446 [ # # ]: 0 : GDIMetaFile aTmpMtf;
1447 : :
1448 [ # # ]: 0 : pVirDev->AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
1449 [ # # ][ # # ]: 0 : WriteRecords( aTmpMtf );
1450 : : }
1451 : 0 : break;
1452 : :
1453 : : case META_WALLPAPER_ACTION:
1454 : : {
1455 : 0 : const MetaWallpaperAction* pA = (const MetaWallpaperAction*) pMA;
1456 [ # # ]: 0 : const Color& rColor = pA->GetWallpaper().GetColor();
1457 : 0 : const Color aOldLineColor( aSrcLineColor );
1458 : 0 : const Color aOldFillColor( aSrcFillColor );
1459 : :
1460 : 0 : aSrcLineColor = rColor;
1461 : 0 : aSrcFillColor = rColor;
1462 [ # # ][ # # ]: 0 : aSrcLineInfo = LineInfo();
[ # # ]
1463 [ # # ]: 0 : SetLineAndFillAttr();
1464 [ # # ]: 0 : WMFRecord_Rectangle( pA->GetRect() );
1465 : 0 : aSrcLineColor = aOldLineColor;
1466 : 0 : aSrcFillColor = aOldFillColor;
1467 : : }
1468 : 0 : break;
1469 : :
1470 : : case META_ISECTRECTCLIPREGION_ACTION:
1471 : : {
1472 : 87 : const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
1473 : 87 : WMFRecord_IntersectClipRect( pA->GetRect() );
1474 : : }
1475 : 87 : break;
1476 : :
1477 : : case META_LINECOLOR_ACTION:
1478 : : {
1479 : 57 : const MetaLineColorAction* pA = (const MetaLineColorAction*) pMA;
1480 : :
1481 [ - + ]: 57 : if( pA->IsSetting() )
1482 : 0 : aSrcLineColor = pA->GetColor();
1483 : : else
1484 : 57 : aSrcLineColor = Color( COL_TRANSPARENT );
1485 : : }
1486 : 57 : break;
1487 : :
1488 : : case META_FILLCOLOR_ACTION:
1489 : : {
1490 : 57 : const MetaFillColorAction* pA = (const MetaFillColorAction*) pMA;
1491 : :
1492 [ + - ]: 57 : if( pA->IsSetting() )
1493 : 57 : aSrcFillColor = pA->GetColor();
1494 : : else
1495 : 0 : aSrcFillColor = Color( COL_TRANSPARENT );
1496 : : }
1497 : 57 : break;
1498 : :
1499 : : case META_TEXTCOLOR_ACTION:
1500 : : {
1501 : 1059 : const MetaTextColorAction* pA = (const MetaTextColorAction*) pMA;
1502 : 1059 : aSrcTextColor = pA->GetColor();
1503 : : }
1504 : 1059 : break;
1505 : :
1506 : : case META_TEXTFILLCOLOR_ACTION:
1507 : : {
1508 : 1050 : const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pMA;
1509 [ - + ]: 1050 : if( pA->IsSetting() )
1510 : 0 : aSrcFont.SetFillColor( pA->GetColor() );
1511 : : else
1512 [ + - ]: 1050 : aSrcFont.SetFillColor( Color( COL_TRANSPARENT ) );
1513 : : }
1514 : 1050 : break;
1515 : :
1516 : : case META_TEXTALIGN_ACTION:
1517 : : {
1518 : 1050 : const MetaTextAlignAction* pA = (const MetaTextAlignAction*) pMA;
1519 : 1050 : eSrcTextAlign = pA->GetTextAlign();
1520 : : }
1521 : 1050 : break;
1522 : :
1523 : : case META_MAPMODE_ACTION:
1524 : : {
1525 : 0 : const MetaMapModeAction* pA = (const MetaMapModeAction*) pMA;
1526 : :
1527 [ # # ]: 0 : if (aSrcMapMode!=pA->GetMapMode())
1528 : : {
1529 [ # # ]: 0 : if( pA->GetMapMode().GetMapUnit() == MAP_RELATIVE )
1530 : : {
1531 [ # # ]: 0 : MapMode aMM = pA->GetMapMode();
1532 [ # # ]: 0 : Fraction aScaleX = aMM.GetScaleX();
1533 [ # # ]: 0 : Fraction aScaleY = aMM.GetScaleY();
1534 : :
1535 : 0 : Point aOrigin = aSrcMapMode.GetOrigin();
1536 [ # # ]: 0 : BigInt aX( aOrigin.X() );
1537 [ # # ][ # # ]: 0 : aX *= BigInt( aScaleX.GetDenominator() );
1538 [ # # ]: 0 : if( aOrigin.X() >= 0 )
1539 [ # # ]: 0 : if( aScaleX.GetNumerator() >= 0 )
1540 [ # # ][ # # ]: 0 : aX += BigInt( aScaleX.GetNumerator()/2 );
1541 : : else
1542 [ # # ][ # # ]: 0 : aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
1543 : : else
1544 [ # # ]: 0 : if( aScaleX.GetNumerator() >= 0 )
1545 [ # # ][ # # ]: 0 : aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
1546 : : else
1547 [ # # ][ # # ]: 0 : aX += BigInt( aScaleX.GetNumerator()/2 );
1548 [ # # ][ # # ]: 0 : aX /= BigInt( aScaleX.GetNumerator() );
1549 [ # # ]: 0 : aOrigin.X() = (long)aX + aMM.GetOrigin().X();
1550 [ # # ]: 0 : BigInt aY( aOrigin.Y() );
1551 [ # # ][ # # ]: 0 : aY *= BigInt( aScaleY.GetDenominator() );
1552 [ # # ]: 0 : if( aOrigin.Y() >= 0 )
1553 [ # # ]: 0 : if( aScaleY.GetNumerator() >= 0 )
1554 [ # # ][ # # ]: 0 : aY += BigInt( aScaleY.GetNumerator()/2 );
1555 : : else
1556 [ # # ][ # # ]: 0 : aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
1557 : : else
1558 [ # # ]: 0 : if( aScaleY.GetNumerator() >= 0 )
1559 [ # # ][ # # ]: 0 : aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
1560 : : else
1561 [ # # ][ # # ]: 0 : aY += BigInt( aScaleY.GetNumerator()/2 );
1562 [ # # ][ # # ]: 0 : aY /= BigInt( aScaleY.GetNumerator() );
1563 [ # # ]: 0 : aOrigin.Y() = (long)aY + aMM.GetOrigin().Y();
1564 [ # # ]: 0 : aSrcMapMode.SetOrigin( aOrigin );
1565 : :
1566 [ # # ]: 0 : aScaleX *= aSrcMapMode.GetScaleX();
1567 [ # # ]: 0 : aScaleY *= aSrcMapMode.GetScaleY();
1568 [ # # ]: 0 : aSrcMapMode.SetScaleX( aScaleX );
1569 [ # # ][ # # ]: 0 : aSrcMapMode.SetScaleY( aScaleY );
1570 : : }
1571 : : else
1572 : 0 : aSrcMapMode=pA->GetMapMode();
1573 : : }
1574 : : }
1575 : 0 : break;
1576 : :
1577 : : case META_FONT_ACTION:
1578 : : {
1579 : 1050 : const MetaFontAction* pA = (const MetaFontAction*) pMA;
1580 : 1050 : aSrcFont = pA->GetFont();
1581 : :
1582 [ + - ]: 1461 : if ( (aSrcFont.GetCharSet() == RTL_TEXTENCODING_DONTKNOW)
[ + + + - ]
1583 : 411 : || (aSrcFont.GetCharSet() == RTL_TEXTENCODING_UNICODE) )
1584 : : {
1585 : 1050 : aSrcFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );
1586 : : }
1587 : 1050 : eSrcTextAlign = aSrcFont.GetAlign();
1588 : 1050 : aSrcTextColor = aSrcFont.GetColor();
1589 : 1050 : aSrcFont.SetAlign( ALIGN_BASELINE );
1590 [ + - ]: 1050 : aSrcFont.SetColor( COL_WHITE );
1591 : : }
1592 : 1050 : break;
1593 : :
1594 : : case META_PUSH_ACTION:
1595 : : {
1596 : 1137 : const MetaPushAction* pA = (const MetaPushAction*)pMA;
1597 : :
1598 [ + - ]: 1137 : WMFWriterAttrStackMember* pAt = new WMFWriterAttrStackMember;
1599 : 1137 : pAt->nFlags = pA->GetFlags();
1600 : 1137 : pAt->aClipRegion = aSrcClipRegion;
1601 : 1137 : pAt->aLineColor=aSrcLineColor;
1602 : 1137 : pAt->aFillColor=aSrcFillColor;
1603 : 1137 : pAt->eRasterOp=eSrcRasterOp;
1604 : 1137 : pAt->aFont=aSrcFont;
1605 : 1137 : pAt->eTextAlign=eSrcTextAlign;
1606 : 1137 : pAt->aTextColor=aSrcTextColor;
1607 : 1137 : pAt->aMapMode=aSrcMapMode;
1608 : 1137 : pAt->aLineInfo=aDstLineInfo;
1609 : 1137 : pAt->pSucc=pAttrStack;
1610 : 1137 : pAttrStack=pAt;
1611 : :
1612 : 1137 : SetAllAttr(); // update ( now all source attributes are equal to the destination attributes )
1613 : 1137 : WMFRecord_SaveDC();
1614 : :
1615 : : }
1616 : 1137 : break;
1617 : :
1618 : : case META_POP_ACTION:
1619 : : {
1620 : 1137 : WMFWriterAttrStackMember * pAt=pAttrStack;
1621 : :
1622 [ + - ]: 1137 : if( pAt )
1623 : : {
1624 : 1137 : aDstLineInfo = pAt->aLineInfo;
1625 : 1137 : aDstLineColor = pAt->aLineColor;
1626 [ + - ]: 1137 : if ( pAt->nFlags & PUSH_LINECOLOR )
1627 : 1137 : aSrcLineColor = pAt->aLineColor;
1628 : 1137 : aDstFillColor = pAt->aFillColor;
1629 [ + - ]: 1137 : if ( pAt->nFlags & PUSH_FILLCOLOR )
1630 : 1137 : aSrcFillColor = pAt->aFillColor;
1631 : 1137 : eDstROP2 = pAt->eRasterOp;
1632 [ + + ]: 1137 : if ( pAt->nFlags & PUSH_RASTEROP )
1633 : 87 : eSrcRasterOp = pAt->eRasterOp;
1634 : 1137 : aDstFont = pAt->aFont;
1635 [ + - ]: 1137 : if ( pAt->nFlags & PUSH_FONT )
1636 : 1137 : aSrcFont = pAt->aFont;
1637 : 1137 : eDstTextAlign = pAt->eTextAlign;
1638 [ + - ]: 1137 : if ( pAt->nFlags & ( PUSH_FONT | PUSH_TEXTALIGN ) )
1639 : 1137 : eSrcTextAlign = pAt->eTextAlign;
1640 : 1137 : aDstTextColor = pAt->aTextColor;
1641 [ + - ]: 1137 : if ( pAt->nFlags & ( PUSH_FONT | PUSH_TEXTCOLOR ) )
1642 : 1137 : aSrcTextColor = pAt->aTextColor;
1643 [ + - ]: 1137 : if ( pAt->nFlags & PUSH_MAPMODE )
1644 : 1137 : aSrcMapMode = pAt->aMapMode;
1645 : 1137 : aDstClipRegion = pAt->aClipRegion;
1646 [ + + ]: 1137 : if ( pAt->nFlags & PUSH_CLIPREGION )
1647 : 87 : aSrcClipRegion = pAt->aClipRegion;
1648 : :
1649 : 1137 : WMFRecord_RestoreDC();
1650 : 1137 : pAttrStack = pAt->pSucc;
1651 [ + - ]: 1137 : delete pAt;
1652 : : }
1653 : : }
1654 : 1137 : break;
1655 : :
1656 : : case META_EPS_ACTION :
1657 : : {
1658 : 0 : const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
1659 [ # # ]: 0 : const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
1660 : :
1661 [ # # ]: 0 : size_t nCount = aGDIMetaFile.GetActionSize();
1662 [ # # ]: 0 : for ( size_t i = 0; i < nCount; i++ )
1663 : : {
1664 [ # # ]: 0 : const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
1665 [ # # ]: 0 : if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
1666 : : {
1667 : 0 : const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
1668 [ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap() );
1669 : 0 : break;
1670 : : }
1671 [ # # ]: 0 : }
1672 : : }
1673 : 0 : break;
1674 : :
1675 : : case META_RASTEROP_ACTION:
1676 : : {
1677 : 0 : const MetaRasterOpAction* pA = (const MetaRasterOpAction*) pMA;
1678 : 0 : eSrcRasterOp=pA->GetRasterOp();
1679 : : }
1680 : 0 : break;
1681 : :
1682 : : case META_TRANSPARENT_ACTION:
1683 : : {
1684 [ # # ]: 0 : aSrcLineInfo = LineInfo();
1685 : 0 : SetLineAndFillAttr();
1686 : 0 : WMFRecord_PolyPolygon( ( (MetaTransparentAction*) pMA )->GetPolyPolygon() );
1687 : : }
1688 : 0 : break;
1689 : :
1690 : : case META_FLOATTRANSPARENT_ACTION:
1691 : : {
1692 : 0 : const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pMA;
1693 : :
1694 [ # # ]: 0 : GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
1695 : 0 : Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
1696 : 0 : const Size aSrcSize( aTmpMtf.GetPrefSize() );
1697 : 0 : const Point aDestPt( pA->GetPoint() );
1698 : 0 : const Size aDestSize( pA->GetSize() );
1699 [ # # ]: 0 : const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
1700 [ # # ]: 0 : const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
1701 : : long nMoveX, nMoveY;
1702 : :
1703 [ # # ][ # # ]: 0 : aSrcLineInfo = LineInfo();
[ # # ]
1704 [ # # ]: 0 : SetAllAttr();
1705 : :
1706 [ # # ][ # # ]: 0 : if( fScaleX != 1.0 || fScaleY != 1.0 )
1707 : : {
1708 [ # # ]: 0 : aTmpMtf.Scale( fScaleX, fScaleY );
1709 : 0 : aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
1710 : : }
1711 : :
1712 : 0 : nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
1713 : :
1714 [ # # ][ # # ]: 0 : if( nMoveX || nMoveY )
1715 [ # # ]: 0 : aTmpMtf.Move( nMoveX, nMoveY );
1716 : :
1717 [ # # ][ # # ]: 0 : WriteRecords( aTmpMtf );
1718 : : }
1719 : 0 : break;
1720 : :
1721 : : case( META_LAYOUTMODE_ACTION ):
1722 : : {
1723 : 174 : sal_uInt32 nLayoutMode = ( (MetaLayoutModeAction*) pMA )->GetLayoutMode();
1724 : 174 : eSrcHorTextAlign = 0; // TA_LEFT
1725 [ - + ]: 174 : if (nLayoutMode & TEXT_LAYOUT_BIDI_RTL)
1726 : : {
1727 : 0 : eSrcHorTextAlign = W_TA_RIGHT | W_TA_RTLREADING;
1728 : : }
1729 [ - + ]: 174 : if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_RIGHT)
1730 : 0 : eSrcHorTextAlign |= W_TA_RIGHT;
1731 [ - + ]: 174 : else if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_LEFT)
1732 : 0 : eSrcHorTextAlign &= ~W_TA_RIGHT;
1733 : 174 : break;
1734 : : }
1735 : :
1736 : : // Unsupported Actions
1737 : : case META_MASK_ACTION:
1738 : : case META_MASKSCALE_ACTION:
1739 : : case META_MASKSCALEPART_ACTION:
1740 : : {
1741 : : OSL_FAIL( "Unsupported action: MetaMask...Action!" );
1742 : : }
1743 : 0 : break;
1744 : :
1745 : : case META_CLIPREGION_ACTION:
1746 : 0 : break;
1747 : :
1748 : : case META_ISECTREGIONCLIPREGION_ACTION:
1749 : : {
1750 : : OSL_FAIL( "Unsupported action: MetaISectRegionClipRegionAction!" );
1751 : : }
1752 : 0 : break;
1753 : :
1754 : : case META_MOVECLIPREGION_ACTION:
1755 : : {
1756 : : OSL_FAIL( "Unsupported action: MetaMoveClipRegionAction!" );
1757 : : }
1758 : 0 : break;
1759 : :
1760 : : case( META_RENDERGRAPHIC_ACTION ):
1761 : : {
1762 : 0 : const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pMA;
1763 [ # # ]: 0 : const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
1764 [ # # ][ # # ]: 0 : const BitmapEx aBmpEx( aRasterizer.Rasterize( pVirDev->LogicToPixel( pA->GetSize(), aSrcMapMode ) ) );
[ # # ]
1765 [ # # ]: 0 : Bitmap aBmp( aBmpEx.GetBitmap() );
1766 [ # # ]: 0 : Bitmap aMsk( aBmpEx.GetMask() );
1767 : :
1768 [ # # ]: 0 : if( !!aMsk )
1769 : : {
1770 [ # # ]: 0 : aBmp.Replace( aMsk, COL_WHITE );
1771 [ # # ]: 0 : aMsk.Invert();
1772 [ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aMsk, W_SRCPAINT );
1773 [ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp, W_SRCAND );
1774 : : }
1775 : : else
1776 [ # # ][ # # ]: 0 : WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp );
[ # # ][ # # ]
[ # # ]
1777 : : }
1778 : 0 : break;
1779 : :
1780 : : default:
1781 : : {
1782 : : OSL_FAIL( "Unsupported meta action!" );
1783 : : }
1784 : 261 : break;
1785 : : }
1786 : :
1787 : 8169 : nWrittenActions++;
1788 : 8169 : MayCallback();
1789 : :
1790 [ - + ]: 8169 : if (pWMF->GetError())
1791 : 0 : bStatus=sal_False;
1792 : :
1793 [ - + ]: 8169 : if(bStatus==sal_False)
1794 : 0 : break;
1795 : : }
1796 : : }
1797 : 87 : }
1798 : :
1799 : : // ------------------------------------------------------------------------
1800 : :
1801 : 87 : void WMFWriter::WriteHeader( const GDIMetaFile &, sal_Bool bPlaceable )
1802 : : {
1803 [ + - ]: 87 : if( bPlaceable )
1804 : : {
1805 : : sal_uInt16 nCheckSum, nValue;
1806 [ + - ][ + - ]: 87 : Size aSize( pVirDev->LogicToLogic(Size(1,1),MapMode(MAP_INCH), aTargetMapMode) );
[ + - ]
1807 : 87 : sal_uInt16 nUnitsPerInch = (sal_uInt16) ( ( aSize.Width() + aSize.Height() ) >> 1 );
1808 : :
1809 : 87 : nCheckSum=0;
1810 [ + - ]: 87 : nValue=0xcdd7; nCheckSum^=nValue; *pWMF << nValue;
1811 [ + - ]: 87 : nValue=0x9ac6; nCheckSum^=nValue; *pWMF << nValue;
1812 [ + - ]: 87 : nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
1813 [ + - ]: 87 : nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
1814 [ + - ]: 87 : nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
1815 [ + - ]: 87 : nValue=(sal_uInt16) aTargetSize.Width(); nCheckSum^=nValue; *pWMF << nValue;
1816 [ + - ]: 87 : nValue=(sal_uInt16) aTargetSize.Height(); nCheckSum^=nValue; *pWMF << nValue;
1817 [ + - ]: 87 : nValue=nUnitsPerInch; nCheckSum^=nValue; *pWMF << nValue;
1818 [ + - ]: 87 : nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
1819 [ + - ]: 87 : nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
1820 [ + - ]: 87 : *pWMF << nCheckSum;
1821 : : }
1822 : :
1823 : 87 : nMetafileHeaderPos=pWMF->Tell();
1824 : 87 : *pWMF << (sal_uInt16)0x0001 // Typ: Datei
1825 : 87 : << (sal_uInt16)0x0009 // Headerlaenge in Worten
1826 : 87 : << (sal_uInt16)0x0300 // Version als BCD-Zahl
1827 : 87 : << (sal_uInt32) 0x00000000 // Dateilaenge (ohne 1. Header), wird spaeter durch UpdateHeader() berichtigt
1828 : 87 : << (sal_uInt16)MAXOBJECTHANDLES // Maximalezahl der gleichzeitigen Objekte
1829 : 87 : << (sal_uInt32) 0x00000000 // Maximale Record-laenge, wird spaeter durch UpdateHeader() berichtigt
1830 : 87 : << (sal_uInt16)0x0000; // Reserved
1831 : 87 : }
1832 : :
1833 : : // ------------------------------------------------------------------------
1834 : :
1835 : 87 : void WMFWriter::UpdateHeader()
1836 : : {
1837 : : sal_uLong nPos;
1838 : : sal_uInt32 nFileSize;
1839 : :
1840 : 87 : nPos=pWMF->Tell(); // Endposition = Gesammtgroesse der Datei
1841 : 87 : nFileSize=nPos-nMetafileHeaderPos; // Groesse des 1. Headers abziehen
1842 [ - + ]: 87 : if ((nFileSize&1)!=0) { // ggf. auf ganze Worte aufrunden
1843 : 0 : *pWMF << (sal_uInt8)0;
1844 : 0 : nPos++;
1845 : 0 : nFileSize++;
1846 : : }
1847 : 87 : nFileSize>>=1; // In Anzahl Worte umrechnen
1848 : 87 : pWMF->Seek(nMetafileHeaderPos+6); // Zum Dateigroessen-Eintrag im zweiten Header
1849 : 87 : *pWMF << nFileSize; // Dateigroesse berichtigen
1850 : 87 : pWMF->SeekRel(2); // Zum Max-Record-Laenge-Eintrag im zweiten Header
1851 : 87 : *pWMF << nMaxRecordSize; // und berichtigen
1852 : 87 : pWMF->Seek(nPos);
1853 : 87 : }
1854 : :
1855 : : // ------------------------------------------------------------------------
1856 : :
1857 : 87 : sal_Bool WMFWriter::WriteWMF( const GDIMetaFile& rMTF, SvStream& rTargetStream,
1858 : : FilterConfigItem* pFConfigItem, sal_Bool bPlaceable )
1859 : : {
1860 : : WMFWriterAttrStackMember * pAt;
1861 : :
1862 : 87 : bEmbedEMF = sal_True;
1863 : 87 : bStatus=sal_True;
1864 : 87 : pConvert = 0;
1865 [ + - ][ + - ]: 87 : pVirDev = new VirtualDevice;
1866 : :
1867 : 87 : pFilterConfigItem = pFConfigItem;
1868 [ + - ]: 87 : if ( pFilterConfigItem )
1869 : : {
1870 [ + - ][ + - ]: 87 : xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
1871 [ - + ]: 87 : if ( xStatusIndicator.is() )
1872 : : {
1873 : 0 : rtl::OUString aMsg;
1874 [ # # ][ # # ]: 0 : xStatusIndicator->start( aMsg, 100 );
1875 : : }
1876 : : }
1877 : 87 : nLastPercent=0;
1878 : :
1879 : 87 : pWMF=&rTargetStream;
1880 [ + - ]: 87 : pWMF->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
1881 : :
1882 : 87 : nMaxRecordSize=0;
1883 : :
1884 [ + - ]: 87 : aSrcMapMode=rMTF.GetPrefMapMode();
1885 : :
1886 [ + - ]: 87 : if( bPlaceable )
1887 : : {
1888 [ + - ]: 87 : aTargetMapMode = aSrcMapMode;
1889 : 87 : aTargetSize = rMTF.GetPrefSize();
1890 [ + - ]: 87 : nTargetDivisor = CalcSaveTargetMapMode(aTargetMapMode, aTargetSize);
1891 : 87 : aTargetSize.Width() /= nTargetDivisor;
1892 : 87 : aTargetSize.Height() /= nTargetDivisor;
1893 : : }
1894 : : else
1895 : : {
1896 [ # # ][ # # ]: 0 : aTargetMapMode = MapMode( MAP_INCH );
[ # # ]
1897 : :
1898 [ # # ]: 0 : const long nUnit = pVirDev->LogicToPixel( Size( 1, 1 ), aTargetMapMode ).Width();
1899 [ # # ]: 0 : const Fraction aFrac( 1, nUnit );
1900 : :
1901 [ # # ]: 0 : aTargetMapMode.SetScaleX( aFrac );
1902 [ # # ]: 0 : aTargetMapMode.SetScaleY( aFrac );
1903 [ # # ]: 0 : aTargetSize = pVirDev->LogicToLogic( rMTF.GetPrefSize(), aSrcMapMode, aTargetMapMode );
1904 : : }
1905 : :
1906 [ + - ]: 87 : pVirDev->SetMapMode( aTargetMapMode );
1907 : :
1908 : 87 : pAttrStack=NULL;
1909 : :
1910 [ + + ]: 1479 : for (sal_uInt16 i=0; i<MAXOBJECTHANDLES; i++)
1911 : 1392 : bHandleAllocated[i]=sal_False;
1912 : :
1913 : 87 : nDstPenHandle=0xffff;
1914 : 87 : nDstFontHandle=0xffff;
1915 : 87 : nDstBrushHandle=0xffff;
1916 : :
1917 : 87 : nNumberOfActions=0;
1918 : 87 : nNumberOfBitmaps=0;
1919 : 87 : nWrittenActions=0;
1920 : 87 : nWrittenBitmaps=0;
1921 : 87 : nActBitmapPercent=0;
1922 : :
1923 [ + - ]: 87 : CountActionsAndBitmaps(rMTF);
1924 : :
1925 [ + - ]: 87 : WriteHeader(rMTF,bPlaceable);
1926 [ + - ]: 87 : if( bEmbedEMF )
1927 [ + - ]: 87 : WriteEmbeddedEMF( rMTF );
1928 [ + - ]: 87 : WMFRecord_SetWindowOrg(Point(0,0));
1929 [ + - ]: 87 : WMFRecord_SetWindowExt(rMTF.GetPrefSize());
1930 [ + - ]: 87 : WMFRecord_SetBkMode( sal_True );
1931 : :
1932 : 87 : eDstROP2 = eSrcRasterOp = ROP_OVERPAINT;
1933 [ + - ]: 87 : WMFRecord_SetROP2(eDstROP2);
1934 : :
1935 [ + - ][ + - ]: 87 : aDstLineInfo = LineInfo();
[ + - ]
1936 : 87 : aDstLineColor = aSrcLineColor = Color( COL_BLACK );
1937 [ + - ]: 87 : CreateSelectDeletePen( aDstLineColor, aDstLineInfo );
1938 : :
1939 : 87 : aDstFillColor = aSrcFillColor = Color( COL_WHITE );
1940 [ + - ]: 87 : CreateSelectDeleteBrush( aDstFillColor );
1941 : :
1942 [ + - ][ + - ]: 87 : aDstClipRegion = aSrcClipRegion = Region();
[ + - ][ + - ]
1943 : 87 : bDstIsClipping = bSrcIsClipping = sal_False;
1944 : :
1945 [ + - ]: 87 : Font aFont;
1946 [ + - ][ + - ]: 87 : aFont.SetCharSet( GetExtendedTextEncoding( RTL_TEXTENCODING_MS_1252 ) );
1947 [ + - ]: 87 : aFont.SetColor( Color( COL_WHITE ) );
1948 [ + - ]: 87 : aFont.SetAlign( ALIGN_BASELINE );
1949 [ + - ][ + - ]: 87 : aDstFont = aSrcFont = aFont;
1950 [ + - ]: 87 : CreateSelectDeleteFont(aDstFont);
1951 : :
1952 : 87 : eDstTextAlign = eSrcTextAlign = ALIGN_BASELINE;
1953 : 87 : eDstHorTextAlign = eSrcHorTextAlign = W_TA_LEFT;
1954 [ + - ]: 87 : WMFRecord_SetTextAlign( eDstTextAlign, eDstHorTextAlign );
1955 : :
1956 : 87 : aDstTextColor = aSrcTextColor = Color( COL_WHITE );
1957 [ + - ]: 87 : WMFRecord_SetTextColor(aDstTextColor);
1958 : :
1959 : : // Write records
1960 [ + - ]: 87 : WriteRecords(rMTF);
1961 : :
1962 [ + - ]: 87 : WMFRecord_EndOfFile();
1963 [ + - ]: 87 : UpdateHeader();
1964 : :
1965 [ - + ]: 87 : while(pAttrStack)
1966 : : {
1967 : 0 : pAt=pAttrStack;
1968 : 0 : pAttrStack=pAt->pSucc;
1969 [ # # ][ # # ]: 0 : delete pAt;
1970 : : }
1971 : :
1972 [ + - ][ + - ]: 87 : delete pVirDev;
1973 [ - + ][ # # ]: 87 : delete pConvert;
1974 : :
1975 [ - + ]: 87 : if ( xStatusIndicator.is() )
1976 [ # # ][ # # ]: 0 : xStatusIndicator->end();
1977 : :
1978 [ + - ]: 87 : return bStatus;
1979 : : }
1980 : :
1981 : : // ------------------------------------------------------------------------
1982 : :
1983 : 87 : sal_uInt16 WMFWriter::CalcSaveTargetMapMode(MapMode& rMapMode,
1984 : : const Size& rPrefSize)
1985 : : {
1986 [ + - ]: 87 : Fraction aDivFrac(2, 1);
1987 : 87 : sal_uInt16 nDivisor = 1;
1988 : :
1989 [ + - ]: 87 : Size aSize = pVirDev->LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
1990 : :
1991 [ + - ][ + - ]: 87 : while( nDivisor <= 64 && (aSize.Width() > 32767 || aSize.Height() > 32767) )
[ - + ][ - + ]
1992 : : {
1993 [ # # ]: 0 : Fraction aFrac = rMapMode.GetScaleX();
1994 : :
1995 [ # # ]: 0 : aFrac *= aDivFrac;
1996 [ # # ]: 0 : rMapMode.SetScaleX(aFrac);
1997 [ # # ]: 0 : aFrac = rMapMode.GetScaleY();
1998 [ # # ]: 0 : aFrac *= aDivFrac;
1999 [ # # ]: 0 : rMapMode.SetScaleY(aFrac);
2000 : 0 : nDivisor <<= 1;
2001 [ # # ]: 0 : aSize = pVirDev->LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
2002 : : }
2003 : :
2004 : 87 : return nDivisor;
2005 : : }
2006 : :
2007 : : // ------------------------------------------------------------------------
2008 : :
2009 : 87 : void WMFWriter::WriteEmbeddedEMF( const GDIMetaFile& rMTF )
2010 : : {
2011 [ + - ]: 87 : SvMemoryStream aStream;
2012 [ + - ]: 87 : EMFWriter aEMFWriter(aStream);
2013 : :
2014 [ + - ][ + - ]: 87 : if( aEMFWriter.WriteEMF( rMTF ) )
2015 : : {
2016 : 87 : sal_Size nTotalSize = aStream.Tell();
2017 : : if( nTotalSize > SAL_MAX_UINT32 )
2018 : 87 : return;
2019 [ + - ]: 87 : aStream.Seek( 0 );
2020 : 87 : sal_uInt32 nRemainingSize = static_cast< sal_uInt32 >( nTotalSize );
2021 : 87 : sal_uInt32 nRecCounts = ( (nTotalSize - 1) / 0x2000 ) + 1;
2022 : 87 : sal_uInt16 nCheckSum = 0, nWord;
2023 : :
2024 : 87 : sal_uInt32 nPos = 0;
2025 : :
2026 [ + + ]: 268329 : while( nPos + 1 < nTotalSize )
2027 : : {
2028 [ + - ]: 268242 : aStream >> nWord;
2029 : 268242 : nCheckSum ^= nWord;
2030 : 268242 : nPos += 2;
2031 : : }
2032 : :
2033 : 87 : nCheckSum = static_cast< sal_uInt16 >( nCheckSum * -1 );
2034 : :
2035 [ + - ]: 87 : aStream.Seek( 0 );
2036 [ + + ]: 207 : while( nRemainingSize > 0 )
2037 : : {
2038 : : sal_uInt32 nCurSize;
2039 [ + + ]: 120 : if( nRemainingSize > 0x2000 )
2040 : : {
2041 : 33 : nCurSize = 0x2000;
2042 : 33 : nRemainingSize -= 0x2000;
2043 : : }
2044 : : else
2045 : : {
2046 : 87 : nCurSize = nRemainingSize;
2047 : 87 : nRemainingSize = 0;
2048 : : }
2049 : : WriteEMFRecord( aStream,
2050 : : nCurSize,
2051 : : nRemainingSize,
2052 : : nTotalSize,
2053 : : nRecCounts,
2054 [ + - ]: 120 : nCheckSum );
2055 : 120 : nCheckSum = 0;
2056 : : }
2057 [ + - ][ - + ]: 87 : }
[ + - ][ + - ]
2058 : : }
2059 : :
2060 : : // ------------------------------------------------------------------------
2061 : :
2062 : 120 : void WMFWriter::WriteEMFRecord( SvMemoryStream& rStream, sal_uInt32 nCurSize, sal_uInt32 nRemainingSize,
2063 : : sal_uInt32 nTotalSize, sal_uInt32 nRecCounts, sal_uInt16 nCheckSum )
2064 : : {
2065 : : // according to http://msdn.microsoft.com/en-us/library/dd366152%28PROT.13%29.aspx
2066 : 120 : WriteRecordHeader( 0, W_META_ESCAPE );
2067 : 120 : *pWMF << (sal_uInt16)W_MFCOMMENT // same as META_ESCAPE_ENHANCED_METAFILE
2068 : 120 : << (sal_uInt16)( nCurSize + 34 ) // we will always have a 34 byte escape header:
2069 : 120 : << (sal_uInt32) 0x43464D57 // WMFC
2070 : 120 : << (sal_uInt32) 0x00000001 // Comment type
2071 : 120 : << (sal_uInt32) 0x00010000 // version
2072 : 120 : << nCheckSum // check sum
2073 : 120 : << (sal_uInt32) 0 // flags = 0
2074 : 120 : << nRecCounts // total number of records
2075 : 120 : << nCurSize // size of this record's data
2076 : 120 : << nRemainingSize // remaining size of data in following records, missing in MSDN documentation
2077 : 120 : << nTotalSize; // total size of EMF stream
2078 : :
2079 : 120 : pWMF->Write( static_cast< const sal_Char* >( rStream.GetData() ) + rStream.Tell(), nCurSize );
2080 : 120 : rStream.SeekRel( nCurSize );
2081 : 120 : UpdateRecordHeader();
2082 : 120 : }
2083 : :
2084 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|