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