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