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