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