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 <algorithm>
21 : #include <string.h>
22 : #include <osl/thread.h>
23 : #include <tools/debug.hxx>
24 : #include <tools/stream.hxx>
25 : #include <tools/helpers.hxx>
26 : #include <vcl/dibtools.hxx>
27 : #include <vcl/virdev.hxx>
28 : #include <vcl/graph.hxx>
29 : #include <vcl/lineinfo.hxx>
30 : #include <rtl/strbuf.hxx>
31 :
32 : #include <cvtsvm.hxx>
33 : #include <boost/scoped_array.hpp>
34 :
35 : // Inlines
36 0 : void ImplReadRect( SvStream& rIStm, Rectangle& rRect )
37 : {
38 0 : Point aTL;
39 0 : Point aBR;
40 :
41 0 : ReadPair( rIStm, aTL );
42 0 : ReadPair( rIStm, aBR );
43 :
44 0 : rRect = Rectangle( aTL, aBR );
45 0 : }
46 :
47 0 : void ImplWriteRect( SvStream& rOStm, const Rectangle& rRect )
48 : {
49 0 : WritePair( rOStm, rRect.TopLeft() );
50 0 : WritePair( rOStm, rRect.BottomRight() );
51 0 : }
52 :
53 0 : void ImplReadPoly( SvStream& rIStm, Polygon& rPoly )
54 : {
55 : sal_Int32 nSize;
56 :
57 0 : rIStm.ReadInt32( nSize );
58 0 : rPoly = Polygon( (sal_uInt16) nSize );
59 :
60 0 : for( sal_uInt16 i = 0; i < (sal_uInt16) nSize; i++ )
61 0 : ReadPair( rIStm, rPoly[ i ] );
62 0 : }
63 :
64 0 : void ImplReadPolyPoly( SvStream& rIStm, tools::PolyPolygon& rPolyPoly )
65 : {
66 0 : Polygon aPoly;
67 : sal_Int32 nPolyCount;
68 :
69 0 : rIStm.ReadInt32( nPolyCount );
70 :
71 0 : for( sal_uInt16 i = 0; i < (sal_uInt16) nPolyCount; i++ )
72 : {
73 0 : ImplReadPoly( rIStm, aPoly );
74 0 : rPolyPoly.Insert( aPoly );
75 0 : }
76 0 : }
77 :
78 0 : void ImplWritePolyPolyAction( SvStream& rOStm, const tools::PolyPolygon& rPolyPoly )
79 : {
80 0 : const sal_uInt16 nPoly = rPolyPoly.Count();
81 0 : sal_uInt16 nPoints = 0;
82 : sal_uInt16 n;
83 :
84 0 : for( n = 0; n < nPoly; n++ )
85 0 : nPoints = sal::static_int_cast<sal_uInt16>(nPoints + rPolyPoly[ n ].GetSize());
86 :
87 0 : rOStm.WriteInt16( GDI_POLYPOLYGON_ACTION );
88 0 : rOStm.WriteInt32( ( 8 + ( nPoly << 2 ) + ( nPoints << 3 ) ) );
89 0 : rOStm.WriteInt32( nPoly );
90 :
91 0 : for( n = 0; n < nPoly; n++ )
92 : {
93 : // #i102224# Here the possible curved nature of Polygon was
94 : // ignored (for all those years). Adapted to at least write
95 : // a polygon representing the curve as good as possible
96 0 : Polygon aSimplePoly;
97 0 : rPolyPoly[n].AdaptiveSubdivide(aSimplePoly);
98 0 : const sal_uInt16 nSize(aSimplePoly.GetSize());
99 :
100 0 : rOStm.WriteInt32( nSize );
101 :
102 0 : for( sal_uInt16 j = 0; j < nSize; j++ )
103 0 : WritePair( rOStm, aSimplePoly[ j ] );
104 0 : }
105 0 : }
106 :
107 0 : void ImplReadColor( SvStream& rIStm, Color& rColor )
108 : {
109 : sal_Int16 nVal;
110 :
111 0 : rIStm.ReadInt16( nVal ); rColor.SetRed( sal::static_int_cast<sal_uInt8>((sal_uInt16)nVal >> 8) );
112 0 : rIStm.ReadInt16( nVal ); rColor.SetGreen( sal::static_int_cast<sal_uInt8>((sal_uInt16)nVal >> 8) );
113 0 : rIStm.ReadInt16( nVal ); rColor.SetBlue( sal::static_int_cast<sal_uInt8>((sal_uInt16)nVal >> 8) );
114 0 : }
115 :
116 0 : void ImplWriteColor( SvStream& rOStm, const Color& rColor )
117 : {
118 : sal_Int16 nVal;
119 :
120 0 : nVal = ( (sal_Int16) rColor.GetRed() << 8 ) | rColor.GetRed();
121 0 : rOStm.WriteInt16( nVal );
122 :
123 0 : nVal = ( (sal_Int16) rColor.GetGreen() << 8 ) | rColor.GetGreen();
124 0 : rOStm.WriteInt16( nVal );
125 :
126 0 : nVal = ( (sal_Int16) rColor.GetBlue() << 8 ) | rColor.GetBlue();
127 0 : rOStm.WriteInt16( nVal );
128 0 : }
129 :
130 0 : void ImplReadMapMode( SvStream& rIStm, MapMode& rMapMode )
131 : {
132 0 : Point aOrg;
133 : sal_Int32 nXNum;
134 : sal_Int32 nXDenom;
135 : sal_Int32 nYNum;
136 : sal_Int32 nYDenom;
137 : sal_Int16 nUnit;
138 :
139 0 : rIStm.ReadInt16( nUnit );
140 0 : ReadPair( rIStm, aOrg );
141 0 : rIStm.ReadInt32( nXNum ).ReadInt32( nXDenom ).ReadInt32( nYNum ).ReadInt32( nYDenom );
142 0 : rMapMode = MapMode( (MapUnit) nUnit, aOrg, Fraction( nXNum, nXDenom ), Fraction( nYNum, nYDenom ) );
143 0 : }
144 :
145 0 : void ImplWriteMapMode( SvStream& rOStm, const MapMode& rMapMode )
146 : {
147 0 : rOStm.WriteInt16( rMapMode.GetMapUnit() );
148 0 : WritePair( rOStm, rMapMode.GetOrigin() );
149 0 : rOStm.WriteInt32( rMapMode.GetScaleX().GetNumerator() );
150 0 : rOStm.WriteInt32( rMapMode.GetScaleX().GetDenominator() );
151 0 : rOStm.WriteInt32( rMapMode.GetScaleY().GetNumerator() );
152 0 : rOStm.WriteInt32( rMapMode.GetScaleY().GetDenominator() );
153 0 : }
154 :
155 0 : void ImplWritePushAction( SvStream& rOStm )
156 : {
157 0 : rOStm.WriteInt16( GDI_PUSH_ACTION );
158 0 : rOStm.WriteInt32( 4 );
159 0 : }
160 :
161 0 : void ImplWritePopAction( SvStream& rOStm )
162 : {
163 0 : rOStm.WriteInt16( GDI_POP_ACTION );
164 0 : rOStm.WriteInt32( 4 );
165 0 : }
166 :
167 0 : void ImplWriteLineColor( SvStream& rOStm, const Color& rColor, sal_Int16 nStyle, sal_Int32 nWidth = 0 )
168 : {
169 0 : if( rColor.GetTransparency() > 127 )
170 0 : nStyle = 0;
171 :
172 0 : rOStm.WriteInt16( GDI_PEN_ACTION );
173 0 : rOStm.WriteInt32( 16 );
174 0 : ImplWriteColor( rOStm, rColor );
175 0 : rOStm.WriteInt32( nWidth );
176 0 : rOStm.WriteInt16( nStyle );
177 0 : }
178 :
179 0 : void ImplWriteFillColor( SvStream& rOStm, const Color& rColor, sal_Int16 nStyle )
180 : {
181 0 : rOStm.WriteInt16( GDI_FILLBRUSH_ACTION );
182 0 : rOStm.WriteInt32( 20 );
183 0 : ImplWriteColor( rOStm, rColor );
184 :
185 0 : if( rColor.GetTransparency() > 127 )
186 0 : nStyle = 0;
187 :
188 0 : if( nStyle > 1 )
189 : {
190 0 : ImplWriteColor( rOStm, COL_WHITE );
191 0 : rOStm.WriteInt16( nStyle );
192 0 : rOStm.WriteInt16( 1 );
193 : }
194 : else
195 : {
196 0 : ImplWriteColor( rOStm, COL_BLACK );
197 0 : rOStm.WriteInt16( nStyle );
198 0 : rOStm.WriteInt16( 0 );
199 : }
200 0 : }
201 :
202 0 : void ImplWriteFont( SvStream& rOStm, const vcl::Font& rFont,
203 : rtl_TextEncoding& rActualCharSet )
204 : {
205 : char aName[33];
206 : short nWeight;
207 :
208 0 : OString aByteName(OUStringToOString(rFont.GetName(),
209 0 : rOStm.GetStreamCharSet()));
210 0 : strncpy( aName, aByteName.getStr(), 32 );
211 0 : aName[32] = 0;
212 :
213 0 : switch ( rFont.GetWeight() )
214 : {
215 : case WEIGHT_THIN:
216 : case WEIGHT_ULTRALIGHT:
217 : case WEIGHT_LIGHT:
218 0 : nWeight = 1;
219 0 : break;
220 :
221 : case WEIGHT_NORMAL:
222 : case WEIGHT_MEDIUM:
223 0 : nWeight = 2;
224 0 : break;
225 :
226 : case WEIGHT_BOLD:
227 : case WEIGHT_ULTRABOLD:
228 : case WEIGHT_BLACK:
229 0 : nWeight = 3;
230 0 : break;
231 :
232 : default:
233 0 : nWeight = 0;
234 0 : break;
235 : }
236 :
237 0 : rOStm.WriteInt16( GDI_FONT_ACTION );
238 0 : rOStm.WriteInt32( 78 );
239 :
240 0 : rActualCharSet = GetStoreCharSet( rFont.GetCharSet() );
241 0 : ImplWriteColor( rOStm, rFont.GetColor() );
242 0 : ImplWriteColor( rOStm, rFont.GetFillColor() );
243 0 : rOStm.Write( aName, 32 );
244 0 : WritePair( rOStm, rFont.GetSize() );
245 0 : rOStm.WriteInt16( 0 ); // no character orientation anymore
246 0 : rOStm.WriteInt16( rFont.GetOrientation() );
247 0 : rOStm.WriteInt16( rActualCharSet );
248 0 : rOStm.WriteInt16( rFont.GetFamily() );
249 0 : rOStm.WriteInt16( rFont.GetPitch() );
250 0 : rOStm.WriteInt16( rFont.GetAlign() );
251 0 : rOStm.WriteInt16( nWeight );
252 0 : rOStm.WriteInt16( rFont.GetUnderline() );
253 0 : rOStm.WriteInt16( rFont.GetStrikeout() );
254 0 : rOStm.WriteUChar( rFont.GetItalic() != ITALIC_NONE );
255 0 : rOStm.WriteUChar( rFont.IsOutline() );
256 0 : rOStm.WriteUChar( rFont.IsShadow() );
257 0 : rOStm.WriteUChar( rFont.IsTransparent() );
258 0 : if ( rActualCharSet == RTL_TEXTENCODING_DONTKNOW )
259 0 : rActualCharSet = osl_getThreadTextEncoding();
260 0 : }
261 :
262 0 : void ImplWriteRasterOpAction( SvStream& rOStm, sal_Int16 nRasterOp )
263 : {
264 0 : rOStm.WriteInt16( GDI_RASTEROP_ACTION ).WriteInt32( 6 ).WriteInt16( nRasterOp );
265 0 : }
266 :
267 0 : bool ImplWriteUnicodeComment( SvStream& rOStm, const OUString& rString )
268 : {
269 0 : sal_Int32 nStringLen = rString.getLength();
270 0 : if ( nStringLen )
271 : {
272 0 : sal_uInt32 nSize = ( nStringLen << 1 ) + 4;
273 0 : sal_uInt16 nType = GDI_UNICODE_COMMENT;
274 :
275 0 : rOStm.WriteUInt16( nType ).WriteUInt32( nSize );
276 0 : write_uInt16s_FromOUString(rOStm, rString);
277 : }
278 0 : return nStringLen != 0;
279 : }
280 :
281 0 : void ImplReadUnicodeComment( sal_uInt32 nStrmPos, SvStream& rIStm, OUString& rString )
282 : {
283 0 : sal_uInt32 nOld = rIStm.Tell();
284 0 : if ( nStrmPos )
285 : {
286 : sal_uInt16 nType;
287 : sal_uInt32 nActionSize;
288 : sal_Size nStringLen;
289 :
290 0 : rIStm.Seek( nStrmPos );
291 0 : rIStm .ReadUInt16( nType )
292 0 : .ReadUInt32( nActionSize );
293 :
294 0 : nStringLen = (nActionSize - 4) >> 1;
295 :
296 0 : if ( nStringLen && ( nType == GDI_UNICODE_COMMENT ) )
297 0 : rString = read_uInt16s_ToOUString(rIStm, nStringLen);
298 : }
299 0 : rIStm.Seek( nOld );
300 0 : }
301 :
302 0 : void ImplSkipActions( SvStream& rIStm, sal_uLong nSkipCount )
303 : {
304 : sal_Int32 nActionSize;
305 : sal_Int16 nType;
306 :
307 0 : for( sal_uLong i = 0UL; i < nSkipCount; i++ )
308 : {
309 0 : rIStm.ReadInt16( nType ).ReadInt32( nActionSize );
310 0 : rIStm.SeekRel( nActionSize - 4L );
311 : }
312 0 : }
313 :
314 0 : bool ImplWriteExtendedPolyPolygonAction(SvStream& rOStm, const tools::PolyPolygon& rPolyPolygon, bool bOnlyWhenCurve)
315 : {
316 0 : const sal_uInt16 nPolygonCount(rPolyPolygon.Count());
317 :
318 0 : if(nPolygonCount)
319 : {
320 0 : sal_uInt32 nAllPolygonCount(0);
321 0 : sal_uInt32 nAllPointCount(0);
322 0 : sal_uInt32 nAllFlagCount(0);
323 0 : sal_uInt16 a(0);
324 :
325 0 : for(a = 0; a < nPolygonCount; a++)
326 : {
327 0 : const Polygon& rCandidate = rPolyPolygon.GetObject(a);
328 0 : const sal_uInt16 nPointCount(rCandidate.GetSize());
329 :
330 0 : if(nPointCount)
331 : {
332 0 : nAllPolygonCount++;
333 0 : nAllPointCount += nPointCount;
334 :
335 0 : if(rCandidate.HasFlags())
336 : {
337 0 : nAllFlagCount += nPointCount;
338 : }
339 : }
340 : }
341 :
342 0 : if((bOnlyWhenCurve && nAllFlagCount) || (!bOnlyWhenCurve && nAllPointCount))
343 : {
344 0 : rOStm.WriteInt16( GDI_EXTENDEDPOLYGON_ACTION );
345 :
346 : const sal_Int32 nActionSize(
347 : 4 + // Action size
348 0 : 2 + // PolygonCount
349 0 : (nAllPolygonCount * 2) + // Points per polygon
350 0 : (nAllPointCount << 3) + // Points themselves
351 0 : nAllPolygonCount + // Bool if (when poly has points) it has flags, too
352 0 : nAllFlagCount); // Flags themselves
353 :
354 0 : rOStm.WriteInt32( nActionSize );
355 0 : rOStm.WriteUInt16( nAllPolygonCount );
356 :
357 0 : for(a = 0; a < nPolygonCount; a++)
358 : {
359 0 : const Polygon& rCandidate = rPolyPolygon.GetObject(a);
360 0 : const sal_uInt16 nPointCount(rCandidate.GetSize());
361 :
362 0 : if(nPointCount)
363 : {
364 0 : rOStm.WriteUInt16( nPointCount );
365 :
366 0 : for(sal_uInt16 b(0); b < nPointCount; b++)
367 : {
368 0 : WritePair( rOStm, rCandidate[b] );
369 : }
370 :
371 0 : if(rCandidate.HasFlags())
372 : {
373 0 : rOStm.WriteUChar( true );
374 :
375 0 : for(sal_uInt16 c(0); c < nPointCount; c++)
376 : {
377 0 : rOStm.WriteUChar( rCandidate.GetFlags(c) );
378 : }
379 : }
380 : else
381 : {
382 0 : rOStm.WriteUChar( false );
383 : }
384 : }
385 : }
386 :
387 0 : return true;
388 : }
389 : }
390 :
391 0 : return false;
392 : }
393 :
394 0 : void ImplReadExtendedPolyPolygonAction(SvStream& rIStm, tools::PolyPolygon& rPolyPoly)
395 : {
396 0 : rPolyPoly.Clear();
397 0 : sal_uInt16 nPolygonCount(0);
398 0 : rIStm.ReadUInt16( nPolygonCount );
399 :
400 0 : if (!nPolygonCount)
401 0 : return;
402 :
403 0 : for(sal_uInt16 a(0); a < nPolygonCount; a++)
404 : {
405 0 : sal_uInt16 nPointCount(0);
406 0 : rIStm.ReadUInt16( nPointCount );
407 0 : Polygon aCandidate(nPointCount);
408 :
409 0 : if(nPointCount)
410 : {
411 0 : for(sal_uInt16 b(0); b < nPointCount; b++)
412 : {
413 0 : ReadPair( rIStm , aCandidate[b] );
414 : }
415 :
416 0 : sal_uInt8 bHasFlags(false);
417 0 : rIStm.ReadUChar( bHasFlags );
418 :
419 0 : if(bHasFlags)
420 : {
421 0 : sal_uInt8 aPolyFlags(0);
422 :
423 0 : for(sal_uInt16 c(0); c < nPointCount; c++)
424 : {
425 0 : rIStm.ReadUChar( aPolyFlags );
426 0 : aCandidate.SetFlags(c, (PolyFlags)aPolyFlags);
427 : }
428 : }
429 : }
430 :
431 0 : rPolyPoly.Insert(aCandidate);
432 0 : }
433 : }
434 :
435 18 : SVMConverter::SVMConverter( SvStream& rStm, GDIMetaFile& rMtf, sal_uLong nConvertMode )
436 : {
437 18 : if( !rStm.GetError() )
438 : {
439 18 : if( CONVERT_FROM_SVM1 == nConvertMode )
440 18 : ImplConvertFromSVM1( rStm, rMtf );
441 0 : else if( CONVERT_TO_SVM1 == nConvertMode )
442 0 : ImplConvertToSVM1( rStm, rMtf );
443 : }
444 18 : }
445 :
446 18 : void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf )
447 : {
448 18 : const sal_uLong nPos = rIStm.Tell();
449 18 : const sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt();
450 :
451 18 : rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
452 :
453 : char aCode[ 5 ];
454 18 : Size aPrefSz;
455 : sal_Int16 nSize;
456 : sal_Int16 nVersion;
457 :
458 : // read header
459 18 : rIStm.Read( (char*) &aCode, sizeof( aCode ) ); // Identifier
460 18 : rIStm.ReadInt16( nSize ); // Size
461 18 : rIStm.ReadInt16( nVersion ); // Version
462 18 : sal_Int32 nTmp32(0);
463 18 : rIStm.ReadInt32( nTmp32 );
464 18 : aPrefSz.Width() = nTmp32; // PrefSize.Width()
465 18 : rIStm.ReadInt32( nTmp32 );
466 18 : aPrefSz.Height() = nTmp32; // PrefSize.Height()
467 :
468 : // check header-magic and version
469 36 : if( rIStm.GetError()
470 18 : || ( memcmp( aCode, "SVGDI", sizeof( aCode ) ) != 0 )
471 18 : || ( nVersion != 200 ) )
472 : {
473 18 : rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
474 18 : rIStm.SetNumberFormatInt( nOldFormat );
475 18 : rIStm.Seek( nPos );
476 36 : return;
477 : }
478 :
479 0 : LineInfo aLineInfo( LINE_NONE, 0 );
480 0 : ::std::stack< LineInfo* > aLIStack;
481 0 : VirtualDevice aFontVDev;
482 0 : rtl_TextEncoding eActualCharSet = osl_getThreadTextEncoding();
483 0 : bool bFatLine = false;
484 :
485 : // TODO: fix reindentation below if you can accept being blamed by the SCM
486 0 : MapMode aMapMode;
487 0 : Polygon aActionPoly;
488 0 : Rectangle aRect;
489 0 : Point aPt, aPt1;
490 0 : Size aSz;
491 0 : Color aActionColor;
492 : sal_Int32 nTmp, nTmp1, nActionSize;
493 : sal_Int32 nActions;
494 : sal_Int16 nType;
495 :
496 0 : sal_uInt32 nUnicodeCommentStreamPos = 0;
497 0 : sal_Int32 nUnicodeCommentActionNumber = 0;
498 :
499 0 : ImplReadMapMode( rIStm, aMapMode ); // MapMode
500 0 : rIStm.ReadInt32( nActions ); // Action count
501 :
502 0 : rMtf.SetPrefSize( aPrefSz );
503 0 : rMtf.SetPrefMapMode( aMapMode );
504 0 : size_t nLastPolygonAction(0);
505 :
506 0 : for (sal_Int32 i = 0; i < nActions; ++i)
507 : {
508 0 : rIStm.ReadInt16( nType );
509 0 : sal_Int32 nActBegin = rIStm.Tell();
510 0 : rIStm.ReadInt32( nActionSize );
511 :
512 : DBG_ASSERT( ( nType <= 33 ) || ( nType >= 1024 ), "Unknown GDIMetaAction while converting!" );
513 :
514 0 : switch( nType )
515 : {
516 : case( GDI_PIXEL_ACTION ):
517 : {
518 0 : ReadPair( rIStm, aPt );
519 0 : ImplReadColor( rIStm, aActionColor );
520 0 : rMtf.AddAction( new MetaPixelAction( aPt, aActionColor ) );
521 : }
522 0 : break;
523 :
524 : case( GDI_POINT_ACTION ):
525 : {
526 0 : ReadPair( rIStm, aPt );
527 0 : rMtf.AddAction( new MetaPointAction( aPt ) );
528 : }
529 0 : break;
530 :
531 : case( GDI_LINE_ACTION ):
532 : {
533 0 : ReadPair( rIStm, aPt );
534 0 : ReadPair( rIStm, aPt1 );
535 0 : rMtf.AddAction( new MetaLineAction( aPt, aPt1, aLineInfo ) );
536 : }
537 0 : break;
538 :
539 : case (GDI_LINEJOIN_ACTION) :
540 : {
541 0 : sal_Int16 nLineJoin(0);
542 0 : rIStm.ReadInt16( nLineJoin );
543 0 : aLineInfo.SetLineJoin((basegfx::B2DLineJoin)nLineJoin);
544 : }
545 0 : break;
546 :
547 : case (GDI_LINECAP_ACTION) :
548 : {
549 0 : sal_Int16 nLineCap(0);
550 0 : rIStm.ReadInt16( nLineCap );
551 0 : aLineInfo.SetLineCap((com::sun::star::drawing::LineCap)nLineCap);
552 : }
553 0 : break;
554 :
555 : case (GDI_LINEDASHDOT_ACTION) :
556 : {
557 0 : sal_Int16 a(0);
558 0 : sal_Int32 b(0);
559 :
560 0 : rIStm.ReadInt16( a ); aLineInfo.SetDashCount(a);
561 0 : rIStm.ReadInt32( b ); aLineInfo.SetDashLen(b);
562 0 : rIStm.ReadInt16( a ); aLineInfo.SetDotCount(a);
563 0 : rIStm.ReadInt32( b ); aLineInfo.SetDotLen(b);
564 0 : rIStm.ReadInt32( b ); aLineInfo.SetDistance(b);
565 :
566 0 : if(((aLineInfo.GetDashCount() && aLineInfo.GetDashLen())
567 0 : || (aLineInfo.GetDotCount() && aLineInfo.GetDotLen()))
568 0 : && aLineInfo.GetDistance())
569 : {
570 0 : aLineInfo.SetStyle(LINE_DASH);
571 : }
572 : }
573 0 : break;
574 :
575 : case (GDI_EXTENDEDPOLYGON_ACTION) :
576 : {
577 : // read the tools::PolyPolygon in every case
578 0 : tools::PolyPolygon aInputPolyPolygon;
579 0 : ImplReadExtendedPolyPolygonAction(rIStm, aInputPolyPolygon);
580 :
581 : // now check if it can be set somewhere
582 0 : if(nLastPolygonAction < rMtf.GetActionSize())
583 : {
584 0 : MetaPolyLineAction* pPolyLineAction = dynamic_cast< MetaPolyLineAction* >(rMtf.GetAction(nLastPolygonAction));
585 :
586 0 : if(pPolyLineAction)
587 : {
588 : // replace MetaPolyLineAction when we have a single polygon. Do not rely on the
589 : // same point count; the originally written GDI_POLYLINE_ACTION may have been
590 : // Subdivided for better quality for older usages
591 0 : if(1 == aInputPolyPolygon.Count())
592 : {
593 : MetaAction* pAction = rMtf.ReplaceAction(
594 : new MetaPolyLineAction(
595 : aInputPolyPolygon.GetObject(0),
596 0 : pPolyLineAction->GetLineInfo()),
597 0 : nLastPolygonAction);
598 0 : if(pAction)
599 0 : pAction->Delete();
600 : }
601 : }
602 : else
603 : {
604 0 : MetaPolyPolygonAction* pPolyPolygonAction = dynamic_cast< MetaPolyPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
605 :
606 0 : if(pPolyPolygonAction)
607 : {
608 : // replace MetaPolyPolygonAction when we have a curved polygon. Do rely on the
609 : // same sub-polygon count
610 0 : if(pPolyPolygonAction->GetPolyPolygon().Count() == aInputPolyPolygon.Count())
611 : {
612 : MetaAction* pAction = rMtf.ReplaceAction(
613 : new MetaPolyPolygonAction(
614 0 : aInputPolyPolygon),
615 0 : nLastPolygonAction);
616 0 : if(pAction)
617 0 : pAction->Delete();
618 : }
619 : }
620 : else
621 : {
622 0 : MetaPolygonAction* pPolygonAction = dynamic_cast< MetaPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
623 :
624 0 : if(pPolygonAction)
625 : {
626 : // replace MetaPolygonAction
627 0 : if(1 == aInputPolyPolygon.Count())
628 : {
629 : MetaAction* pAction = rMtf.ReplaceAction(
630 : new MetaPolygonAction(
631 0 : aInputPolyPolygon.GetObject(0)),
632 0 : nLastPolygonAction);
633 0 : if(pAction)
634 0 : pAction->Delete();
635 : }
636 : }
637 : }
638 : }
639 0 : }
640 : }
641 0 : break;
642 :
643 : case( GDI_RECT_ACTION ):
644 : {
645 0 : ImplReadRect( rIStm, aRect );
646 0 : rIStm.ReadInt32( nTmp ).ReadInt32( nTmp1 );
647 :
648 0 : if( nTmp || nTmp1 )
649 0 : rMtf.AddAction( new MetaRoundRectAction( aRect, nTmp, nTmp1 ) );
650 : else
651 : {
652 0 : rMtf.AddAction( new MetaRectAction( aRect ) );
653 :
654 0 : if( bFatLine )
655 0 : rMtf.AddAction( new MetaPolyLineAction( aRect, aLineInfo ) );
656 : }
657 : }
658 0 : break;
659 :
660 : case( GDI_ELLIPSE_ACTION ):
661 : {
662 0 : ImplReadRect( rIStm, aRect );
663 :
664 0 : if( bFatLine )
665 : {
666 0 : const Polygon aPoly( aRect.Center(), aRect.GetWidth() >> 1, aRect.GetHeight() >> 1 );
667 :
668 0 : rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
669 0 : rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
670 0 : rMtf.AddAction( new MetaPolygonAction( aPoly ) );
671 0 : rMtf.AddAction( new MetaPopAction() );
672 0 : rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
673 : }
674 : else
675 0 : rMtf.AddAction( new MetaEllipseAction( aRect ) );
676 : }
677 0 : break;
678 :
679 : case( GDI_ARC_ACTION ):
680 : {
681 0 : ImplReadRect( rIStm, aRect );
682 0 : ReadPair( rIStm, aPt );
683 0 : ReadPair( rIStm, aPt1 );
684 :
685 0 : if( bFatLine )
686 : {
687 0 : const Polygon aPoly( aRect, aPt, aPt1, POLY_ARC );
688 :
689 0 : rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
690 0 : rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
691 0 : rMtf.AddAction( new MetaPolygonAction( aPoly ) );
692 0 : rMtf.AddAction( new MetaPopAction() );
693 0 : rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
694 : }
695 : else
696 0 : rMtf.AddAction( new MetaArcAction( aRect, aPt, aPt1 ) );
697 : }
698 0 : break;
699 :
700 : case( GDI_PIE_ACTION ):
701 : {
702 0 : ImplReadRect( rIStm, aRect );
703 0 : ReadPair( rIStm, aPt );
704 0 : ReadPair( rIStm, aPt1 );
705 :
706 0 : if( bFatLine )
707 : {
708 0 : const Polygon aPoly( aRect, aPt, aPt1, POLY_PIE );
709 :
710 0 : rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
711 0 : rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
712 0 : rMtf.AddAction( new MetaPolygonAction( aPoly ) );
713 0 : rMtf.AddAction( new MetaPopAction() );
714 0 : rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
715 : }
716 : else
717 0 : rMtf.AddAction( new MetaPieAction( aRect, aPt, aPt1 ) );
718 : }
719 0 : break;
720 :
721 : case( GDI_INVERTRECT_ACTION ):
722 : case( GDI_HIGHLIGHTRECT_ACTION ):
723 : {
724 0 : ImplReadRect( rIStm, aRect );
725 0 : rMtf.AddAction( new MetaPushAction( PushFlags::RASTEROP ) );
726 0 : rMtf.AddAction( new MetaRasterOpAction( ROP_INVERT ) );
727 0 : rMtf.AddAction( new MetaRectAction( aRect ) );
728 0 : rMtf.AddAction( new MetaPopAction() );
729 : }
730 0 : break;
731 :
732 : case( GDI_POLYLINE_ACTION ):
733 : {
734 0 : ImplReadPoly( rIStm, aActionPoly );
735 0 : nLastPolygonAction = rMtf.GetActionSize();
736 :
737 0 : if( bFatLine )
738 0 : rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
739 : else
740 0 : rMtf.AddAction( new MetaPolyLineAction( aActionPoly ) );
741 : }
742 0 : break;
743 :
744 : case( GDI_POLYGON_ACTION ):
745 : {
746 0 : ImplReadPoly( rIStm, aActionPoly );
747 :
748 0 : if( bFatLine )
749 : {
750 0 : rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
751 0 : rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
752 0 : rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
753 0 : rMtf.AddAction( new MetaPopAction() );
754 0 : rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
755 : }
756 : else
757 : {
758 0 : nLastPolygonAction = rMtf.GetActionSize();
759 0 : rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
760 : }
761 : }
762 0 : break;
763 :
764 : case( GDI_POLYPOLYGON_ACTION ):
765 : {
766 0 : tools::PolyPolygon aPolyPoly;
767 :
768 0 : ImplReadPolyPoly( rIStm, aPolyPoly );
769 :
770 0 : if( bFatLine )
771 : {
772 0 : rMtf.AddAction( new MetaPushAction( PushFlags::LINECOLOR ) );
773 0 : rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, false ) );
774 0 : rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
775 0 : rMtf.AddAction( new MetaPopAction() );
776 :
777 0 : for( sal_uInt16 nPoly = 0, nCount = aPolyPoly.Count(); nPoly < nCount; nPoly++ )
778 0 : rMtf.AddAction( new MetaPolyLineAction( aPolyPoly[ nPoly ], aLineInfo ) );
779 : }
780 : else
781 : {
782 0 : nLastPolygonAction = rMtf.GetActionSize();
783 0 : rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
784 0 : }
785 : }
786 0 : break;
787 :
788 : case( GDI_FONT_ACTION ):
789 : {
790 0 : vcl::Font aFont;
791 : char aName[ 32 ];
792 : sal_Int32 nWidth, nHeight;
793 : sal_Int16 nCharSet, nFamily, nPitch, nAlign, nWeight, nUnderline, nStrikeout;
794 : sal_Int16 nCharOrient, nLineOrient;
795 : bool bItalic, bOutline, bShadow, bTransparent;
796 :
797 0 : ImplReadColor( rIStm, aActionColor ); aFont.SetColor( aActionColor );
798 0 : ImplReadColor( rIStm, aActionColor ); aFont.SetFillColor( aActionColor );
799 0 : rIStm.Read( aName, 32 );
800 0 : aFont.SetName( OUString( aName, strlen(aName), rIStm.GetStreamCharSet() ) );
801 0 : rIStm.ReadInt32( nWidth ).ReadInt32( nHeight );
802 0 : rIStm.ReadInt16( nCharOrient ).ReadInt16( nLineOrient );
803 0 : rIStm.ReadInt16( nCharSet ).ReadInt16( nFamily ).ReadInt16( nPitch ).ReadInt16( nAlign ).ReadInt16( nWeight ).ReadInt16( nUnderline ).ReadInt16( nStrikeout );
804 0 : rIStm.ReadCharAsBool( bItalic ).ReadCharAsBool( bOutline ).ReadCharAsBool( bShadow ).ReadCharAsBool( bTransparent );
805 :
806 0 : aFont.SetSize( Size( nWidth, nHeight ) );
807 0 : aFont.SetCharSet( (rtl_TextEncoding) nCharSet );
808 0 : aFont.SetFamily( (FontFamily) nFamily );
809 0 : aFont.SetPitch( (FontPitch) nPitch );
810 0 : aFont.SetAlign( (FontAlign) nAlign );
811 0 : aFont.SetWeight( ( nWeight == 1 ) ? WEIGHT_LIGHT : ( nWeight == 2 ) ? WEIGHT_NORMAL :
812 0 : ( nWeight == 3 ) ? WEIGHT_BOLD : WEIGHT_DONTKNOW );
813 0 : aFont.SetUnderline( (FontUnderline) nUnderline );
814 0 : aFont.SetStrikeout( (FontStrikeout) nStrikeout );
815 0 : aFont.SetItalic( bItalic ? ITALIC_NORMAL : ITALIC_NONE );
816 0 : aFont.SetOutline( bOutline );
817 0 : aFont.SetShadow( bShadow );
818 0 : aFont.SetOrientation( nLineOrient );
819 0 : aFont.SetTransparent( bTransparent );
820 :
821 0 : eActualCharSet = aFont.GetCharSet();
822 0 : if ( eActualCharSet == RTL_TEXTENCODING_DONTKNOW )
823 0 : eActualCharSet = osl_getThreadTextEncoding();
824 :
825 0 : rMtf.AddAction( new MetaFontAction( aFont ) );
826 0 : rMtf.AddAction( new MetaTextAlignAction( aFont.GetAlign() ) );
827 0 : rMtf.AddAction( new MetaTextColorAction( aFont.GetColor() ) );
828 0 : rMtf.AddAction( new MetaTextFillColorAction( aFont.GetFillColor(), !aFont.IsTransparent() ) );
829 :
830 : // #106172# Track font relevant data in shadow VDev
831 0 : aFontVDev.SetFont( aFont );
832 : }
833 0 : break;
834 :
835 : case( GDI_TEXT_ACTION ):
836 : {
837 : sal_Int32 nIndex, nLen;
838 :
839 0 : ReadPair( rIStm, aPt ).ReadInt32( nIndex ).ReadInt32( nLen ).ReadInt32( nTmp );
840 0 : if (nTmp > 0)
841 : {
842 0 : OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
843 0 : sal_uInt8 nTerminator = 0;
844 0 : rIStm.ReadUChar( nTerminator );
845 : DBG_ASSERT( nTerminator == 0, "expected string to be NULL terminated" );
846 :
847 0 : OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
848 0 : if ( nUnicodeCommentActionNumber == i )
849 0 : ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
850 0 : rMtf.AddAction( new MetaTextAction( aPt, aStr, nIndex, nLen ) );
851 : }
852 0 : rIStm.Seek( nActBegin + nActionSize );
853 : }
854 0 : break;
855 :
856 : case( GDI_TEXTARRAY_ACTION ):
857 : {
858 : sal_Int32 nIndex, nLen, nAryLen;
859 :
860 0 : ReadPair( rIStm, aPt ).ReadInt32( nIndex ).ReadInt32( nLen ).ReadInt32( nTmp ).ReadInt32( nAryLen );
861 0 : if (nTmp > 0)
862 : {
863 0 : OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
864 0 : sal_uInt8 nTerminator = 0;
865 0 : rIStm.ReadUChar( nTerminator );
866 : DBG_ASSERT( nTerminator == 0, "expected string to be NULL terminated" );
867 :
868 0 : OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
869 :
870 0 : boost::scoped_array<long> pDXAry;
871 0 : if (nAryLen > 0)
872 : {
873 0 : sal_Int32 nStrLen( aStr.getLength() );
874 :
875 0 : pDXAry.reset(new long[ std::max( nAryLen, nStrLen ) ]);
876 :
877 0 : for (sal_Int32 j = 0; j < nAryLen; ++j)
878 0 : rIStm.ReadInt32( nTmp ), pDXAry[ j ] = nTmp;
879 :
880 : // #106172# Add last DX array elem, if missing
881 0 : if( nAryLen != nStrLen )
882 : {
883 0 : if( nAryLen+1 == nStrLen )
884 : {
885 0 : boost::scoped_array<long> pTmpAry(new long[nStrLen]);
886 :
887 0 : aFontVDev.GetTextArray( aStr, pTmpAry.get(), nIndex, nLen );
888 :
889 : // now, the difference between the
890 : // last and the second last DX array
891 : // is the advancement for the last
892 : // glyph. Thus, to complete our meta
893 : // action's DX array, just add that
894 : // difference to last elem and store
895 : // in very last.
896 0 : if( nStrLen > 1 )
897 0 : pDXAry[ nStrLen-1 ] = pDXAry[ nStrLen-2 ] + pTmpAry[ nStrLen-1 ] - pTmpAry[ nStrLen-2 ];
898 : else
899 0 : pDXAry[ nStrLen-1 ] = pTmpAry[ nStrLen-1 ]; // len=1: 0th position taken to be 0
900 : }
901 : #ifdef DBG_UTIL
902 : else
903 : OSL_FAIL("More than one DX array element missing on SVM import");
904 : #endif
905 : }
906 : }
907 0 : if ( nUnicodeCommentActionNumber == i )
908 0 : ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
909 0 : rMtf.AddAction( new MetaTextArrayAction( aPt, aStr, pDXAry.get(), nIndex, nLen ) );
910 : }
911 0 : rIStm.Seek( nActBegin + nActionSize );
912 : }
913 0 : break;
914 :
915 : case( GDI_STRETCHTEXT_ACTION ):
916 : {
917 : sal_Int32 nIndex, nLen, nWidth;
918 :
919 0 : ReadPair( rIStm, aPt ).ReadInt32( nIndex ).ReadInt32( nLen ).ReadInt32( nTmp ).ReadInt32( nWidth );
920 0 : if (nTmp > 0)
921 : {
922 0 : OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
923 0 : sal_uInt8 nTerminator = 0;
924 0 : rIStm.ReadUChar( nTerminator );
925 : DBG_ASSERT( nTerminator == 0, "expected string to be NULL terminated" );
926 :
927 0 : OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
928 0 : if ( nUnicodeCommentActionNumber == i )
929 0 : ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
930 0 : rMtf.AddAction( new MetaStretchTextAction( aPt, nWidth, aStr, nIndex, nLen ) );
931 : }
932 0 : rIStm.Seek( nActBegin + nActionSize );
933 : }
934 0 : break;
935 :
936 : case( GDI_BITMAP_ACTION ):
937 : {
938 0 : Bitmap aBmp;
939 :
940 0 : ReadPair( rIStm, aPt );
941 0 : ReadDIB(aBmp, rIStm, true);
942 0 : rMtf.AddAction( new MetaBmpAction( aPt, aBmp ) );
943 : }
944 0 : break;
945 :
946 : case( GDI_BITMAPSCALE_ACTION ):
947 : {
948 0 : Bitmap aBmp;
949 :
950 0 : ReadPair( rIStm, aPt );
951 0 : ReadPair( rIStm, aSz );
952 0 : ReadDIB(aBmp, rIStm, true);
953 0 : rMtf.AddAction( new MetaBmpScaleAction( aPt, aSz, aBmp ) );
954 : }
955 0 : break;
956 :
957 : case( GDI_BITMAPSCALEPART_ACTION ):
958 : {
959 0 : Bitmap aBmp;
960 0 : Size aSz2;
961 :
962 0 : ReadPair( rIStm, aPt );
963 0 : ReadPair( rIStm, aSz );
964 0 : ReadPair( rIStm, aPt1 );
965 0 : ReadPair( rIStm, aSz2 );
966 0 : ReadDIB(aBmp, rIStm, true);
967 0 : rMtf.AddAction( new MetaBmpScalePartAction( aPt, aSz, aPt1, aSz2, aBmp ) );
968 : }
969 0 : break;
970 :
971 : case( GDI_PEN_ACTION ):
972 : {
973 : sal_Int32 nPenWidth;
974 : sal_Int16 nPenStyle;
975 :
976 0 : ImplReadColor( rIStm, aActionColor );
977 0 : rIStm.ReadInt32( nPenWidth ).ReadInt16( nPenStyle );
978 :
979 0 : aLineInfo.SetStyle( nPenStyle ? LINE_SOLID : LINE_NONE );
980 0 : aLineInfo.SetWidth( nPenWidth );
981 0 : bFatLine = nPenStyle && !aLineInfo.IsDefault();
982 :
983 0 : rMtf.AddAction( new MetaLineColorAction( aActionColor, nPenStyle != 0 ) );
984 : }
985 0 : break;
986 :
987 : case( GDI_FILLBRUSH_ACTION ):
988 : {
989 : sal_Int16 nBrushStyle;
990 :
991 0 : ImplReadColor( rIStm, aActionColor );
992 0 : rIStm.SeekRel( 6L );
993 0 : rIStm.ReadInt16( nBrushStyle );
994 0 : rMtf.AddAction( new MetaFillColorAction( aActionColor, nBrushStyle != 0 ) );
995 0 : rIStm.SeekRel( 2L );
996 : }
997 0 : break;
998 :
999 : case( GDI_MAPMODE_ACTION ):
1000 : {
1001 0 : ImplReadMapMode( rIStm, aMapMode );
1002 0 : rMtf.AddAction( new MetaMapModeAction( aMapMode ) );
1003 :
1004 : // #106172# Track font relevant data in shadow VDev
1005 0 : aFontVDev.SetMapMode( aMapMode );
1006 : }
1007 0 : break;
1008 :
1009 : case( GDI_CLIPREGION_ACTION ):
1010 : {
1011 0 : vcl::Region aRegion;
1012 : sal_Int16 nRegType;
1013 : sal_Int16 bIntersect;
1014 0 : bool bClip = false;
1015 :
1016 0 : rIStm.ReadInt16( nRegType ).ReadInt16( bIntersect );
1017 0 : ImplReadRect( rIStm, aRect );
1018 :
1019 0 : switch( nRegType )
1020 : {
1021 : case( 0 ):
1022 0 : break;
1023 :
1024 : case( 1 ):
1025 : {
1026 0 : Rectangle aRegRect;
1027 :
1028 0 : ImplReadRect( rIStm, aRegRect );
1029 0 : aRegion = vcl::Region( aRegRect );
1030 0 : bClip = true;
1031 : }
1032 0 : break;
1033 :
1034 : case( 2 ):
1035 : {
1036 0 : ImplReadPoly( rIStm, aActionPoly );
1037 0 : aRegion = vcl::Region( aActionPoly );
1038 0 : bClip = true;
1039 : }
1040 0 : break;
1041 :
1042 : case( 3 ):
1043 : {
1044 0 : tools::PolyPolygon aPolyPoly;
1045 : sal_Int32 nPolyCount;
1046 :
1047 0 : rIStm.ReadInt32( nPolyCount );
1048 :
1049 0 : for( sal_uInt16 j = 0; j < (sal_uInt16) nPolyCount; j++ )
1050 : {
1051 0 : ImplReadPoly( rIStm, aActionPoly );
1052 0 : aPolyPoly.Insert( aActionPoly );
1053 : }
1054 :
1055 0 : aRegion = vcl::Region( aPolyPoly );
1056 0 : bClip = true;
1057 : }
1058 0 : break;
1059 : }
1060 :
1061 0 : if( bIntersect )
1062 0 : aRegion.Intersect( aRect );
1063 :
1064 0 : rMtf.AddAction( new MetaClipRegionAction( aRegion, bClip ) );
1065 : }
1066 0 : break;
1067 :
1068 : case( GDI_MOVECLIPREGION_ACTION ):
1069 : {
1070 0 : rIStm.ReadInt32( nTmp ).ReadInt32( nTmp1 );
1071 0 : rMtf.AddAction( new MetaMoveClipRegionAction( nTmp, nTmp1 ) );
1072 : }
1073 0 : break;
1074 :
1075 : case( GDI_ISECTCLIPREGION_ACTION ):
1076 : {
1077 0 : ImplReadRect( rIStm, aRect );
1078 0 : rMtf.AddAction( new MetaISectRectClipRegionAction( aRect ) );
1079 : }
1080 0 : break;
1081 :
1082 : case( GDI_RASTEROP_ACTION ):
1083 : {
1084 : RasterOp eRasterOp;
1085 : sal_Int16 nRasterOp;
1086 :
1087 0 : rIStm.ReadInt16( nRasterOp );
1088 :
1089 0 : switch( nRasterOp )
1090 : {
1091 : case( 1 ):
1092 0 : eRasterOp = ROP_INVERT;
1093 0 : break;
1094 :
1095 : case( 4 ):
1096 : case( 5 ):
1097 0 : eRasterOp = ROP_XOR;
1098 0 : break;
1099 :
1100 : default:
1101 0 : eRasterOp = ROP_OVERPAINT;
1102 0 : break;
1103 : }
1104 :
1105 0 : rMtf.AddAction( new MetaRasterOpAction( eRasterOp ) );
1106 : }
1107 0 : break;
1108 :
1109 : case( GDI_PUSH_ACTION ):
1110 : {
1111 0 : aLIStack.push( new LineInfo( aLineInfo ) );
1112 0 : rMtf.AddAction( new MetaPushAction( PushFlags::ALL ) );
1113 :
1114 : // #106172# Track font relevant data in shadow VDev
1115 0 : aFontVDev.Push();
1116 : }
1117 0 : break;
1118 :
1119 : case( GDI_POP_ACTION ):
1120 : {
1121 :
1122 : LineInfo* pLineInfo;
1123 0 : if (aLIStack.empty())
1124 0 : pLineInfo = NULL;
1125 : else
1126 : {
1127 0 : pLineInfo = aLIStack.top();
1128 0 : aLIStack.pop();
1129 : }
1130 :
1131 : // restore line info
1132 0 : if( pLineInfo )
1133 : {
1134 0 : aLineInfo = *pLineInfo;
1135 0 : delete pLineInfo;
1136 0 : bFatLine = ( LINE_NONE != aLineInfo.GetStyle() ) && !aLineInfo.IsDefault();
1137 : }
1138 :
1139 0 : rMtf.AddAction( new MetaPopAction() );
1140 :
1141 : // #106172# Track font relevant data in shadow VDev
1142 0 : aFontVDev.Pop();
1143 : }
1144 0 : break;
1145 :
1146 : case( GDI_GRADIENT_ACTION ):
1147 : {
1148 0 : Color aStartCol;
1149 0 : Color aEndCol;
1150 : sal_Int16 nStyle;
1151 : sal_Int16 nAngle;
1152 : sal_Int16 nBorder;
1153 : sal_Int16 nOfsX;
1154 : sal_Int16 nOfsY;
1155 : sal_Int16 nIntensityStart;
1156 : sal_Int16 nIntensityEnd;
1157 :
1158 0 : ImplReadRect( rIStm, aRect );
1159 0 : rIStm.ReadInt16( nStyle );
1160 0 : ImplReadColor( rIStm, aStartCol );
1161 0 : ImplReadColor( rIStm, aEndCol );
1162 0 : rIStm.ReadInt16( nAngle ).ReadInt16( nBorder ).ReadInt16( nOfsX ).ReadInt16( nOfsY ).ReadInt16( nIntensityStart ).ReadInt16( nIntensityEnd );
1163 :
1164 0 : Gradient aGrad( (GradientStyle) nStyle, aStartCol, aEndCol );
1165 :
1166 0 : aGrad.SetAngle( nAngle );
1167 0 : aGrad.SetBorder( nBorder );
1168 0 : aGrad.SetOfsX( nOfsX );
1169 0 : aGrad.SetOfsY( nOfsY );
1170 0 : aGrad.SetStartIntensity( nIntensityStart );
1171 0 : aGrad.SetEndIntensity( nIntensityEnd );
1172 0 : rMtf.AddAction( new MetaGradientAction( aRect, aGrad ) );
1173 : }
1174 0 : break;
1175 :
1176 : case( GDI_TRANSPARENT_COMMENT ):
1177 : {
1178 0 : tools::PolyPolygon aPolyPoly;
1179 : sal_Int32 nFollowingActionCount;
1180 : sal_Int16 nTrans;
1181 :
1182 0 : ReadPolyPolygon( rIStm, aPolyPoly );
1183 0 : rIStm.ReadInt16( nTrans ).ReadInt32( nFollowingActionCount );
1184 0 : ImplSkipActions( rIStm, nFollowingActionCount );
1185 0 : rMtf.AddAction( new MetaTransparentAction( aPolyPoly, nTrans ) );
1186 :
1187 0 : i += nFollowingActionCount;
1188 : }
1189 0 : break;
1190 :
1191 : case( GDI_FLOATTRANSPARENT_COMMENT ):
1192 : {
1193 0 : GDIMetaFile aMtf;
1194 0 : Point aPos;
1195 0 : Size aSize;
1196 0 : Gradient aGradient;
1197 : sal_Int32 nFollowingActionCount;
1198 :
1199 0 : ReadGDIMetaFile( rIStm, aMtf );
1200 0 : ReadPair( rIStm, aPos );
1201 0 : ReadPair( rIStm, aSize );
1202 0 : ReadGradient( rIStm, aGradient );
1203 0 : rIStm.ReadInt32( nFollowingActionCount );
1204 0 : ImplSkipActions( rIStm, nFollowingActionCount );
1205 0 : rMtf.AddAction( new MetaFloatTransparentAction( aMtf, aPos, aSize, aGradient ) );
1206 :
1207 0 : i += nFollowingActionCount;
1208 : }
1209 0 : break;
1210 :
1211 : case( GDI_HATCH_COMMENT ):
1212 : {
1213 0 : tools::PolyPolygon aPolyPoly;
1214 0 : Hatch aHatch;
1215 : sal_Int32 nFollowingActionCount;
1216 :
1217 0 : ReadPolyPolygon( rIStm, aPolyPoly );
1218 0 : ReadHatch( rIStm, aHatch );
1219 0 : rIStm.ReadInt32( nFollowingActionCount );
1220 0 : ImplSkipActions( rIStm, nFollowingActionCount );
1221 0 : rMtf.AddAction( new MetaHatchAction( aPolyPoly, aHatch ) );
1222 :
1223 0 : i += nFollowingActionCount;
1224 : }
1225 0 : break;
1226 :
1227 : case( GDI_REFPOINT_COMMENT ):
1228 : {
1229 0 : Point aRefPoint;
1230 : bool bSet;
1231 : sal_Int32 nFollowingActionCount;
1232 :
1233 0 : ReadPair( rIStm, aRefPoint );
1234 0 : rIStm.ReadCharAsBool( bSet ).ReadInt32( nFollowingActionCount );
1235 0 : ImplSkipActions( rIStm, nFollowingActionCount );
1236 0 : rMtf.AddAction( new MetaRefPointAction( aRefPoint, bSet ) );
1237 :
1238 0 : i += nFollowingActionCount;
1239 :
1240 : // #106172# Track font relevant data in shadow VDev
1241 0 : if( bSet )
1242 0 : aFontVDev.SetRefPoint( aRefPoint );
1243 : else
1244 0 : aFontVDev.SetRefPoint();
1245 : }
1246 0 : break;
1247 :
1248 : case( GDI_TEXTLINECOLOR_COMMENT ):
1249 : {
1250 0 : Color aColor;
1251 : bool bSet;
1252 : sal_Int32 nFollowingActionCount;
1253 :
1254 0 : ReadColor( rIStm, aColor );
1255 0 : rIStm.ReadCharAsBool( bSet ).ReadInt32( nFollowingActionCount );
1256 0 : ImplSkipActions( rIStm, nFollowingActionCount );
1257 0 : rMtf.AddAction( new MetaTextLineColorAction( aColor, bSet ) );
1258 :
1259 0 : i += nFollowingActionCount;
1260 : }
1261 0 : break;
1262 :
1263 : case( GDI_TEXTLINE_COMMENT ):
1264 : {
1265 0 : Point aStartPt;
1266 : sal_Int32 nWidth;
1267 : sal_uInt32 nStrikeout;
1268 : sal_uInt32 nUnderline;
1269 : sal_Int32 nFollowingActionCount;
1270 :
1271 0 : ReadPair( rIStm, aStartPt );
1272 0 : rIStm.ReadInt32( nWidth ).ReadUInt32( nStrikeout ).ReadUInt32( nUnderline ).ReadInt32( nFollowingActionCount );
1273 0 : ImplSkipActions( rIStm, nFollowingActionCount );
1274 : rMtf.AddAction( new MetaTextLineAction( aStartPt, nWidth,
1275 : (FontStrikeout) nStrikeout,
1276 : (FontUnderline) nUnderline,
1277 0 : UNDERLINE_NONE ) );
1278 :
1279 0 : i += nFollowingActionCount;
1280 : }
1281 0 : break;
1282 :
1283 : case( GDI_GRADIENTEX_COMMENT ):
1284 : {
1285 0 : tools::PolyPolygon aPolyPoly;
1286 0 : Gradient aGradient;
1287 : sal_Int32 nFollowingActionCount;
1288 :
1289 0 : ReadPolyPolygon( rIStm, aPolyPoly );
1290 0 : ReadGradient( rIStm, aGradient );
1291 0 : rIStm.ReadInt32( nFollowingActionCount );
1292 0 : ImplSkipActions( rIStm, nFollowingActionCount );
1293 0 : rMtf.AddAction( new MetaGradientExAction( aPolyPoly, aGradient ) );
1294 :
1295 0 : i += nFollowingActionCount;
1296 : }
1297 0 : break;
1298 :
1299 : case( GDI_COMMENT_COMMENT ):
1300 : {
1301 : sal_Int32 nValue;
1302 : sal_uInt32 nDataSize;
1303 : sal_uInt8* pData;
1304 : sal_Int32 nFollowingActionCount;
1305 :
1306 0 : OString aComment = read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm);
1307 0 : rIStm.ReadInt32( nValue ).ReadUInt32( nDataSize );
1308 :
1309 0 : if( nDataSize )
1310 : {
1311 0 : pData = new sal_uInt8[ nDataSize ];
1312 0 : rIStm.Read( pData, nDataSize );
1313 : }
1314 : else
1315 0 : pData = NULL;
1316 :
1317 0 : rIStm.ReadInt32( nFollowingActionCount );
1318 0 : ImplSkipActions( rIStm, nFollowingActionCount );
1319 0 : rMtf.AddAction( new MetaCommentAction( aComment, nValue, pData, nDataSize ) );
1320 :
1321 0 : i += nFollowingActionCount;
1322 : }
1323 0 : break;
1324 :
1325 : case ( GDI_UNICODE_COMMENT ):
1326 : {
1327 0 : nUnicodeCommentActionNumber = i + 1;
1328 0 : nUnicodeCommentStreamPos = rIStm.Tell() - 6;
1329 0 : rIStm.SeekRel( nActionSize - 4 );
1330 : }
1331 0 : break;
1332 :
1333 : default:
1334 0 : rIStm.SeekRel( nActionSize - 4L );
1335 0 : break;
1336 : }
1337 : }
1338 :
1339 : // cleanup push-pop stack if necessary
1340 0 : while( !aLIStack.empty() )
1341 : {
1342 0 : delete aLIStack.top();
1343 0 : aLIStack.pop();
1344 : }
1345 :
1346 0 : rIStm.SetNumberFormatInt( nOldFormat );
1347 : }
1348 :
1349 0 : void SVMConverter::ImplConvertToSVM1( SvStream& rOStm, GDIMetaFile& rMtf )
1350 : {
1351 : sal_uLong nCountPos;
1352 0 : vcl::Font aSaveFont;
1353 0 : const sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt();
1354 0 : rtl_TextEncoding eActualCharSet = osl_getThreadTextEncoding();
1355 0 : const Size aPrefSize( rMtf.GetPrefSize() );
1356 0 : bool bRop_0_1 = false;
1357 0 : VirtualDevice aSaveVDev;
1358 0 : Color aLineCol( COL_BLACK );
1359 0 : ::std::stack< Color* > aLineColStack;
1360 :
1361 0 : rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1362 :
1363 : // Write MagicCode
1364 0 : rOStm.WriteCharPtr( "SVGDI" ); // Identifier
1365 0 : rOStm.WriteInt16( 42 ); // HeaderSize
1366 0 : rOStm.WriteInt16( 200 ); // VERSION
1367 0 : rOStm.WriteInt32( aPrefSize.Width() );
1368 0 : rOStm.WriteInt32( aPrefSize.Height() );
1369 0 : ImplWriteMapMode( rOStm, rMtf.GetPrefMapMode() );
1370 :
1371 : // ActionCount will be written later
1372 0 : nCountPos = rOStm.Tell();
1373 0 : rOStm.SeekRel( 4L );
1374 :
1375 0 : const sal_Int32 nActCount = ImplWriteActions( rOStm, rMtf, aSaveVDev, bRop_0_1, aLineCol, aLineColStack, eActualCharSet );
1376 0 : const sal_uLong nActPos = rOStm.Tell();
1377 :
1378 0 : rOStm.Seek( nCountPos );
1379 0 : rOStm.WriteInt32( nActCount );
1380 0 : rOStm.Seek( nActPos );
1381 0 : rOStm.SetNumberFormatInt( nOldFormat );
1382 :
1383 : // cleanup push-pop stack if necessary
1384 0 : while ( !aLineColStack.empty() )
1385 : {
1386 0 : delete aLineColStack.top();
1387 0 : aLineColStack.pop();
1388 0 : }
1389 0 : }
1390 :
1391 0 : sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
1392 : VirtualDevice& rSaveVDev, bool& rRop_0_1,
1393 : Color& rLineCol, ::std::stack< Color* >& rLineColStack,
1394 : rtl_TextEncoding& rActualCharSet )
1395 : {
1396 0 : sal_uLong nCount = 0;
1397 0 : for( size_t i = 0, nActionCount = rMtf.GetActionSize(); i < nActionCount; i++ )
1398 : {
1399 0 : const MetaAction* pAction = rMtf.GetAction( i );
1400 :
1401 0 : switch( pAction->GetType() )
1402 : {
1403 : case( META_PIXEL_ACTION ):
1404 : {
1405 0 : const MetaPixelAction* pAct = static_cast<const MetaPixelAction*>(pAction);
1406 :
1407 0 : rOStm.WriteInt16( GDI_PIXEL_ACTION );
1408 0 : rOStm.WriteInt32( 18 );
1409 0 : WritePair( rOStm, pAct->GetPoint() );
1410 0 : ImplWriteColor( rOStm, pAct->GetColor() );
1411 0 : nCount++;
1412 : }
1413 0 : break;
1414 :
1415 : case( META_POINT_ACTION ):
1416 : {
1417 0 : const MetaPointAction* pAct = static_cast<const MetaPointAction*>(pAction);
1418 :
1419 0 : rOStm.WriteInt16( GDI_POINT_ACTION );
1420 0 : rOStm.WriteInt32( 12 );
1421 0 : WritePair( rOStm, pAct->GetPoint() );
1422 0 : nCount++;
1423 : }
1424 0 : break;
1425 :
1426 : case( META_LINE_ACTION ):
1427 : {
1428 0 : const MetaLineAction* pAct = static_cast<const MetaLineAction*>(pAction);
1429 0 : const LineInfo& rInfo = pAct->GetLineInfo();
1430 0 : const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
1431 0 : const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
1432 0 : const bool bLineCap(bFatLine && com::sun::star::drawing::LineCap_BUTT != rInfo.GetLineCap());
1433 0 : const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
1434 :
1435 0 : if( bFatLine )
1436 : {
1437 0 : ImplWritePushAction( rOStm );
1438 0 : ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
1439 :
1440 0 : if(bLineJoin)
1441 : {
1442 0 : rOStm.WriteInt16( GDI_LINEJOIN_ACTION );
1443 0 : rOStm.WriteInt32( 6 );
1444 0 : rOStm.WriteInt16( rInfo.GetLineJoin() );
1445 : }
1446 :
1447 0 : if(bLineCap)
1448 : {
1449 0 : rOStm.WriteInt16( GDI_LINECAP_ACTION );
1450 0 : rOStm.WriteInt32( 6 );
1451 0 : rOStm.WriteInt16( rInfo.GetLineCap() );
1452 : }
1453 : }
1454 :
1455 0 : if(bLineDashDot)
1456 : {
1457 0 : rOStm.WriteInt16( GDI_LINEDASHDOT_ACTION );
1458 0 : rOStm.WriteInt32( 4 + 16 );
1459 0 : rOStm.WriteInt16( rInfo.GetDashCount() );
1460 0 : rOStm.WriteInt32( rInfo.GetDashLen() );
1461 0 : rOStm.WriteInt16( rInfo.GetDotCount() );
1462 0 : rOStm.WriteInt32( rInfo.GetDotLen() );
1463 0 : rOStm.WriteInt32( rInfo.GetDistance() );
1464 : }
1465 :
1466 0 : rOStm.WriteInt16( GDI_LINE_ACTION );
1467 0 : rOStm.WriteInt32( 20 );
1468 0 : WritePair( rOStm, pAct->GetStartPoint() );
1469 0 : WritePair( rOStm, pAct->GetEndPoint() );
1470 0 : nCount++;
1471 :
1472 0 : if( bFatLine )
1473 : {
1474 0 : ImplWritePopAction( rOStm );
1475 0 : nCount += 3;
1476 :
1477 0 : if(bLineJoin)
1478 : {
1479 0 : nCount += 1;
1480 : }
1481 :
1482 0 : if(bLineCap)
1483 : {
1484 0 : nCount += 1;
1485 : }
1486 : }
1487 :
1488 0 : if(bLineDashDot)
1489 : {
1490 0 : nCount += 1;
1491 : }
1492 : }
1493 0 : break;
1494 :
1495 : case( META_RECT_ACTION ):
1496 : {
1497 0 : const MetaRectAction* pAct = static_cast<const MetaRectAction*>(pAction);
1498 :
1499 0 : rOStm.WriteInt16( GDI_RECT_ACTION );
1500 0 : rOStm.WriteInt32( 28 );
1501 0 : ImplWriteRect( rOStm, pAct->GetRect() );
1502 0 : rOStm.WriteInt32( 0 );
1503 0 : rOStm.WriteInt32( 0 );
1504 0 : nCount++;
1505 : }
1506 0 : break;
1507 :
1508 : case( META_ROUNDRECT_ACTION ):
1509 : {
1510 0 : const MetaRoundRectAction* pAct = static_cast<const MetaRoundRectAction*>(pAction);
1511 :
1512 0 : rOStm.WriteInt16( GDI_RECT_ACTION );
1513 0 : rOStm.WriteInt32( 28 );
1514 0 : ImplWriteRect( rOStm, pAct->GetRect() );
1515 0 : rOStm.WriteInt32( pAct->GetHorzRound() );
1516 0 : rOStm.WriteInt32( pAct->GetVertRound() );
1517 0 : nCount++;
1518 : }
1519 0 : break;
1520 :
1521 : case( META_ELLIPSE_ACTION ):
1522 : {
1523 0 : const MetaEllipseAction* pAct = static_cast<const MetaEllipseAction*>(pAction);
1524 :
1525 0 : rOStm.WriteInt16( GDI_ELLIPSE_ACTION );
1526 0 : rOStm.WriteInt32( 20 );
1527 0 : ImplWriteRect( rOStm, pAct->GetRect() );
1528 0 : nCount++;
1529 : }
1530 0 : break;
1531 :
1532 : case( META_ARC_ACTION ):
1533 : {
1534 0 : const MetaArcAction* pAct = static_cast<const MetaArcAction*>(pAction);
1535 :
1536 0 : rOStm.WriteInt16( GDI_ARC_ACTION );
1537 0 : rOStm.WriteInt32( 36 );
1538 0 : ImplWriteRect( rOStm, pAct->GetRect() );
1539 0 : WritePair( rOStm, pAct->GetStartPoint() );
1540 0 : WritePair( rOStm, pAct->GetEndPoint() );
1541 0 : nCount++;
1542 : }
1543 0 : break;
1544 :
1545 : case( META_PIE_ACTION ):
1546 : {
1547 0 : const MetaPieAction* pAct = static_cast<const MetaPieAction*>(pAction);
1548 :
1549 0 : rOStm.WriteInt16( GDI_PIE_ACTION );
1550 0 : rOStm.WriteInt32( 36 );
1551 0 : ImplWriteRect( rOStm, pAct->GetRect() );
1552 0 : WritePair( rOStm, pAct->GetStartPoint() );
1553 0 : WritePair( rOStm, pAct->GetEndPoint() );
1554 0 : nCount++;
1555 : }
1556 0 : break;
1557 :
1558 : case( META_CHORD_ACTION ):
1559 : {
1560 0 : const MetaChordAction* pAct = static_cast<const MetaChordAction*>(pAction);
1561 0 : Polygon aChordPoly( pAct->GetRect(), pAct->GetStartPoint(),
1562 0 : pAct->GetEndPoint(), POLY_CHORD );
1563 0 : const sal_uInt16 nPoints = aChordPoly.GetSize();
1564 :
1565 0 : rOStm.WriteInt16( GDI_POLYGON_ACTION );
1566 0 : rOStm.WriteInt32( ( 8 + ( nPoints << 3 ) ) );
1567 0 : rOStm.WriteInt32( nPoints );
1568 :
1569 0 : for( sal_uInt16 n = 0; n < nPoints; n++ )
1570 0 : WritePair( rOStm, aChordPoly[ n ] );
1571 0 : nCount++;
1572 : }
1573 0 : break;
1574 :
1575 : case( META_POLYLINE_ACTION ):
1576 : {
1577 : // #i102224#
1578 0 : const MetaPolyLineAction* pAct = static_cast<const MetaPolyLineAction*>(pAction);
1579 : // #i102224# Here the possible curved nature of Polygon was
1580 : // ignored (for all those years). Adapted to at least write
1581 : // a polygon representing the curve as good as possible
1582 0 : Polygon aSimplePoly;
1583 0 : pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
1584 0 : const LineInfo& rInfo = pAct->GetLineInfo();
1585 0 : const sal_uInt16 nPoints(aSimplePoly.GetSize());
1586 0 : const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
1587 0 : const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
1588 0 : const bool bLineCap(bFatLine && com::sun::star::drawing::LineCap_BUTT != rInfo.GetLineCap());
1589 0 : const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
1590 :
1591 0 : if( bFatLine )
1592 : {
1593 0 : ImplWritePushAction( rOStm );
1594 0 : ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
1595 :
1596 0 : if(bLineJoin)
1597 : {
1598 0 : rOStm.WriteInt16( GDI_LINEJOIN_ACTION );
1599 0 : rOStm.WriteInt32( 6 );
1600 0 : rOStm.WriteInt16( rInfo.GetLineJoin() );
1601 : }
1602 :
1603 0 : if(bLineCap)
1604 : {
1605 0 : rOStm.WriteInt16( GDI_LINECAP_ACTION );
1606 0 : rOStm.WriteInt32( 6 );
1607 0 : rOStm.WriteInt16( rInfo.GetLineCap() );
1608 : }
1609 : }
1610 :
1611 0 : if(bLineDashDot)
1612 : {
1613 0 : rOStm.WriteInt16( GDI_LINEDASHDOT_ACTION );
1614 0 : rOStm.WriteInt32( 4 + 16 );
1615 0 : rOStm.WriteInt16( rInfo.GetDashCount() );
1616 0 : rOStm.WriteInt32( rInfo.GetDashLen() );
1617 0 : rOStm.WriteInt16( rInfo.GetDotCount() );
1618 0 : rOStm.WriteInt32( rInfo.GetDotLen() );
1619 0 : rOStm.WriteInt32( rInfo.GetDistance() );
1620 : }
1621 :
1622 0 : rOStm.WriteInt16( GDI_POLYLINE_ACTION );
1623 0 : rOStm.WriteInt32( ( 8 + ( nPoints << 3 ) ) );
1624 0 : rOStm.WriteInt32( nPoints );
1625 :
1626 0 : for( sal_uInt16 n = 0; n < nPoints; n++ )
1627 : {
1628 0 : WritePair( rOStm, aSimplePoly[ n ] );
1629 : }
1630 :
1631 0 : nCount++;
1632 :
1633 0 : const tools::PolyPolygon aPolyPolygon(pAct->GetPolygon());
1634 0 : if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
1635 : {
1636 0 : nCount++;
1637 : }
1638 :
1639 0 : if( bFatLine )
1640 : {
1641 0 : ImplWritePopAction( rOStm );
1642 0 : nCount += 3;
1643 :
1644 0 : if(bLineJoin)
1645 : {
1646 0 : nCount += 1;
1647 : }
1648 :
1649 0 : if(bLineCap)
1650 : {
1651 0 : nCount += 1;
1652 : }
1653 : }
1654 :
1655 0 : if(bLineDashDot)
1656 : {
1657 0 : nCount += 1;
1658 0 : }
1659 : }
1660 0 : break;
1661 :
1662 : case( META_POLYGON_ACTION ):
1663 : {
1664 0 : const MetaPolygonAction* pAct = static_cast<const MetaPolygonAction*>(pAction);
1665 : // #i102224# Here the possible curved nature of Polygon was
1666 : // ignored (for all those years). Adapted to at least write
1667 : // a polygon representing the curve as good as possible
1668 0 : Polygon aSimplePoly;
1669 0 : pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
1670 0 : const sal_uInt16 nPoints(aSimplePoly.GetSize());
1671 :
1672 0 : rOStm.WriteInt16( GDI_POLYGON_ACTION );
1673 0 : rOStm.WriteInt32( ( 8 + ( nPoints << 3 ) ) );
1674 0 : rOStm.WriteInt32( nPoints );
1675 :
1676 0 : for( sal_uInt16 n = 0; n < nPoints; n++ )
1677 0 : WritePair( rOStm, aSimplePoly[ n ] );
1678 :
1679 0 : nCount++;
1680 :
1681 0 : const tools::PolyPolygon aPolyPolygon(pAct->GetPolygon());
1682 0 : if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
1683 : {
1684 0 : nCount++;
1685 0 : }
1686 : }
1687 0 : break;
1688 :
1689 : case( META_POLYPOLYGON_ACTION ):
1690 : {
1691 0 : const MetaPolyPolygonAction* pAct = static_cast<const MetaPolyPolygonAction*>(pAction);
1692 0 : ImplWritePolyPolyAction( rOStm, pAct->GetPolyPolygon() );
1693 0 : nCount++;
1694 :
1695 0 : if(ImplWriteExtendedPolyPolygonAction(rOStm, pAct->GetPolyPolygon(), true))
1696 : {
1697 0 : nCount++;
1698 : }
1699 : }
1700 0 : break;
1701 :
1702 : case( META_TEXT_ACTION ):
1703 : {
1704 0 : const MetaTextAction* pAct = static_cast<const MetaTextAction*>(pAction);
1705 0 : OUString aUniText( pAct->GetText() );
1706 0 : OString aText(OUStringToOString(aUniText, rActualCharSet));
1707 0 : const sal_Int32 nStrLen = aText.getLength();
1708 :
1709 0 : if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
1710 0 : nCount++;
1711 :
1712 0 : rOStm.WriteInt16( GDI_TEXT_ACTION );
1713 0 : rOStm.WriteInt32( ( 24 + ( nStrLen + 1 ) ) );
1714 0 : WritePair( rOStm, pAct->GetPoint() );
1715 0 : rOStm.WriteInt32( pAct->GetIndex() );
1716 0 : rOStm.WriteInt32( pAct->GetLen() );
1717 0 : rOStm.WriteInt32( nStrLen );
1718 0 : rOStm.Write( aText.getStr(), nStrLen + 1 );
1719 0 : nCount++;
1720 : }
1721 0 : break;
1722 :
1723 : case( META_TEXTARRAY_ACTION ):
1724 : {
1725 0 : const MetaTextArrayAction* pAct = static_cast<const MetaTextArrayAction*>(pAction);
1726 0 : OString aText(OUStringToOString(pAct->GetText(), rActualCharSet));
1727 0 : OUString aUniText = pAct->GetText().copy(
1728 : pAct->GetIndex(),
1729 0 : std::min<sal_Int32>(pAct->GetText().getLength() - pAct->GetIndex(), pAct->GetLen()) );
1730 : sal_Int32 nAryLen;
1731 0 : sal_Int32 nLen = pAct->GetLen();
1732 0 : const sal_Int32 nTextLen = aText.getLength();
1733 0 : long* pDXArray = pAct->GetDXArray();
1734 :
1735 0 : if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
1736 0 : nCount++;
1737 :
1738 0 : if( ( nLen + pAct->GetIndex() ) > nTextLen )
1739 : {
1740 0 : if( pAct->GetIndex() <= nTextLen )
1741 0 : nLen = nTextLen - pAct->GetIndex();
1742 : else
1743 0 : nLen = 0;
1744 : }
1745 :
1746 0 : if( !pDXArray || !nLen )
1747 0 : nAryLen = 0;
1748 : else
1749 0 : nAryLen = nLen; // #105987# Write out all of DX array
1750 :
1751 0 : rOStm.WriteInt16( GDI_TEXTARRAY_ACTION );
1752 0 : rOStm.WriteInt32( ( 28 + ( nLen + 1 ) + ( nAryLen * 4 ) ) );
1753 0 : WritePair( rOStm, pAct->GetPoint() );
1754 0 : rOStm.WriteInt32( 0 );
1755 0 : rOStm.WriteInt32( nLen );
1756 0 : rOStm.WriteInt32( nLen );
1757 0 : rOStm.WriteInt32( nAryLen );
1758 0 : rOStm.Write( aText.getStr()+pAct->GetIndex(), nLen + 1 );
1759 :
1760 0 : for (sal_Int32 n = 0; n < nAryLen; ++n)
1761 0 : rOStm.WriteInt32( pDXArray[ n ] );
1762 :
1763 0 : nCount++;
1764 : }
1765 0 : break;
1766 :
1767 : case( META_STRETCHTEXT_ACTION ):
1768 : {
1769 0 : const MetaStretchTextAction* pAct = static_cast<const MetaStretchTextAction*>(pAction);
1770 0 : OUString aUniText( pAct->GetText() );
1771 0 : OString aText(OUStringToOString(aUniText, rActualCharSet));
1772 0 : const sal_Int32 nStrLen = aText.getLength();
1773 :
1774 0 : if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
1775 0 : nCount++;
1776 :
1777 0 : rOStm.WriteInt16( GDI_STRETCHTEXT_ACTION );
1778 0 : rOStm.WriteInt32( ( 28 + ( nStrLen + 1 ) ) );
1779 0 : WritePair( rOStm, pAct->GetPoint() );
1780 0 : rOStm.WriteInt32( pAct->GetIndex() );
1781 0 : rOStm.WriteInt32( pAct->GetLen() );
1782 0 : rOStm.WriteInt32( nStrLen );
1783 0 : rOStm.WriteInt32( pAct->GetWidth() );
1784 0 : rOStm.Write( aText.getStr(), nStrLen + 1 );
1785 0 : nCount++;
1786 : }
1787 0 : break;
1788 :
1789 : case( META_BMP_ACTION ):
1790 : {
1791 0 : const MetaBmpAction* pAct = static_cast<const MetaBmpAction*>(pAction);
1792 :
1793 0 : rOStm.WriteInt16( GDI_BITMAP_ACTION );
1794 0 : rOStm.WriteInt32( 12 );
1795 0 : WritePair( rOStm, pAct->GetPoint() );
1796 0 : WriteDIB(pAct->GetBitmap(), rOStm, false, true);
1797 0 : nCount++;
1798 : }
1799 0 : break;
1800 :
1801 : case( META_BMPSCALE_ACTION ):
1802 : {
1803 0 : const MetaBmpScaleAction* pAct = static_cast<const MetaBmpScaleAction*>(pAction);
1804 :
1805 0 : rOStm.WriteInt16( GDI_BITMAPSCALE_ACTION );
1806 0 : rOStm.WriteInt32( 20 );
1807 0 : WritePair( rOStm, pAct->GetPoint() );
1808 0 : WritePair( rOStm, pAct->GetSize() );
1809 0 : WriteDIB(pAct->GetBitmap(), rOStm, false, true);
1810 0 : nCount++;
1811 : }
1812 0 : break;
1813 :
1814 : case( META_BMPSCALEPART_ACTION ):
1815 : {
1816 0 : const MetaBmpScalePartAction* pAct = static_cast<const MetaBmpScalePartAction*>(pAction);
1817 :
1818 0 : rOStm.WriteInt16( GDI_BITMAPSCALEPART_ACTION );
1819 0 : rOStm.WriteInt32( 36 );
1820 0 : WritePair( rOStm, pAct->GetDestPoint() );
1821 0 : WritePair( rOStm, pAct->GetDestSize() );
1822 0 : WritePair( rOStm, pAct->GetSrcPoint() );
1823 0 : WritePair( rOStm, pAct->GetSrcSize() );
1824 0 : WriteDIB(pAct->GetBitmap(), rOStm, false, true);
1825 0 : nCount++;
1826 : }
1827 0 : break;
1828 :
1829 : case( META_BMPEX_ACTION ):
1830 : {
1831 0 : const MetaBmpExAction* pAct = static_cast<const MetaBmpExAction*>(pAction);
1832 0 : const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
1833 :
1834 0 : rOStm.WriteInt16( GDI_BITMAP_ACTION );
1835 0 : rOStm.WriteInt32( 12 );
1836 0 : WritePair( rOStm, pAct->GetPoint() );
1837 0 : WriteDIB(aBmp, rOStm, false, true);
1838 0 : nCount++;
1839 : }
1840 0 : break;
1841 :
1842 : case( META_BMPEXSCALE_ACTION ):
1843 : {
1844 0 : const MetaBmpExScaleAction* pAct = static_cast<const MetaBmpExScaleAction*>(pAction);
1845 0 : const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
1846 :
1847 0 : rOStm.WriteInt16( GDI_BITMAPSCALE_ACTION );
1848 0 : rOStm.WriteInt32( 20 );
1849 0 : WritePair( rOStm, pAct->GetPoint() );
1850 0 : WritePair( rOStm, pAct->GetSize() );
1851 0 : WriteDIB(aBmp, rOStm, false, true);
1852 0 : nCount++;
1853 : }
1854 0 : break;
1855 :
1856 : case( META_BMPEXSCALEPART_ACTION ):
1857 : {
1858 0 : const MetaBmpExScalePartAction* pAct = static_cast<const MetaBmpExScalePartAction*>(pAction);
1859 0 : const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
1860 :
1861 0 : rOStm.WriteInt16( GDI_BITMAPSCALEPART_ACTION );
1862 0 : rOStm.WriteInt32( 36 );
1863 0 : WritePair( rOStm, pAct->GetDestPoint() );
1864 0 : WritePair( rOStm, pAct->GetDestSize() );
1865 0 : WritePair( rOStm, pAct->GetSrcPoint() );
1866 0 : WritePair( rOStm, pAct->GetSrcSize() );
1867 0 : WriteDIB(aBmp, rOStm, false, true);
1868 0 : nCount++;
1869 : }
1870 0 : break;
1871 :
1872 : case( META_GRADIENT_ACTION ):
1873 : {
1874 0 : const MetaGradientAction* pAct = static_cast<const MetaGradientAction*>(pAction);
1875 0 : const Gradient& rGrad = pAct->GetGradient();
1876 :
1877 0 : rOStm.WriteInt16( GDI_GRADIENT_ACTION );
1878 0 : rOStm.WriteInt32( 46 );
1879 0 : ImplWriteRect( rOStm, pAct->GetRect() );
1880 0 : rOStm.WriteInt16( rGrad.GetStyle() );
1881 0 : ImplWriteColor( rOStm, rGrad.GetStartColor() );
1882 0 : ImplWriteColor( rOStm, rGrad.GetEndColor() );
1883 0 : rOStm.WriteInt16( rGrad.GetAngle() );
1884 0 : rOStm.WriteInt16( rGrad.GetBorder() );
1885 0 : rOStm.WriteInt16( rGrad.GetOfsX() );
1886 0 : rOStm.WriteInt16( rGrad.GetOfsY() );
1887 0 : rOStm.WriteInt16( rGrad.GetStartIntensity() );
1888 0 : rOStm.WriteInt16( rGrad.GetEndIntensity() );
1889 0 : nCount++;
1890 : }
1891 0 : break;
1892 :
1893 : case( META_GRADIENTEX_ACTION ):
1894 : {
1895 0 : const MetaGradientExAction* pA = static_cast<const MetaGradientExAction*>(pAction);
1896 : sal_uLong nOldPos, nNewPos;
1897 :
1898 : // write RefPoint comment
1899 0 : rOStm.WriteInt16( GDI_GRADIENTEX_COMMENT );
1900 :
1901 : // we'll write the ActionSize later
1902 0 : nOldPos = rOStm.Tell();
1903 0 : rOStm.SeekRel( 4 );
1904 :
1905 : // write data
1906 0 : WritePolyPolygon( rOStm, pA->GetPolyPolygon() );
1907 0 : WriteGradient( rOStm, pA->GetGradient() );
1908 0 : rOStm.WriteInt32( 0 ); // number of actions that follow this comment
1909 :
1910 : // calculate and write ActionSize of comment
1911 0 : nNewPos = rOStm.Tell();
1912 0 : rOStm.Seek( nOldPos );
1913 0 : rOStm.WriteInt32( ( nNewPos - nOldPos ) );
1914 0 : rOStm.Seek( nNewPos );
1915 :
1916 0 : nCount++;
1917 : }
1918 0 : break;
1919 :
1920 : case( META_WALLPAPER_ACTION ):
1921 : {
1922 0 : const MetaWallpaperAction* pAct = static_cast<const MetaWallpaperAction*>(pAction);
1923 0 : const Color& rColor = pAct->GetWallpaper().GetColor();
1924 :
1925 0 : ImplWritePushAction( rOStm );
1926 0 : ImplWriteLineColor( rOStm, rColor, 1 );
1927 0 : ImplWriteFillColor( rOStm, rColor, 1 );
1928 :
1929 0 : rOStm.WriteInt16( GDI_RECT_ACTION );
1930 0 : rOStm.WriteInt32( 28 );
1931 0 : ImplWriteRect( rOStm, pAct->GetRect() );
1932 0 : rOStm.WriteInt32( 0 );
1933 0 : rOStm.WriteInt32( 0 );
1934 :
1935 0 : ImplWritePopAction( rOStm );
1936 0 : nCount += 5;
1937 : }
1938 0 : break;
1939 :
1940 : case( META_CLIPREGION_ACTION ):
1941 : {
1942 0 : const MetaClipRegionAction* pAct = static_cast<const MetaClipRegionAction*>(pAction);
1943 0 : const vcl::Region& rRegion = pAct->GetRegion();
1944 0 : Rectangle aClipRect;
1945 :
1946 0 : rOStm.WriteInt16( GDI_CLIPREGION_ACTION );
1947 0 : rOStm.WriteInt32( 24 );
1948 :
1949 0 : if( pAct->IsClipping() )
1950 : {
1951 0 : aClipRect = rRegion.GetBoundRect();
1952 0 : rOStm.WriteInt16( 1 );
1953 : }
1954 : else
1955 0 : rOStm.WriteInt16( 0 );
1956 :
1957 0 : rOStm.WriteInt16( 0 );
1958 0 : ImplWriteRect( rOStm, aClipRect );
1959 :
1960 0 : if( pAct->IsClipping() )
1961 0 : ImplWriteRect( rOStm, aClipRect );
1962 :
1963 0 : nCount++;
1964 : }
1965 0 : break;
1966 :
1967 : case( META_ISECTRECTCLIPREGION_ACTION ):
1968 : {
1969 0 : const MetaISectRectClipRegionAction* pAct = static_cast<const MetaISectRectClipRegionAction*>(pAction);
1970 :
1971 0 : rOStm.WriteInt16( GDI_ISECTCLIPREGION_ACTION );
1972 0 : rOStm.WriteInt32( 20 );
1973 0 : WriteRectangle( rOStm, pAct->GetRect() );
1974 0 : nCount++;
1975 : }
1976 0 : break;
1977 :
1978 : case( META_MOVECLIPREGION_ACTION ):
1979 : {
1980 0 : const MetaMoveClipRegionAction* pAct = static_cast<const MetaMoveClipRegionAction*>(pAction);
1981 :
1982 0 : rOStm.WriteInt16( GDI_MOVECLIPREGION_ACTION );
1983 0 : rOStm.WriteInt32( 12 );
1984 0 : rOStm.WriteInt32( pAct->GetHorzMove() );
1985 0 : rOStm.WriteInt32( pAct->GetVertMove() );
1986 0 : nCount++;
1987 : }
1988 0 : break;
1989 :
1990 : case( META_LINECOLOR_ACTION ):
1991 : {
1992 0 : const MetaLineColorAction* pAct = static_cast<const MetaLineColorAction*>(pAction);
1993 0 : ImplWriteLineColor( rOStm, rLineCol = pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
1994 0 : nCount++;
1995 : }
1996 0 : break;
1997 :
1998 : case( META_FILLCOLOR_ACTION ):
1999 : {
2000 0 : const MetaFillColorAction* pAct = static_cast<const MetaFillColorAction*>(pAction);
2001 0 : ImplWriteFillColor( rOStm, pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
2002 0 : nCount++;
2003 : }
2004 0 : break;
2005 :
2006 : case( META_FONT_ACTION ):
2007 : {
2008 0 : rSaveVDev.SetFont( static_cast<const MetaFontAction*>(pAction)->GetFont() );
2009 0 : ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2010 0 : nCount++;
2011 : }
2012 0 : break;
2013 :
2014 : case( META_TEXTCOLOR_ACTION ):
2015 : {
2016 0 : vcl::Font aSaveFont( rSaveVDev.GetFont() );
2017 :
2018 0 : aSaveFont.SetColor( static_cast<const MetaTextColorAction*>(pAction)->GetColor() );
2019 0 : rSaveVDev.SetFont( aSaveFont );
2020 0 : ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2021 0 : nCount++;
2022 : }
2023 0 : break;
2024 :
2025 : case( META_TEXTFILLCOLOR_ACTION ):
2026 : {
2027 0 : const MetaTextFillColorAction* pAct = static_cast<const MetaTextFillColorAction*>(pAction);
2028 0 : vcl::Font aSaveFont( rSaveVDev.GetFont() );
2029 :
2030 0 : if( pAct->IsSetting() )
2031 0 : aSaveFont.SetFillColor( pAct->GetColor() );
2032 : else
2033 0 : aSaveFont.SetFillColor( Color( COL_TRANSPARENT ) );
2034 :
2035 0 : rSaveVDev.SetFont( aSaveFont );
2036 0 : ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2037 0 : nCount++;
2038 : }
2039 0 : break;
2040 :
2041 : case( META_TEXTALIGN_ACTION ):
2042 : {
2043 0 : vcl::Font aSaveFont( rSaveVDev.GetFont() );
2044 :
2045 0 : aSaveFont.SetAlign( static_cast<const MetaTextAlignAction*>(pAction)->GetTextAlign() );
2046 0 : rSaveVDev.SetFont( aSaveFont );
2047 0 : ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2048 0 : nCount++;
2049 : }
2050 0 : break;
2051 :
2052 : case( META_MAPMODE_ACTION ):
2053 : {
2054 0 : const MetaMapModeAction* pAct = static_cast<const MetaMapModeAction*>(pAction);
2055 :
2056 0 : rOStm.WriteInt16( GDI_MAPMODE_ACTION );
2057 0 : rOStm.WriteInt32( 30 );
2058 0 : ImplWriteMapMode( rOStm, pAct->GetMapMode() );
2059 0 : nCount++;
2060 : }
2061 0 : break;
2062 :
2063 : case( META_PUSH_ACTION ):
2064 : {
2065 0 : ImplWritePushAction( rOStm );
2066 0 : rLineColStack.push( new Color( rLineCol ) );
2067 0 : rSaveVDev.Push();
2068 0 : nCount++;
2069 : }
2070 0 : break;
2071 :
2072 : case( META_POP_ACTION ):
2073 : {
2074 : Color* pCol;
2075 0 : if (rLineColStack.empty())
2076 0 : pCol = NULL;
2077 : else
2078 : {
2079 0 : pCol = rLineColStack.top();
2080 0 : rLineColStack.pop();
2081 : }
2082 :
2083 0 : if( pCol )
2084 : {
2085 0 : rLineCol = *pCol;
2086 0 : delete pCol;
2087 : }
2088 :
2089 0 : ImplWritePopAction( rOStm );
2090 0 : rSaveVDev.Pop();
2091 0 : nCount++;
2092 : }
2093 0 : break;
2094 :
2095 : case( META_RASTEROP_ACTION ):
2096 : {
2097 0 : const MetaRasterOpAction* pAct = static_cast<const MetaRasterOpAction*>(pAction);
2098 :
2099 0 : if( ( pAct->GetRasterOp() != ROP_0 ) && ( pAct->GetRasterOp() != ROP_1 ) )
2100 : {
2101 : sal_Int16 nRasterOp;
2102 :
2103 : // If ROP_0/1 was set earlier, restore old state
2104 : // via a Pop first
2105 0 : if( rRop_0_1 )
2106 : {
2107 0 : ImplWritePopAction( rOStm );
2108 0 : rSaveVDev.Pop();
2109 0 : rRop_0_1 = false;
2110 0 : nCount++;
2111 : }
2112 :
2113 0 : switch( pAct->GetRasterOp() )
2114 : {
2115 0 : case( ROP_OVERPAINT ) : nRasterOp = 0; break;
2116 0 : case( ROP_XOR ) : nRasterOp = 4; break;
2117 0 : case( ROP_INVERT ): nRasterOp = 1; break;
2118 0 : default: nRasterOp = 0; break;
2119 : }
2120 :
2121 0 : ImplWriteRasterOpAction( rOStm, nRasterOp );
2122 0 : nCount++;
2123 : }
2124 : else
2125 : {
2126 0 : ImplWritePushAction( rOStm );
2127 0 : rSaveVDev.Push();
2128 :
2129 0 : if( pAct->GetRasterOp() == ROP_0 )
2130 : {
2131 0 : ImplWriteLineColor( rOStm, COL_BLACK, 1 );
2132 0 : ImplWriteFillColor( rOStm, COL_BLACK, 1 );
2133 : }
2134 : else
2135 : {
2136 0 : ImplWriteLineColor( rOStm, COL_WHITE, 1 );
2137 0 : ImplWriteFillColor( rOStm, COL_WHITE, 1 );
2138 : }
2139 :
2140 0 : ImplWriteRasterOpAction( rOStm, 0 );
2141 0 : rRop_0_1 = true;
2142 0 : nCount += 4;
2143 : }
2144 : }
2145 0 : break;
2146 :
2147 : case( META_TRANSPARENT_ACTION ):
2148 : {
2149 0 : const tools::PolyPolygon& rPolyPoly = static_cast<const MetaTransparentAction*>(pAction)->GetPolyPolygon();
2150 0 : const sal_Int16 nTrans = static_cast<const MetaTransparentAction*>(pAction)->GetTransparence();
2151 0 : const sal_Int16 nBrushStyle = ( nTrans < 38 ) ? 8 : ( nTrans < 63 ) ? 9 : 10;
2152 : sal_uLong nOldPos, nNewPos;
2153 :
2154 : // write transparence comment
2155 0 : rOStm.WriteInt16( GDI_TRANSPARENT_COMMENT );
2156 :
2157 : // we'll write the ActionSize later
2158 0 : nOldPos = rOStm.Tell();
2159 0 : rOStm.SeekRel( 4 );
2160 :
2161 : // write comment data
2162 0 : WritePolyPolygon( rOStm, rPolyPoly );
2163 0 : rOStm.WriteInt16( nTrans );
2164 0 : rOStm.WriteInt32( 15 ); // number of actions that follow this comment
2165 :
2166 : // calculate and write ActionSize of comment
2167 0 : nNewPos = rOStm.Tell();
2168 0 : rOStm.Seek( nOldPos );
2169 0 : rOStm.WriteInt32( ( nNewPos - nOldPos ) );
2170 0 : rOStm.Seek( nNewPos );
2171 :
2172 : {
2173 : // write actions for transparence
2174 0 : ImplWritePushAction( rOStm );
2175 : {
2176 0 : ImplWriteRasterOpAction( rOStm, 4 );
2177 0 : ImplWritePolyPolyAction( rOStm, rPolyPoly );
2178 :
2179 0 : ImplWritePushAction( rOStm );
2180 : {
2181 0 : ImplWriteRasterOpAction( rOStm, 2 );
2182 0 : ImplWriteFillColor( rOStm, COL_BLACK, nBrushStyle );
2183 0 : ImplWritePolyPolyAction( rOStm, rPolyPoly );
2184 : }
2185 0 : ImplWritePopAction( rOStm );
2186 :
2187 0 : ImplWriteRasterOpAction( rOStm, 4 );
2188 0 : ImplWritePolyPolyAction( rOStm, rPolyPoly );
2189 : }
2190 0 : ImplWritePopAction( rOStm );
2191 :
2192 0 : ImplWritePushAction( rOStm );
2193 : {
2194 0 : ImplWriteFillColor( rOStm, Color(), 0 );
2195 0 : ImplWritePolyPolyAction( rOStm, rPolyPoly );
2196 : }
2197 0 : ImplWritePopAction( rOStm );
2198 :
2199 0 : nCount += 15;
2200 : }
2201 :
2202 0 : nCount++;
2203 : }
2204 0 : break;
2205 :
2206 : case( META_FLOATTRANSPARENT_ACTION ):
2207 : {
2208 0 : const MetaFloatTransparentAction* pA = static_cast<const MetaFloatTransparentAction*>(pAction);
2209 0 : const GDIMetaFile& rTransMtf = pA->GetGDIMetaFile();
2210 0 : const Point& rPos = pA->GetPoint();
2211 0 : const Size& rSize = pA->GetSize();
2212 0 : const Gradient& rGradient = pA->GetGradient();
2213 : sal_uLong nOldPos, nNewPos;
2214 :
2215 : // write RefPoint comment
2216 0 : rOStm.WriteInt16( GDI_FLOATTRANSPARENT_COMMENT );
2217 :
2218 : // we'll write the ActionSize later
2219 0 : nOldPos = rOStm.Tell();
2220 0 : rOStm.SeekRel( 4 );
2221 :
2222 : // write comment data
2223 0 : WriteGDIMetaFile( rOStm, rTransMtf );
2224 0 : WritePair( rOStm, rPos );
2225 0 : WritePair( rOStm, rSize );
2226 0 : WriteGradient( rOStm, rGradient );
2227 :
2228 : // calculate and write ActionSize of comment
2229 0 : nNewPos = rOStm.Tell();
2230 0 : rOStm.Seek( nOldPos );
2231 0 : rOStm.WriteInt32( ( nNewPos - nOldPos + 4 ) );
2232 0 : rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
2233 :
2234 : {
2235 : // write actions for float transparence
2236 : sal_uLong nAddCount;
2237 0 : GDIMetaFile aMtf( rTransMtf );
2238 0 : const Size aSrcSize( rTransMtf.GetPrefSize() );
2239 0 : Point aSrcPt( rTransMtf.GetPrefMapMode().GetOrigin() );
2240 0 : const double fScaleX = aSrcSize.Width() ? (double) rSize.Width() / aSrcSize.Width() : 1.0;
2241 0 : const double fScaleY = aSrcSize.Height() ? (double) rSize.Height() / aSrcSize.Height() : 1.0;
2242 : long nMoveX, nMoveY;
2243 :
2244 0 : if( fScaleX != 1.0 || fScaleY != 1.0 )
2245 : {
2246 0 : aMtf.Scale( fScaleX, fScaleY );
2247 0 : aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
2248 : }
2249 :
2250 0 : nMoveX = rPos.X() - aSrcPt.X(), nMoveY = rPos.Y() - aSrcPt.Y();
2251 :
2252 0 : if( nMoveX || nMoveY )
2253 0 : aMtf.Move( nMoveX, nMoveY );
2254 :
2255 0 : nAddCount = ImplWriteActions( rOStm, aMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
2256 0 : nNewPos = rOStm.Tell();
2257 0 : rOStm.Seek( nOldPos );
2258 0 : rOStm.WriteInt32( nAddCount );
2259 0 : rOStm.Seek( nNewPos );
2260 :
2261 0 : nCount += nAddCount;
2262 : }
2263 :
2264 0 : nCount++;
2265 : }
2266 0 : break;
2267 :
2268 : case( META_HATCH_ACTION ):
2269 : {
2270 0 : const MetaHatchAction* pA = static_cast<const MetaHatchAction*>(pAction);
2271 0 : const tools::PolyPolygon& rPolyPoly = pA->GetPolyPolygon();
2272 0 : const Hatch& rHatch = pA->GetHatch();
2273 : sal_uLong nOldPos, nNewPos, nAddCount;
2274 :
2275 : // write hatch comment
2276 0 : rOStm.WriteInt16( GDI_HATCH_COMMENT );
2277 :
2278 : // we'll write the ActionSize later
2279 0 : nOldPos = rOStm.Tell();
2280 0 : rOStm.SeekRel( 4 );
2281 :
2282 : // write comment data
2283 0 : WritePolyPolygon( rOStm, rPolyPoly );
2284 0 : WriteHatch( rOStm, rHatch );
2285 :
2286 : // calculate and write ActionSize of comment
2287 0 : nNewPos = rOStm.Tell();
2288 0 : rOStm.Seek( nOldPos );
2289 0 : rOStm.WriteInt32( ( nNewPos - nOldPos + 4 ) );
2290 0 : rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
2291 :
2292 : {
2293 : // write actions for hatch
2294 0 : VirtualDevice aVDev;
2295 0 : GDIMetaFile aTmpMtf;
2296 :
2297 0 : aVDev.AddHatchActions( rPolyPoly, rHatch, aTmpMtf );
2298 0 : nAddCount = ImplWriteActions( rOStm, aTmpMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
2299 0 : nNewPos = rOStm.Tell();
2300 0 : rOStm.Seek( nOldPos );
2301 0 : rOStm.WriteInt32( nAddCount );
2302 0 : rOStm.Seek( nNewPos );
2303 :
2304 0 : nCount += nAddCount;
2305 : }
2306 :
2307 0 : nCount++;
2308 : }
2309 0 : break;
2310 :
2311 : case( META_REFPOINT_ACTION ):
2312 : {
2313 0 : const MetaRefPointAction* pA = static_cast<const MetaRefPointAction*>(pAction);
2314 0 : const Point& rRefPoint = pA->GetRefPoint();
2315 0 : const bool bSet = pA->IsSetting();
2316 : sal_uLong nOldPos, nNewPos;
2317 :
2318 : // write RefPoint comment
2319 0 : rOStm.WriteInt16( GDI_REFPOINT_COMMENT );
2320 :
2321 : // we'll write the ActionSize later
2322 0 : nOldPos = rOStm.Tell();
2323 0 : rOStm.SeekRel( 4 );
2324 :
2325 : // write data
2326 0 : WritePair( rOStm, rRefPoint );
2327 0 : rOStm.WriteUChar( bSet );
2328 0 : rOStm.WriteInt32( 0 ); // number of actions that follow this comment
2329 :
2330 : // calculate and write ActionSize of comment
2331 0 : nNewPos = rOStm.Tell();
2332 0 : rOStm.Seek( nOldPos );
2333 0 : rOStm.WriteInt32( ( nNewPos - nOldPos ) );
2334 0 : rOStm.Seek( nNewPos );
2335 :
2336 0 : nCount++;
2337 : }
2338 0 : break;
2339 :
2340 : case( META_TEXTLINECOLOR_ACTION ):
2341 : {
2342 0 : const MetaTextLineColorAction* pA = static_cast<const MetaTextLineColorAction*>(pAction);
2343 0 : const Color& rColor = pA->GetColor();
2344 0 : const bool bSet = pA->IsSetting();
2345 : sal_uLong nOldPos, nNewPos;
2346 :
2347 : // write RefPoint comment
2348 0 : rOStm.WriteInt16( GDI_TEXTLINECOLOR_COMMENT );
2349 :
2350 : // we'll write the ActionSize later
2351 0 : nOldPos = rOStm.Tell();
2352 0 : rOStm.SeekRel( 4 );
2353 :
2354 : // write data
2355 0 : WriteColor( rOStm, rColor );
2356 0 : rOStm.WriteUChar( bSet );
2357 0 : rOStm.WriteInt32( 0 ); // number of actions that follow this comment
2358 :
2359 : // calculate and write ActionSize of comment
2360 0 : nNewPos = rOStm.Tell();
2361 0 : rOStm.Seek( nOldPos );
2362 0 : rOStm.WriteInt32( ( nNewPos - nOldPos ) );
2363 0 : rOStm.Seek( nNewPos );
2364 :
2365 0 : nCount++;
2366 : }
2367 0 : break;
2368 :
2369 : case( META_TEXTLINE_ACTION ):
2370 : {
2371 0 : const MetaTextLineAction* pA = static_cast<const MetaTextLineAction*>(pAction);
2372 0 : const Point& rStartPt = pA->GetStartPoint();
2373 0 : const sal_Int32 nWidth = (sal_Int32) pA->GetWidth();
2374 0 : const FontStrikeout eStrikeout = pA->GetStrikeout();
2375 0 : const FontUnderline eUnderline = pA->GetUnderline();
2376 : sal_uLong nOldPos, nNewPos;
2377 :
2378 : // write RefPoint comment
2379 0 : rOStm.WriteInt16( GDI_TEXTLINE_COMMENT );
2380 :
2381 : // we'll write the ActionSize later
2382 0 : nOldPos = rOStm.Tell();
2383 0 : rOStm.SeekRel( 4 );
2384 :
2385 : // write data
2386 0 : WritePair( rOStm, rStartPt );
2387 0 : rOStm.WriteInt32( nWidth ).WriteUInt32( eStrikeout ).WriteUInt32( eUnderline );
2388 0 : rOStm.WriteInt32( 0 ); // number of actions that follow this comment
2389 :
2390 : // calculate and write ActionSize of comment
2391 0 : nNewPos = rOStm.Tell();
2392 0 : rOStm.Seek( nOldPos );
2393 0 : rOStm.WriteInt32( ( nNewPos - nOldPos ) );
2394 0 : rOStm.Seek( nNewPos );
2395 :
2396 0 : nCount++;
2397 : }
2398 0 : break;
2399 :
2400 : case( META_EPS_ACTION ):
2401 0 : break;
2402 :
2403 : case( META_COMMENT_ACTION ):
2404 : {
2405 0 : const MetaCommentAction* pA = static_cast<const MetaCommentAction*>(pAction);
2406 0 : const sal_uInt32 nDataSize = pA->GetDataSize();
2407 : sal_uLong nOldPos, nNewPos;
2408 :
2409 : // write RefPoint comment
2410 0 : rOStm.WriteInt16( GDI_COMMENT_COMMENT );
2411 :
2412 : // we'll write the ActionSize later
2413 0 : nOldPos = rOStm.Tell();
2414 0 : rOStm.SeekRel( 4 );
2415 :
2416 : // write data
2417 0 : write_uInt16_lenPrefixed_uInt8s_FromOString(rOStm, pA->GetComment());
2418 0 : rOStm.WriteInt32( pA->GetValue() ).WriteUInt32( nDataSize );
2419 :
2420 0 : if( nDataSize )
2421 0 : rOStm.Write( pA->GetData(), nDataSize );
2422 :
2423 0 : rOStm.WriteInt32( 0 ); // number of actions that follow this comment
2424 :
2425 : // calculate and write ActionSize of comment
2426 0 : nNewPos = rOStm.Tell();
2427 0 : rOStm.Seek( nOldPos );
2428 0 : rOStm.WriteInt32( ( nNewPos - nOldPos ) );
2429 0 : rOStm.Seek( nNewPos );
2430 :
2431 0 : nCount++;
2432 : }
2433 0 : break;
2434 :
2435 : #ifdef DBG_UTIL
2436 : default:
2437 : {
2438 : OStringBuffer aStr("Missing implementation for Action#: ");
2439 : aStr.append(static_cast<sal_Int32>(pAction->GetType()));
2440 : aStr.append('!');
2441 : OSL_FAIL(aStr.getStr());
2442 : }
2443 : break;
2444 : #endif
2445 : }
2446 : }
2447 :
2448 0 : return nCount;
2449 1233 : }
2450 :
2451 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|