xref: /aoo42x/main/vcl/source/gdi/cvtsvm.cxx (revision 9f62ea84)
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