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