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