Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "emfwr.hxx"
21 : #include <rtl/strbuf.hxx>
22 : #include <tools/helpers.hxx>
23 : #include <basegfx/polygon/b2dpolygon.hxx>
24 : #include <basegfx/polygon/b2dpolypolygon.hxx>
25 : #include <vcl/lineinfo.hxx>
26 :
27 : // -----------
28 : // - Defines -
29 : // -----------
30 :
31 : #define WIN_EMR_HEADER 1
32 : #define WIN_EMR_POLYBEZIER 2
33 : #define WIN_EMR_POLYGON 3
34 : #define WIN_EMR_POLYLINE 4
35 : #define WIN_EMR_POLYBEZIERTO 5
36 : #define WIN_EMR_POLYLINETO 6
37 : #define WIN_EMR_POLYPOLYLINE 7
38 : #define WIN_EMR_POLYPOLYGON 8
39 : #define WIN_EMR_SETWINDOWEXTEX 9
40 : #define WIN_EMR_SETWINDOWORGEX 10
41 : #define WIN_EMR_SETVIEWPORTEXTEX 11
42 : #define WIN_EMR_SETVIEWPORTORGEX 12
43 : #define WIN_EMR_SETBRUSHORGEX 13
44 : #define WIN_EMR_EOF 14
45 : #define WIN_EMR_SETPIXELV 15
46 : #define WIN_EMR_SETMAPPERFLAGS 16
47 : #define WIN_EMR_SETMAPMODE 17
48 : #define WIN_EMR_SETBKMODE 18
49 : #define WIN_EMR_SETPOLYFILLMODE 19
50 : #define WIN_EMR_SETROP2 20
51 : #define WIN_EMR_SETSTRETCHBLTMODE 21
52 : #define WIN_EMR_SETTEXTALIGN 22
53 : #define WIN_EMR_SETCOLORADJUSTMENT 23
54 : #define WIN_EMR_SETTEXTCOLOR 24
55 : #define WIN_EMR_SETBKCOLOR 25
56 : #define WIN_EMR_OFFSETCLIPRGN 26
57 : #define WIN_EMR_MOVETOEX 27
58 : #define WIN_EMR_SETMETARGN 28
59 : #define WIN_EMR_EXCLUDECLIPRECT 29
60 : #define WIN_EMR_INTERSECTCLIPRECT 30
61 : #define WIN_EMR_SCALEVIEWPORTEXTEX 31
62 : #define WIN_EMR_SCALEWINDOWEXTEX 32
63 : #define WIN_EMR_SAVEDC 33
64 : #define WIN_EMR_RESTOREDC 34
65 : #define WIN_EMR_SETWORLDTRANSFORM 35
66 : #define WIN_EMR_MODIFYWORLDTRANSFORM 36
67 : #define WIN_EMR_SELECTOBJECT 37
68 : #define WIN_EMR_CREATEPEN 38
69 : #define WIN_EMR_CREATEBRUSHINDIRECT 39
70 : #define WIN_EMR_DELETEOBJECT 40
71 : #define WIN_EMR_ANGLEARC 41
72 : #define WIN_EMR_ELLIPSE 42
73 : #define WIN_EMR_RECTANGLE 43
74 : #define WIN_EMR_ROUNDRECT 44
75 : #define WIN_EMR_ARC 45
76 : #define WIN_EMR_CHORD 46
77 : #define WIN_EMR_PIE 47
78 : #define WIN_EMR_SELECTPALETTE 48
79 : #define WIN_EMR_CREATEPALETTE 49
80 : #define WIN_EMR_SETPALETTEENTRIES 50
81 : #define WIN_EMR_RESIZEPALETTE 51
82 : #define WIN_EMR_REALIZEPALETTE 52
83 : #define WIN_EMR_EXTFLOODFILL 53
84 : #define WIN_EMR_LINETO 54
85 : #define WIN_EMR_ARCTO 55
86 : #define WIN_EMR_POLYDRAW 56
87 : #define WIN_EMR_SETARCDIRECTION 57
88 : #define WIN_EMR_SETMITERLIMIT 58
89 : #define WIN_EMR_BEGINPATH 59
90 : #define WIN_EMR_ENDPATH 60
91 : #define WIN_EMR_CLOSEFIGURE 61
92 : #define WIN_EMR_FILLPATH 62
93 : #define WIN_EMR_STROKEANDFILLPATH 63
94 : #define WIN_EMR_STROKEPATH 64
95 : #define WIN_EMR_FLATTENPATH 65
96 : #define WIN_EMR_WIDENPATH 66
97 : #define WIN_EMR_SELECTCLIPPATH 67
98 : #define WIN_EMR_ABORTPATH 68
99 :
100 : #define WIN_EMR_GDICOMMENT 70
101 : #define WIN_EMR_FILLRGN 71
102 : #define WIN_EMR_FRAMERGN 72
103 : #define WIN_EMR_INVERTRGN 73
104 : #define WIN_EMR_PAINTRGN 74
105 : #define WIN_EMR_EXTSELECTCLIPRGN 75
106 : #define WIN_EMR_BITBLT 76
107 : #define WIN_EMR_STRETCHBLT 77
108 : #define WIN_EMR_MASKBLT 78
109 : #define WIN_EMR_PLGBLT 79
110 : #define WIN_EMR_SETDIBITSTODEVICE 80
111 : #define WIN_EMR_STRETCHDIBITS 81
112 : #define WIN_EMR_EXTCREATEFONTINDIRECTW 82
113 : #define WIN_EMR_EXTTEXTOUTA 83
114 : #define WIN_EMR_EXTTEXTOUTW 84
115 : #define WIN_EMR_POLYBEZIER16 85
116 : #define WIN_EMR_POLYGON16 86
117 : #define WIN_EMR_POLYLINE16 87
118 : #define WIN_EMR_POLYBEZIERTO16 88
119 : #define WIN_EMR_POLYLINETO16 89
120 : #define WIN_EMR_POLYPOLYLINE16 90
121 : #define WIN_EMR_POLYPOLYGON16 91
122 : #define WIN_EMR_POLYDRAW16 92
123 : #define WIN_EMR_CREATEMONOBRUSH 93
124 : #define WIN_EMR_CREATEDIBPATTERNBRUSHPT 94
125 : #define WIN_EMR_EXTCREATEPEN 95
126 : #define WIN_EMR_POLYTEXTOUTA 96
127 : #define WIN_EMR_POLYTEXTOUTW 97
128 :
129 : #define WIN_SRCCOPY 0x00CC0020L
130 : #define WIN_SRCPAINT 0x00EE0086L
131 : #define WIN_SRCAND 0x008800C6L
132 : #define WIN_SRCINVERT 0x00660046L
133 : #define WIN_EMR_COMMENT_EMFSPOOL 0x00000000L
134 : #define WIN_EMR_COMMENT_EMFPLUS 0x2B464D45L
135 : #define WIN_EMR_COMMENT_PUBLIC 0x43494447L
136 :
137 : #define HANDLE_INVALID 0xffffffff
138 : #define MAXHANDLES 65000
139 :
140 : #define LINE_SELECT 0x00000001
141 : #define FILL_SELECT 0x00000002
142 : #define TEXT_SELECT 0x00000004
143 :
144 : /* Text Alignment Options */
145 : #define TA_NOUPDATECP 0
146 : #define TA_UPDATECP 1
147 :
148 : #define TA_LEFT 0
149 : #define TA_RIGHT 2
150 : #define TA_CENTER 6
151 :
152 : #define TA_TOP 0
153 : #define TA_BOTTOM 8
154 : #define TA_BASELINE 24
155 : #define TA_RTLREADING 256
156 : #define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING)
157 :
158 : #define MM_ANISOTROPIC 8
159 :
160 : typedef enum
161 : {
162 : EmfPlusHeader = 0x4001,
163 : EmfPlusEndOfFile = 0x4002,
164 : EmfPlusComment = 0x4003,
165 : EmfPlusGetDC = 0x4004,
166 : EmfPlusMultiFormatStart = 0x4005,
167 : EmfPlusMultiFormatSection = 0x4006,
168 : EmfPlusMultiFormatEnd = 0x4007,
169 : EmfPlusObject = 0x4008,
170 : EmfPlusClear = 0x4009,
171 : EmfPlusFillRects = 0x400A,
172 : EmfPlusDrawRects = 0x400B,
173 : EmfPlusFillPolygon = 0x400C,
174 : EmfPlusDrawLines = 0x400D,
175 : EmfPlusFillEllipse = 0x400E,
176 : EmfPlusDrawEllipse = 0x400F,
177 : EmfPlusFillPie = 0x4010,
178 : EmfPlusDrawPie = 0x4011,
179 : EmfPlusDrawArc = 0x4012,
180 : EmfPlusFillRegion = 0x4013,
181 : EmfPlusFillPath = 0x4014,
182 : EmfPlusDrawPath = 0x4015,
183 : EmfPlusFillClosedCurve = 0x4016,
184 : EmfPlusDrawClosedCurve = 0x4017,
185 : EmfPlusDrawCurve = 0x4018,
186 : EmfPlusDrawBeziers = 0x4019,
187 : EmfPlusDrawImage = 0x401A,
188 : EmfPlusDrawImagePoints = 0x401B,
189 : EmfPlusDrawstring = 0x401C,
190 : EmfPlusSetRenderingOrigin = 0x401D,
191 : EmfPlusSetAntiAliasMode = 0x401E,
192 : EmfPlusSetTextRenderingHint = 0x401F,
193 : EmfPlusSetTextContrast = 0x4020,
194 : EmfPlusSetInterpolationMode = 0x4021,
195 : EmfPlusSetPixelOffsetMode = 0x4022,
196 : EmfPlusSetCompositingMode = 0x4023,
197 : EmfPlusSetCompositingQuality = 0x4024,
198 : EmfPlusSave = 0x4025,
199 : EmfPlusRestore = 0x4026,
200 : EmfPlusBeginContainer = 0x4027,
201 : EmfPlusBeginContainerNoParams = 0x4028,
202 : EmfPlusEndContainer = 0x4029,
203 : EmfPlusSetWorldTransform = 0x402A,
204 : EmfPlusResetWorldTransform = 0x402B,
205 : EmfPlusMultiplyWorldTransform = 0x402C,
206 : EmfPlusTranslateWorldTransform = 0x402D,
207 : EmfPlusScaleWorldTransform = 0x402E,
208 : EmfPlusRotateWorldTransform = 0x402F,
209 : EmfPlusSetPageTransform = 0x4030,
210 : EmfPlusResetClip = 0x4031,
211 : EmfPlusSetClipRect = 0x4032,
212 : EmfPlusSetClipPath = 0x4033,
213 : EmfPlusSetClipRegion = 0x4034,
214 : EmfPlusOffsetClip = 0x4035,
215 : EmfPlusDrawDriverstring = 0x4036,
216 : EmfPlusStrokeFillPath = 0x4037,
217 : EmfPlusSerializableObject = 0x4038,
218 : EmfPlusSetTSGraphics = 0x4039,
219 : EmfPlusSetTSClip = 0x403A
220 : } EmfPlusRecordType;
221 :
222 :
223 : // -------------
224 : // - EMFWriter -
225 : // -------------
226 :
227 90 : void EMFWriter::ImplBeginCommentRecord( sal_Int32 nCommentType )
228 : {
229 90 : ImplBeginRecord( WIN_EMR_GDICOMMENT );
230 90 : m_rStm.SeekRel( 4 );
231 90 : m_rStm<< (sal_Int32) nCommentType;
232 90 : }
233 :
234 90 : void EMFWriter::ImplEndCommentRecord()
235 : {
236 90 : if( mbRecordOpen )
237 : {
238 90 : sal_Int32 nActPos = m_rStm.Tell();
239 90 : m_rStm.Seek( mnRecordPos + 8 );
240 90 : m_rStm << (sal_uInt32)( nActPos - mnRecordPos - 0xc );
241 90 : m_rStm.Seek( nActPos );
242 : }
243 90 : ImplEndRecord();
244 90 : }
245 :
246 210 : void EMFWriter::ImplBeginPlusRecord( sal_uInt16 nType, sal_uInt16 nFlags )
247 : {
248 : DBG_ASSERT( !mbRecordPlusOpen, "Another EMF+ record is already opened!" );
249 :
250 210 : if( !mbRecordPlusOpen )
251 : {
252 210 : mbRecordPlusOpen = sal_True;
253 210 : mnRecordPlusPos = m_rStm.Tell();
254 :
255 210 : m_rStm << (sal_uInt16) nType << (sal_uInt16) nFlags;
256 210 : m_rStm.SeekRel( 8 );
257 : }
258 210 : }
259 :
260 : // -----------------------------------------------------------------------------
261 :
262 210 : void EMFWriter::ImplEndPlusRecord()
263 : {
264 : DBG_ASSERT( mbRecordPlusOpen, "EMF+ Record was not opened!" );
265 :
266 210 : if( mbRecordPlusOpen )
267 : {
268 210 : sal_Int32 nActPos = m_rStm.Tell();
269 210 : sal_Int32 nSize = nActPos - mnRecordPlusPos;
270 210 : m_rStm.Seek( mnRecordPlusPos + 4 );
271 210 : m_rStm << (sal_uInt32)( nSize ) // Size
272 420 : << (sal_uInt32) ( nSize - 0xc ); // Data Size
273 210 : m_rStm.Seek( nActPos );
274 210 : mbRecordPlusOpen = sal_False;
275 : }
276 210 : }
277 :
278 210 : void EMFWriter::ImplPlusRecord( sal_uInt16 nType, sal_uInt16 nFlags )
279 : {
280 210 : ImplBeginPlusRecord( nType, nFlags );
281 210 : ImplEndPlusRecord();
282 210 : }
283 :
284 30 : void EMFWriter::WriteEMFPlusHeader( const Size &rMtfSizePix, const Size &rMtfSizeLog )
285 : {
286 30 : ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
287 :
288 30 : sal_Int32 nDPIX = rMtfSizePix.Width()*25;
289 30 : sal_Int32 nDivX = rMtfSizeLog.Width()/100;
290 30 : if (nDivX)
291 30 : nDPIX /= nDivX; // DPI X
292 :
293 30 : sal_Int32 nDPIY = rMtfSizePix.Height()*25;
294 30 : sal_Int32 nDivY = rMtfSizeLog.Height()/100;
295 30 : if (nDivY)
296 30 : nDPIY /= nDivY; // DPI Y
297 :
298 30 : m_rStm<< (sal_Int16) EmfPlusHeader;
299 30 : m_rStm<< (sal_Int16) 0x01 // Flags - Dual Mode // TODO: Check this
300 30 : << (sal_Int32) 0x1C // Size
301 30 : << (sal_Int32) 0x10 // Data Size
302 30 : << (sal_Int32) 0xdbc01002 // (lower 12bits) 1-> v1 2-> v1.1 // TODO: Check this
303 30 : << (sal_Int32) 0x01 // Video display
304 30 : << nDPIX
305 30 : << nDPIY;
306 30 : ImplEndCommentRecord();
307 :
308 : // Write more properties
309 30 : ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
310 30 : ImplPlusRecord( EmfPlusSetPixelOffsetMode, 0x0 );
311 30 : ImplPlusRecord( EmfPlusSetAntiAliasMode, 0x09 ); // TODO: Check actual values for AntiAlias
312 30 : ImplPlusRecord( EmfPlusSetCompositingQuality, 0x0100 ); // Default Quality
313 30 : ImplPlusRecord( EmfPlusSetPageTransform, 1 );
314 30 : ImplPlusRecord( EmfPlusSetInterpolationMode, 0x00 ); // Default
315 30 : ImplPlusRecord( EmfPlusGetDC, 0x00 );
316 30 : ImplEndCommentRecord();
317 30 : }
318 :
319 30 : void EMFWriter::ImplWritePlusEOF()
320 : {
321 30 : ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
322 30 : ImplPlusRecord( EmfPlusEndOfFile, 0x0 );
323 30 : ImplEndCommentRecord();
324 30 : }
325 :
326 0 : void EMFWriter::ImplWritePlusColor( const Color& rColor, const sal_uInt32& nTrans )
327 : {
328 0 : sal_uInt32 nAlpha = ((100-nTrans)*0xFF)/100;
329 0 : sal_uInt32 nCol = rColor.GetBlue();
330 :
331 0 : nCol |= ( (sal_uInt32) rColor.GetGreen() ) << 8;
332 0 : nCol |= ( (sal_uInt32) rColor.GetRed() ) << 16;
333 0 : nCol |= ( nAlpha << 24 );
334 0 : m_rStm << nCol;
335 0 : }
336 :
337 0 : void EMFWriter::ImplWritePlusPoint( const Point& rPoint )
338 : {
339 : // Convert to pixels
340 0 : const Point aPoint(maVDev.LogicToPixel( rPoint, maDestMapMode ));
341 0 : m_rStm << (sal_uInt16) aPoint.X() << (sal_uInt16) aPoint.Y();
342 0 : }
343 :
344 0 : void EMFWriter::ImplWritePlusFillPolygonRecord( const Polygon& rPoly, const sal_uInt32& nTrans )
345 : {
346 0 : ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
347 0 : if( rPoly.GetSize() )
348 : {
349 0 : ImplBeginPlusRecord( EmfPlusFillPolygon, 0xC000 ); // Sets the color as well
350 0 : ImplWritePlusColor( maVDev.GetFillColor(), nTrans );
351 0 : m_rStm << (sal_uInt32) rPoly.GetSize();
352 0 : for( sal_uInt16 i = 0; i < rPoly.GetSize(); i++ )
353 0 : ImplWritePlusPoint( rPoly[ i ] );
354 0 : ImplEndPlusRecord();
355 : }
356 0 : ImplEndCommentRecord();
357 0 : }
358 :
359 30 : sal_Bool EMFWriter::WriteEMF( const GDIMetaFile& rMtf, FilterConfigItem* pFilterConfigItem )
360 : {
361 30 : const sal_uLong nHeaderPos = m_rStm.Tell();
362 :
363 30 : mpHandlesUsed = new sal_Bool[ MAXHANDLES ];
364 30 : memset( mpHandlesUsed, 0, MAXHANDLES * sizeof( sal_Bool ) );
365 30 : mnHorTextAlign = mnHandleCount = mnLastPercent = mnRecordPos = mnRecordCount = 0;
366 30 : mnRecordPlusPos = 0;
367 30 : mnLineHandle = mnFillHandle = mnTextHandle = HANDLE_INVALID;
368 30 : mbRecordOpen = sal_False;
369 30 : mbRecordPlusOpen = false;
370 :
371 :
372 30 : maVDev.EnableOutput( sal_False );
373 30 : maVDev.SetMapMode( rMtf.GetPrefMapMode() );
374 30 : mpFilterConfigItem = pFilterConfigItem;
375 :
376 : // don't work with pixel as destination map mode -> higher resolution preferrable
377 30 : maDestMapMode.SetMapUnit( MAP_100TH_MM );
378 :
379 30 : const Size aMtfSizePix( maVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
380 30 : const Size aMtfSizeLog( maVDev.LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_100TH_MM ) );
381 :
382 : // seek over header
383 : // use [MS-EMF 2.2.11] HeaderExtension2 Object, otherwise resulting EMF cannot be converted with GetWinMetaFileBits()
384 30 : m_rStm.SeekRel( 108 );
385 :
386 : // Write EMF+ Header
387 30 : WriteEMFPlusHeader( aMtfSizePix, aMtfSizeLog );
388 :
389 : // write initial values
390 :
391 : // set 100th mm map mode in EMF
392 30 : ImplBeginRecord( WIN_EMR_SETMAPMODE );
393 30 : m_rStm << (sal_Int32) MM_ANISOTROPIC;
394 30 : ImplEndRecord();
395 :
396 30 : ImplBeginRecord( WIN_EMR_SETVIEWPORTEXTEX );
397 30 : m_rStm << (sal_Int32) maVDev.ImplGetDPIX() << (sal_Int32) maVDev.ImplGetDPIY();
398 30 : ImplEndRecord();
399 :
400 30 : ImplBeginRecord( WIN_EMR_SETWINDOWEXTEX );
401 30 : m_rStm << (sal_Int32) 2540 << (sal_Int32) 2540;
402 30 : ImplEndRecord();
403 :
404 30 : ImplBeginRecord( WIN_EMR_SETVIEWPORTORGEX );
405 30 : m_rStm << (sal_Int32) 0 << (sal_Int32) 0;
406 30 : ImplEndRecord();
407 :
408 30 : ImplBeginRecord( WIN_EMR_SETWINDOWORGEX );
409 30 : m_rStm << (sal_Int32) 0 << (sal_Int32) 0;
410 30 : ImplEndRecord();
411 :
412 30 : ImplWriteRasterOp( ROP_OVERPAINT );
413 :
414 30 : ImplBeginRecord( WIN_EMR_SETBKMODE );
415 30 : m_rStm << (sal_uInt32) 1; // TRANSPARENT
416 30 : ImplEndRecord();
417 :
418 : // write emf data
419 30 : ImplWrite( rMtf );
420 :
421 30 : ImplWritePlusEOF();
422 :
423 30 : ImplBeginRecord( WIN_EMR_EOF );
424 30 : m_rStm<< (sal_uInt32)0 // nPalEntries
425 30 : << (sal_uInt32)0x10 // offPalEntries
426 30 : << (sal_uInt32)0x14; // nSizeLast
427 30 : ImplEndRecord();
428 :
429 :
430 : // write header
431 30 : const sal_uLong nEndPos = m_rStm.Tell(); m_rStm.Seek( nHeaderPos );
432 :
433 30 : m_rStm << (sal_uInt32) 0x00000001 << (sal_uInt32) 108 //use [MS-EMF 2.2.11] HeaderExtension2 Object
434 60 : << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) ( aMtfSizePix.Width() - 1 ) << (sal_Int32) ( aMtfSizePix.Height() - 1 )
435 60 : << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) ( aMtfSizeLog.Width() - 1 ) << (sal_Int32) ( aMtfSizeLog.Height() - 1 )
436 60 : << (sal_uInt32) 0x464d4520 << (sal_uInt32) 0x10000 << (sal_uInt32) ( nEndPos - nHeaderPos )
437 60 : << (sal_uInt32) mnRecordCount << (sal_uInt16) ( mnHandleCount + 1 ) << (sal_uInt16) 0 << (sal_uInt32) 0 << (sal_uInt32) 0 << (sal_uInt32) 0
438 60 : << (sal_Int32) aMtfSizePix.Width() << (sal_Int32) aMtfSizePix.Height()
439 60 : << (sal_Int32) ( aMtfSizeLog.Width() / 100 ) << (sal_Int32) ( aMtfSizeLog.Height() / 100 )
440 30 : << (sal_uInt32) 0 << (sal_uInt32) 0 << (sal_uInt32) 0
441 60 : << (sal_Int32) ( aMtfSizeLog.Width() * 10 ) << (sal_Int32) ( aMtfSizeLog.Height() * 10 ); //use [MS-EMF 2.2.11] HeaderExtension2 Object
442 :
443 30 : m_rStm.Seek( nEndPos );
444 30 : delete[] mpHandlesUsed;
445 :
446 30 : return( m_rStm.GetError() == ERRCODE_NONE );
447 : }
448 :
449 : // -----------------------------------------------------------------------------
450 :
451 371 : sal_uLong EMFWriter::ImplAcquireHandle()
452 : {
453 371 : sal_uLong nHandle = HANDLE_INVALID;
454 :
455 799 : for( sal_uLong i = 0; i < MAXHANDLES && ( HANDLE_INVALID == nHandle ); i++ )
456 : {
457 428 : if( !mpHandlesUsed[ i ] )
458 : {
459 371 : mpHandlesUsed[ i ] = sal_True;
460 :
461 371 : if( ( nHandle = i ) == mnHandleCount )
462 52 : mnHandleCount++;
463 : }
464 : }
465 :
466 : DBG_ASSERT( nHandle != HANDLE_INVALID, "No more handles available" );
467 371 : return( nHandle != HANDLE_INVALID ? nHandle + 1 : HANDLE_INVALID );
468 : }
469 :
470 : // -----------------------------------------------------------------------------
471 :
472 319 : void EMFWriter::ImplReleaseHandle( sal_uLong nHandle )
473 : {
474 : DBG_ASSERT( nHandle && ( nHandle < MAXHANDLES ), "Handle out of range" );
475 319 : mpHandlesUsed[ nHandle - 1 ] = sal_False;
476 319 : }
477 :
478 : // -----------------------------------------------------------------------------
479 :
480 3909 : void EMFWriter::ImplBeginRecord( sal_uInt32 nType )
481 : {
482 : DBG_ASSERT( !mbRecordOpen, "Another record is already opened!" );
483 :
484 3909 : if( !mbRecordOpen )
485 : {
486 3909 : mbRecordOpen = sal_True;
487 3909 : mnRecordPos = m_rStm.Tell();
488 :
489 3909 : m_rStm << nType;
490 3909 : m_rStm.SeekRel( 4 );
491 : }
492 3909 : }
493 :
494 : // -----------------------------------------------------------------------------
495 :
496 3909 : void EMFWriter::ImplEndRecord()
497 : {
498 : DBG_ASSERT( mbRecordOpen, "Record was not opened!" );
499 :
500 3909 : if( mbRecordOpen )
501 : {
502 3909 : sal_Int32 nFillBytes, nActPos = m_rStm.Tell();
503 3909 : m_rStm.Seek( mnRecordPos + 4 );
504 3909 : nFillBytes = nActPos - mnRecordPos;
505 3909 : nFillBytes += 3; // each record has to be dword aligned
506 3909 : nFillBytes ^= 3;
507 3909 : nFillBytes &= 3;
508 3909 : m_rStm << (sal_uInt32)( ( nActPos - mnRecordPos ) + nFillBytes );
509 3909 : m_rStm.Seek( nActPos );
510 7818 : while( nFillBytes-- )
511 0 : m_rStm << (sal_uInt8)0;
512 3909 : mnRecordCount++;
513 3909 : mbRecordOpen = sal_False;
514 : }
515 3909 : }
516 :
517 : // -----------------------------------------------------------------------------
518 :
519 371 : sal_Bool EMFWriter::ImplPrepareHandleSelect( sal_uInt32& rHandle, sal_uLong nSelectType )
520 : {
521 371 : if( rHandle != HANDLE_INVALID )
522 : {
523 319 : sal_uInt32 nStockObject = 0x80000000;
524 :
525 319 : if( LINE_SELECT == nSelectType )
526 8 : nStockObject |= 0x00000007;
527 311 : else if( FILL_SELECT == nSelectType )
528 8 : nStockObject |= 0x00000001;
529 303 : else if( TEXT_SELECT == nSelectType )
530 303 : nStockObject |= 0x0000000a;
531 :
532 : // select stock object first
533 319 : ImplBeginRecord( WIN_EMR_SELECTOBJECT );
534 319 : m_rStm << nStockObject;
535 319 : ImplEndRecord();
536 :
537 : // destroy handle of created object
538 319 : ImplBeginRecord( WIN_EMR_DELETEOBJECT );
539 319 : m_rStm << rHandle;
540 319 : ImplEndRecord();
541 :
542 : // mark handle as free
543 319 : ImplReleaseHandle( rHandle );
544 : }
545 :
546 371 : rHandle = ImplAcquireHandle();
547 :
548 371 : return( HANDLE_INVALID != rHandle );
549 : }
550 :
551 : // -----------------------------------------------------------------------------
552 :
553 19 : void EMFWriter::ImplCheckLineAttr()
554 : {
555 19 : if( mbLineChanged && ImplPrepareHandleSelect( mnLineHandle, LINE_SELECT ) )
556 : {
557 19 : sal_uInt32 nStyle = maVDev.IsLineColor() ? 0 : 5;
558 19 : sal_uInt32 nWidth = 0, nHeight = 0;
559 :
560 19 : ImplBeginRecord( WIN_EMR_CREATEPEN );
561 19 : m_rStm << mnLineHandle << nStyle << nWidth << nHeight;
562 19 : ImplWriteColor( maVDev.GetLineColor() );
563 19 : ImplEndRecord();
564 :
565 19 : ImplBeginRecord( WIN_EMR_SELECTOBJECT );
566 19 : m_rStm << mnLineHandle;
567 19 : ImplEndRecord();
568 : }
569 19 : }
570 :
571 : // -----------------------------------------------------------------------------
572 :
573 19 : void EMFWriter::ImplCheckFillAttr()
574 : {
575 19 : if( mbFillChanged && ImplPrepareHandleSelect( mnFillHandle, FILL_SELECT ) )
576 : {
577 19 : sal_uInt32 nStyle = maVDev.IsFillColor() ? 0 : 1;
578 19 : sal_uInt32 nPatternStyle = 0;
579 :
580 19 : ImplBeginRecord( WIN_EMR_CREATEBRUSHINDIRECT );
581 19 : m_rStm << mnFillHandle << nStyle;
582 19 : ImplWriteColor( maVDev.GetFillColor() );
583 19 : m_rStm << nPatternStyle;
584 19 : ImplEndRecord();
585 :
586 19 : ImplBeginRecord( WIN_EMR_SELECTOBJECT );
587 19 : m_rStm << mnFillHandle;
588 19 : ImplEndRecord();
589 : }
590 19 : }
591 :
592 : // -----------------------------------------------------------------------------
593 :
594 333 : void EMFWriter::ImplCheckTextAttr()
595 : {
596 333 : if( mbTextChanged && ImplPrepareHandleSelect( mnTextHandle, TEXT_SELECT ) )
597 : {
598 333 : const Font& rFont = maVDev.GetFont();
599 333 : String aFontName( rFont.GetName() );
600 : sal_Int32 nWeight;
601 : sal_uInt16 i;
602 : sal_uInt8 nPitchAndFamily;
603 :
604 333 : ImplBeginRecord( WIN_EMR_EXTCREATEFONTINDIRECTW );
605 333 : m_rStm << mnTextHandle;
606 333 : ImplWriteExtent( -rFont.GetSize().Height() );
607 333 : ImplWriteExtent( rFont.GetSize().Width() );
608 333 : m_rStm << (sal_Int32) rFont.GetOrientation() << (sal_Int32) rFont.GetOrientation();
609 :
610 333 : switch( rFont.GetWeight() )
611 : {
612 0 : case WEIGHT_THIN: nWeight = 100; break;
613 0 : case WEIGHT_ULTRALIGHT: nWeight = 200; break;
614 0 : case WEIGHT_LIGHT: nWeight = 300; break;
615 0 : case WEIGHT_SEMILIGHT: nWeight = 300; break;
616 333 : case WEIGHT_NORMAL: nWeight = 400; break;
617 0 : case WEIGHT_MEDIUM: nWeight = 500; break;
618 0 : case WEIGHT_SEMIBOLD: nWeight = 600; break;
619 0 : case WEIGHT_BOLD: nWeight = 700; break;
620 0 : case WEIGHT_ULTRABOLD: nWeight = 800; break;
621 0 : case WEIGHT_BLACK: nWeight = 900; break;
622 0 : default: nWeight = 0; break;
623 : }
624 :
625 333 : m_rStm << nWeight;
626 333 : m_rStm << (sal_uInt8) ( ( ITALIC_NONE == rFont.GetItalic() ) ? 0 : 1 );
627 333 : m_rStm << (sal_uInt8) ( ( UNDERLINE_NONE == rFont.GetUnderline() ) ? 0 : 1 );
628 333 : m_rStm << (sal_uInt8) ( ( STRIKEOUT_NONE == rFont.GetStrikeout() ) ? 0 : 1 );
629 333 : m_rStm << (sal_uInt8) ( ( RTL_TEXTENCODING_SYMBOL == rFont.GetCharSet() ) ? 2 : 0 );
630 333 : m_rStm << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0;
631 :
632 333 : switch( rFont.GetPitch() )
633 : {
634 0 : case PITCH_FIXED: nPitchAndFamily = 0x01; break;
635 2 : case PITCH_VARIABLE: nPitchAndFamily = 0x02; break;
636 331 : default: nPitchAndFamily = 0x00; break;
637 : }
638 :
639 333 : switch( rFont.GetFamily() )
640 : {
641 0 : case FAMILY_DECORATIVE: nPitchAndFamily |= 0x50; break;
642 0 : case FAMILY_MODERN: nPitchAndFamily |= 0x30; break;
643 213 : case FAMILY_ROMAN: nPitchAndFamily |= 0x10; break;
644 0 : case FAMILY_SCRIPT: nPitchAndFamily |= 0x40; break;
645 2 : case FAMILY_SWISS: nPitchAndFamily |= 0x20; break;
646 118 : default: break;
647 : }
648 :
649 333 : m_rStm << nPitchAndFamily;
650 :
651 10989 : for( i = 0; i < 32; i++ )
652 10656 : m_rStm << (sal_Unicode) ( ( i < aFontName.Len() ) ? aFontName.GetChar( i ) : 0 );
653 :
654 : // dummy elfFullName
655 21645 : for( i = 0; i < 64; i++ )
656 21312 : m_rStm << (sal_Unicode) 0;
657 :
658 : // dummy elfStyle
659 10989 : for( i = 0; i < 32; i++ )
660 10656 : m_rStm << (sal_Unicode) 0;
661 :
662 : // dummy elfVersion, elfStyleSize, elfMatch, elfReserved
663 333 : m_rStm << (sal_uInt32) 0 << (sal_uInt32) 0 << (sal_uInt32) 0 << (sal_uInt32) 0 ;
664 :
665 : // dummy elfVendorId
666 333 : m_rStm << (sal_uInt32) 0;
667 :
668 : // dummy elfCulture
669 333 : m_rStm << (sal_uInt32) 0;
670 :
671 : // dummy elfPanose
672 333 : m_rStm << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0;
673 :
674 : // fill record to get a record size divideable by 4
675 333 : m_rStm << (sal_uInt16) 0;
676 :
677 333 : ImplEndRecord();
678 :
679 : // TextAlign
680 : sal_uInt32 nTextAlign;
681 :
682 333 : switch( rFont.GetAlign() )
683 : {
684 0 : case ALIGN_TOP: nTextAlign = TA_TOP; break;
685 0 : case ALIGN_BOTTOM: nTextAlign = TA_BOTTOM; break;
686 333 : default: nTextAlign = TA_BASELINE; break;
687 : }
688 333 : nTextAlign |= mnHorTextAlign;
689 :
690 333 : ImplBeginRecord( WIN_EMR_SETTEXTALIGN );
691 333 : m_rStm << nTextAlign;
692 333 : ImplEndRecord();
693 :
694 : // Text color
695 333 : ImplBeginRecord( WIN_EMR_SETTEXTCOLOR );
696 333 : ImplWriteColor( maVDev.GetTextColor() );
697 333 : ImplEndRecord();
698 :
699 333 : ImplBeginRecord( WIN_EMR_SELECTOBJECT );
700 333 : m_rStm << mnTextHandle;
701 333 : ImplEndRecord();
702 : }
703 333 : }
704 :
705 : // -----------------------------------------------------------------------------
706 :
707 371 : void EMFWriter::ImplWriteColor( const Color& rColor )
708 : {
709 371 : sal_uInt32 nCol = rColor.GetRed();
710 :
711 371 : nCol |= ( (sal_uInt32) rColor.GetGreen() ) << 8;
712 371 : nCol |= ( (sal_uInt32) rColor.GetBlue() ) << 16;
713 :
714 371 : m_rStm << nCol;
715 371 : }
716 :
717 : // -----------------------------------------------------------------------------
718 :
719 414 : void EMFWriter::ImplWriteRasterOp( RasterOp eRop )
720 : {
721 : sal_uInt32 nROP2;
722 :
723 414 : switch( eRop )
724 : {
725 0 : case ROP_INVERT: nROP2 = 6; break;
726 0 : case ROP_XOR: nROP2 = 7; break;
727 414 : default: nROP2 = 13;break;
728 : }
729 :
730 414 : ImplBeginRecord( WIN_EMR_SETROP2 );
731 414 : m_rStm << nROP2;
732 414 : ImplEndRecord();
733 414 : }
734 :
735 : // -----------------------------------------------------------------------------
736 :
737 1044 : void EMFWriter::ImplWriteExtent( long nExtent )
738 : {
739 1044 : nExtent = maVDev.LogicToLogic( Size( nExtent, 0 ), maVDev.GetMapMode(), maDestMapMode ).Width();
740 1044 : m_rStm << (sal_Int32) nExtent;
741 1044 : }
742 :
743 : // -----------------------------------------------------------------------------
744 :
745 333 : void EMFWriter::ImplWritePoint( const Point& rPoint )
746 : {
747 333 : const Point aPoint( maVDev.LogicToLogic( rPoint, maVDev.GetMapMode(), maDestMapMode ));
748 333 : m_rStm << (sal_Int32) aPoint.X() << (sal_Int32) aPoint.Y();
749 333 : }
750 :
751 : // -----------------------------------------------------------------------------
752 :
753 0 : void EMFWriter::ImplWriteSize( const Size& rSize)
754 : {
755 0 : const Size aSize( maVDev.LogicToLogic( rSize, maVDev.GetMapMode(), maDestMapMode ));
756 0 : m_rStm << (sal_Int32) aSize.Width() << (sal_Int32) aSize.Height();
757 0 : }
758 :
759 : // -----------------------------------------------------------------------------
760 :
761 381 : void EMFWriter::ImplWriteRect( const Rectangle& rRect )
762 : {
763 381 : const Rectangle aRect( maVDev.LogicToLogic ( rRect, maVDev.GetMapMode(), maDestMapMode ));
764 : m_rStm
765 381 : << static_cast<sal_Int32>(aRect.Left())
766 762 : << static_cast<sal_Int32>(aRect.Top())
767 762 : << static_cast<sal_Int32>(aRect.Right())
768 762 : << static_cast<sal_Int32>(aRect.Bottom());
769 381 : }
770 :
771 : // -----------------------------------------------------------------------------
772 :
773 0 : void EMFWriter::ImplWritePolygonRecord( const Polygon& rPoly, sal_Bool bClose )
774 : {
775 0 : if( rPoly.GetSize() )
776 : {
777 0 : if( rPoly.HasFlags() )
778 0 : ImplWritePath( rPoly, bClose );
779 : else
780 : {
781 0 : if( bClose )
782 0 : ImplCheckFillAttr();
783 :
784 0 : ImplCheckLineAttr();
785 :
786 0 : ImplBeginRecord( bClose ? WIN_EMR_POLYGON : WIN_EMR_POLYLINE );
787 0 : ImplWriteRect( rPoly.GetBoundRect() );
788 0 : m_rStm << (sal_uInt32) rPoly.GetSize();
789 :
790 0 : for( sal_uInt16 i = 0; i < rPoly.GetSize(); i++ )
791 0 : ImplWritePoint( rPoly[ i ] );
792 :
793 0 : ImplEndRecord();
794 : }
795 : }
796 0 : }
797 :
798 : // -----------------------------------------------------------------------------
799 :
800 0 : void EMFWriter::ImplWritePolyPolygonRecord( const PolyPolygon& rPolyPoly )
801 : {
802 0 : sal_uInt16 n, i, nPolyCount = rPolyPoly.Count();
803 :
804 0 : if( nPolyCount )
805 : {
806 0 : if( 1 == nPolyCount )
807 0 : ImplWritePolygonRecord( rPolyPoly[ 0 ], sal_True );
808 : else
809 : {
810 0 : sal_Bool bHasFlags = sal_False;
811 0 : sal_uInt32 nTotalPoints = 0;
812 :
813 0 : for( i = 0; i < nPolyCount; i++ )
814 : {
815 0 : nTotalPoints += rPolyPoly[ i ].GetSize();
816 0 : if ( rPolyPoly[ i ].HasFlags() )
817 0 : bHasFlags = sal_True;
818 : }
819 0 : if( nTotalPoints )
820 : {
821 0 : if ( bHasFlags )
822 0 : ImplWritePath( rPolyPoly, sal_True );
823 : else
824 : {
825 0 : ImplCheckFillAttr();
826 0 : ImplCheckLineAttr();
827 :
828 0 : ImplBeginRecord( WIN_EMR_POLYPOLYGON );
829 0 : ImplWriteRect( rPolyPoly.GetBoundRect() );
830 0 : m_rStm << (sal_uInt32)nPolyCount << nTotalPoints;
831 :
832 0 : for( i = 0; i < nPolyCount; i++ )
833 0 : m_rStm << (sal_uInt32)rPolyPoly[ i ].GetSize();
834 :
835 0 : for( i = 0; i < nPolyCount; i++ )
836 : {
837 0 : const Polygon& rPoly = rPolyPoly[ i ];
838 :
839 0 : for( n = 0; n < rPoly.GetSize(); n++ )
840 0 : ImplWritePoint( rPoly[ n ] );
841 : }
842 0 : ImplEndRecord();
843 : }
844 : }
845 : }
846 : }
847 0 : }
848 :
849 : // -----------------------------------------------------------------------------
850 :
851 0 : void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed )
852 : {
853 0 : if ( bClosed )
854 0 : ImplCheckFillAttr();
855 0 : ImplCheckLineAttr();
856 :
857 0 : ImplBeginRecord( WIN_EMR_BEGINPATH );
858 0 : ImplEndRecord();
859 :
860 0 : sal_uInt16 i, n, o, nPolyCount = rPolyPoly.Count();
861 0 : for ( i = 0; i < nPolyCount; i++ )
862 : {
863 0 : n = 0;
864 0 : const Polygon& rPoly = rPolyPoly[ i ];
865 0 : while ( n < rPoly.GetSize() )
866 : {
867 0 : if( n == 0 )
868 : {
869 0 : ImplBeginRecord( WIN_EMR_MOVETOEX );
870 0 : ImplWritePoint( rPoly[ 0 ] );
871 0 : ImplEndRecord();
872 0 : n++;
873 0 : continue;
874 : }
875 :
876 0 : sal_uInt16 nBezPoints = 0;
877 :
878 0 : while ( ( ( nBezPoints + n + 2 ) < rPoly.GetSize() ) && ( rPoly.GetFlags( nBezPoints + n ) == POLY_CONTROL ) )
879 0 : nBezPoints += 3;
880 :
881 0 : if ( nBezPoints )
882 : {
883 0 : ImplBeginRecord( WIN_EMR_POLYBEZIERTO );
884 0 : Polygon aNewPoly( nBezPoints + 1 );
885 0 : aNewPoly[ 0 ] = rPoly[ n - 1 ];
886 0 : for ( o = 0; o < nBezPoints; o++ )
887 0 : aNewPoly[ o + 1 ] = rPoly[ n + o ];
888 0 : ImplWriteRect( aNewPoly.GetBoundRect() );
889 0 : m_rStm << (sal_uInt32)nBezPoints;
890 0 : for( o = 1; o < aNewPoly.GetSize(); o++ )
891 0 : ImplWritePoint( aNewPoly[ o ] );
892 0 : ImplEndRecord();
893 0 : n = n + nBezPoints;
894 : }
895 : else
896 : {
897 0 : sal_uInt16 nPoints = 1;
898 0 : while( ( nPoints + n ) < rPoly.GetSize() && ( rPoly.GetFlags( nPoints + n ) != POLY_CONTROL ) )
899 0 : nPoints++;
900 :
901 0 : if ( nPoints > 1 )
902 : {
903 0 : ImplBeginRecord( WIN_EMR_POLYLINETO );
904 0 : Polygon aNewPoly( nPoints + 1 );
905 0 : aNewPoly[ 0 ] = rPoly[ n - 1];
906 0 : for ( o = 1; o <= nPoints; o++ )
907 0 : aNewPoly[ o ] = rPoly[ n - 1 + o ];
908 0 : ImplWriteRect( aNewPoly.GetBoundRect() );
909 0 : m_rStm << (sal_uInt32)( nPoints );
910 0 : for( o = 1; o < aNewPoly.GetSize(); o++ )
911 0 : ImplWritePoint( aNewPoly[ o ] );
912 0 : ImplEndRecord();
913 : }
914 : else
915 : {
916 0 : ImplBeginRecord( WIN_EMR_LINETO );
917 0 : ImplWritePoint( rPoly[ n ] );
918 0 : ImplEndRecord();
919 : }
920 0 : n = n + nPoints;
921 : }
922 0 : if ( bClosed && ( n == rPoly.GetSize() ) )
923 : {
924 0 : ImplBeginRecord( WIN_EMR_CLOSEFIGURE );
925 0 : ImplEndRecord();
926 : }
927 : }
928 : }
929 0 : ImplBeginRecord( WIN_EMR_ENDPATH );
930 0 : ImplEndRecord();
931 0 : ImplBeginRecord( bClosed ? WIN_EMR_FILLPATH : WIN_EMR_STROKEPATH );
932 0 : ImplWriteRect( rPolyPoly.GetBoundRect() );
933 0 : ImplEndRecord();
934 0 : }
935 :
936 : // -----------------------------------------------------------------------------
937 :
938 0 : void EMFWriter::ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt,
939 : const Size& rSz, sal_uInt32 nROP )
940 : {
941 0 : if( !!rBmp )
942 : {
943 0 : SvMemoryStream aMemStm( 65535, 65535 );
944 0 : const Size aBmpSizePixel( rBmp.GetSizePixel() );
945 :
946 0 : ImplBeginRecord( WIN_EMR_STRETCHDIBITS );
947 0 : ImplWriteRect( Rectangle( rPt, rSz ) );
948 0 : ImplWritePoint( rPt );
949 0 : m_rStm << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) aBmpSizePixel.Width() << (sal_Int32) aBmpSizePixel.Height();
950 :
951 : // write offset positions and sizes later
952 0 : const sal_uLong nOffPos = m_rStm.Tell();
953 0 : m_rStm.SeekRel( 16 );
954 :
955 0 : m_rStm << (sal_uInt32) 0 << sal_Int32( ( ROP_XOR == maVDev.GetRasterOp() && WIN_SRCCOPY == nROP ) ? WIN_SRCINVERT : nROP );
956 0 : ImplWriteSize( rSz );
957 :
958 0 : rBmp.Write( aMemStm, sal_True, sal_False );
959 :
960 0 : sal_uInt32 nDIBSize = aMemStm.Tell(), nHeaderSize, nCompression, nColsUsed, nPalCount, nImageSize;
961 : sal_uInt16 nBitCount;
962 :
963 : // get DIB parameters
964 0 : aMemStm.Seek( 0 );
965 0 : aMemStm >> nHeaderSize;
966 0 : aMemStm.SeekRel( 10 );
967 0 : aMemStm >> nBitCount >> nCompression >> nImageSize;
968 0 : aMemStm.SeekRel( 8 );
969 0 : aMemStm >> nColsUsed;
970 :
971 : nPalCount = ( nBitCount <= 8 ) ? ( nColsUsed ? nColsUsed : ( 1 << (sal_uInt32) nBitCount ) ) :
972 0 : ( ( 3 == nCompression ) ? 12 : 0 );
973 :
974 0 : m_rStm.Write( aMemStm.GetData(), nDIBSize );
975 :
976 0 : const sal_uLong nEndPos = m_rStm.Tell();
977 0 : m_rStm.Seek( nOffPos );
978 0 : m_rStm << (sal_uInt32) 80 << (sal_uInt32)( nHeaderSize + ( nPalCount << 2 ) );
979 0 : m_rStm << (sal_uInt32)( 80 + ( nHeaderSize + ( nPalCount << 2 ) ) ) << nImageSize;
980 0 : m_rStm.Seek( nEndPos );
981 :
982 0 : ImplEndRecord();
983 : }
984 0 : }
985 :
986 : // -----------------------------------------------------------------------------
987 :
988 333 : void EMFWriter::ImplWriteTextRecord( const Point& rPos, const String rText, const sal_Int32* pDXArray, sal_uInt32 nWidth )
989 : {
990 333 : xub_StrLen nLen = rText.Len(), i;
991 :
992 333 : if( nLen )
993 : {
994 : sal_uInt32 nNormWidth;
995 : sal_Int32* pOwnArray;
996 : sal_Int32* pDX;
997 :
998 : // get text sizes
999 333 : if( pDXArray )
1000 : {
1001 2 : pOwnArray = NULL;
1002 2 : nNormWidth = maVDev.GetTextWidth( rText );
1003 2 : pDX = (sal_Int32*) pDXArray;
1004 : }
1005 : else
1006 : {
1007 331 : pOwnArray = new sal_Int32[ nLen ];
1008 331 : nNormWidth = maVDev.GetTextArray( rText, pOwnArray );
1009 331 : pDX = pOwnArray;
1010 : }
1011 :
1012 333 : if( nLen > 1 )
1013 : {
1014 23 : nNormWidth = pDX[ nLen - 2 ] + maVDev.GetTextWidth( rtl::OUString(rText.GetChar( nLen - 1 )) );
1015 :
1016 23 : if( nWidth && nNormWidth && ( nWidth != nNormWidth ) )
1017 : {
1018 20 : const double fFactor = (double) nWidth / nNormWidth;
1019 :
1020 60 : for( i = 0; i < ( nLen - 1 ); i++ )
1021 40 : pDX[ i ] = FRound( pDX[ i ] * fFactor );
1022 : }
1023 : }
1024 :
1025 : // write text record
1026 333 : ImplBeginRecord( WIN_EMR_EXTTEXTOUTW );
1027 :
1028 333 : ImplWriteRect( Rectangle( rPos, Size( nNormWidth, maVDev.GetTextHeight() ) ) );
1029 333 : m_rStm << (sal_uInt32)1;
1030 333 : m_rStm << (sal_Int32) 0 << (sal_Int32) 0;
1031 333 : ImplWritePoint( rPos );
1032 333 : m_rStm << (sal_uInt32) nLen << (sal_uInt32) 76 << (sal_uInt32) 2;
1033 333 : m_rStm << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) 0;
1034 333 : m_rStm << (sal_uInt32) ( 76 + ( nLen << 1 ) + ( (nLen & 1 ) ? 2 : 0 ) );
1035 :
1036 : // write text
1037 711 : for( i = 0; i < nLen; i++ )
1038 378 : m_rStm << (sal_Unicode)rText.GetChar( i );
1039 :
1040 : // padding word
1041 333 : if( nLen & 1 )
1042 326 : m_rStm << (sal_uInt16) 0;
1043 :
1044 : // write DX array
1045 333 : ImplWriteExtent( pDX[ 0 ] );
1046 :
1047 333 : if( nLen > 1 )
1048 : {
1049 45 : for( i = 1; i < ( nLen - 1 ); i++ )
1050 22 : ImplWriteExtent( pDX[ i ] - pDX[ i - 1 ] );
1051 :
1052 23 : ImplWriteExtent( pDX[ nLen - 2 ] / ( nLen - 1 ) );
1053 : }
1054 :
1055 333 : ImplEndRecord();
1056 333 : delete[] pOwnArray;
1057 : }
1058 333 : }
1059 :
1060 : // -----------------------------------------------------------------------------
1061 :
1062 0 : void EMFWriter::Impl_handleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
1063 : {
1064 0 : if(rLinePolygon.count())
1065 : {
1066 0 : basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
1067 0 : basegfx::B2DPolyPolygon aFillPolyPolygon;
1068 :
1069 0 : rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
1070 :
1071 0 : if(aLinePolyPolygon.count())
1072 : {
1073 0 : for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
1074 : {
1075 0 : const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
1076 0 : ImplWritePolygonRecord( Polygon(aCandidate), sal_False );
1077 0 : }
1078 : }
1079 :
1080 0 : if(aFillPolyPolygon.count())
1081 : {
1082 0 : const Color aOldLineColor(maVDev.GetLineColor());
1083 0 : const Color aOldFillColor(maVDev.GetFillColor());
1084 :
1085 0 : maVDev.SetLineColor();
1086 0 : maVDev.SetFillColor(aOldLineColor);
1087 :
1088 0 : for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
1089 : {
1090 0 : const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
1091 0 : ImplWritePolyPolygonRecord(PolyPolygon(Polygon(aPolygon)));
1092 0 : }
1093 :
1094 0 : maVDev.SetLineColor(aOldLineColor);
1095 0 : maVDev.SetFillColor(aOldFillColor);
1096 0 : }
1097 : }
1098 0 : }
1099 :
1100 : // -----------------------------------------------------------------------------
1101 :
1102 30 : void EMFWriter::ImplWrite( const GDIMetaFile& rMtf )
1103 : {
1104 2781 : for( size_t j = 0, nActionCount = rMtf.GetActionSize(); j < nActionCount; j++ )
1105 : {
1106 2751 : const MetaAction* pAction = rMtf.GetAction( j );
1107 2751 : const sal_uInt16 nType = pAction->GetType();
1108 :
1109 2751 : switch( nType )
1110 : {
1111 : case( META_PIXEL_ACTION ):
1112 : {
1113 0 : const MetaPixelAction* pA = (const MetaPixelAction*) pAction;
1114 :
1115 0 : ImplCheckLineAttr();
1116 0 : ImplBeginRecord( WIN_EMR_SETPIXELV );
1117 0 : ImplWritePoint( pA->GetPoint() );
1118 0 : ImplWriteColor( pA->GetColor() );
1119 0 : ImplEndRecord();
1120 : }
1121 0 : break;
1122 :
1123 : case( META_POINT_ACTION ):
1124 : {
1125 0 : if( maVDev.IsLineColor() )
1126 : {
1127 0 : const MetaPointAction* pA = (const MetaPointAction*) pAction;
1128 :
1129 0 : ImplCheckLineAttr();
1130 0 : ImplBeginRecord( WIN_EMR_SETPIXELV );
1131 0 : ImplWritePoint( pA->GetPoint() );
1132 0 : ImplWriteColor( maVDev.GetLineColor() );
1133 0 : ImplEndRecord();
1134 : }
1135 : }
1136 0 : break;
1137 :
1138 : case( META_LINE_ACTION ):
1139 : {
1140 0 : if( maVDev.IsLineColor() )
1141 : {
1142 0 : const MetaLineAction* pA = (const MetaLineAction*) pAction;
1143 :
1144 0 : if(pA->GetLineInfo().IsDefault())
1145 : {
1146 0 : ImplCheckLineAttr();
1147 :
1148 0 : ImplBeginRecord( WIN_EMR_MOVETOEX );
1149 0 : ImplWritePoint( pA->GetStartPoint() );
1150 0 : ImplEndRecord();
1151 :
1152 0 : ImplBeginRecord( WIN_EMR_LINETO );
1153 0 : ImplWritePoint( pA->GetEndPoint() );
1154 0 : ImplEndRecord();
1155 :
1156 0 : ImplBeginRecord( WIN_EMR_SETPIXELV );
1157 0 : ImplWritePoint( pA->GetEndPoint() );
1158 0 : ImplWriteColor( maVDev.GetLineColor() );
1159 0 : ImplEndRecord();
1160 : }
1161 : else
1162 : {
1163 : // LineInfo used; handle Dash/Dot and fat lines
1164 0 : basegfx::B2DPolygon aPolygon;
1165 0 : aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
1166 0 : aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
1167 0 : Impl_handleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
1168 : }
1169 : }
1170 : }
1171 0 : break;
1172 :
1173 : case( META_RECT_ACTION ):
1174 : {
1175 19 : if( maVDev.IsLineColor() || maVDev.IsFillColor() )
1176 : {
1177 19 : const MetaRectAction* pA = (const MetaRectAction*) pAction;
1178 :
1179 19 : ImplCheckFillAttr();
1180 19 : ImplCheckLineAttr();
1181 :
1182 19 : ImplBeginRecord( WIN_EMR_RECTANGLE );
1183 19 : ImplWriteRect( pA->GetRect() );
1184 19 : ImplEndRecord();
1185 : }
1186 : }
1187 19 : break;
1188 :
1189 : case( META_ROUNDRECT_ACTION ):
1190 : {
1191 0 : if( maVDev.IsLineColor() || maVDev.IsFillColor() )
1192 : {
1193 0 : const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pAction;
1194 :
1195 0 : ImplCheckFillAttr();
1196 0 : ImplCheckLineAttr();
1197 :
1198 0 : ImplBeginRecord( WIN_EMR_ROUNDRECT );
1199 0 : ImplWriteRect( pA->GetRect() );
1200 0 : ImplWriteSize( Size( pA->GetHorzRound(), pA->GetVertRound() ) );
1201 0 : ImplEndRecord();
1202 : }
1203 : }
1204 0 : break;
1205 :
1206 : case( META_ELLIPSE_ACTION ):
1207 : {
1208 0 : if( maVDev.IsLineColor() || maVDev.IsFillColor() )
1209 : {
1210 0 : const MetaEllipseAction* pA = (const MetaEllipseAction*) pAction;
1211 :
1212 0 : ImplCheckFillAttr();
1213 0 : ImplCheckLineAttr();
1214 :
1215 0 : ImplBeginRecord( WIN_EMR_ELLIPSE );
1216 0 : ImplWriteRect( pA->GetRect() );
1217 0 : ImplEndRecord();
1218 : }
1219 : }
1220 0 : break;
1221 :
1222 : case( META_ARC_ACTION ):
1223 : case( META_PIE_ACTION ):
1224 : case( META_CHORD_ACTION ):
1225 : case( META_POLYGON_ACTION ):
1226 : {
1227 0 : if( maVDev.IsLineColor() || maVDev.IsFillColor() )
1228 : {
1229 0 : Polygon aPoly;
1230 :
1231 0 : switch( nType )
1232 : {
1233 : case( META_ARC_ACTION ):
1234 : {
1235 0 : const MetaArcAction* pA = (const MetaArcAction*) pAction;
1236 0 : aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_ARC );
1237 : }
1238 0 : break;
1239 :
1240 : case( META_PIE_ACTION ):
1241 : {
1242 0 : const MetaPieAction* pA = (const MetaPieAction*) pAction;
1243 0 : aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_PIE );
1244 : }
1245 0 : break;
1246 :
1247 : case( META_CHORD_ACTION ):
1248 : {
1249 0 : const MetaChordAction* pA = (const MetaChordAction*) pAction;
1250 0 : aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_CHORD );
1251 : }
1252 0 : break;
1253 :
1254 : case( META_POLYGON_ACTION ):
1255 0 : aPoly = ( (const MetaPolygonAction*) pAction )->GetPolygon();
1256 0 : break;
1257 : }
1258 :
1259 0 : ImplWritePolygonRecord( aPoly, nType != META_ARC_ACTION );
1260 : }
1261 : }
1262 0 : break;
1263 :
1264 : case( META_POLYLINE_ACTION ):
1265 : {
1266 0 : if( maVDev.IsLineColor() )
1267 : {
1268 0 : const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pAction;
1269 0 : const Polygon& rPoly = pA->GetPolygon();
1270 :
1271 0 : if( rPoly.GetSize() )
1272 : {
1273 0 : if(pA->GetLineInfo().IsDefault())
1274 : {
1275 0 : ImplWritePolygonRecord( rPoly, sal_False );
1276 : }
1277 : else
1278 : {
1279 : // LineInfo used; handle Dash/Dot and fat lines
1280 0 : Impl_handleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
1281 : }
1282 : }
1283 : }
1284 : }
1285 0 : break;
1286 :
1287 : case( META_POLYPOLYGON_ACTION ):
1288 : {
1289 0 : if( maVDev.IsLineColor() || maVDev.IsFillColor() )
1290 0 : ImplWritePolyPolygonRecord( ( (const MetaPolyPolygonAction*) pAction )->GetPolyPolygon() );
1291 : }
1292 0 : break;
1293 :
1294 : case( META_GRADIENT_ACTION ):
1295 : {
1296 0 : const MetaGradientAction* pA = (const MetaGradientAction*) pAction;
1297 0 : GDIMetaFile aTmpMtf;
1298 :
1299 0 : maVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
1300 0 : ImplWrite( aTmpMtf );
1301 : }
1302 0 : break;
1303 :
1304 : case META_HATCH_ACTION:
1305 : {
1306 0 : const MetaHatchAction* pA = (const MetaHatchAction*) pAction;
1307 0 : GDIMetaFile aTmpMtf;
1308 :
1309 0 : maVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
1310 0 : ImplWrite( aTmpMtf );
1311 : }
1312 0 : break;
1313 :
1314 : case META_TRANSPARENT_ACTION:
1315 : {
1316 0 : const PolyPolygon& rPolyPoly = ( (MetaTransparentAction*) pAction )->GetPolyPolygon();
1317 0 : if( rPolyPoly.Count() )
1318 0 : ImplWritePlusFillPolygonRecord( rPolyPoly[0], ( (MetaTransparentAction*)pAction)->GetTransparence() );
1319 0 : ImplCheckFillAttr();
1320 0 : ImplCheckLineAttr();
1321 0 : ImplWritePolyPolygonRecord( rPolyPoly );
1322 :
1323 0 : ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
1324 0 : ImplPlusRecord( EmfPlusGetDC, 0x00 );
1325 0 : ImplEndCommentRecord();
1326 : }
1327 0 : break;
1328 :
1329 : case META_FLOATTRANSPARENT_ACTION:
1330 : {
1331 0 : const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pAction;
1332 :
1333 0 : GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
1334 0 : Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
1335 0 : const Size aSrcSize( aTmpMtf.GetPrefSize() );
1336 0 : const Point aDestPt( pA->GetPoint() );
1337 0 : const Size aDestSize( pA->GetSize() );
1338 0 : const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
1339 0 : const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
1340 : long nMoveX, nMoveY;
1341 :
1342 0 : if( fScaleX != 1.0 || fScaleY != 1.0 )
1343 : {
1344 0 : aTmpMtf.Scale( fScaleX, fScaleY );
1345 0 : aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
1346 : }
1347 :
1348 0 : nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
1349 :
1350 0 : if( nMoveX || nMoveY )
1351 0 : aTmpMtf.Move( nMoveX, nMoveY );
1352 :
1353 0 : ImplCheckFillAttr();
1354 0 : ImplCheckLineAttr();
1355 0 : ImplCheckTextAttr();
1356 0 : ImplWrite( aTmpMtf );
1357 : }
1358 0 : break;
1359 :
1360 : case( META_EPS_ACTION ):
1361 : {
1362 0 : const MetaEPSAction* pA = (const MetaEPSAction*) pAction;
1363 0 : const GDIMetaFile aSubstitute( pA->GetSubstitute() );
1364 :
1365 0 : for( size_t i = 0, nCount = aSubstitute.GetActionSize(); i < nCount; i++ )
1366 : {
1367 0 : const MetaAction* pSubstAct = aSubstitute.GetAction( i );
1368 0 : if( pSubstAct->GetType() == META_BMPSCALE_ACTION )
1369 : {
1370 0 : maVDev.Push( PUSH_ALL );
1371 0 : ImplBeginRecord( WIN_EMR_SAVEDC );
1372 0 : ImplEndRecord();
1373 :
1374 0 : MapMode aMapMode( aSubstitute.GetPrefMapMode() );
1375 0 : Size aOutSize( maVDev.LogicToLogic( pA->GetSize(), maVDev.GetMapMode(), aMapMode ) );
1376 0 : aMapMode.SetScaleX( Fraction( aOutSize.Width(), aSubstitute.GetPrefSize().Width() ) );
1377 0 : aMapMode.SetScaleY( Fraction( aOutSize.Height(), aSubstitute.GetPrefSize().Height() ) );
1378 0 : aMapMode.SetOrigin( maVDev.LogicToLogic( pA->GetPoint(), maVDev.GetMapMode(), aMapMode ) );
1379 0 : maVDev.SetMapMode( aMapMode );
1380 0 : ImplWrite( aSubstitute );
1381 :
1382 0 : maVDev.Pop();
1383 0 : ImplBeginRecord( WIN_EMR_RESTOREDC );
1384 0 : m_rStm << (sal_Int32) -1;
1385 0 : ImplEndRecord();
1386 0 : break;
1387 : }
1388 0 : }
1389 : }
1390 0 : break;
1391 :
1392 : case META_BMP_ACTION:
1393 : {
1394 0 : const MetaBmpAction* pA = (const MetaBmpAction *) pAction;
1395 0 : ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), maVDev.PixelToLogic( pA->GetBitmap().GetSizePixel() ), WIN_SRCCOPY );
1396 : }
1397 0 : break;
1398 :
1399 : case META_BMPSCALE_ACTION:
1400 : {
1401 0 : const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction;
1402 0 : ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
1403 : }
1404 0 : break;
1405 :
1406 : case META_BMPSCALEPART_ACTION:
1407 : {
1408 0 : const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pAction;
1409 0 : Bitmap aTmp( pA->GetBitmap() );
1410 :
1411 0 : if( aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
1412 0 : ImplWriteBmpRecord( aTmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
1413 : }
1414 0 : break;
1415 :
1416 : case META_BMPEX_ACTION:
1417 : {
1418 0 : const MetaBmpExAction* pA = (const MetaBmpExAction *) pAction;
1419 0 : Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
1420 0 : Bitmap aMsk( pA->GetBitmapEx().GetMask() );
1421 :
1422 0 : if( !!aMsk )
1423 : {
1424 0 : aBmp.Replace( aMsk, COL_WHITE );
1425 0 : aMsk.Invert();
1426 0 : ImplWriteBmpRecord( aMsk, pA->GetPoint(), maVDev.PixelToLogic( aMsk.GetSizePixel() ), WIN_SRCPAINT );
1427 0 : ImplWriteBmpRecord( aBmp, pA->GetPoint(), maVDev.PixelToLogic( aBmp.GetSizePixel() ), WIN_SRCAND );
1428 : }
1429 : else
1430 0 : ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCCOPY );
1431 : }
1432 0 : break;
1433 :
1434 : case META_BMPEXSCALE_ACTION:
1435 : {
1436 0 : const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction;
1437 0 : Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
1438 0 : Bitmap aMsk( pA->GetBitmapEx().GetMask() );
1439 :
1440 0 : if( !!aMsk )
1441 : {
1442 0 : aBmp.Replace( aMsk, COL_WHITE );
1443 0 : aMsk.Invert();
1444 0 : ImplWriteBmpRecord( aMsk, pA->GetPoint(), pA->GetSize(), WIN_SRCPAINT );
1445 0 : ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCAND );
1446 : }
1447 : else
1448 0 : ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
1449 : }
1450 0 : break;
1451 :
1452 : case META_BMPEXSCALEPART_ACTION:
1453 : {
1454 0 : const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pAction;
1455 0 : BitmapEx aBmpEx( pA->GetBitmapEx() );
1456 0 : aBmpEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
1457 0 : Bitmap aBmp( aBmpEx.GetBitmap() );
1458 0 : Bitmap aMsk( aBmpEx.GetMask() );
1459 :
1460 0 : if( !!aMsk )
1461 : {
1462 0 : aBmp.Replace( aMsk, COL_WHITE );
1463 0 : aMsk.Invert();
1464 0 : ImplWriteBmpRecord( aMsk, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCPAINT );
1465 0 : ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCAND );
1466 : }
1467 : else
1468 0 : ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
1469 : }
1470 0 : break;
1471 :
1472 : case META_TEXT_ACTION:
1473 : {
1474 0 : const MetaTextAction* pA = (const MetaTextAction*) pAction;
1475 0 : const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
1476 :
1477 0 : ImplCheckTextAttr();
1478 0 : ImplWriteTextRecord( pA->GetPoint(), aText, NULL, 0 );
1479 : }
1480 0 : break;
1481 :
1482 : case META_TEXTRECT_ACTION:
1483 : {
1484 0 : const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction;
1485 0 : const String aText( pA->GetText() );
1486 :
1487 0 : ImplCheckTextAttr();
1488 0 : ImplWriteTextRecord( pA->GetRect().TopLeft(), aText, NULL, 0 );
1489 : }
1490 0 : break;
1491 :
1492 : case META_TEXTARRAY_ACTION:
1493 : {
1494 2 : const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pAction;
1495 2 : const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
1496 :
1497 2 : ImplCheckTextAttr();
1498 2 : ImplWriteTextRecord( pA->GetPoint(), aText, pA->GetDXArray(), 0 );
1499 : }
1500 2 : break;
1501 :
1502 : case META_STRETCHTEXT_ACTION:
1503 : {
1504 331 : const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction;
1505 331 : const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
1506 :
1507 331 : ImplCheckTextAttr();
1508 331 : ImplWriteTextRecord( pA->GetPoint(), aText, NULL, pA->GetWidth() );
1509 : }
1510 331 : break;
1511 :
1512 : case( META_LINECOLOR_ACTION ):
1513 : {
1514 21 : ( (MetaAction*) pAction )->Execute( &maVDev );
1515 21 : mbLineChanged = sal_True;
1516 : }
1517 21 : break;
1518 :
1519 : case( META_FILLCOLOR_ACTION ):
1520 : {
1521 19 : ( (MetaAction*) pAction )->Execute( &maVDev );
1522 19 : mbFillChanged = sal_True;
1523 : }
1524 19 : break;
1525 :
1526 : case( META_TEXTCOLOR_ACTION ):
1527 : case( META_TEXTLINECOLOR_ACTION ):
1528 : case( META_TEXTFILLCOLOR_ACTION ):
1529 : case( META_TEXTALIGN_ACTION ):
1530 : case( META_FONT_ACTION ):
1531 : {
1532 1408 : ( (MetaAction*) pAction )->Execute( &maVDev );
1533 1408 : mbTextChanged = sal_True;
1534 : }
1535 1408 : break;
1536 :
1537 : case( META_ISECTRECTCLIPREGION_ACTION ):
1538 : {
1539 29 : ( (MetaAction*) pAction )->Execute( &maVDev );
1540 :
1541 29 : ImplBeginRecord( WIN_EMR_INTERSECTCLIPRECT );
1542 29 : ImplWriteRect( ( (MetaISectRectClipRegionAction*) pAction )->GetRect() );
1543 29 : ImplEndRecord();
1544 : }
1545 29 : break;
1546 :
1547 : case( META_CLIPREGION_ACTION ):
1548 : case( META_ISECTREGIONCLIPREGION_ACTION ):
1549 : case( META_MOVECLIPREGION_ACTION ):
1550 : {
1551 4 : ( (MetaAction*) pAction )->Execute( &maVDev );
1552 : }
1553 4 : break;
1554 :
1555 : case( META_REFPOINT_ACTION ):
1556 : case( META_MAPMODE_ACTION ):
1557 0 : ( (MetaAction*) pAction )->Execute( &maVDev );
1558 0 : break;
1559 :
1560 : case( META_PUSH_ACTION ):
1561 : {
1562 384 : ( (MetaAction*) pAction )->Execute( &maVDev );
1563 :
1564 384 : ImplBeginRecord( WIN_EMR_SAVEDC );
1565 384 : ImplEndRecord();
1566 : }
1567 384 : break;
1568 :
1569 : case( META_POP_ACTION ):
1570 : {
1571 384 : ( (MetaAction*) pAction )->Execute( &maVDev );
1572 :
1573 384 : ImplBeginRecord( WIN_EMR_RESTOREDC );
1574 384 : m_rStm << (sal_Int32) -1;
1575 384 : ImplEndRecord();
1576 :
1577 384 : ImplWriteRasterOp( maVDev.GetRasterOp() );
1578 384 : mbLineChanged = mbFillChanged = mbTextChanged = sal_True;
1579 : }
1580 384 : break;
1581 :
1582 : case( META_RASTEROP_ACTION ):
1583 : {
1584 0 : ( (MetaAction*) pAction )->Execute( &maVDev );
1585 0 : ImplWriteRasterOp( ( (MetaRasterOpAction*) pAction )->GetRasterOp() );
1586 : }
1587 0 : break;
1588 :
1589 : case( META_LAYOUTMODE_ACTION ):
1590 : {
1591 60 : sal_uInt32 nLayoutMode = ( (MetaLayoutModeAction*) pAction )->GetLayoutMode();
1592 60 : mnHorTextAlign = 0;
1593 60 : if (nLayoutMode & TEXT_LAYOUT_BIDI_RTL)
1594 : {
1595 0 : mnHorTextAlign = TA_RIGHT | TA_RTLREADING;
1596 : }
1597 60 : if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_RIGHT)
1598 0 : mnHorTextAlign |= TA_RIGHT;
1599 60 : else if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_LEFT)
1600 0 : mnHorTextAlign &= ~TA_RIGHT;
1601 60 : break;
1602 : }
1603 :
1604 : case( META_MASK_ACTION ):
1605 : case( META_MASKSCALE_ACTION ):
1606 : case( META_MASKSCALEPART_ACTION ):
1607 : case( META_WALLPAPER_ACTION ):
1608 : case( META_TEXTLINE_ACTION ):
1609 : case( META_COMMENT_ACTION ):
1610 : case( META_GRADIENTEX_ACTION ):
1611 : {
1612 : // !!! >>> we don't want to support these actions
1613 : }
1614 0 : break;
1615 :
1616 : default:
1617 : OSL_FAIL(rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM(
1618 : "EMFWriter::ImplWriteActions: unsupported MetaAction #" )).
1619 : append(static_cast<sal_Int32>(nType)).getStr());
1620 90 : break;
1621 : }
1622 : }
1623 30 : }
1624 :
1625 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|