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