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