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