xref: /trunk/main/vcl/source/gdi/cvtsvm.cxx (revision 50e6b0721ed882c1c74690abd9bee6b3a8da8cfd)
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_LINEDASHDOT_ACTION) :
603                 {
604                     sal_Int16 a(0);
605                     sal_Int32 b(0);
606 
607                     rIStm >> a; aLineInfo.SetDashCount(a);
608                     rIStm >> b; aLineInfo.SetDashLen(b);
609                     rIStm >> a; aLineInfo.SetDotCount(a);
610                     rIStm >> b; aLineInfo.SetDotLen(b);
611                     rIStm >> b; aLineInfo.SetDistance(b);
612 
613                     if(((aLineInfo.GetDashCount() && aLineInfo.GetDashLen())
614                         || (aLineInfo.GetDotCount() && aLineInfo.GetDotLen()))
615                         && aLineInfo.GetDistance())
616                     {
617                         aLineInfo.SetStyle(LINE_DASH);
618                     }
619                 }
620                 break;
621 
622                 case (GDI_EXTENDEDPOLYGON_ACTION) :
623                 {
624                     // read the PolyPolygon in every case
625                     PolyPolygon aInputPolyPolygon;
626                     ImplReadExtendedPolyPolygonAction(rIStm, aInputPolyPolygon);
627 
628                     // now check if it can be set somewhere
629                     if(nLastPolygonAction < rMtf.GetActionCount())
630                     {
631                         MetaPolyLineAction* pPolyLineAction = dynamic_cast< MetaPolyLineAction* >(rMtf.GetAction(nLastPolygonAction));
632 
633                         if(pPolyLineAction)
634                         {
635                             // replace MetaPolyLineAction when we have a single polygon. Do not rely on the
636                             // same point count; the originally written GDI_POLYLINE_ACTION may have been
637                             // Subdivided for better quality for older usages
638                             if(1 == aInputPolyPolygon.Count())
639                             {
640                                 rMtf.ReplaceAction(
641                                     new MetaPolyLineAction(
642                                         aInputPolyPolygon.GetObject(0),
643                                         pPolyLineAction->GetLineInfo()),
644                                     nLastPolygonAction);
645                                 pPolyLineAction->Delete();
646                             }
647                         }
648                         else
649                         {
650                             MetaPolyPolygonAction* pPolyPolygonAction = dynamic_cast< MetaPolyPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
651 
652                             if(pPolyPolygonAction)
653                             {
654                                 // replace MetaPolyPolygonAction when we have a curved polygon. Do rely on the
655                                 // same sub-polygon count
656                                 if(pPolyPolygonAction->GetPolyPolygon().Count() == aInputPolyPolygon.Count())
657                                 {
658                                     rMtf.ReplaceAction(
659                                         new MetaPolyPolygonAction(
660                                             aInputPolyPolygon),
661                                         nLastPolygonAction);
662                                     pPolyPolygonAction->Delete();
663                                 }
664                             }
665                             else
666                             {
667                                 MetaPolygonAction* pPolygonAction = dynamic_cast< MetaPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
668 
669                                 if(pPolygonAction)
670                                 {
671                                     // replace MetaPolygonAction
672                                     if(1 == aInputPolyPolygon.Count())
673                                     {
674                                         rMtf.ReplaceAction(
675                                             new MetaPolygonAction(
676                                                 aInputPolyPolygon.GetObject(0)),
677                                             nLastPolygonAction);
678                                         pPolygonAction->Delete();
679                                     }
680                                 }
681                             }
682                         }
683                     }
684                 }
685                 break;
686 
687                 case( GDI_RECT_ACTION ):
688                 {
689                     ImplReadRect( rIStm, aRect );
690                     rIStm >> nTmp >> nTmp1;
691 
692                     if( nTmp || nTmp1 )
693                         rMtf.AddAction( new MetaRoundRectAction( aRect, nTmp, nTmp1 ) );
694                     else
695                     {
696                         rMtf.AddAction( new MetaRectAction( aRect ) );
697 
698                         if( bFatLine )
699                             rMtf.AddAction( new MetaPolyLineAction( aRect, aLineInfo ) );
700                     }
701                 }
702                 break;
703 
704                 case( GDI_ELLIPSE_ACTION ):
705                 {
706                     ImplReadRect( rIStm, aRect );
707 
708                     if( bFatLine )
709                     {
710                         const Polygon aPoly( aRect.Center(), aRect.GetWidth() >> 1, aRect.GetHeight() >> 1 );
711 
712                         rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
713                         rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
714                         rMtf.AddAction( new MetaPolygonAction( aPoly ) );
715                         rMtf.AddAction( new MetaPopAction() );
716                         rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
717                     }
718                     else
719                         rMtf.AddAction( new MetaEllipseAction( aRect ) );
720                 }
721                 break;
722 
723                 case( GDI_ARC_ACTION ):
724                 {
725                     ImplReadRect( rIStm, aRect );
726                     rIStm >> aPt >> aPt1;
727 
728                     if( bFatLine )
729                     {
730                         const Polygon aPoly( aRect, aPt, aPt1, POLY_ARC );
731 
732                         rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
733                         rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
734                         rMtf.AddAction( new MetaPolygonAction( aPoly ) );
735                         rMtf.AddAction( new MetaPopAction() );
736                         rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
737                     }
738                     else
739                         rMtf.AddAction( new MetaArcAction( aRect, aPt, aPt1 ) );
740                 }
741                 break;
742 
743                 case( GDI_PIE_ACTION ):
744                 {
745                     ImplReadRect( rIStm, aRect );
746                     rIStm >> aPt >> aPt1;
747 
748                     if( bFatLine )
749                     {
750                         const Polygon aPoly( aRect, aPt, aPt1, POLY_PIE );
751 
752                         rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
753                         rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
754                         rMtf.AddAction( new MetaPolygonAction( aPoly ) );
755                         rMtf.AddAction( new MetaPopAction() );
756                         rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
757                     }
758                     else
759                         rMtf.AddAction( new MetaPieAction( aRect, aPt, aPt1 ) );
760                 }
761                 break;
762 
763                 case( GDI_INVERTRECT_ACTION ):
764                 case( GDI_HIGHLIGHTRECT_ACTION ):
765                 {
766                     ImplReadRect( rIStm, aRect );
767                     rMtf.AddAction( new MetaPushAction( PUSH_RASTEROP ) );
768                     rMtf.AddAction( new MetaRasterOpAction( ROP_INVERT ) );
769                     rMtf.AddAction( new MetaRectAction( aRect ) );
770                     rMtf.AddAction( new MetaPopAction() );
771                 }
772                 break;
773 
774                 case( GDI_POLYLINE_ACTION ):
775                 {
776                     ImplReadPoly( rIStm, aActionPoly );
777                     nLastPolygonAction = rMtf.GetActionCount();
778 
779                     if( bFatLine )
780                         rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
781                     else
782                         rMtf.AddAction( new MetaPolyLineAction( aActionPoly ) );
783                 }
784                 break;
785 
786                 case( GDI_POLYGON_ACTION ):
787                 {
788                     ImplReadPoly( rIStm, aActionPoly );
789 
790                     if( bFatLine )
791                     {
792                         rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
793                         rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
794                         rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
795                         rMtf.AddAction( new MetaPopAction() );
796                         rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
797                     }
798                     else
799                     {
800                         nLastPolygonAction = rMtf.GetActionCount();
801                         rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
802                     }
803                 }
804                 break;
805 
806                 case( GDI_POLYPOLYGON_ACTION ):
807                 {
808                     PolyPolygon aPolyPoly;
809 
810                     ImplReadPolyPoly( rIStm, aPolyPoly );
811 
812                     if( bFatLine )
813                     {
814                         rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
815                         rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
816                         rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
817                         rMtf.AddAction( new MetaPopAction() );
818 
819                         for( sal_uInt16 nPoly = 0, nCount = aPolyPoly.Count(); nPoly < nCount; nPoly++ )
820                             rMtf.AddAction( new MetaPolyLineAction( aPolyPoly[ nPoly ], aLineInfo ) );
821                     }
822                     else
823                     {
824                         nLastPolygonAction = rMtf.GetActionCount();
825                         rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
826                     }
827                 }
828                 break;
829 
830                 case( GDI_FONT_ACTION ):
831                 {
832                     Font    aFont;
833                     char    aName[ 32 ];
834                     sal_Int32   nWidth, nHeight;
835                     sal_Int16   nCharSet, nFamily, nPitch, nAlign, nWeight, nUnderline, nStrikeout;
836                     sal_Int16   nCharOrient, nLineOrient;
837                     sal_Bool    bItalic, bOutline, bShadow, bTransparent;
838 
839                     ImplReadColor( rIStm, aActionColor ); aFont.SetColor( aActionColor );
840                     ImplReadColor( rIStm, aActionColor ); aFont.SetFillColor( aActionColor );
841                     rIStm.Read( aName, 32 );
842                     aFont.SetName( UniString( aName, rIStm.GetStreamCharSet() ) );
843                     rIStm >> nWidth >> nHeight;
844                     rIStm >> nCharOrient >> nLineOrient;
845                     rIStm >> nCharSet >> nFamily >> nPitch >> nAlign >> nWeight >> nUnderline >> nStrikeout;
846                     rIStm >> bItalic >> bOutline >> bShadow >> bTransparent;
847 
848                     aFont.SetSize( Size( nWidth, nHeight ) );
849                     aFont.SetCharSet( (CharSet) nCharSet );
850                     aFont.SetFamily( (FontFamily) nFamily );
851                     aFont.SetPitch( (FontPitch) nPitch );
852                     aFont.SetAlign( (FontAlign) nAlign );
853                     aFont.SetWeight( ( nWeight == 1 ) ? WEIGHT_LIGHT : ( nWeight == 2 ) ? WEIGHT_NORMAL :
854                                      ( nWeight == 3 ) ? WEIGHT_BOLD : WEIGHT_DONTKNOW );
855                     aFont.SetUnderline( (FontUnderline) nUnderline );
856                     aFont.SetStrikeout( (FontStrikeout) nStrikeout );
857                     aFont.SetItalic( bItalic ? ITALIC_NORMAL : ITALIC_NONE );
858                     aFont.SetOutline( bOutline );
859                     aFont.SetShadow( bShadow );
860                     aFont.SetOrientation( nLineOrient );
861                     aFont.SetTransparent( bTransparent );
862 
863                     eActualCharSet = aFont.GetCharSet();
864                     if ( eActualCharSet == RTL_TEXTENCODING_DONTKNOW )
865                         eActualCharSet = gsl_getSystemTextEncoding();
866 
867                     rMtf.AddAction( new MetaFontAction( aFont ) );
868                     rMtf.AddAction( new MetaTextAlignAction( aFont.GetAlign() ) );
869                     rMtf.AddAction( new MetaTextColorAction( aFont.GetColor() ) );
870                     rMtf.AddAction( new MetaTextFillColorAction( aFont.GetFillColor(), !aFont.IsTransparent() ) );
871 
872                     // #106172# Track font relevant data in shadow VDev
873                     aFontVDev.SetFont( aFont );
874                 }
875                 break;
876 
877                 case( GDI_TEXT_ACTION ):
878                 {
879                     ByteString  aByteStr;
880                     sal_Int32       nIndex, nLen;
881 
882                     rIStm >> aPt >> nIndex >> nLen >> nTmp;
883                     if ( nTmp && ( static_cast< sal_uInt32 >( nTmp ) < ( SAL_MAX_UINT16 - 1 ) ) )
884                                         {
885                         rIStm.Read( aByteStr.AllocBuffer( (sal_uInt16)nTmp ), nTmp + 1 );
886                         UniString aStr( aByteStr, eActualCharSet );
887                         if ( nUnicodeCommentActionNumber == i )
888                             ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
889                         rMtf.AddAction( new MetaTextAction( aPt, aStr, (sal_uInt16) nIndex, (sal_uInt16) nLen ) );
890                     }
891                             rIStm.Seek( nActBegin + nActionSize );
892                 }
893                 break;
894 
895                 case( GDI_TEXTARRAY_ACTION ):
896                 {
897                     ByteString  aByteStr;
898                     sal_Int32*  pDXAry = NULL;
899                     sal_Int32       nIndex, nLen, nAryLen;
900 
901                     rIStm >> aPt >> nIndex >> nLen >> nTmp >> nAryLen;
902                     if ( nTmp && ( static_cast< sal_uInt32 >( nTmp ) < ( SAL_MAX_UINT16 - 1 ) ) )
903                     {
904                         rIStm.Read( aByteStr.AllocBuffer( (sal_uInt16)nTmp ), nTmp + 1 );
905                         UniString aStr( aByteStr, eActualCharSet );
906 
907                         if( nAryLen > 0L )
908                         {
909                             sal_Int32 nStrLen( aStr.Len() );
910 
911                             pDXAry = new sal_Int32[ Max( nAryLen, nStrLen ) ];
912 
913                             for( long j = 0L; j < nAryLen; j++ )
914                                 rIStm >> nTmp, pDXAry[ j ] = nTmp;
915 
916                             // #106172# Add last DX array elem, if missing
917                             if( nAryLen != nStrLen )
918                             {
919                                 if( nAryLen+1 == nStrLen )
920                                 {
921                                     sal_Int32* pTmpAry = new sal_Int32[nStrLen];
922 
923                                     aFontVDev.GetTextArray( aStr, pTmpAry, (sal_uInt16) nIndex, (sal_uInt16) nLen );
924 
925                                     // now, the difference between the
926                                     // last and the second last DX array
927                                     // is the advancement for the last
928                                     // glyph. Thus, to complete our meta
929                                     // action's DX array, just add that
930                                     // difference to last elem and store
931                                     // in very last.
932                                     if( nStrLen > 1 )
933                                         pDXAry[ nStrLen-1 ] = pDXAry[ nStrLen-2 ] + pTmpAry[ nStrLen-1 ] - pTmpAry[ nStrLen-2 ];
934                                     else
935                                         pDXAry[ nStrLen-1 ] = pTmpAry[ nStrLen-1 ]; // len=1: 0th position taken to be 0
936 
937                                     delete[] pTmpAry;
938                                 }
939     #ifdef DBG_UTIL
940                                 else
941                                     DBG_ERROR("More than one DX array element missing on SVM import");
942     #endif
943                             }
944                         }
945                         if ( nUnicodeCommentActionNumber == i )
946                             ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
947                         rMtf.AddAction( new MetaTextArrayAction( aPt, aStr, pDXAry, (sal_uInt16) nIndex, (sal_uInt16) nLen ) );
948 
949                         if( pDXAry )
950                             delete[] pDXAry;
951                     }
952                             rIStm.Seek( nActBegin + nActionSize );
953                 }
954                 break;
955 
956                 case( GDI_STRETCHTEXT_ACTION ):
957                 {
958                     ByteString  aByteStr;
959                     sal_Int32       nIndex, nLen, nWidth;
960 
961                     rIStm >> aPt >> nIndex >> nLen >> nTmp >> nWidth;
962                     if ( nTmp && ( static_cast< sal_uInt32 >( nTmp ) < ( SAL_MAX_INT16 - 1 ) ) )
963                     {
964                         rIStm.Read( aByteStr.AllocBuffer( (sal_uInt16)nTmp ), nTmp + 1 );
965                         UniString aStr( aByteStr, eActualCharSet );
966                         if ( nUnicodeCommentActionNumber == i )
967                             ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
968                         rMtf.AddAction( new MetaStretchTextAction( aPt, nWidth, aStr, (sal_uInt16) nIndex, (sal_uInt16) nLen ) );
969                     }
970                                         rIStm.Seek( nActBegin + nActionSize );
971                 }
972                 break;
973 
974                 case( GDI_BITMAP_ACTION ):
975                 {
976                     Bitmap aBmp;
977 
978                     rIStm >> aPt >> aBmp;
979                     rMtf.AddAction( new MetaBmpAction( aPt, aBmp ) );
980                 }
981                 break;
982 
983                 case( GDI_BITMAPSCALE_ACTION ):
984                 {
985                     Bitmap aBmp;
986 
987                     rIStm >> aPt >> aSz >> aBmp;
988                     rMtf.AddAction( new MetaBmpScaleAction( aPt, aSz, aBmp ) );
989                 }
990                 break;
991 
992                 case( GDI_BITMAPSCALEPART_ACTION ):
993                 {
994                     Bitmap  aBmp;
995                     Size    aSz2;
996 
997                     rIStm >> aPt >> aSz >> aPt1 >> aSz2 >> aBmp;
998                     rMtf.AddAction( new MetaBmpScalePartAction( aPt, aSz, aPt1, aSz2, aBmp ) );
999                 }
1000                 break;
1001 
1002                 case( GDI_PEN_ACTION ):
1003                 {
1004                     sal_Int32 nPenWidth;
1005                     sal_Int16 nPenStyle;
1006 
1007                     ImplReadColor( rIStm, aActionColor );
1008                     rIStm >> nPenWidth >> nPenStyle;
1009 
1010                     aLineInfo.SetStyle( nPenStyle ? LINE_SOLID : LINE_NONE );
1011                     aLineInfo.SetWidth( nPenWidth );
1012                     bFatLine = nPenStyle && !aLineInfo.IsDefault();
1013 
1014                     rMtf.AddAction( new MetaLineColorAction( aActionColor, nPenStyle != 0 ) );
1015                 }
1016                 break;
1017 
1018                 case( GDI_FILLBRUSH_ACTION ):
1019                 {
1020                     sal_Int16 nBrushStyle;
1021 
1022                     ImplReadColor( rIStm, aActionColor );
1023                     rIStm.SeekRel( 6L );
1024                     rIStm >> nBrushStyle;
1025                     rMtf.AddAction( new MetaFillColorAction( aActionColor, nBrushStyle != 0 ) );
1026                     rIStm.SeekRel( 2L );
1027                 }
1028                 break;
1029 
1030                 case( GDI_MAPMODE_ACTION ):
1031                 {
1032                     ImplReadMapMode( rIStm, aMapMode );
1033                     rMtf.AddAction( new MetaMapModeAction( aMapMode ) );
1034 
1035                     // #106172# Track font relevant data in shadow VDev
1036                     aFontVDev.SetMapMode( aMapMode );
1037                 }
1038                 break;
1039 
1040                 case( GDI_CLIPREGION_ACTION ):
1041                 {
1042                     Region  aRegion;
1043                     sal_Int16   nRegType;
1044                     sal_Int16   bIntersect;
1045                     sal_Bool    bClip = sal_False;
1046 
1047                     rIStm >> nRegType >> bIntersect;
1048                     ImplReadRect( rIStm, aRect );
1049 
1050                     switch( nRegType )
1051                     {
1052                         case( 0 ):
1053                         break;
1054 
1055                         case( 1 ):
1056                         {
1057                             Rectangle aRegRect;
1058 
1059                             ImplReadRect( rIStm, aRegRect );
1060                             aRegion = Region( aRegRect );
1061                             bClip = sal_True;
1062                         }
1063                         break;
1064 
1065                         case( 2 ):
1066                         {
1067                             ImplReadPoly( rIStm, aActionPoly );
1068                             aRegion = Region( aActionPoly );
1069                             bClip = sal_True;
1070                         }
1071                         break;
1072 
1073                         case( 3 ):
1074                         {
1075                             PolyPolygon aPolyPoly;
1076                             sal_Int32       nPolyCount;
1077 
1078                             rIStm >> nPolyCount;
1079 
1080                             for( sal_uInt16 j = 0; j < (sal_uInt16) nPolyCount; j++ )
1081                             {
1082                                 ImplReadPoly( rIStm, aActionPoly );
1083                                 aPolyPoly.Insert( aActionPoly );
1084                             }
1085 
1086                             aRegion = Region( aPolyPoly );
1087                             bClip = sal_True;
1088                         }
1089                         break;
1090                     }
1091 
1092                     if( bIntersect )
1093                         aRegion.Intersect( aRect );
1094 
1095                     rMtf.AddAction( new MetaClipRegionAction( aRegion, bClip ) );
1096                 }
1097                 break;
1098 
1099                 case( GDI_MOVECLIPREGION_ACTION ):
1100                 {
1101                     rIStm >> nTmp >> nTmp1;
1102                     rMtf.AddAction( new MetaMoveClipRegionAction( nTmp, nTmp1 ) );
1103                 }
1104                 break;
1105 
1106                 case( GDI_ISECTCLIPREGION_ACTION ):
1107                 {
1108                     ImplReadRect( rIStm, aRect );
1109                     rMtf.AddAction( new MetaISectRectClipRegionAction( aRect ) );
1110                 }
1111                 break;
1112 
1113                 case( GDI_RASTEROP_ACTION ):
1114                 {
1115                     RasterOp    eRasterOp;
1116                     sal_Int16       nRasterOp;
1117 
1118                     rIStm >> nRasterOp;
1119 
1120                     switch( nRasterOp )
1121                     {
1122                         case( 1 ):
1123                             eRasterOp = ROP_INVERT;
1124                         break;
1125 
1126                         case( 4 ):
1127                         case( 5 ):
1128                             eRasterOp = ROP_XOR;
1129                         break;
1130 
1131                         default:
1132                             eRasterOp = ROP_OVERPAINT;
1133                         break;
1134                     }
1135 
1136                     rMtf.AddAction( new MetaRasterOpAction( eRasterOp ) );
1137                 }
1138                 break;
1139 
1140                 case( GDI_PUSH_ACTION ):
1141                 {
1142                     aLIStack.Push( new LineInfo( aLineInfo ) );
1143                     rMtf.AddAction( new MetaPushAction( PUSH_ALL ) );
1144 
1145                     // #106172# Track font relevant data in shadow VDev
1146                     aFontVDev.Push();
1147                 }
1148                 break;
1149 
1150                 case( GDI_POP_ACTION ):
1151                 {
1152 
1153                     LineInfo* pLineInfo = (LineInfo*) aLIStack.Pop();
1154 
1155                     // restore line info
1156                     if( pLineInfo )
1157                     {
1158                         aLineInfo = *pLineInfo;
1159                         delete pLineInfo;
1160                         bFatLine = ( LINE_NONE != aLineInfo.GetStyle() ) && !aLineInfo.IsDefault();
1161                     }
1162 
1163                     rMtf.AddAction( new MetaPopAction() );
1164 
1165                     // #106172# Track font relevant data in shadow VDev
1166                     aFontVDev.Pop();
1167                 }
1168                 break;
1169 
1170                 case( GDI_GRADIENT_ACTION ):
1171                 {
1172                     Color   aStartCol;
1173                     Color   aEndCol;
1174                     sal_Int16   nStyle;
1175                     sal_Int16   nAngle;
1176                     sal_Int16   nBorder;
1177                     sal_Int16   nOfsX;
1178                     sal_Int16   nOfsY;
1179                     sal_Int16   nIntensityStart;
1180                     sal_Int16   nIntensityEnd;
1181 
1182                     ImplReadRect( rIStm, aRect );
1183                     rIStm >> nStyle;
1184                     ImplReadColor( rIStm, aStartCol );
1185                     ImplReadColor( rIStm, aEndCol );
1186                     rIStm >> nAngle >> nBorder >> nOfsX >> nOfsY >> nIntensityStart >> nIntensityEnd;
1187 
1188                     Gradient aGrad( (GradientStyle) nStyle, aStartCol, aEndCol );
1189 
1190                     aGrad.SetAngle( nAngle );
1191                     aGrad.SetBorder( nBorder );
1192                     aGrad.SetOfsX( nOfsX );
1193                     aGrad.SetOfsY( nOfsY );
1194                     aGrad.SetStartIntensity( nIntensityStart );
1195                     aGrad.SetEndIntensity( nIntensityEnd );
1196                     rMtf.AddAction( new MetaGradientAction( aRect, aGrad ) );
1197                 }
1198                 break;
1199 
1200                 case( GDI_TRANSPARENT_COMMENT ):
1201                 {
1202                     PolyPolygon aPolyPoly;
1203                     sal_Int32       nFollowingActionCount;
1204                     sal_Int16       nTrans;
1205 
1206                     rIStm >> aPolyPoly >> nTrans >> nFollowingActionCount;
1207                     ImplSkipActions( rIStm, nFollowingActionCount );
1208                     rMtf.AddAction( new MetaTransparentAction( aPolyPoly, nTrans ) );
1209 
1210 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
1211                     i += nFollowingActionCount;
1212 #endif
1213                 }
1214                 break;
1215 
1216                 case( GDI_FLOATTRANSPARENT_COMMENT ):
1217                 {
1218                     GDIMetaFile aMtf;
1219                     Point       aPos;
1220                     Size        aSize;
1221                     Gradient    aGradient;
1222                     sal_Int32       nFollowingActionCount;
1223 
1224                     rIStm >> aMtf >> aPos >> aSize >> aGradient >> nFollowingActionCount;
1225                     ImplSkipActions( rIStm, nFollowingActionCount );
1226                     rMtf.AddAction( new MetaFloatTransparentAction( aMtf, aPos, aSize, aGradient ) );
1227 
1228 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
1229                     i += nFollowingActionCount;
1230 #endif
1231                 }
1232                 break;
1233 
1234                 case( GDI_HATCH_COMMENT ):
1235                 {
1236                     PolyPolygon aPolyPoly;
1237                     Hatch       aHatch;
1238                     sal_Int32       nFollowingActionCount;
1239 
1240                     rIStm >> aPolyPoly >> aHatch >> nFollowingActionCount;
1241                     ImplSkipActions( rIStm, nFollowingActionCount );
1242                     rMtf.AddAction( new MetaHatchAction( aPolyPoly, aHatch ) );
1243 
1244 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
1245                     i += nFollowingActionCount;
1246 #endif
1247                 }
1248                 break;
1249 
1250                 case( GDI_REFPOINT_COMMENT ):
1251                 {
1252                     Point   aRefPoint;
1253                     sal_Bool    bSet;
1254                     sal_Int32   nFollowingActionCount;
1255 
1256                     rIStm >> aRefPoint >> bSet >> nFollowingActionCount;
1257                     ImplSkipActions( rIStm, nFollowingActionCount );
1258                     rMtf.AddAction( new MetaRefPointAction( aRefPoint, bSet ) );
1259 
1260 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
1261                     i += nFollowingActionCount;
1262 #endif
1263 
1264                     // #106172# Track font relevant data in shadow VDev
1265                     if( bSet )
1266                         aFontVDev.SetRefPoint( aRefPoint );
1267                     else
1268                         aFontVDev.SetRefPoint();
1269                 }
1270                 break;
1271 
1272                 case( GDI_TEXTLINECOLOR_COMMENT ):
1273                 {
1274                     Color   aColor;
1275                     sal_Bool    bSet;
1276                     sal_Int32   nFollowingActionCount;
1277 
1278                     rIStm >> aColor >> bSet >> nFollowingActionCount;
1279                     ImplSkipActions( rIStm, nFollowingActionCount );
1280                     rMtf.AddAction( new MetaTextLineColorAction( aColor, bSet ) );
1281 
1282 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
1283                     i += nFollowingActionCount;
1284 #endif
1285                 }
1286                 break;
1287 
1288                 case( GDI_TEXTLINE_COMMENT ):
1289                 {
1290                     Point   aStartPt;
1291                     long    nWidth;
1292                     sal_uInt32 nStrikeout;
1293                     sal_uInt32 nUnderline;
1294                     sal_Int32   nFollowingActionCount;
1295 
1296                     rIStm >> aStartPt >> nWidth >> nStrikeout >> nUnderline >> nFollowingActionCount;
1297                     ImplSkipActions( rIStm, nFollowingActionCount );
1298                     rMtf.AddAction( new MetaTextLineAction( aStartPt, nWidth,
1299                                                             (FontStrikeout) nStrikeout,
1300                                                             (FontUnderline) nUnderline,
1301                                                             UNDERLINE_NONE ) );
1302 
1303 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
1304                     i += nFollowingActionCount;
1305 #endif
1306                 }
1307                 break;
1308 
1309                 case( GDI_GRADIENTEX_COMMENT ):
1310                 {
1311                     PolyPolygon aPolyPoly;
1312                     Gradient    aGradient;
1313                     sal_Int32       nFollowingActionCount;
1314 
1315                     rIStm >> aPolyPoly >> aGradient >> nFollowingActionCount;
1316                     ImplSkipActions( rIStm, nFollowingActionCount );
1317                     rMtf.AddAction( new MetaGradientExAction( aPolyPoly, aGradient ) );
1318 
1319 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
1320                     i += nFollowingActionCount;
1321 #endif
1322                 }
1323                 break;
1324 
1325                 case( GDI_COMMENT_COMMENT ):
1326                 {
1327                     ByteString  aComment;
1328                     sal_Int32   nValue;
1329                     sal_uInt32  nDataSize;
1330                     sal_uInt8*      pData;
1331                     sal_Int32       nFollowingActionCount;
1332 
1333                     rIStm >> aComment >> nValue >> nDataSize;
1334 
1335                     if( nDataSize )
1336                     {
1337                         pData = new sal_uInt8[ nDataSize ];
1338                         rIStm.Read( pData, nDataSize );
1339                     }
1340                     else
1341                         pData = NULL;
1342 
1343                     rIStm >> nFollowingActionCount;
1344                     ImplSkipActions( rIStm, nFollowingActionCount );
1345                     rMtf.AddAction( new MetaCommentAction( aComment, nValue, pData, nDataSize ) );
1346 
1347 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
1348                     i += nFollowingActionCount;
1349 #endif
1350                 }
1351                 break;
1352 
1353                 case ( GDI_UNICODE_COMMENT ):
1354                 {
1355                     nUnicodeCommentActionNumber = i + 1;
1356                     nUnicodeCommentStreamPos = rIStm.Tell() - 6;
1357                     rIStm.SeekRel( nActionSize - 4 );
1358                 }
1359                 break;
1360 
1361                 default:
1362                     rIStm.SeekRel( nActionSize - 4L );
1363                 break;
1364             }
1365                 }
1366 
1367         // cleanup push-pop stack if neccessary
1368         for( void* pLineInfo = aLIStack.Pop(); pLineInfo; pLineInfo = aLIStack.Pop() )
1369             delete (LineInfo*) pLineInfo;
1370 
1371     rIStm.SetNumberFormatInt( nOldFormat );
1372 }
1373 
1374 // ------------------------------------------------------------------------
1375 
1376 void SVMConverter::ImplConvertToSVM1( SvStream& rOStm, GDIMetaFile& rMtf )
1377 {
1378     sal_uLong               nPos;
1379     sal_uLong               nCountPos;
1380     Font                aSaveFont;
1381     const sal_uInt16        nOldFormat = rOStm.GetNumberFormatInt();
1382     rtl_TextEncoding    eActualCharSet = gsl_getSystemTextEncoding();
1383     const Size          aPrefSize( rMtf.GetPrefSize() );
1384     sal_Bool                bRop_0_1 = sal_False;
1385     VirtualDevice       aSaveVDev;
1386     Color               aLineCol( COL_BLACK );
1387     Stack               aLineColStack;
1388 
1389     rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1390 
1391     //MagicCode schreiben
1392     rOStm << "SVGDI";                                   // Kennung
1393     nPos = rOStm.Tell();
1394     rOStm << (sal_Int16) 42;                                // HeaderSize
1395     rOStm << (sal_Int16) 200;                               // VERSION
1396     rOStm << (sal_Int32) aPrefSize.Width();
1397     rOStm << (sal_Int32) aPrefSize.Height();
1398     ImplWriteMapMode( rOStm, rMtf.GetPrefMapMode() );
1399 
1400     // ActionCount wird spaeter geschrieben
1401     nCountPos = rOStm.Tell();
1402     rOStm.SeekRel( 4L );
1403 
1404     const sal_Int32 nActCount = ImplWriteActions( rOStm, rMtf, aSaveVDev, bRop_0_1, aLineCol, aLineColStack, eActualCharSet );
1405     const sal_uLong nActPos = rOStm.Tell();
1406 
1407     rOStm.Seek( nCountPos );
1408     rOStm << nActCount;
1409     rOStm.Seek( nActPos );
1410     rOStm.SetNumberFormatInt( nOldFormat );
1411 
1412     // cleanup push-pop stack if neccessary
1413     for( void* pCol = aLineColStack.Pop(); pCol; pCol = aLineColStack.Pop() )
1414         delete (Color*) pCol;
1415 }
1416 
1417 // ------------------------------------------------------------------------
1418 
1419 sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
1420                                       VirtualDevice& rSaveVDev, sal_Bool& rRop_0_1,
1421                                       Color& rLineCol, Stack& rLineColStack,
1422                                       rtl_TextEncoding& rActualCharSet )
1423 {
1424     sal_uLong nCount = 0;
1425     for( sal_uLong i = 0, nActionCount = rMtf.GetActionCount(); i < nActionCount; i++ )
1426     {
1427         const MetaAction* pAction = rMtf.GetAction( i );
1428 
1429         switch( pAction->GetType() )
1430         {
1431             case( META_PIXEL_ACTION ):
1432             {
1433                 MetaPixelAction* pAct = (MetaPixelAction*) pAction;
1434 
1435                 rOStm << (sal_Int16) GDI_PIXEL_ACTION;
1436                 rOStm << (sal_Int32) 18;
1437                 rOStm << pAct->GetPoint();
1438                 ImplWriteColor( rOStm, pAct->GetColor() );
1439                 nCount++;
1440             }
1441             break;
1442 
1443             case( META_POINT_ACTION ):
1444             {
1445                 MetaPointAction* pAct = (MetaPointAction*) pAction;
1446 
1447                 rOStm << (sal_Int16) GDI_POINT_ACTION;
1448                 rOStm << (sal_Int32) 12;
1449                 rOStm << pAct->GetPoint();
1450                 nCount++;
1451             }
1452             break;
1453 
1454             case( META_LINE_ACTION ):
1455             {
1456                 MetaLineAction* pAct = (MetaLineAction*) pAction;
1457                 const LineInfo& rInfo = pAct->GetLineInfo();
1458                 const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
1459                 const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
1460                 const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
1461 
1462                 if( bFatLine )
1463                 {
1464                     ImplWritePushAction( rOStm );
1465                     ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
1466 
1467                     if(bLineJoin)
1468                     {
1469                         rOStm << (sal_Int16) GDI_LINEJOIN_ACTION;
1470                         rOStm << (sal_Int32) 6;
1471                         rOStm << (sal_Int16) rInfo.GetLineJoin();
1472                     }
1473 
1474                     if(bLineDashDot)
1475                     {
1476                         rOStm << (sal_Int16) GDI_LINEDASHDOT_ACTION;
1477                         rOStm << (sal_Int32) 4 + 16;
1478                         rOStm << (sal_Int16)rInfo.GetDashCount();
1479                         rOStm << (sal_Int32)rInfo.GetDashLen();
1480                         rOStm << (sal_Int16)rInfo.GetDotCount();
1481                         rOStm << (sal_Int32)rInfo.GetDotLen();
1482                         rOStm << (sal_Int32)rInfo.GetDistance();
1483                     }
1484                 }
1485 
1486                 rOStm << (sal_Int16) GDI_LINE_ACTION;
1487                 rOStm << (sal_Int32) 20;
1488                 rOStm << pAct->GetStartPoint();
1489                 rOStm << pAct->GetEndPoint();
1490                 nCount++;
1491 
1492                 if( bFatLine )
1493                 {
1494                     ImplWritePopAction( rOStm );
1495                     nCount += 3;
1496 
1497                     if(bLineJoin)
1498                     {
1499                         nCount += 1;
1500                     }
1501 
1502                     if(bLineDashDot)
1503                     {
1504                         nCount += 1;
1505                     }
1506                 }
1507             }
1508             break;
1509 
1510             case( META_RECT_ACTION ):
1511             {
1512                 MetaRectAction* pAct = (MetaRectAction*) pAction;
1513 
1514                 rOStm << (sal_Int16) GDI_RECT_ACTION;
1515                 rOStm << (sal_Int32) 28;
1516                 ImplWriteRect( rOStm, pAct->GetRect() );
1517                 rOStm << (sal_Int32) 0;
1518                 rOStm << (sal_Int32) 0;
1519                 nCount++;
1520             }
1521             break;
1522 
1523             case( META_ROUNDRECT_ACTION ):
1524             {
1525                 MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction;
1526 
1527                 rOStm << (sal_Int16) GDI_RECT_ACTION;
1528                 rOStm << (sal_Int32) 28;
1529                 ImplWriteRect( rOStm, pAct->GetRect() );
1530                 rOStm << (sal_Int32) pAct->GetHorzRound();
1531                 rOStm << (sal_Int32) pAct->GetVertRound();
1532                 nCount++;
1533             }
1534             break;
1535 
1536             case( META_ELLIPSE_ACTION ):
1537             {
1538                 MetaEllipseAction* pAct = (MetaEllipseAction*) pAction;
1539 
1540                 rOStm << (sal_Int16) GDI_ELLIPSE_ACTION;
1541                 rOStm << (sal_Int32) 20;
1542                 ImplWriteRect( rOStm, pAct->GetRect() );
1543                 nCount++;
1544             }
1545             break;
1546 
1547             case( META_ARC_ACTION ):
1548             {
1549                 MetaArcAction* pAct = (MetaArcAction*) pAction;
1550 
1551                 rOStm << (sal_Int16) GDI_ARC_ACTION;
1552                 rOStm << (sal_Int32) 36;
1553                 ImplWriteRect( rOStm, pAct->GetRect() );
1554                 rOStm << pAct->GetStartPoint();
1555                 rOStm << pAct->GetEndPoint();
1556                 nCount++;
1557             }
1558             break;
1559 
1560             case( META_PIE_ACTION ):
1561             {
1562                 MetaPieAction* pAct = (MetaPieAction*) pAction;
1563 
1564                 rOStm << (sal_Int16) GDI_PIE_ACTION;
1565                 rOStm << (sal_Int32) 36;
1566                 ImplWriteRect( rOStm, pAct->GetRect() );
1567                 rOStm << pAct->GetStartPoint();
1568                 rOStm << pAct->GetEndPoint();
1569                 nCount++;
1570             }
1571             break;
1572 
1573             case( META_CHORD_ACTION ):
1574             {
1575                 MetaChordAction*    pAct = (MetaChordAction*) pAction;
1576                 Polygon             aChordPoly( pAct->GetRect(), pAct->GetStartPoint(),
1577                                                 pAct->GetEndPoint(), POLY_CHORD );
1578                 const sal_uInt16        nPoints = aChordPoly.GetSize();
1579 
1580                 rOStm << (sal_Int16) GDI_POLYGON_ACTION;
1581                 rOStm << (sal_Int32) ( 8 + ( nPoints << 3 ) );
1582                 rOStm << (sal_Int32) nPoints;
1583 
1584                 for( sal_uInt16 n = 0; n < nPoints; n++ )
1585                     rOStm << aChordPoly[ n ];
1586                 nCount++;
1587             }
1588             break;
1589 
1590             case( META_POLYLINE_ACTION ):
1591             {
1592                 // #i102224#
1593                 MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction;
1594                 // #i102224# Here the evtl. curved nature of Polygon was
1595                 // ignored (for all those Years). Adapted to at least write
1596                 // a polygon representing the curve as good as possible
1597                 Polygon aSimplePoly;
1598                 pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
1599                 const LineInfo& rInfo = pAct->GetLineInfo();
1600                 const sal_uInt16 nPoints(aSimplePoly.GetSize());
1601                 const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
1602                 const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
1603                 const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
1604 
1605                 if( bFatLine )
1606                 {
1607                     ImplWritePushAction( rOStm );
1608                     ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
1609 
1610                     if(bLineJoin)
1611                     {
1612                         rOStm << (sal_Int16) GDI_LINEJOIN_ACTION;
1613                         rOStm << (sal_Int32) 6;
1614                         rOStm << (sal_Int16) rInfo.GetLineJoin();
1615                     }
1616                 }
1617 
1618                 if(bLineDashDot)
1619                 {
1620                     rOStm << (sal_Int16) GDI_LINEDASHDOT_ACTION;
1621                     rOStm << (sal_Int32) 4 + 16;
1622                     rOStm << (sal_Int16)rInfo.GetDashCount();
1623                     rOStm << (sal_Int32)rInfo.GetDashLen();
1624                     rOStm << (sal_Int16)rInfo.GetDotCount();
1625                     rOStm << (sal_Int32)rInfo.GetDotLen();
1626                     rOStm << (sal_Int32)rInfo.GetDistance();
1627                 }
1628 
1629                 rOStm << (sal_Int16) GDI_POLYLINE_ACTION;
1630                 rOStm << (sal_Int32) ( 8 + ( nPoints << 3 ) );
1631                 rOStm << (sal_Int32) nPoints;
1632 
1633                 for( sal_uInt16 n = 0; n < nPoints; n++ )
1634                 {
1635                     rOStm << aSimplePoly[ n ];
1636                 }
1637 
1638                 nCount++;
1639 
1640                 const PolyPolygon aPolyPolygon(pAct->GetPolygon());
1641                 if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
1642                 {
1643                     nCount++;
1644                 }
1645 
1646                 if( bFatLine )
1647                 {
1648                     ImplWritePopAction( rOStm );
1649                     nCount += 3;
1650 
1651                     if(bLineJoin)
1652                     {
1653                         nCount += 1;
1654                     }
1655                 }
1656 
1657                 if(bLineDashDot)
1658                 {
1659                     nCount += 1;
1660                 }
1661             }
1662             break;
1663 
1664             case( META_POLYGON_ACTION ):
1665             {
1666                 MetaPolygonAction* pAct = (MetaPolygonAction*)pAction;
1667                 // #i102224# Here the evtl. curved nature of Polygon was
1668                 // ignored (for all those Years). Adapted to at least write
1669                 // a polygon representing the curve as good as possible
1670                 Polygon aSimplePoly;
1671                 pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
1672                 const sal_uInt16 nPoints(aSimplePoly.GetSize());
1673 
1674                 rOStm << (sal_Int16) GDI_POLYGON_ACTION;
1675                 rOStm << (sal_Int32) ( 8 + ( nPoints << 3 ) );
1676                 rOStm << (sal_Int32) nPoints;
1677 
1678                 for( sal_uInt16 n = 0; n < nPoints; n++ )
1679                     rOStm << aSimplePoly[ n ];
1680 
1681                 nCount++;
1682 
1683                 const PolyPolygon aPolyPolygon(pAct->GetPolygon());
1684                 if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
1685                 {
1686                     nCount++;
1687                 }
1688             }
1689             break;
1690 
1691             case( META_POLYPOLYGON_ACTION ):
1692             {
1693                 MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction;
1694                 ImplWritePolyPolyAction( rOStm, pAct->GetPolyPolygon() );
1695                 nCount++;
1696 
1697                 if(ImplWriteExtendedPolyPolygonAction(rOStm, pAct->GetPolyPolygon(), true))
1698                 {
1699                     nCount++;
1700                 }
1701             }
1702             break;
1703 
1704             case( META_TEXT_ACTION ):
1705             {
1706                 MetaTextAction* pAct = (MetaTextAction*) pAction;
1707                 String          aUniText( pAct->GetText() );
1708                 ByteString      aText( aUniText, rActualCharSet );
1709                 const sal_uLong     nStrLen = aText.Len();
1710 
1711                 if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
1712                     nCount++;
1713 
1714                 rOStm << (sal_Int16) GDI_TEXT_ACTION;
1715                 rOStm << (sal_Int32) ( 24 + ( nStrLen + 1 ) );
1716                 rOStm << pAct->GetPoint();
1717                 rOStm << (sal_Int32) pAct->GetIndex();
1718                 rOStm << (sal_Int32) pAct->GetLen();
1719                 rOStm << (sal_Int32) nStrLen;
1720                 rOStm.Write( aText.GetBuffer(), nStrLen + 1 );
1721                 nCount++;
1722             }
1723             break;
1724 
1725             case( META_TEXTARRAY_ACTION ):
1726             {
1727                 MetaTextArrayAction*    pAct = (MetaTextArrayAction*)pAction;
1728                 ByteString              aText( pAct->GetText(), rActualCharSet );
1729                 String                  aUniText( pAct->GetText(), pAct->GetIndex(), pAct->GetLen() );
1730                 sal_uLong                   nAryLen;
1731                 sal_uLong                   nLen = pAct->GetLen();
1732                 const sal_uLong             nTextLen = aText.Len();
1733                 sal_Int32*              pDXArray = pAct->GetDXArray();
1734 
1735                 if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
1736                     nCount++;
1737 
1738                 if( ( nLen + pAct->GetIndex() ) > nTextLen )
1739                 {
1740                     if( pAct->GetIndex() <= nTextLen )
1741                         nLen = nTextLen - pAct->GetIndex();
1742                     else
1743                         nLen = 0UL;
1744                 }
1745 
1746                 if( !pDXArray || !nLen )
1747                     nAryLen = 0;
1748                 else
1749                     nAryLen = nLen; // #105987# Write out all of DX array
1750 
1751                 rOStm << (sal_Int16) GDI_TEXTARRAY_ACTION;
1752                 rOStm << (sal_Int32) ( 28 + ( nLen + 1 ) + ( nAryLen * 4 ) );
1753                 rOStm << pAct->GetPoint();
1754                 rOStm << (sal_Int32) 0;
1755                 rOStm << (sal_Int32) nLen;
1756                 rOStm << (sal_Int32) nLen;
1757                 rOStm << (sal_Int32) nAryLen;
1758                 rOStm.Write( aText.GetBuffer()+pAct->GetIndex(), nLen + 1 );
1759 
1760                 for( sal_uLong n = 0UL ; n < nAryLen; n++ )
1761                     rOStm << (sal_Int32) pDXArray[ n ];
1762 
1763                 nCount++;
1764             }
1765             break;
1766 
1767             case( META_STRETCHTEXT_ACTION ):
1768             {
1769                 MetaStretchTextAction*  pAct = (MetaStretchTextAction*) pAction;
1770                 String                  aUniText( pAct->GetText() );
1771                 ByteString              aText( aUniText, rActualCharSet );
1772                 const sal_uLong             nStrLen = aText.Len();
1773 
1774                 if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
1775                     nCount++;
1776 
1777                 rOStm << (sal_Int16) GDI_STRETCHTEXT_ACTION;
1778                 rOStm << (sal_Int32) ( 28 + ( nStrLen + 1 ) );
1779                 rOStm << pAct->GetPoint();
1780                 rOStm << (sal_Int32) pAct->GetIndex();
1781                 rOStm << (sal_Int32) pAct->GetLen();
1782                 rOStm << (sal_Int32) nStrLen;
1783                 rOStm << (sal_Int32) pAct->GetWidth();
1784                 rOStm.Write( aText.GetBuffer(), nStrLen + 1 );
1785                 nCount++;
1786             }
1787             break;
1788 
1789             case( META_BMP_ACTION ):
1790             {
1791                 MetaBmpAction* pAct = (MetaBmpAction*) pAction;
1792 
1793                 rOStm << (sal_Int16) GDI_BITMAP_ACTION;
1794                 rOStm << (sal_Int32) 12;
1795                 rOStm << pAct->GetPoint();
1796                 rOStm << pAct->GetBitmap();
1797                 nCount++;
1798             }
1799             break;
1800 
1801             case( META_BMPSCALE_ACTION ):
1802             {
1803                 MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
1804 
1805                 rOStm << (sal_Int16) GDI_BITMAPSCALE_ACTION;
1806                 rOStm << (sal_Int32) 20;
1807                 rOStm << pAct->GetPoint();
1808                 rOStm << pAct->GetSize();
1809                 rOStm << pAct->GetBitmap();
1810                 nCount++;
1811             }
1812             break;
1813 
1814             case( META_BMPSCALEPART_ACTION ):
1815             {
1816                 MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
1817 
1818                 rOStm << (sal_Int16) GDI_BITMAPSCALEPART_ACTION;
1819                 rOStm << (sal_Int32) 36;
1820                 rOStm << pAct->GetDestPoint();
1821                 rOStm << pAct->GetDestSize();
1822                 rOStm << pAct->GetSrcPoint();
1823                 rOStm << pAct->GetSrcSize();
1824                 rOStm << pAct->GetBitmap();
1825                 nCount++;
1826             }
1827             break;
1828 
1829             case( META_BMPEX_ACTION ):
1830             {
1831                 MetaBmpExAction*    pAct = (MetaBmpExAction*) pAction;
1832                 const Bitmap        aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
1833 
1834                 rOStm << (sal_Int16) GDI_BITMAP_ACTION;
1835                 rOStm << (sal_Int32) 12;
1836                 rOStm << pAct->GetPoint();
1837                 rOStm << aBmp;
1838                 nCount++;
1839             }
1840             break;
1841 
1842             case( META_BMPEXSCALE_ACTION ):
1843             {
1844                 MetaBmpExScaleAction*   pAct = (MetaBmpExScaleAction*) pAction;
1845                 const Bitmap            aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
1846 
1847                 rOStm << (sal_Int16) GDI_BITMAPSCALE_ACTION;
1848                 rOStm << (sal_Int32) 20;
1849                 rOStm << pAct->GetPoint();
1850                 rOStm << pAct->GetSize();
1851                 rOStm << aBmp;
1852                 nCount++;
1853             }
1854             break;
1855 
1856             case( META_BMPEXSCALEPART_ACTION ):
1857             {
1858                 MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction;
1859                 const Bitmap            aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
1860 
1861                 rOStm << (sal_Int16) GDI_BITMAPSCALEPART_ACTION;
1862                 rOStm << (sal_Int32) 36;
1863                 rOStm << pAct->GetDestPoint();
1864                 rOStm << pAct->GetDestSize();
1865                 rOStm << pAct->GetSrcPoint();
1866                 rOStm << pAct->GetSrcSize();
1867                 rOStm << aBmp;
1868                 nCount++;
1869             }
1870             break;
1871 
1872             case( META_GRADIENT_ACTION ):
1873             {
1874                 MetaGradientAction* pAct = (MetaGradientAction*) pAction;
1875                 const Gradient&     rGrad = pAct->GetGradient();
1876 
1877                 rOStm << (sal_Int16) GDI_GRADIENT_ACTION;
1878                 rOStm << (sal_Int32) 46;
1879                 ImplWriteRect( rOStm, pAct->GetRect() );
1880                 rOStm << (sal_Int16) rGrad.GetStyle();
1881                 ImplWriteColor( rOStm, rGrad.GetStartColor() );
1882                 ImplWriteColor( rOStm, rGrad.GetEndColor() );
1883                 rOStm << (sal_Int16) rGrad.GetAngle();
1884                 rOStm << (sal_Int16) rGrad.GetBorder();
1885                 rOStm << (sal_Int16) rGrad.GetOfsX();
1886                 rOStm << (sal_Int16) rGrad.GetOfsY();
1887                 rOStm << (sal_Int16) rGrad.GetStartIntensity();
1888                 rOStm << (sal_Int16) rGrad.GetEndIntensity();
1889                 nCount++;
1890             }
1891             break;
1892 
1893             case( META_GRADIENTEX_ACTION ):
1894             {
1895                 const MetaGradientExAction* pA = (MetaGradientExAction*) pAction;
1896                 sal_uLong                       nOldPos, nNewPos;
1897 
1898                 // write RefPoint comment
1899                 rOStm << (sal_Int16) GDI_GRADIENTEX_COMMENT;
1900 
1901                 // we'll write the ActionSize later
1902                 nOldPos = rOStm.Tell();
1903                 rOStm.SeekRel( 4 );
1904 
1905                 // write data
1906                 rOStm << pA->GetPolyPolygon() << pA->GetGradient();
1907                 rOStm << (sal_Int32) 0; // number of actions that follow this comment
1908 
1909                 // calculate and write ActionSize of comment
1910                 nNewPos = rOStm.Tell();
1911                 rOStm.Seek( nOldPos );
1912                 rOStm << (sal_Int32) ( nNewPos - nOldPos );
1913                 rOStm.Seek( nNewPos );
1914 
1915                 nCount++;
1916             }
1917             break;
1918 
1919             case( META_WALLPAPER_ACTION ):
1920             {
1921                 MetaWallpaperAction*    pAct = (MetaWallpaperAction*) pAction;
1922                 const Color&            rColor = pAct->GetWallpaper().GetColor();
1923 
1924                 ImplWritePushAction( rOStm );
1925                 ImplWriteLineColor( rOStm, rColor, 1 );
1926                 ImplWriteFillColor( rOStm, rColor, 1 );
1927 
1928                 rOStm << (sal_Int16) GDI_RECT_ACTION;
1929                 rOStm << (sal_Int32) 28;
1930                 ImplWriteRect( rOStm, pAct->GetRect() );
1931                 rOStm << (sal_Int32) 0;
1932                 rOStm << (sal_Int32) 0;
1933 
1934                 ImplWritePopAction( rOStm );
1935                 nCount += 5;
1936             }
1937             break;
1938 
1939             case( META_CLIPREGION_ACTION ):
1940             {
1941                 MetaClipRegionAction*   pAct = (MetaClipRegionAction*) pAction;
1942                 const Region&           rRegion = pAct->GetRegion();
1943                 Rectangle               aClipRect;
1944 
1945                 rOStm << (sal_Int16) GDI_CLIPREGION_ACTION;
1946                 rOStm << (sal_Int32) 24;
1947 
1948                 if( pAct->IsClipping() )
1949                 {
1950                     aClipRect = rRegion.GetBoundRect();
1951                     rOStm << (sal_Int16) 1;
1952                 }
1953                 else
1954                     rOStm << (sal_Int16) 0;
1955 
1956                 rOStm << (sal_Int16) 0;
1957                 ImplWriteRect( rOStm, aClipRect );
1958 
1959                 if( pAct->IsClipping() )
1960                     ImplWriteRect( rOStm, aClipRect );
1961 
1962                 nCount++;
1963             }
1964             break;
1965 
1966             case( META_ISECTRECTCLIPREGION_ACTION ):
1967             {
1968                 MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction;
1969 
1970                 rOStm << (sal_Int16) GDI_ISECTCLIPREGION_ACTION;
1971                 rOStm << (sal_Int32) 20;
1972                 rOStm << pAct->GetRect();
1973                 nCount++;
1974             }
1975             break;
1976 
1977             case( META_MOVECLIPREGION_ACTION ):
1978             {
1979                 MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction;
1980 
1981                 rOStm << (sal_Int16) GDI_MOVECLIPREGION_ACTION;
1982                 rOStm << (sal_Int32) 12;
1983                 rOStm << (sal_Int32) pAct->GetHorzMove();
1984                 rOStm << (sal_Int32) pAct->GetVertMove();
1985                 nCount++;
1986             }
1987             break;
1988 
1989             case( META_LINECOLOR_ACTION ):
1990             {
1991                 MetaLineColorAction* pAct = (MetaLineColorAction*) pAction;
1992                 ImplWriteLineColor( rOStm, rLineCol = pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
1993                 nCount++;
1994             }
1995             break;
1996 
1997             case( META_FILLCOLOR_ACTION ):
1998             {
1999                 MetaFillColorAction* pAct = (MetaFillColorAction*) pAction;
2000                 ImplWriteFillColor( rOStm, pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
2001                 nCount++;
2002             }
2003             break;
2004 
2005             case( META_FONT_ACTION ):
2006             {
2007                 rSaveVDev.SetFont( ( (MetaFontAction*) pAction )->GetFont() );
2008                 ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2009                 nCount++;
2010             }
2011             break;
2012 
2013             case( META_TEXTCOLOR_ACTION ):
2014             {
2015                 Font aSaveFont( rSaveVDev.GetFont() );
2016 
2017                 aSaveFont.SetColor( ( (MetaTextColorAction*) pAction )->GetColor() );
2018                 rSaveVDev.SetFont( aSaveFont );
2019                 ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2020                 nCount++;
2021             }
2022             break;
2023 
2024             case( META_TEXTFILLCOLOR_ACTION ):
2025             {
2026                 MetaTextFillColorAction*    pAct = (MetaTextFillColorAction*) pAction;
2027                 Font                        aSaveFont( rSaveVDev.GetFont() );
2028 
2029                 if( pAct->IsSetting() )
2030                     aSaveFont.SetFillColor( pAct->GetColor() );
2031                 else
2032                     aSaveFont.SetFillColor( Color( COL_TRANSPARENT ) );
2033 
2034                 rSaveVDev.SetFont( aSaveFont );
2035                 ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2036                 nCount++;
2037             }
2038             break;
2039 
2040             case( META_TEXTALIGN_ACTION ):
2041             {
2042                 Font aSaveFont( rSaveVDev.GetFont() );
2043 
2044                 aSaveFont.SetAlign( ( (MetaTextAlignAction*) pAction )->GetTextAlign() );
2045                 rSaveVDev.SetFont( aSaveFont );
2046                 ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2047                 nCount++;
2048             }
2049             break;
2050 
2051             case( META_MAPMODE_ACTION ):
2052             {
2053                 MetaMapModeAction* pAct = (MetaMapModeAction*) pAction;
2054 
2055                 rOStm << (sal_Int16) GDI_MAPMODE_ACTION;
2056                 rOStm << (sal_Int32) 30;
2057                 ImplWriteMapMode( rOStm, pAct->GetMapMode() );
2058                 nCount++;
2059             }
2060             break;
2061 
2062             case( META_PUSH_ACTION ):
2063             {
2064                 ImplWritePushAction( rOStm );
2065                 rLineColStack.Push( new Color( rLineCol ) );
2066                 rSaveVDev.Push();
2067                 nCount++;
2068             }
2069             break;
2070 
2071             case( META_POP_ACTION ):
2072             {
2073                 Color* pCol = (Color*) rLineColStack.Pop();
2074 
2075                 if( pCol )
2076                 {
2077                     rLineCol = *pCol;
2078                     delete pCol;
2079                 }
2080 
2081                 ImplWritePopAction( rOStm );
2082                 rSaveVDev.Pop();
2083                 nCount++;
2084             }
2085             break;
2086 
2087             case( META_RASTEROP_ACTION ):
2088             {
2089                 MetaRasterOpAction* pAct = (MetaRasterOpAction*) pAction;
2090 
2091                 if( ( pAct->GetRasterOp() != ROP_0 ) && ( pAct->GetRasterOp() != ROP_1 ) )
2092                 {
2093                     sal_Int16 nRasterOp;
2094 
2095                     // Falls vorher ROP_0/1 gesetzt war, alten
2096                     // Zustand durch Pop erst wieder herstellen
2097                     if( rRop_0_1 )
2098                     {
2099                         ImplWritePopAction( rOStm );
2100                         rSaveVDev.Pop();
2101                         rRop_0_1 = sal_False;
2102                         nCount++;
2103                     }
2104 
2105                     switch( pAct->GetRasterOp() )
2106                     {
2107                         case( ROP_OVERPAINT ) : nRasterOp = 0; break;
2108                         case( ROP_XOR ) :       nRasterOp = 4; break;
2109                         case( ROP_INVERT ):     nRasterOp = 1; break;
2110                         default:                nRasterOp = 0; break;
2111                     }
2112 
2113                     ImplWriteRasterOpAction( rOStm, nRasterOp );
2114                     nCount++;
2115                 }
2116                 else
2117                 {
2118                     ImplWritePushAction( rOStm );
2119                     rSaveVDev.Push();
2120 
2121                     if( pAct->GetRasterOp() == ROP_0 )
2122                     {
2123                         ImplWriteLineColor( rOStm, COL_BLACK, 1 );
2124                         ImplWriteFillColor( rOStm, COL_BLACK, 1 );
2125                     }
2126                     else
2127                     {
2128                         ImplWriteLineColor( rOStm, COL_WHITE, 1 );
2129                         ImplWriteFillColor( rOStm, COL_WHITE, 1 );
2130                     }
2131 
2132                     ImplWriteRasterOpAction( rOStm, 0 );
2133                     rRop_0_1 = sal_True;
2134                     nCount += 4;
2135                 }
2136             }
2137             break;
2138 
2139             case( META_TRANSPARENT_ACTION ):
2140             {
2141                 const PolyPolygon&  rPolyPoly = ( (MetaTransparentAction*) pAction )->GetPolyPolygon();
2142                 const sal_Int16         nTrans = ( (MetaTransparentAction*) pAction )->GetTransparence();
2143                 const sal_Int16         nBrushStyle = ( nTrans < 38 ) ? 8 : ( nTrans < 63 ) ? 9 : 10;
2144                 sal_uLong               nOldPos, nNewPos;
2145 
2146                 // write transparence comment
2147                 rOStm << (sal_Int16) GDI_TRANSPARENT_COMMENT;
2148 
2149                 // we'll write the ActionSize later
2150                 nOldPos = rOStm.Tell();
2151                 rOStm.SeekRel( 4 );
2152 
2153                 // write comment data
2154                 rOStm << rPolyPoly;
2155                 rOStm << nTrans;
2156                 rOStm << (sal_Int32) 15; // number of actions that follow this comment
2157 
2158                 // calculate and write ActionSize of comment
2159                 nNewPos = rOStm.Tell();
2160                 rOStm.Seek( nOldPos );
2161                 rOStm << (sal_Int32) ( nNewPos - nOldPos );
2162                 rOStm.Seek( nNewPos );
2163 
2164                 {
2165                     // write actions for transparence
2166                     ImplWritePushAction( rOStm );
2167                     {
2168                         ImplWriteRasterOpAction( rOStm, 4 );
2169                         ImplWritePolyPolyAction( rOStm, rPolyPoly );
2170 
2171                         ImplWritePushAction( rOStm );
2172                         {
2173                             ImplWriteRasterOpAction( rOStm, 2 );
2174                             ImplWriteFillColor( rOStm, COL_BLACK, nBrushStyle );
2175                             ImplWritePolyPolyAction( rOStm, rPolyPoly );
2176                         }
2177                         ImplWritePopAction( rOStm );
2178 
2179                         ImplWriteRasterOpAction( rOStm, 4 );
2180                         ImplWritePolyPolyAction( rOStm, rPolyPoly );
2181                     }
2182                     ImplWritePopAction( rOStm );
2183 
2184                     ImplWritePushAction( rOStm );
2185                     {
2186                         ImplWriteFillColor( rOStm, Color(), 0 );
2187                         ImplWritePolyPolyAction( rOStm, rPolyPoly );
2188                     }
2189                     ImplWritePopAction( rOStm );
2190 
2191 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
2192                     nCount += 15;
2193 #endif
2194                 }
2195 
2196                 nCount++;
2197             }
2198             break;
2199 
2200             case( META_FLOATTRANSPARENT_ACTION ):
2201             {
2202                 const MetaFloatTransparentAction*   pA = (MetaFloatTransparentAction*) pAction;
2203                 const GDIMetaFile&                  rTransMtf = pA->GetGDIMetaFile();
2204                 const Point&                        rPos = pA->GetPoint();
2205                 const Size&                         rSize = pA->GetSize();
2206                 const Gradient&                     rGradient = pA->GetGradient();
2207                 sal_uLong                               nOldPos, nNewPos;
2208 
2209                 // write RefPoint comment
2210                 rOStm << (sal_Int16) GDI_FLOATTRANSPARENT_COMMENT;
2211 
2212                 // we'll write the ActionSize later
2213                 nOldPos = rOStm.Tell();
2214                 rOStm.SeekRel( 4 );
2215 
2216                 // write comment data
2217                 rOStm << rTransMtf << rPos << rSize << rGradient;
2218 
2219                 // calculate and write ActionSize of comment
2220                 nNewPos = rOStm.Tell();
2221                 rOStm.Seek( nOldPos );
2222                 rOStm << (sal_Int32) ( nNewPos - nOldPos + 4 );
2223                 rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
2224 
2225                 {
2226                     // write actions for float transparence
2227                     sal_uLong           nAddCount;
2228                     GDIMetaFile     aMtf( rTransMtf );
2229                     const Size      aSrcSize( rTransMtf.GetPrefSize() );
2230                     Point           aSrcPt( rTransMtf.GetPrefMapMode().GetOrigin() );
2231                     const double    fScaleX = aSrcSize.Width() ? (double) rSize.Width() / aSrcSize.Width() : 1.0;
2232                     const double    fScaleY = aSrcSize.Height() ? (double) rSize.Height() / aSrcSize.Height() : 1.0;
2233                     long            nMoveX, nMoveY;
2234 
2235                     if( fScaleX != 1.0 || fScaleY != 1.0 )
2236                     {
2237                         aMtf.Scale( fScaleX, fScaleY );
2238                         aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
2239                     }
2240 
2241                     nMoveX = rPos.X() - aSrcPt.X(), nMoveY = rPos.Y() - aSrcPt.Y();
2242 
2243                     if( nMoveX || nMoveY )
2244                         aMtf.Move( nMoveX, nMoveY );
2245 
2246                     nAddCount = ImplWriteActions( rOStm, aMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
2247                     nNewPos = rOStm.Tell();
2248                     rOStm.Seek( nOldPos );
2249                     rOStm << (sal_Int32) nAddCount;
2250                     rOStm.Seek( nNewPos );
2251 
2252 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
2253                     nCount += nAddCount;
2254 #endif
2255                 }
2256 
2257                 nCount++;
2258             }
2259             break;
2260 
2261             case( META_HATCH_ACTION ):
2262             {
2263                 const MetaHatchAction*  pA = (MetaHatchAction*) pAction;
2264                 const PolyPolygon&      rPolyPoly = pA->GetPolyPolygon();
2265                 const Hatch&            rHatch = pA->GetHatch();
2266                 sal_uLong                   nOldPos, nNewPos, nAddCount;
2267 
2268                 // write hatch comment
2269                 rOStm << (sal_Int16) GDI_HATCH_COMMENT;
2270 
2271                 // we'll write the ActionSize later
2272                 nOldPos = rOStm.Tell();
2273                 rOStm.SeekRel( 4 );
2274 
2275                 // write comment data
2276                 rOStm << rPolyPoly;
2277                 rOStm << rHatch;
2278 
2279                 // calculate and write ActionSize of comment
2280                 nNewPos = rOStm.Tell();
2281                 rOStm.Seek( nOldPos );
2282                 rOStm << (sal_Int32) ( nNewPos - nOldPos + 4 );
2283                 rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
2284 
2285                 {
2286                     // write actions for hatch
2287                     VirtualDevice   aVDev;
2288                     GDIMetaFile     aTmpMtf;
2289 
2290                     aVDev.AddHatchActions( rPolyPoly, rHatch, aTmpMtf );
2291                     nAddCount = ImplWriteActions( rOStm, aTmpMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
2292                     nNewPos = rOStm.Tell();
2293                     rOStm.Seek( nOldPos );
2294                     rOStm << (sal_Int32) nAddCount;
2295                     rOStm.Seek( nNewPos );
2296 
2297 #ifdef CVTSVM_WRITE_SUBACTIONCOUNT
2298                     nCount += nAddCount;
2299 #endif
2300                 }
2301 
2302                 nCount++;
2303             }
2304             break;
2305 
2306             case( META_REFPOINT_ACTION ):
2307             {
2308                 const MetaRefPointAction*   pA = (MetaRefPointAction*) pAction;
2309                 const Point&                rRefPoint = pA->GetRefPoint();
2310                 const sal_Bool                  bSet = pA->IsSetting();
2311                 sal_uLong                       nOldPos, nNewPos;
2312 
2313                 // write RefPoint comment
2314                 rOStm << (sal_Int16) GDI_REFPOINT_COMMENT;
2315 
2316                 // we'll write the ActionSize later
2317                 nOldPos = rOStm.Tell();
2318                 rOStm.SeekRel( 4 );
2319 
2320                 // write data
2321                 rOStm << rRefPoint << bSet;
2322                 rOStm << (sal_Int32) 0; // number of actions that follow this comment
2323 
2324                 // calculate and write ActionSize of comment
2325                 nNewPos = rOStm.Tell();
2326                 rOStm.Seek( nOldPos );
2327                 rOStm << (sal_Int32) ( nNewPos - nOldPos );
2328                 rOStm.Seek( nNewPos );
2329 
2330                 nCount++;
2331             }
2332             break;
2333 
2334             case( META_TEXTLINECOLOR_ACTION ):
2335             {
2336                 const MetaTextLineColorAction*  pA = (MetaTextLineColorAction*) pAction;
2337                 const Color&                    rColor = pA->GetColor();
2338                 const sal_Bool                      bSet = pA->IsSetting();
2339                 sal_uLong                           nOldPos, nNewPos;
2340 
2341                 // write RefPoint comment
2342                 rOStm << (sal_Int16) GDI_TEXTLINECOLOR_COMMENT;
2343 
2344                 // we'll write the ActionSize later
2345                 nOldPos = rOStm.Tell();
2346                 rOStm.SeekRel( 4 );
2347 
2348                 // write data
2349                 rOStm << rColor << bSet;
2350                 rOStm << (sal_Int32) 0; // number of actions that follow this comment
2351 
2352                 // calculate and write ActionSize of comment
2353                 nNewPos = rOStm.Tell();
2354                 rOStm.Seek( nOldPos );
2355                 rOStm << (sal_Int32) ( nNewPos - nOldPos );
2356                 rOStm.Seek( nNewPos );
2357 
2358                 nCount++;
2359             }
2360             break;
2361 
2362 #if 0
2363             case( META_OVERLINECOLOR_ACTION ):
2364             break;
2365 #endif
2366 
2367             case( META_TEXTLINE_ACTION ):
2368             {
2369                 const MetaTextLineAction*   pA = (MetaTextLineAction*) pAction;
2370                 const Point&                rStartPt = pA->GetStartPoint();
2371                 const long                  nWidth = pA->GetWidth();
2372                 const FontStrikeout         eStrikeout = pA->GetStrikeout();
2373                 const FontUnderline         eUnderline = pA->GetUnderline();
2374                 sal_uLong                       nOldPos, nNewPos;
2375 
2376                 // write RefPoint comment
2377                 rOStm << (sal_Int16) GDI_TEXTLINE_COMMENT;
2378 
2379                 // we'll write the ActionSize later
2380                 nOldPos = rOStm.Tell();
2381                 rOStm.SeekRel( 4 );
2382 
2383                 // write data
2384                 rOStm << rStartPt << nWidth <<
2385                     static_cast<sal_uInt32>(eStrikeout) <<
2386                     static_cast<sal_uInt32>(eUnderline);
2387                 rOStm << (sal_Int32) 0; // number of actions that follow this comment
2388 
2389                 // calculate and write ActionSize of comment
2390                 nNewPos = rOStm.Tell();
2391                 rOStm.Seek( nOldPos );
2392                 rOStm << (sal_Int32) ( nNewPos - nOldPos );
2393                 rOStm.Seek( nNewPos );
2394 
2395                 nCount++;
2396             }
2397             break;
2398 
2399             case( META_EPS_ACTION ):
2400             break;
2401 
2402             case( META_COMMENT_ACTION ):
2403             {
2404                 const MetaCommentAction*    pA = (MetaCommentAction*) pAction;
2405                 const sal_uInt32            nDataSize = pA->GetDataSize();
2406                 sal_uLong                       nOldPos, nNewPos;
2407 
2408                 // write RefPoint comment
2409                 rOStm << (sal_Int16) GDI_COMMENT_COMMENT;
2410 
2411                 // we'll write the ActionSize later
2412                 nOldPos = rOStm.Tell();
2413                 rOStm.SeekRel( 4 );
2414 
2415                 // write data
2416                 rOStm << pA->GetComment() << pA->GetValue() << nDataSize;
2417 
2418                 if( nDataSize )
2419                     rOStm.Write( pA->GetData(), nDataSize );
2420 
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 #ifdef DBG_UTIL
2434             default:
2435             {
2436                 ByteString aStr( "Missing implementation for Action#: " );
2437                 aStr += ByteString::CreateFromInt32( pAction->GetType() );
2438                 aStr += '!';
2439                 DBG_ERROR( aStr.GetBuffer() );
2440             }
2441             break;
2442 #endif
2443 
2444 /*
2445             case( META_TEXTRECT_ACTION ):
2446             {
2447                 MetaTextRectAction* pAct = (MetaTextRectAction*) pAction;
2448 
2449                 rOStm << ;
2450                 rOStm << ;
2451 
2452                 nCount++;
2453             }
2454             break;
2455 */
2456 
2457 /*
2458             case( META_MASK_ACTION ):
2459             {
2460                 MetaMaskAction* pAct = (MetaMaskAction*) pAction;
2461 
2462                 rOStm << ;
2463                 rOStm << ;
2464 
2465                 nCount++;
2466             }
2467             break;
2468 */
2469 
2470 /*
2471             case( META_MASKSCALE_ACTION ):
2472             {
2473                 MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction;
2474 
2475                 rOStm << ;
2476                 rOStm << ;
2477 
2478                 nCount++;
2479             }
2480             break;
2481 */
2482 
2483 /*
2484             case( META_MASKSCALEPART_ACTION ):
2485             {
2486                 MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
2487 
2488                 rOStm << ;
2489                 rOStm << ;
2490 
2491                 nCount++;
2492             }
2493             break;
2494 */
2495 
2496 /*
2497             case( META_ISECTREGIONCLIPREGION_ACTION ):
2498             {
2499                 MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction;
2500 
2501                 rOStm << ;
2502                 rOStm << ;
2503 
2504                 nCount++;
2505             }
2506             break;
2507 */
2508         }
2509     }
2510 
2511     return nCount;
2512 }
2513