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