update credits
[LibreOffice.git] / vcl / source / gdi / cvtsvm.cxx
blob63134b496917126ef296ceb7faef22599ed3c76b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <algorithm>
21 #include <string.h>
22 #include <tools/debug.hxx>
23 #include <tools/stream.hxx>
24 #include <tools/helpers.hxx>
25 #include <vcl/virdev.hxx>
26 #include <vcl/graph.hxx>
27 #include <vcl/lineinfo.hxx>
28 #include <vcl/cvtsvm.hxx>
29 #include <rtl/strbuf.hxx>
31 // Inlines
32 void ImplReadRect( SvStream& rIStm, Rectangle& rRect )
34 Point aTL;
35 Point aBR;
37 rIStm >> aTL;
38 rIStm >> aBR;
40 rRect = Rectangle( aTL, aBR );
43 void ImplWriteRect( SvStream& rOStm, const Rectangle& rRect )
45 rOStm << rRect.TopLeft();
46 rOStm << rRect.BottomRight();
49 void ImplReadPoly( SvStream& rIStm, Polygon& rPoly )
51 sal_Int32 nSize;
53 rIStm >> nSize;
54 rPoly = Polygon( (sal_uInt16) nSize );
56 for( sal_uInt16 i = 0; i < (sal_uInt16) nSize; i++ )
57 rIStm >> rPoly[ i ];
60 void ImplReadPolyPoly( SvStream& rIStm, PolyPolygon& rPolyPoly )
62 Polygon aPoly;
63 sal_Int32 nPolyCount;
65 rIStm >> nPolyCount;
67 for( sal_uInt16 i = 0; i < (sal_uInt16) nPolyCount; i++ )
69 ImplReadPoly( rIStm, aPoly );
70 rPolyPoly.Insert( aPoly );
74 void ImplWritePolyPolyAction( SvStream& rOStm, const PolyPolygon& rPolyPoly )
76 const sal_uInt16 nPoly = rPolyPoly.Count();
77 sal_uInt16 nPoints = 0;
78 sal_uInt16 n;
80 for( n = 0; n < nPoly; n++ )
81 nPoints = sal::static_int_cast<sal_uInt16>(nPoints + rPolyPoly[ n ].GetSize());
83 rOStm << (sal_Int16) GDI_POLYPOLYGON_ACTION;
84 rOStm << (sal_Int32) ( 8 + ( nPoly << 2 ) + ( nPoints << 3 ) );
85 rOStm << (sal_Int32) nPoly;
87 for( n = 0; n < nPoly; n++ )
89 // #i102224# Here the possible curved nature of Polygon was
90 // ignored (for all those years). Adapted to at least write
91 // a polygon representing the curve as good as possible
92 Polygon aSimplePoly;
93 rPolyPoly[n].AdaptiveSubdivide(aSimplePoly);
94 const sal_uInt16 nSize(aSimplePoly.GetSize());
96 rOStm << (sal_Int32) nSize;
98 for( sal_uInt16 j = 0; j < nSize; j++ )
99 rOStm << aSimplePoly[ j ];
103 void ImplReadColor( SvStream& rIStm, Color& rColor )
105 sal_Int16 nVal;
107 rIStm >> nVal; rColor.SetRed( sal::static_int_cast<sal_uInt8>((sal_uInt16)nVal >> 8) );
108 rIStm >> nVal; rColor.SetGreen( sal::static_int_cast<sal_uInt8>((sal_uInt16)nVal >> 8) );
109 rIStm >> nVal; rColor.SetBlue( sal::static_int_cast<sal_uInt8>((sal_uInt16)nVal >> 8) );
112 void ImplWriteColor( SvStream& rOStm, const Color& rColor )
114 sal_Int16 nVal;
116 nVal = ( (sal_Int16) rColor.GetRed() << 8 ) | rColor.GetRed();
117 rOStm << nVal;
119 nVal = ( (sal_Int16) rColor.GetGreen() << 8 ) | rColor.GetGreen();
120 rOStm << nVal;
122 nVal = ( (sal_Int16) rColor.GetBlue() << 8 ) | rColor.GetBlue();
123 rOStm << nVal;
126 void ImplReadMapMode( SvStream& rIStm, MapMode& rMapMode )
128 Point aOrg;
129 sal_Int32 nXNum;
130 sal_Int32 nXDenom;
131 sal_Int32 nYNum;
132 sal_Int32 nYDenom;
133 sal_Int16 nUnit;
135 rIStm >> nUnit >> aOrg >> nXNum >> nXDenom >> nYNum >> nYDenom;
136 rMapMode = MapMode( (MapUnit) nUnit, aOrg, Fraction( nXNum, nXDenom ), Fraction( nYNum, nYDenom ) );
139 void ImplWriteMapMode( SvStream& rOStm, const MapMode& rMapMode )
141 rOStm << (sal_Int16) rMapMode.GetMapUnit();
142 rOStm << rMapMode.GetOrigin();
143 rOStm << (sal_Int32) rMapMode.GetScaleX().GetNumerator();
144 rOStm << (sal_Int32) rMapMode.GetScaleX().GetDenominator();
145 rOStm << (sal_Int32) rMapMode.GetScaleY().GetNumerator();
146 rOStm << (sal_Int32) rMapMode.GetScaleY().GetDenominator();
149 void ImplWritePushAction( SvStream& rOStm )
151 rOStm << (sal_Int16) GDI_PUSH_ACTION;
152 rOStm << (sal_Int32) 4;
155 void ImplWritePopAction( SvStream& rOStm )
157 rOStm << (sal_Int16) GDI_POP_ACTION;
158 rOStm << (sal_Int32) 4;
161 void ImplWriteLineColor( SvStream& rOStm, const Color& rColor, sal_Int16 nStyle, sal_Int32 nWidth = 0L )
163 if( rColor.GetTransparency() > 127 )
164 nStyle = 0;
166 rOStm << (sal_Int16) GDI_PEN_ACTION;
167 rOStm << (sal_Int32) 16;
168 ImplWriteColor( rOStm, rColor );
169 rOStm << nWidth;
170 rOStm << nStyle;
173 void ImplWriteFillColor( SvStream& rOStm, const Color& rColor, sal_Int16 nStyle )
175 rOStm << (sal_Int16) GDI_FILLBRUSH_ACTION;
176 rOStm << (sal_Int32) 20;
177 ImplWriteColor( rOStm, rColor );
179 if( rColor.GetTransparency() > 127 )
180 nStyle = 0;
182 if( nStyle > 1 )
184 ImplWriteColor( rOStm, COL_WHITE );
185 rOStm << nStyle;
186 rOStm << (sal_Int16) 1;
188 else
190 ImplWriteColor( rOStm, COL_BLACK );
191 rOStm << nStyle;
192 rOStm << (sal_Int16) 0;
196 void ImplWriteFont( SvStream& rOStm, const Font& rFont,
197 rtl_TextEncoding& rActualCharSet )
199 char aName[32];
200 short nWeight;
202 OString aByteName(OUStringToOString(rFont.GetName(),
203 rOStm.GetStreamCharSet()));
204 strncpy( aName, aByteName.getStr(), 32 );
206 switch ( rFont.GetWeight() )
208 case WEIGHT_THIN:
209 case WEIGHT_ULTRALIGHT:
210 case WEIGHT_LIGHT:
211 nWeight = 1;
212 break;
214 case WEIGHT_NORMAL:
215 case WEIGHT_MEDIUM:
216 nWeight = 2;
217 break;
219 case WEIGHT_BOLD:
220 case WEIGHT_ULTRABOLD:
221 case WEIGHT_BLACK:
222 nWeight = 3;
223 break;
225 default:
226 nWeight = 0;
227 break;
230 rOStm << (sal_Int16) GDI_FONT_ACTION;
231 rOStm << (sal_Int32) 78;
233 rActualCharSet = GetStoreCharSet( rFont.GetCharSet() );
234 ImplWriteColor( rOStm, rFont.GetColor() );
235 ImplWriteColor( rOStm, rFont.GetFillColor() );
236 rOStm.Write( aName, 32 );
237 rOStm << rFont.GetSize();
238 rOStm << (sal_Int16) 0; // no character orientation anymore
239 rOStm << (sal_Int16) rFont.GetOrientation();
240 rOStm << (sal_Int16) rActualCharSet;
241 rOStm << (sal_Int16) rFont.GetFamily();
242 rOStm << (sal_Int16) rFont.GetPitch();
243 rOStm << (sal_Int16) rFont.GetAlign();
244 rOStm << (sal_Int16) nWeight;
245 rOStm << (sal_Int16) rFont.GetUnderline();
246 rOStm << (sal_Int16) rFont.GetStrikeout();
247 rOStm << (sal_Bool) ( rFont.GetItalic() != ITALIC_NONE );
248 rOStm << rFont.IsOutline();
249 rOStm << rFont.IsShadow();
250 rOStm << rFont.IsTransparent();
251 if ( rActualCharSet == RTL_TEXTENCODING_DONTKNOW )
252 rActualCharSet = osl_getThreadTextEncoding();
255 void ImplWriteRasterOpAction( SvStream& rOStm, sal_Int16 nRasterOp )
257 rOStm << (sal_Int16) GDI_RASTEROP_ACTION << (sal_Int32) 6 << nRasterOp;
260 sal_Bool ImplWriteUnicodeComment( SvStream& rOStm, const String& rString )
262 xub_StrLen nStringLen = rString.Len();
263 if ( nStringLen )
265 sal_uInt32 nSize = ( nStringLen << 1 ) + 4;
266 sal_uInt16 nType = GDI_UNICODE_COMMENT;
268 rOStm << nType << nSize;
269 write_uInt16s_FromOUString(rOStm, rString);
271 return nStringLen != 0;
274 void ImplReadUnicodeComment( sal_uInt32 nStrmPos, SvStream& rIStm, OUString& rString )
276 sal_uInt32 nOld = rIStm.Tell();
277 if ( nStrmPos )
279 sal_uInt16 nType;
280 sal_uInt32 nActionSize;
281 xub_StrLen nStringLen;
283 rIStm.Seek( nStrmPos );
284 rIStm >> nType
285 >> nActionSize;
287 nStringLen = sal::static_int_cast<xub_StrLen>(( nActionSize - 4 ) >> 1);
289 if ( nStringLen && ( nType == GDI_UNICODE_COMMENT ) )
290 rString = read_uInt16s_ToOUString(rIStm, nStringLen);
292 rIStm.Seek( nOld );
295 void ImplSkipActions( SvStream& rIStm, sal_uLong nSkipCount )
297 sal_Int32 nActionSize;
298 sal_Int16 nType;
300 for( sal_uLong i = 0UL; i < nSkipCount; i++ )
302 rIStm >> nType >> nActionSize;
303 rIStm.SeekRel( nActionSize - 4L );
307 bool ImplWriteExtendedPolyPolygonAction(SvStream& rOStm, const PolyPolygon& rPolyPolygon, bool bOnlyWhenCurve)
309 const sal_uInt16 nPolygonCount(rPolyPolygon.Count());
311 if(nPolygonCount)
313 sal_uInt32 nAllPolygonCount(0);
314 sal_uInt32 nAllPointCount(0);
315 sal_uInt32 nAllFlagCount(0);
316 sal_uInt16 a(0);
318 for(a = 0; a < nPolygonCount; a++)
320 const Polygon& rCandidate = rPolyPolygon.GetObject(a);
321 const sal_uInt16 nPointCount(rCandidate.GetSize());
323 if(nPointCount)
325 nAllPolygonCount++;
326 nAllPointCount += nPointCount;
328 if(rCandidate.HasFlags())
330 nAllFlagCount += nPointCount;
335 if((bOnlyWhenCurve && nAllFlagCount) || (!bOnlyWhenCurve && nAllPointCount))
337 rOStm << (sal_Int16) GDI_EXTENDEDPOLYGON_ACTION;
339 const sal_Int32 nActionSize(
340 4 + // Action size
341 2 + // PolygonCount
342 (nAllPolygonCount * 2) + // Points per polygon
343 (nAllPointCount << 3) + // Points themselves
344 nAllPolygonCount + // Bool if (when poly has points) it has flags, too
345 nAllFlagCount); // Flags themselves
347 rOStm << nActionSize;
348 rOStm << (sal_uInt16)nAllPolygonCount;
350 for(a = 0; a < nPolygonCount; a++)
352 const Polygon& rCandidate = rPolyPolygon.GetObject(a);
353 const sal_uInt16 nPointCount(rCandidate.GetSize());
355 if(nPointCount)
357 rOStm << nPointCount;
359 for(sal_uInt16 b(0); b < nPointCount; b++)
361 rOStm << rCandidate[b];
364 if(rCandidate.HasFlags())
366 rOStm << (sal_uInt8)true;
368 for(sal_uInt16 c(0); c < nPointCount; c++)
370 rOStm << (sal_uInt8)rCandidate.GetFlags(c);
373 else
375 rOStm << (sal_uInt8)false;
380 return true;
384 return false;
387 void ImplReadExtendedPolyPolygonAction(SvStream& rIStm, PolyPolygon& rPolyPoly)
389 rPolyPoly.Clear();
390 sal_uInt16 nPolygonCount(0);
391 rIStm >> nPolygonCount;
393 for(sal_uInt16 a(0); a < nPolygonCount; a++)
395 sal_uInt16 nPointCount(0);
396 rIStm >> nPointCount;
397 Polygon aCandidate(nPointCount);
399 if(nPointCount)
401 for(sal_uInt16 b(0); b < nPointCount; b++)
403 rIStm >> aCandidate[b];
406 sal_uInt8 bHasFlags(false);
407 rIStm >> bHasFlags;
409 if(bHasFlags)
411 sal_uInt8 aPolyFlags(0);
413 for(sal_uInt16 c(0); c < nPointCount; c++)
415 rIStm >> aPolyFlags;
416 aCandidate.SetFlags(c, (PolyFlags)aPolyFlags);
421 rPolyPoly.Insert(aCandidate);
425 SVMConverter::SVMConverter( SvStream& rStm, GDIMetaFile& rMtf, sal_uLong nConvertMode )
427 if( !rStm.GetError() )
429 if( CONVERT_FROM_SVM1 == nConvertMode )
430 ImplConvertFromSVM1( rStm, rMtf );
431 else if( CONVERT_TO_SVM1 == nConvertMode )
432 ImplConvertToSVM1( rStm, rMtf );
436 void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf )
438 const sal_uLong nPos = rIStm.Tell();
439 const sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt();
441 rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
443 char aCode[ 5 ];
444 Size aPrefSz;
445 sal_Int16 nSize;
446 sal_Int16 nVersion;
448 // read header
449 rIStm.Read( (char*) &aCode, sizeof( aCode ) ); // Identifier
450 rIStm >> nSize; // Size
451 rIStm >> nVersion; // Version
452 //#fdo39428 SvStream no longer supports operator>>(long&)
453 sal_Int32 nTmp32(0);
454 rIStm >> nTmp32;
455 aPrefSz.Width() = nTmp32; // PrefSize.Width()
456 rIStm >> nTmp32;
457 aPrefSz.Height() = nTmp32; // PrefSize.Height()
459 // check header-magic and version
460 if( rIStm.GetError()
461 || ( memcmp( aCode, "SVGDI", sizeof( aCode ) ) != 0 )
462 || ( nVersion != 200 ) )
464 rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
465 rIStm.SetNumberFormatInt( nOldFormat );
466 rIStm.Seek( nPos );
467 return;
470 LineInfo aLineInfo( LINE_NONE, 0 );
471 ::std::stack< LineInfo* > aLIStack;
472 VirtualDevice aFontVDev;
473 rtl_TextEncoding eActualCharSet = osl_getThreadTextEncoding();
474 sal_Bool bFatLine = sal_False;
476 // TODO: fix reindentation below if you can accept being blamed by the SCM
477 MapMode aMapMode;
478 Polygon aActionPoly;
479 Rectangle aRect;
480 Point aPt, aPt1;
481 Size aSz;
482 Color aActionColor;
483 sal_Int32 nTmp, nTmp1, nActionSize;
484 sal_Int32 nActions;
485 sal_Int16 nType;
487 sal_uInt32 nUnicodeCommentStreamPos = 0;
488 sal_Int32 nUnicodeCommentActionNumber = 0;
490 ImplReadMapMode( rIStm, aMapMode ); // MapMode
491 rIStm >> nActions; // Action count
493 rMtf.SetPrefSize( aPrefSz );
494 rMtf.SetPrefMapMode( aMapMode );
495 size_t nLastPolygonAction(0);
497 for( sal_Int32 i = 0L; i < nActions; i++ )
499 rIStm >> nType;
500 sal_Int32 nActBegin = rIStm.Tell();
501 rIStm >> nActionSize;
503 DBG_ASSERT( ( nType <= 33 ) || ( nType >= 1024 ), "Unknown GDIMetaAction while converting!" );
505 switch( nType )
507 case( GDI_PIXEL_ACTION ):
509 rIStm >> aPt;
510 ImplReadColor( rIStm, aActionColor );
511 rMtf.AddAction( new MetaPixelAction( aPt, aActionColor ) );
513 break;
515 case( GDI_POINT_ACTION ):
517 rIStm >> aPt;
518 rMtf.AddAction( new MetaPointAction( aPt ) );
520 break;
522 case( GDI_LINE_ACTION ):
524 rIStm >> aPt >> aPt1;
525 rMtf.AddAction( new MetaLineAction( aPt, aPt1, aLineInfo ) );
527 break;
529 case (GDI_LINEJOIN_ACTION) :
531 sal_Int16 nLineJoin(0);
532 rIStm >> nLineJoin;
533 aLineInfo.SetLineJoin((basegfx::B2DLineJoin)nLineJoin);
535 break;
537 case (GDI_LINECAP_ACTION) :
539 sal_Int16 nLineCap(0);
540 rIStm >> nLineCap;
541 aLineInfo.SetLineCap((com::sun::star::drawing::LineCap)nLineCap);
543 break;
545 case (GDI_LINEDASHDOT_ACTION) :
547 sal_Int16 a(0);
548 sal_Int32 b(0);
550 rIStm >> a; aLineInfo.SetDashCount(a);
551 rIStm >> b; aLineInfo.SetDashLen(b);
552 rIStm >> a; aLineInfo.SetDotCount(a);
553 rIStm >> b; aLineInfo.SetDotLen(b);
554 rIStm >> b; aLineInfo.SetDistance(b);
556 if(((aLineInfo.GetDashCount() && aLineInfo.GetDashLen())
557 || (aLineInfo.GetDotCount() && aLineInfo.GetDotLen()))
558 && aLineInfo.GetDistance())
560 aLineInfo.SetStyle(LINE_DASH);
563 break;
565 case (GDI_EXTENDEDPOLYGON_ACTION) :
567 // read the PolyPolygon in every case
568 PolyPolygon aInputPolyPolygon;
569 ImplReadExtendedPolyPolygonAction(rIStm, aInputPolyPolygon);
571 // now check if it can be set somewhere
572 if(nLastPolygonAction < rMtf.GetActionSize())
574 MetaPolyLineAction* pPolyLineAction = dynamic_cast< MetaPolyLineAction* >(rMtf.GetAction(nLastPolygonAction));
576 if(pPolyLineAction)
578 // replace MetaPolyLineAction when we have a single polygon. Do not rely on the
579 // same point count; the originally written GDI_POLYLINE_ACTION may have been
580 // Subdivided for better quality for older usages
581 if(1 == aInputPolyPolygon.Count())
583 MetaAction* pAction = rMtf.ReplaceAction(
584 new MetaPolyLineAction(
585 aInputPolyPolygon.GetObject(0),
586 pPolyLineAction->GetLineInfo()),
587 nLastPolygonAction);
588 if(pAction)
589 pAction->Delete();
592 else
594 MetaPolyPolygonAction* pPolyPolygonAction = dynamic_cast< MetaPolyPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
596 if(pPolyPolygonAction)
598 // replace MetaPolyPolygonAction when we have a curved polygon. Do rely on the
599 // same sub-polygon count
600 if(pPolyPolygonAction->GetPolyPolygon().Count() == aInputPolyPolygon.Count())
602 MetaAction* pAction = rMtf.ReplaceAction(
603 new MetaPolyPolygonAction(
604 aInputPolyPolygon),
605 nLastPolygonAction);
606 if(pAction)
607 pAction->Delete();
610 else
612 MetaPolygonAction* pPolygonAction = dynamic_cast< MetaPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
614 if(pPolygonAction)
616 // replace MetaPolygonAction
617 if(1 == aInputPolyPolygon.Count())
619 MetaAction* pAction = rMtf.ReplaceAction(
620 new MetaPolygonAction(
621 aInputPolyPolygon.GetObject(0)),
622 nLastPolygonAction);
623 if(pAction)
624 pAction->Delete();
631 break;
633 case( GDI_RECT_ACTION ):
635 ImplReadRect( rIStm, aRect );
636 rIStm >> nTmp >> nTmp1;
638 if( nTmp || nTmp1 )
639 rMtf.AddAction( new MetaRoundRectAction( aRect, nTmp, nTmp1 ) );
640 else
642 rMtf.AddAction( new MetaRectAction( aRect ) );
644 if( bFatLine )
645 rMtf.AddAction( new MetaPolyLineAction( aRect, aLineInfo ) );
648 break;
650 case( GDI_ELLIPSE_ACTION ):
652 ImplReadRect( rIStm, aRect );
654 if( bFatLine )
656 const Polygon aPoly( aRect.Center(), aRect.GetWidth() >> 1, aRect.GetHeight() >> 1 );
658 rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
659 rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
660 rMtf.AddAction( new MetaPolygonAction( aPoly ) );
661 rMtf.AddAction( new MetaPopAction() );
662 rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
664 else
665 rMtf.AddAction( new MetaEllipseAction( aRect ) );
667 break;
669 case( GDI_ARC_ACTION ):
671 ImplReadRect( rIStm, aRect );
672 rIStm >> aPt >> aPt1;
674 if( bFatLine )
676 const Polygon aPoly( aRect, aPt, aPt1, POLY_ARC );
678 rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
679 rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
680 rMtf.AddAction( new MetaPolygonAction( aPoly ) );
681 rMtf.AddAction( new MetaPopAction() );
682 rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
684 else
685 rMtf.AddAction( new MetaArcAction( aRect, aPt, aPt1 ) );
687 break;
689 case( GDI_PIE_ACTION ):
691 ImplReadRect( rIStm, aRect );
692 rIStm >> aPt >> aPt1;
694 if( bFatLine )
696 const Polygon aPoly( aRect, aPt, aPt1, POLY_PIE );
698 rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
699 rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
700 rMtf.AddAction( new MetaPolygonAction( aPoly ) );
701 rMtf.AddAction( new MetaPopAction() );
702 rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
704 else
705 rMtf.AddAction( new MetaPieAction( aRect, aPt, aPt1 ) );
707 break;
709 case( GDI_INVERTRECT_ACTION ):
710 case( GDI_HIGHLIGHTRECT_ACTION ):
712 ImplReadRect( rIStm, aRect );
713 rMtf.AddAction( new MetaPushAction( PUSH_RASTEROP ) );
714 rMtf.AddAction( new MetaRasterOpAction( ROP_INVERT ) );
715 rMtf.AddAction( new MetaRectAction( aRect ) );
716 rMtf.AddAction( new MetaPopAction() );
718 break;
720 case( GDI_POLYLINE_ACTION ):
722 ImplReadPoly( rIStm, aActionPoly );
723 nLastPolygonAction = rMtf.GetActionSize();
725 if( bFatLine )
726 rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
727 else
728 rMtf.AddAction( new MetaPolyLineAction( aActionPoly ) );
730 break;
732 case( GDI_POLYGON_ACTION ):
734 ImplReadPoly( rIStm, aActionPoly );
736 if( bFatLine )
738 rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
739 rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
740 rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
741 rMtf.AddAction( new MetaPopAction() );
742 rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
744 else
746 nLastPolygonAction = rMtf.GetActionSize();
747 rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
750 break;
752 case( GDI_POLYPOLYGON_ACTION ):
754 PolyPolygon aPolyPoly;
756 ImplReadPolyPoly( rIStm, aPolyPoly );
758 if( bFatLine )
760 rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
761 rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
762 rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
763 rMtf.AddAction( new MetaPopAction() );
765 for( sal_uInt16 nPoly = 0, nCount = aPolyPoly.Count(); nPoly < nCount; nPoly++ )
766 rMtf.AddAction( new MetaPolyLineAction( aPolyPoly[ nPoly ], aLineInfo ) );
768 else
770 nLastPolygonAction = rMtf.GetActionSize();
771 rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
774 break;
776 case( GDI_FONT_ACTION ):
778 Font aFont;
779 char aName[ 32 ];
780 sal_Int32 nWidth, nHeight;
781 sal_Int16 nCharSet, nFamily, nPitch, nAlign, nWeight, nUnderline, nStrikeout;
782 sal_Int16 nCharOrient, nLineOrient;
783 sal_Bool bItalic, bOutline, bShadow, bTransparent;
785 ImplReadColor( rIStm, aActionColor ); aFont.SetColor( aActionColor );
786 ImplReadColor( rIStm, aActionColor ); aFont.SetFillColor( aActionColor );
787 rIStm.Read( aName, 32 );
788 aFont.SetName( String( aName, rIStm.GetStreamCharSet() ) );
789 rIStm >> nWidth >> nHeight;
790 rIStm >> nCharOrient >> nLineOrient;
791 rIStm >> nCharSet >> nFamily >> nPitch >> nAlign >> nWeight >> nUnderline >> nStrikeout;
792 rIStm >> bItalic >> bOutline >> bShadow >> bTransparent;
794 aFont.SetSize( Size( nWidth, nHeight ) );
795 aFont.SetCharSet( (CharSet) nCharSet );
796 aFont.SetFamily( (FontFamily) nFamily );
797 aFont.SetPitch( (FontPitch) nPitch );
798 aFont.SetAlign( (FontAlign) nAlign );
799 aFont.SetWeight( ( nWeight == 1 ) ? WEIGHT_LIGHT : ( nWeight == 2 ) ? WEIGHT_NORMAL :
800 ( nWeight == 3 ) ? WEIGHT_BOLD : WEIGHT_DONTKNOW );
801 aFont.SetUnderline( (FontUnderline) nUnderline );
802 aFont.SetStrikeout( (FontStrikeout) nStrikeout );
803 aFont.SetItalic( bItalic ? ITALIC_NORMAL : ITALIC_NONE );
804 aFont.SetOutline( bOutline );
805 aFont.SetShadow( bShadow );
806 aFont.SetOrientation( nLineOrient );
807 aFont.SetTransparent( bTransparent );
809 eActualCharSet = aFont.GetCharSet();
810 if ( eActualCharSet == RTL_TEXTENCODING_DONTKNOW )
811 eActualCharSet = osl_getThreadTextEncoding();
813 rMtf.AddAction( new MetaFontAction( aFont ) );
814 rMtf.AddAction( new MetaTextAlignAction( aFont.GetAlign() ) );
815 rMtf.AddAction( new MetaTextColorAction( aFont.GetColor() ) );
816 rMtf.AddAction( new MetaTextFillColorAction( aFont.GetFillColor(), !aFont.IsTransparent() ) );
818 // #106172# Track font relevant data in shadow VDev
819 aFontVDev.SetFont( aFont );
821 break;
823 case( GDI_TEXT_ACTION ):
825 sal_Int32 nIndex, nLen;
827 rIStm >> aPt >> nIndex >> nLen >> nTmp;
828 if ( nTmp && ( static_cast< sal_uInt32 >( nTmp ) < ( SAL_MAX_UINT16 - 1 ) ) )
830 OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
831 sal_uInt8 nTerminator = 0;
832 rIStm >> nTerminator;
833 DBG_ASSERT( nTerminator == 0, "expected string to be NULL terminated" );
835 OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
836 if ( nUnicodeCommentActionNumber == i )
837 ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
838 rMtf.AddAction( new MetaTextAction( aPt, aStr, (sal_uInt16) nIndex, (sal_uInt16) nLen ) );
840 rIStm.Seek( nActBegin + nActionSize );
842 break;
844 case( GDI_TEXTARRAY_ACTION ):
846 sal_Int32* pDXAry = NULL;
847 sal_Int32 nIndex, nLen, nAryLen;
849 rIStm >> aPt >> nIndex >> nLen >> nTmp >> nAryLen;
850 if ( nTmp && ( static_cast< sal_uInt32 >( nTmp ) < ( SAL_MAX_UINT16 - 1 ) ) )
852 OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
853 sal_uInt8 nTerminator = 0;
854 rIStm >> nTerminator;
855 DBG_ASSERT( nTerminator == 0, "expected string to be NULL terminated" );
857 OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
859 if( nAryLen > 0L )
861 sal_Int32 nStrLen( aStr.getLength() );
863 pDXAry = new sal_Int32[ std::max( nAryLen, nStrLen ) ];
865 for( long j = 0L; j < nAryLen; j++ )
866 rIStm >> nTmp, pDXAry[ j ] = nTmp;
868 // #106172# Add last DX array elem, if missing
869 if( nAryLen != nStrLen )
871 if( nAryLen+1 == nStrLen )
873 sal_Int32* pTmpAry = new sal_Int32[nStrLen];
875 aFontVDev.GetTextArray( aStr, pTmpAry, (sal_uInt16) nIndex, (sal_uInt16) nLen );
877 // now, the difference between the
878 // last and the second last DX array
879 // is the advancement for the last
880 // glyph. Thus, to complete our meta
881 // action's DX array, just add that
882 // difference to last elem and store
883 // in very last.
884 if( nStrLen > 1 )
885 pDXAry[ nStrLen-1 ] = pDXAry[ nStrLen-2 ] + pTmpAry[ nStrLen-1 ] - pTmpAry[ nStrLen-2 ];
886 else
887 pDXAry[ nStrLen-1 ] = pTmpAry[ nStrLen-1 ]; // len=1: 0th position taken to be 0
889 delete[] pTmpAry;
891 #ifdef DBG_UTIL
892 else
893 OSL_FAIL("More than one DX array element missing on SVM import");
894 #endif
897 if ( nUnicodeCommentActionNumber == i )
898 ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
899 rMtf.AddAction( new MetaTextArrayAction( aPt, aStr, pDXAry, (sal_uInt16) nIndex, (sal_uInt16) nLen ) );
901 if( pDXAry )
902 delete[] pDXAry;
904 rIStm.Seek( nActBegin + nActionSize );
906 break;
908 case( GDI_STRETCHTEXT_ACTION ):
910 sal_Int32 nIndex, nLen, nWidth;
912 rIStm >> aPt >> nIndex >> nLen >> nTmp >> nWidth;
913 if ( nTmp && ( static_cast< sal_uInt32 >( nTmp ) < ( SAL_MAX_INT16 - 1 ) ) )
915 OString aByteStr = read_uInt8s_ToOString(rIStm, nTmp);
916 sal_uInt8 nTerminator = 0;
917 rIStm >> nTerminator;
918 DBG_ASSERT( nTerminator == 0, "expected string to be NULL terminated" );
920 OUString aStr(OStringToOUString(aByteStr, eActualCharSet));
921 if ( nUnicodeCommentActionNumber == i )
922 ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
923 rMtf.AddAction( new MetaStretchTextAction( aPt, nWidth, aStr, (sal_uInt16) nIndex, (sal_uInt16) nLen ) );
925 rIStm.Seek( nActBegin + nActionSize );
927 break;
929 case( GDI_BITMAP_ACTION ):
931 Bitmap aBmp;
933 rIStm >> aPt >> aBmp;
934 rMtf.AddAction( new MetaBmpAction( aPt, aBmp ) );
936 break;
938 case( GDI_BITMAPSCALE_ACTION ):
940 Bitmap aBmp;
942 rIStm >> aPt >> aSz >> aBmp;
943 rMtf.AddAction( new MetaBmpScaleAction( aPt, aSz, aBmp ) );
945 break;
947 case( GDI_BITMAPSCALEPART_ACTION ):
949 Bitmap aBmp;
950 Size aSz2;
952 rIStm >> aPt >> aSz >> aPt1 >> aSz2 >> aBmp;
953 rMtf.AddAction( new MetaBmpScalePartAction( aPt, aSz, aPt1, aSz2, aBmp ) );
955 break;
957 case( GDI_PEN_ACTION ):
959 sal_Int32 nPenWidth;
960 sal_Int16 nPenStyle;
962 ImplReadColor( rIStm, aActionColor );
963 rIStm >> nPenWidth >> nPenStyle;
965 aLineInfo.SetStyle( nPenStyle ? LINE_SOLID : LINE_NONE );
966 aLineInfo.SetWidth( nPenWidth );
967 bFatLine = nPenStyle && !aLineInfo.IsDefault();
969 rMtf.AddAction( new MetaLineColorAction( aActionColor, nPenStyle != 0 ) );
971 break;
973 case( GDI_FILLBRUSH_ACTION ):
975 sal_Int16 nBrushStyle;
977 ImplReadColor( rIStm, aActionColor );
978 rIStm.SeekRel( 6L );
979 rIStm >> nBrushStyle;
980 rMtf.AddAction( new MetaFillColorAction( aActionColor, nBrushStyle != 0 ) );
981 rIStm.SeekRel( 2L );
983 break;
985 case( GDI_MAPMODE_ACTION ):
987 ImplReadMapMode( rIStm, aMapMode );
988 rMtf.AddAction( new MetaMapModeAction( aMapMode ) );
990 // #106172# Track font relevant data in shadow VDev
991 aFontVDev.SetMapMode( aMapMode );
993 break;
995 case( GDI_CLIPREGION_ACTION ):
997 Region aRegion;
998 sal_Int16 nRegType;
999 sal_Int16 bIntersect;
1000 sal_Bool bClip = sal_False;
1002 rIStm >> nRegType >> bIntersect;
1003 ImplReadRect( rIStm, aRect );
1005 switch( nRegType )
1007 case( 0 ):
1008 break;
1010 case( 1 ):
1012 Rectangle aRegRect;
1014 ImplReadRect( rIStm, aRegRect );
1015 aRegion = Region( aRegRect );
1016 bClip = sal_True;
1018 break;
1020 case( 2 ):
1022 ImplReadPoly( rIStm, aActionPoly );
1023 aRegion = Region( aActionPoly );
1024 bClip = sal_True;
1026 break;
1028 case( 3 ):
1030 PolyPolygon aPolyPoly;
1031 sal_Int32 nPolyCount;
1033 rIStm >> nPolyCount;
1035 for( sal_uInt16 j = 0; j < (sal_uInt16) nPolyCount; j++ )
1037 ImplReadPoly( rIStm, aActionPoly );
1038 aPolyPoly.Insert( aActionPoly );
1041 aRegion = Region( aPolyPoly );
1042 bClip = sal_True;
1044 break;
1047 if( bIntersect )
1048 aRegion.Intersect( aRect );
1050 rMtf.AddAction( new MetaClipRegionAction( aRegion, bClip ) );
1052 break;
1054 case( GDI_MOVECLIPREGION_ACTION ):
1056 rIStm >> nTmp >> nTmp1;
1057 rMtf.AddAction( new MetaMoveClipRegionAction( nTmp, nTmp1 ) );
1059 break;
1061 case( GDI_ISECTCLIPREGION_ACTION ):
1063 ImplReadRect( rIStm, aRect );
1064 rMtf.AddAction( new MetaISectRectClipRegionAction( aRect ) );
1066 break;
1068 case( GDI_RASTEROP_ACTION ):
1070 RasterOp eRasterOp;
1071 sal_Int16 nRasterOp;
1073 rIStm >> nRasterOp;
1075 switch( nRasterOp )
1077 case( 1 ):
1078 eRasterOp = ROP_INVERT;
1079 break;
1081 case( 4 ):
1082 case( 5 ):
1083 eRasterOp = ROP_XOR;
1084 break;
1086 default:
1087 eRasterOp = ROP_OVERPAINT;
1088 break;
1091 rMtf.AddAction( new MetaRasterOpAction( eRasterOp ) );
1093 break;
1095 case( GDI_PUSH_ACTION ):
1097 aLIStack.push( new LineInfo( aLineInfo ) );
1098 rMtf.AddAction( new MetaPushAction( PUSH_ALL ) );
1100 // #106172# Track font relevant data in shadow VDev
1101 aFontVDev.Push();
1103 break;
1105 case( GDI_POP_ACTION ):
1108 LineInfo* pLineInfo;
1109 if (aLIStack.empty())
1110 pLineInfo = NULL;
1111 else
1113 pLineInfo = aLIStack.top();
1114 aLIStack.pop();
1117 // restore line info
1118 if( pLineInfo )
1120 aLineInfo = *pLineInfo;
1121 delete pLineInfo;
1122 bFatLine = ( LINE_NONE != aLineInfo.GetStyle() ) && !aLineInfo.IsDefault();
1125 rMtf.AddAction( new MetaPopAction() );
1127 // #106172# Track font relevant data in shadow VDev
1128 aFontVDev.Pop();
1130 break;
1132 case( GDI_GRADIENT_ACTION ):
1134 Color aStartCol;
1135 Color aEndCol;
1136 sal_Int16 nStyle;
1137 sal_Int16 nAngle;
1138 sal_Int16 nBorder;
1139 sal_Int16 nOfsX;
1140 sal_Int16 nOfsY;
1141 sal_Int16 nIntensityStart;
1142 sal_Int16 nIntensityEnd;
1144 ImplReadRect( rIStm, aRect );
1145 rIStm >> nStyle;
1146 ImplReadColor( rIStm, aStartCol );
1147 ImplReadColor( rIStm, aEndCol );
1148 rIStm >> nAngle >> nBorder >> nOfsX >> nOfsY >> nIntensityStart >> nIntensityEnd;
1150 Gradient aGrad( (GradientStyle) nStyle, aStartCol, aEndCol );
1152 aGrad.SetAngle( nAngle );
1153 aGrad.SetBorder( nBorder );
1154 aGrad.SetOfsX( nOfsX );
1155 aGrad.SetOfsY( nOfsY );
1156 aGrad.SetStartIntensity( nIntensityStart );
1157 aGrad.SetEndIntensity( nIntensityEnd );
1158 rMtf.AddAction( new MetaGradientAction( aRect, aGrad ) );
1160 break;
1162 case( GDI_TRANSPARENT_COMMENT ):
1164 PolyPolygon aPolyPoly;
1165 sal_Int32 nFollowingActionCount;
1166 sal_Int16 nTrans;
1168 rIStm >> aPolyPoly >> nTrans >> nFollowingActionCount;
1169 ImplSkipActions( rIStm, nFollowingActionCount );
1170 rMtf.AddAction( new MetaTransparentAction( aPolyPoly, nTrans ) );
1172 i += nFollowingActionCount;
1174 break;
1176 case( GDI_FLOATTRANSPARENT_COMMENT ):
1178 GDIMetaFile aMtf;
1179 Point aPos;
1180 Size aSize;
1181 Gradient aGradient;
1182 sal_Int32 nFollowingActionCount;
1184 rIStm >> aMtf >> aPos >> aSize >> aGradient >> nFollowingActionCount;
1185 ImplSkipActions( rIStm, nFollowingActionCount );
1186 rMtf.AddAction( new MetaFloatTransparentAction( aMtf, aPos, aSize, aGradient ) );
1188 i += nFollowingActionCount;
1190 break;
1192 case( GDI_HATCH_COMMENT ):
1194 PolyPolygon aPolyPoly;
1195 Hatch aHatch;
1196 sal_Int32 nFollowingActionCount;
1198 rIStm >> aPolyPoly >> aHatch >> nFollowingActionCount;
1199 ImplSkipActions( rIStm, nFollowingActionCount );
1200 rMtf.AddAction( new MetaHatchAction( aPolyPoly, aHatch ) );
1202 i += nFollowingActionCount;
1204 break;
1206 case( GDI_REFPOINT_COMMENT ):
1208 Point aRefPoint;
1209 sal_Bool bSet;
1210 sal_Int32 nFollowingActionCount;
1212 rIStm >> aRefPoint >> bSet >> nFollowingActionCount;
1213 ImplSkipActions( rIStm, nFollowingActionCount );
1214 rMtf.AddAction( new MetaRefPointAction( aRefPoint, bSet ) );
1216 i += nFollowingActionCount;
1218 // #106172# Track font relevant data in shadow VDev
1219 if( bSet )
1220 aFontVDev.SetRefPoint( aRefPoint );
1221 else
1222 aFontVDev.SetRefPoint();
1224 break;
1226 case( GDI_TEXTLINECOLOR_COMMENT ):
1228 Color aColor;
1229 sal_Bool bSet;
1230 sal_Int32 nFollowingActionCount;
1232 rIStm >> aColor >> bSet >> nFollowingActionCount;
1233 ImplSkipActions( rIStm, nFollowingActionCount );
1234 rMtf.AddAction( new MetaTextLineColorAction( aColor, bSet ) );
1236 i += nFollowingActionCount;
1238 break;
1240 case( GDI_TEXTLINE_COMMENT ):
1242 Point aStartPt;
1243 //#fdo39428 SvStream no longer supports operator>>(long&)
1244 sal_Int32 nWidth;
1245 sal_uInt32 nStrikeout;
1246 sal_uInt32 nUnderline;
1247 sal_Int32 nFollowingActionCount;
1249 rIStm >> aStartPt >> nWidth >> nStrikeout >> nUnderline >> nFollowingActionCount;
1250 ImplSkipActions( rIStm, nFollowingActionCount );
1251 rMtf.AddAction( new MetaTextLineAction( aStartPt, nWidth,
1252 (FontStrikeout) nStrikeout,
1253 (FontUnderline) nUnderline,
1254 UNDERLINE_NONE ) );
1256 i += nFollowingActionCount;
1258 break;
1260 case( GDI_GRADIENTEX_COMMENT ):
1262 PolyPolygon aPolyPoly;
1263 Gradient aGradient;
1264 sal_Int32 nFollowingActionCount;
1266 rIStm >> aPolyPoly >> aGradient >> nFollowingActionCount;
1267 ImplSkipActions( rIStm, nFollowingActionCount );
1268 rMtf.AddAction( new MetaGradientExAction( aPolyPoly, aGradient ) );
1270 i += nFollowingActionCount;
1272 break;
1274 case( GDI_COMMENT_COMMENT ):
1276 sal_Int32 nValue;
1277 sal_uInt32 nDataSize;
1278 sal_uInt8* pData;
1279 sal_Int32 nFollowingActionCount;
1281 OString aComment = read_lenPrefixed_uInt8s_ToOString<sal_uInt16>(rIStm);
1282 rIStm >> nValue >> nDataSize;
1284 if( nDataSize )
1286 pData = new sal_uInt8[ nDataSize ];
1287 rIStm.Read( pData, nDataSize );
1289 else
1290 pData = NULL;
1292 rIStm >> nFollowingActionCount;
1293 ImplSkipActions( rIStm, nFollowingActionCount );
1294 rMtf.AddAction( new MetaCommentAction( aComment, nValue, pData, nDataSize ) );
1296 i += nFollowingActionCount;
1298 break;
1300 case ( GDI_UNICODE_COMMENT ):
1302 nUnicodeCommentActionNumber = i + 1;
1303 nUnicodeCommentStreamPos = rIStm.Tell() - 6;
1304 rIStm.SeekRel( nActionSize - 4 );
1306 break;
1308 default:
1309 rIStm.SeekRel( nActionSize - 4L );
1310 break;
1314 // cleanup push-pop stack if necessary
1315 while( !aLIStack.empty() )
1317 delete aLIStack.top();
1318 aLIStack.pop();
1321 rIStm.SetNumberFormatInt( nOldFormat );
1324 void SVMConverter::ImplConvertToSVM1( SvStream& rOStm, GDIMetaFile& rMtf )
1326 sal_uLong nCountPos;
1327 Font aSaveFont;
1328 const sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt();
1329 rtl_TextEncoding eActualCharSet = osl_getThreadTextEncoding();
1330 const Size aPrefSize( rMtf.GetPrefSize() );
1331 sal_Bool bRop_0_1 = sal_False;
1332 VirtualDevice aSaveVDev;
1333 Color aLineCol( COL_BLACK );
1334 ::std::stack< Color* > aLineColStack;
1336 rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1338 // Write MagicCode
1339 rOStm << "SVGDI"; // Identifier
1340 rOStm << (sal_Int16) 42; // HeaderSize
1341 rOStm << (sal_Int16) 200; // VERSION
1342 rOStm << (sal_Int32) aPrefSize.Width();
1343 rOStm << (sal_Int32) aPrefSize.Height();
1344 ImplWriteMapMode( rOStm, rMtf.GetPrefMapMode() );
1346 // ActionCount will be written later
1347 nCountPos = rOStm.Tell();
1348 rOStm.SeekRel( 4L );
1350 const sal_Int32 nActCount = ImplWriteActions( rOStm, rMtf, aSaveVDev, bRop_0_1, aLineCol, aLineColStack, eActualCharSet );
1351 const sal_uLong nActPos = rOStm.Tell();
1353 rOStm.Seek( nCountPos );
1354 rOStm << nActCount;
1355 rOStm.Seek( nActPos );
1356 rOStm.SetNumberFormatInt( nOldFormat );
1358 // cleanup push-pop stack if necessary
1359 while ( !aLineColStack.empty() )
1361 delete aLineColStack.top();
1362 aLineColStack.pop();
1366 sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
1367 VirtualDevice& rSaveVDev, sal_Bool& rRop_0_1,
1368 Color& rLineCol, ::std::stack< Color* >& rLineColStack,
1369 rtl_TextEncoding& rActualCharSet )
1371 sal_uLong nCount = 0;
1372 for( size_t i = 0, nActionCount = rMtf.GetActionSize(); i < nActionCount; i++ )
1374 const MetaAction* pAction = rMtf.GetAction( i );
1376 switch( pAction->GetType() )
1378 case( META_PIXEL_ACTION ):
1380 MetaPixelAction* pAct = (MetaPixelAction*) pAction;
1382 rOStm << (sal_Int16) GDI_PIXEL_ACTION;
1383 rOStm << (sal_Int32) 18;
1384 rOStm << pAct->GetPoint();
1385 ImplWriteColor( rOStm, pAct->GetColor() );
1386 nCount++;
1388 break;
1390 case( META_POINT_ACTION ):
1392 MetaPointAction* pAct = (MetaPointAction*) pAction;
1394 rOStm << (sal_Int16) GDI_POINT_ACTION;
1395 rOStm << (sal_Int32) 12;
1396 rOStm << pAct->GetPoint();
1397 nCount++;
1399 break;
1401 case( META_LINE_ACTION ):
1403 MetaLineAction* pAct = (MetaLineAction*) pAction;
1404 const LineInfo& rInfo = pAct->GetLineInfo();
1405 const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
1406 const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
1407 const bool bLineCap(bFatLine && com::sun::star::drawing::LineCap_BUTT != rInfo.GetLineCap());
1408 const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
1410 if( bFatLine )
1412 ImplWritePushAction( rOStm );
1413 ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
1415 if(bLineJoin)
1417 rOStm << (sal_Int16) GDI_LINEJOIN_ACTION;
1418 rOStm << (sal_Int32) 6;
1419 rOStm << (sal_Int16) rInfo.GetLineJoin();
1422 if(bLineCap)
1424 rOStm << (sal_Int16) GDI_LINECAP_ACTION;
1425 rOStm << (sal_Int32) 6;
1426 rOStm << (sal_Int16) rInfo.GetLineCap();
1430 if(bLineDashDot)
1432 rOStm << (sal_Int16) GDI_LINEDASHDOT_ACTION;
1433 rOStm << (sal_Int32) 4 + 16;
1434 rOStm << (sal_Int16)rInfo.GetDashCount();
1435 rOStm << (sal_Int32)rInfo.GetDashLen();
1436 rOStm << (sal_Int16)rInfo.GetDotCount();
1437 rOStm << (sal_Int32)rInfo.GetDotLen();
1438 rOStm << (sal_Int32)rInfo.GetDistance();
1441 rOStm << (sal_Int16) GDI_LINE_ACTION;
1442 rOStm << (sal_Int32) 20;
1443 rOStm << pAct->GetStartPoint();
1444 rOStm << pAct->GetEndPoint();
1445 nCount++;
1447 if( bFatLine )
1449 ImplWritePopAction( rOStm );
1450 nCount += 3;
1452 if(bLineJoin)
1454 nCount += 1;
1457 if(bLineCap)
1459 nCount += 1;
1463 if(bLineDashDot)
1465 nCount += 1;
1468 break;
1470 case( META_RECT_ACTION ):
1472 MetaRectAction* pAct = (MetaRectAction*) pAction;
1474 rOStm << (sal_Int16) GDI_RECT_ACTION;
1475 rOStm << (sal_Int32) 28;
1476 ImplWriteRect( rOStm, pAct->GetRect() );
1477 rOStm << (sal_Int32) 0;
1478 rOStm << (sal_Int32) 0;
1479 nCount++;
1481 break;
1483 case( META_ROUNDRECT_ACTION ):
1485 MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction;
1487 rOStm << (sal_Int16) GDI_RECT_ACTION;
1488 rOStm << (sal_Int32) 28;
1489 ImplWriteRect( rOStm, pAct->GetRect() );
1490 rOStm << (sal_Int32) pAct->GetHorzRound();
1491 rOStm << (sal_Int32) pAct->GetVertRound();
1492 nCount++;
1494 break;
1496 case( META_ELLIPSE_ACTION ):
1498 MetaEllipseAction* pAct = (MetaEllipseAction*) pAction;
1500 rOStm << (sal_Int16) GDI_ELLIPSE_ACTION;
1501 rOStm << (sal_Int32) 20;
1502 ImplWriteRect( rOStm, pAct->GetRect() );
1503 nCount++;
1505 break;
1507 case( META_ARC_ACTION ):
1509 MetaArcAction* pAct = (MetaArcAction*) pAction;
1511 rOStm << (sal_Int16) GDI_ARC_ACTION;
1512 rOStm << (sal_Int32) 36;
1513 ImplWriteRect( rOStm, pAct->GetRect() );
1514 rOStm << pAct->GetStartPoint();
1515 rOStm << pAct->GetEndPoint();
1516 nCount++;
1518 break;
1520 case( META_PIE_ACTION ):
1522 MetaPieAction* pAct = (MetaPieAction*) pAction;
1524 rOStm << (sal_Int16) GDI_PIE_ACTION;
1525 rOStm << (sal_Int32) 36;
1526 ImplWriteRect( rOStm, pAct->GetRect() );
1527 rOStm << pAct->GetStartPoint();
1528 rOStm << pAct->GetEndPoint();
1529 nCount++;
1531 break;
1533 case( META_CHORD_ACTION ):
1535 MetaChordAction* pAct = (MetaChordAction*) pAction;
1536 Polygon aChordPoly( pAct->GetRect(), pAct->GetStartPoint(),
1537 pAct->GetEndPoint(), POLY_CHORD );
1538 const sal_uInt16 nPoints = aChordPoly.GetSize();
1540 rOStm << (sal_Int16) GDI_POLYGON_ACTION;
1541 rOStm << (sal_Int32) ( 8 + ( nPoints << 3 ) );
1542 rOStm << (sal_Int32) nPoints;
1544 for( sal_uInt16 n = 0; n < nPoints; n++ )
1545 rOStm << aChordPoly[ n ];
1546 nCount++;
1548 break;
1550 case( META_POLYLINE_ACTION ):
1552 // #i102224#
1553 MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction;
1554 // #i102224# Here the possible curved nature of Polygon was
1555 // ignored (for all those years). Adapted to at least write
1556 // a polygon representing the curve as good as possible
1557 Polygon aSimplePoly;
1558 pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
1559 const LineInfo& rInfo = pAct->GetLineInfo();
1560 const sal_uInt16 nPoints(aSimplePoly.GetSize());
1561 const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
1562 const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
1563 const bool bLineCap(bFatLine && com::sun::star::drawing::LineCap_BUTT != rInfo.GetLineCap());
1564 const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
1566 if( bFatLine )
1568 ImplWritePushAction( rOStm );
1569 ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
1571 if(bLineJoin)
1573 rOStm << (sal_Int16) GDI_LINEJOIN_ACTION;
1574 rOStm << (sal_Int32) 6;
1575 rOStm << (sal_Int16) rInfo.GetLineJoin();
1578 if(bLineCap)
1580 rOStm << (sal_Int16) GDI_LINECAP_ACTION;
1581 rOStm << (sal_Int32) 6;
1582 rOStm << (sal_Int16) rInfo.GetLineCap();
1586 if(bLineDashDot)
1588 rOStm << (sal_Int16) GDI_LINEDASHDOT_ACTION;
1589 rOStm << (sal_Int32) 4 + 16;
1590 rOStm << (sal_Int16)rInfo.GetDashCount();
1591 rOStm << (sal_Int32)rInfo.GetDashLen();
1592 rOStm << (sal_Int16)rInfo.GetDotCount();
1593 rOStm << (sal_Int32)rInfo.GetDotLen();
1594 rOStm << (sal_Int32)rInfo.GetDistance();
1597 rOStm << (sal_Int16) GDI_POLYLINE_ACTION;
1598 rOStm << (sal_Int32) ( 8 + ( nPoints << 3 ) );
1599 rOStm << (sal_Int32) nPoints;
1601 for( sal_uInt16 n = 0; n < nPoints; n++ )
1603 rOStm << aSimplePoly[ n ];
1606 nCount++;
1608 const PolyPolygon aPolyPolygon(pAct->GetPolygon());
1609 if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
1611 nCount++;
1614 if( bFatLine )
1616 ImplWritePopAction( rOStm );
1617 nCount += 3;
1619 if(bLineJoin)
1621 nCount += 1;
1624 if(bLineCap)
1626 nCount += 1;
1630 if(bLineDashDot)
1632 nCount += 1;
1635 break;
1637 case( META_POLYGON_ACTION ):
1639 MetaPolygonAction* pAct = (MetaPolygonAction*)pAction;
1640 // #i102224# Here the possible curved nature of Polygon was
1641 // ignored (for all those years). Adapted to at least write
1642 // a polygon representing the curve as good as possible
1643 Polygon aSimplePoly;
1644 pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
1645 const sal_uInt16 nPoints(aSimplePoly.GetSize());
1647 rOStm << (sal_Int16) GDI_POLYGON_ACTION;
1648 rOStm << (sal_Int32) ( 8 + ( nPoints << 3 ) );
1649 rOStm << (sal_Int32) nPoints;
1651 for( sal_uInt16 n = 0; n < nPoints; n++ )
1652 rOStm << aSimplePoly[ n ];
1654 nCount++;
1656 const PolyPolygon aPolyPolygon(pAct->GetPolygon());
1657 if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
1659 nCount++;
1662 break;
1664 case( META_POLYPOLYGON_ACTION ):
1666 MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction;
1667 ImplWritePolyPolyAction( rOStm, pAct->GetPolyPolygon() );
1668 nCount++;
1670 if(ImplWriteExtendedPolyPolygonAction(rOStm, pAct->GetPolyPolygon(), true))
1672 nCount++;
1675 break;
1677 case( META_TEXT_ACTION ):
1679 MetaTextAction* pAct = (MetaTextAction*) pAction;
1680 String aUniText( pAct->GetText() );
1681 OString aText(OUStringToOString(aUniText,
1682 rActualCharSet));
1683 const sal_uLong nStrLen = aText.getLength();
1685 if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
1686 nCount++;
1688 rOStm << (sal_Int16) GDI_TEXT_ACTION;
1689 rOStm << (sal_Int32) ( 24 + ( nStrLen + 1 ) );
1690 rOStm << pAct->GetPoint();
1691 rOStm << (sal_Int32) pAct->GetIndex();
1692 rOStm << (sal_Int32) pAct->GetLen();
1693 rOStm << (sal_Int32) nStrLen;
1694 rOStm.Write( aText.getStr(), nStrLen + 1 );
1695 nCount++;
1697 break;
1699 case( META_TEXTARRAY_ACTION ):
1701 MetaTextArrayAction* pAct = (MetaTextArrayAction*)pAction;
1702 OString aText(OUStringToOString(pAct->GetText(),
1703 rActualCharSet));
1704 String aUniText( pAct->GetText(), pAct->GetIndex(), pAct->GetLen() );
1705 sal_uLong nAryLen;
1706 sal_uLong nLen = pAct->GetLen();
1707 const sal_uLong nTextLen = aText.getLength();
1708 sal_Int32* pDXArray = pAct->GetDXArray();
1710 if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
1711 nCount++;
1713 if( ( nLen + pAct->GetIndex() ) > nTextLen )
1715 if( pAct->GetIndex() <= nTextLen )
1716 nLen = nTextLen - pAct->GetIndex();
1717 else
1718 nLen = 0UL;
1721 if( !pDXArray || !nLen )
1722 nAryLen = 0;
1723 else
1724 nAryLen = nLen; // #105987# Write out all of DX array
1726 rOStm << (sal_Int16) GDI_TEXTARRAY_ACTION;
1727 rOStm << (sal_Int32) ( 28 + ( nLen + 1 ) + ( nAryLen * 4 ) );
1728 rOStm << pAct->GetPoint();
1729 rOStm << (sal_Int32) 0;
1730 rOStm << (sal_Int32) nLen;
1731 rOStm << (sal_Int32) nLen;
1732 rOStm << (sal_Int32) nAryLen;
1733 rOStm.Write( aText.getStr()+pAct->GetIndex(), nLen + 1 );
1735 for( sal_uLong n = 0UL ; n < nAryLen; n++ )
1736 rOStm << (sal_Int32) pDXArray[ n ];
1738 nCount++;
1740 break;
1742 case( META_STRETCHTEXT_ACTION ):
1744 MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction;
1745 String aUniText( pAct->GetText() );
1746 OString aText(OUStringToOString(aUniText,
1747 rActualCharSet));
1748 const sal_uLong nStrLen = aText.getLength();
1750 if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
1751 nCount++;
1753 rOStm << (sal_Int16) GDI_STRETCHTEXT_ACTION;
1754 rOStm << (sal_Int32) ( 28 + ( nStrLen + 1 ) );
1755 rOStm << pAct->GetPoint();
1756 rOStm << (sal_Int32) pAct->GetIndex();
1757 rOStm << (sal_Int32) pAct->GetLen();
1758 rOStm << (sal_Int32) nStrLen;
1759 rOStm << (sal_Int32) pAct->GetWidth();
1760 rOStm.Write( aText.getStr(), nStrLen + 1 );
1761 nCount++;
1763 break;
1765 case( META_BMP_ACTION ):
1767 MetaBmpAction* pAct = (MetaBmpAction*) pAction;
1769 rOStm << (sal_Int16) GDI_BITMAP_ACTION;
1770 rOStm << (sal_Int32) 12;
1771 rOStm << pAct->GetPoint();
1772 rOStm << pAct->GetBitmap();
1773 nCount++;
1775 break;
1777 case( META_BMPSCALE_ACTION ):
1779 MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
1781 rOStm << (sal_Int16) GDI_BITMAPSCALE_ACTION;
1782 rOStm << (sal_Int32) 20;
1783 rOStm << pAct->GetPoint();
1784 rOStm << pAct->GetSize();
1785 rOStm << pAct->GetBitmap();
1786 nCount++;
1788 break;
1790 case( META_BMPSCALEPART_ACTION ):
1792 MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
1794 rOStm << (sal_Int16) GDI_BITMAPSCALEPART_ACTION;
1795 rOStm << (sal_Int32) 36;
1796 rOStm << pAct->GetDestPoint();
1797 rOStm << pAct->GetDestSize();
1798 rOStm << pAct->GetSrcPoint();
1799 rOStm << pAct->GetSrcSize();
1800 rOStm << pAct->GetBitmap();
1801 nCount++;
1803 break;
1805 case( META_BMPEX_ACTION ):
1807 MetaBmpExAction* pAct = (MetaBmpExAction*) pAction;
1808 const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
1810 rOStm << (sal_Int16) GDI_BITMAP_ACTION;
1811 rOStm << (sal_Int32) 12;
1812 rOStm << pAct->GetPoint();
1813 rOStm << aBmp;
1814 nCount++;
1816 break;
1818 case( META_BMPEXSCALE_ACTION ):
1820 MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction;
1821 const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
1823 rOStm << (sal_Int16) GDI_BITMAPSCALE_ACTION;
1824 rOStm << (sal_Int32) 20;
1825 rOStm << pAct->GetPoint();
1826 rOStm << pAct->GetSize();
1827 rOStm << aBmp;
1828 nCount++;
1830 break;
1832 case( META_BMPEXSCALEPART_ACTION ):
1834 MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction;
1835 const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
1837 rOStm << (sal_Int16) GDI_BITMAPSCALEPART_ACTION;
1838 rOStm << (sal_Int32) 36;
1839 rOStm << pAct->GetDestPoint();
1840 rOStm << pAct->GetDestSize();
1841 rOStm << pAct->GetSrcPoint();
1842 rOStm << pAct->GetSrcSize();
1843 rOStm << aBmp;
1844 nCount++;
1846 break;
1848 case( META_GRADIENT_ACTION ):
1850 MetaGradientAction* pAct = (MetaGradientAction*) pAction;
1851 const Gradient& rGrad = pAct->GetGradient();
1853 rOStm << (sal_Int16) GDI_GRADIENT_ACTION;
1854 rOStm << (sal_Int32) 46;
1855 ImplWriteRect( rOStm, pAct->GetRect() );
1856 rOStm << (sal_Int16) rGrad.GetStyle();
1857 ImplWriteColor( rOStm, rGrad.GetStartColor() );
1858 ImplWriteColor( rOStm, rGrad.GetEndColor() );
1859 rOStm << (sal_Int16) rGrad.GetAngle();
1860 rOStm << (sal_Int16) rGrad.GetBorder();
1861 rOStm << (sal_Int16) rGrad.GetOfsX();
1862 rOStm << (sal_Int16) rGrad.GetOfsY();
1863 rOStm << (sal_Int16) rGrad.GetStartIntensity();
1864 rOStm << (sal_Int16) rGrad.GetEndIntensity();
1865 nCount++;
1867 break;
1869 case( META_GRADIENTEX_ACTION ):
1871 const MetaGradientExAction* pA = (MetaGradientExAction*) pAction;
1872 sal_uLong nOldPos, nNewPos;
1874 // write RefPoint comment
1875 rOStm << (sal_Int16) GDI_GRADIENTEX_COMMENT;
1877 // we'll write the ActionSize later
1878 nOldPos = rOStm.Tell();
1879 rOStm.SeekRel( 4 );
1881 // write data
1882 rOStm << pA->GetPolyPolygon() << pA->GetGradient();
1883 rOStm << (sal_Int32) 0; // number of actions that follow this comment
1885 // calculate and write ActionSize of comment
1886 nNewPos = rOStm.Tell();
1887 rOStm.Seek( nOldPos );
1888 rOStm << (sal_Int32) ( nNewPos - nOldPos );
1889 rOStm.Seek( nNewPos );
1891 nCount++;
1893 break;
1895 case( META_WALLPAPER_ACTION ):
1897 MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction;
1898 const Color& rColor = pAct->GetWallpaper().GetColor();
1900 ImplWritePushAction( rOStm );
1901 ImplWriteLineColor( rOStm, rColor, 1 );
1902 ImplWriteFillColor( rOStm, rColor, 1 );
1904 rOStm << (sal_Int16) GDI_RECT_ACTION;
1905 rOStm << (sal_Int32) 28;
1906 ImplWriteRect( rOStm, pAct->GetRect() );
1907 rOStm << (sal_Int32) 0;
1908 rOStm << (sal_Int32) 0;
1910 ImplWritePopAction( rOStm );
1911 nCount += 5;
1913 break;
1915 case( META_CLIPREGION_ACTION ):
1917 MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction;
1918 const Region& rRegion = pAct->GetRegion();
1919 Rectangle aClipRect;
1921 rOStm << (sal_Int16) GDI_CLIPREGION_ACTION;
1922 rOStm << (sal_Int32) 24;
1924 if( pAct->IsClipping() )
1926 aClipRect = rRegion.GetBoundRect();
1927 rOStm << (sal_Int16) 1;
1929 else
1930 rOStm << (sal_Int16) 0;
1932 rOStm << (sal_Int16) 0;
1933 ImplWriteRect( rOStm, aClipRect );
1935 if( pAct->IsClipping() )
1936 ImplWriteRect( rOStm, aClipRect );
1938 nCount++;
1940 break;
1942 case( META_ISECTRECTCLIPREGION_ACTION ):
1944 MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction;
1946 rOStm << (sal_Int16) GDI_ISECTCLIPREGION_ACTION;
1947 rOStm << (sal_Int32) 20;
1948 rOStm << pAct->GetRect();
1949 nCount++;
1951 break;
1953 case( META_MOVECLIPREGION_ACTION ):
1955 MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction;
1957 rOStm << (sal_Int16) GDI_MOVECLIPREGION_ACTION;
1958 rOStm << (sal_Int32) 12;
1959 rOStm << (sal_Int32) pAct->GetHorzMove();
1960 rOStm << (sal_Int32) pAct->GetVertMove();
1961 nCount++;
1963 break;
1965 case( META_LINECOLOR_ACTION ):
1967 MetaLineColorAction* pAct = (MetaLineColorAction*) pAction;
1968 ImplWriteLineColor( rOStm, rLineCol = pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
1969 nCount++;
1971 break;
1973 case( META_FILLCOLOR_ACTION ):
1975 MetaFillColorAction* pAct = (MetaFillColorAction*) pAction;
1976 ImplWriteFillColor( rOStm, pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
1977 nCount++;
1979 break;
1981 case( META_FONT_ACTION ):
1983 rSaveVDev.SetFont( ( (MetaFontAction*) pAction )->GetFont() );
1984 ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
1985 nCount++;
1987 break;
1989 case( META_TEXTCOLOR_ACTION ):
1991 Font aSaveFont( rSaveVDev.GetFont() );
1993 aSaveFont.SetColor( ( (MetaTextColorAction*) pAction )->GetColor() );
1994 rSaveVDev.SetFont( aSaveFont );
1995 ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
1996 nCount++;
1998 break;
2000 case( META_TEXTFILLCOLOR_ACTION ):
2002 MetaTextFillColorAction* pAct = (MetaTextFillColorAction*) pAction;
2003 Font aSaveFont( rSaveVDev.GetFont() );
2005 if( pAct->IsSetting() )
2006 aSaveFont.SetFillColor( pAct->GetColor() );
2007 else
2008 aSaveFont.SetFillColor( Color( COL_TRANSPARENT ) );
2010 rSaveVDev.SetFont( aSaveFont );
2011 ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2012 nCount++;
2014 break;
2016 case( META_TEXTALIGN_ACTION ):
2018 Font aSaveFont( rSaveVDev.GetFont() );
2020 aSaveFont.SetAlign( ( (MetaTextAlignAction*) pAction )->GetTextAlign() );
2021 rSaveVDev.SetFont( aSaveFont );
2022 ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
2023 nCount++;
2025 break;
2027 case( META_MAPMODE_ACTION ):
2029 MetaMapModeAction* pAct = (MetaMapModeAction*) pAction;
2031 rOStm << (sal_Int16) GDI_MAPMODE_ACTION;
2032 rOStm << (sal_Int32) 30;
2033 ImplWriteMapMode( rOStm, pAct->GetMapMode() );
2034 nCount++;
2036 break;
2038 case( META_PUSH_ACTION ):
2040 ImplWritePushAction( rOStm );
2041 rLineColStack.push( new Color( rLineCol ) );
2042 rSaveVDev.Push();
2043 nCount++;
2045 break;
2047 case( META_POP_ACTION ):
2049 Color* pCol;
2050 if (rLineColStack.empty())
2051 pCol = NULL;
2052 else
2054 pCol = rLineColStack.top();
2055 rLineColStack.pop();
2058 if( pCol )
2060 rLineCol = *pCol;
2061 delete pCol;
2064 ImplWritePopAction( rOStm );
2065 rSaveVDev.Pop();
2066 nCount++;
2068 break;
2070 case( META_RASTEROP_ACTION ):
2072 MetaRasterOpAction* pAct = (MetaRasterOpAction*) pAction;
2074 if( ( pAct->GetRasterOp() != ROP_0 ) && ( pAct->GetRasterOp() != ROP_1 ) )
2076 sal_Int16 nRasterOp;
2078 // If ROP_0/1 was set earlier, restore old state
2079 // via a Pop first
2080 if( rRop_0_1 )
2082 ImplWritePopAction( rOStm );
2083 rSaveVDev.Pop();
2084 rRop_0_1 = sal_False;
2085 nCount++;
2088 switch( pAct->GetRasterOp() )
2090 case( ROP_OVERPAINT ) : nRasterOp = 0; break;
2091 case( ROP_XOR ) : nRasterOp = 4; break;
2092 case( ROP_INVERT ): nRasterOp = 1; break;
2093 default: nRasterOp = 0; break;
2096 ImplWriteRasterOpAction( rOStm, nRasterOp );
2097 nCount++;
2099 else
2101 ImplWritePushAction( rOStm );
2102 rSaveVDev.Push();
2104 if( pAct->GetRasterOp() == ROP_0 )
2106 ImplWriteLineColor( rOStm, COL_BLACK, 1 );
2107 ImplWriteFillColor( rOStm, COL_BLACK, 1 );
2109 else
2111 ImplWriteLineColor( rOStm, COL_WHITE, 1 );
2112 ImplWriteFillColor( rOStm, COL_WHITE, 1 );
2115 ImplWriteRasterOpAction( rOStm, 0 );
2116 rRop_0_1 = sal_True;
2117 nCount += 4;
2120 break;
2122 case( META_TRANSPARENT_ACTION ):
2124 const PolyPolygon& rPolyPoly = ( (MetaTransparentAction*) pAction )->GetPolyPolygon();
2125 const sal_Int16 nTrans = ( (MetaTransparentAction*) pAction )->GetTransparence();
2126 const sal_Int16 nBrushStyle = ( nTrans < 38 ) ? 8 : ( nTrans < 63 ) ? 9 : 10;
2127 sal_uLong nOldPos, nNewPos;
2129 // write transparence comment
2130 rOStm << (sal_Int16) GDI_TRANSPARENT_COMMENT;
2132 // we'll write the ActionSize later
2133 nOldPos = rOStm.Tell();
2134 rOStm.SeekRel( 4 );
2136 // write comment data
2137 rOStm << rPolyPoly;
2138 rOStm << nTrans;
2139 rOStm << (sal_Int32) 15; // number of actions that follow this comment
2141 // calculate and write ActionSize of comment
2142 nNewPos = rOStm.Tell();
2143 rOStm.Seek( nOldPos );
2144 rOStm << (sal_Int32) ( nNewPos - nOldPos );
2145 rOStm.Seek( nNewPos );
2148 // write actions for transparence
2149 ImplWritePushAction( rOStm );
2151 ImplWriteRasterOpAction( rOStm, 4 );
2152 ImplWritePolyPolyAction( rOStm, rPolyPoly );
2154 ImplWritePushAction( rOStm );
2156 ImplWriteRasterOpAction( rOStm, 2 );
2157 ImplWriteFillColor( rOStm, COL_BLACK, nBrushStyle );
2158 ImplWritePolyPolyAction( rOStm, rPolyPoly );
2160 ImplWritePopAction( rOStm );
2162 ImplWriteRasterOpAction( rOStm, 4 );
2163 ImplWritePolyPolyAction( rOStm, rPolyPoly );
2165 ImplWritePopAction( rOStm );
2167 ImplWritePushAction( rOStm );
2169 ImplWriteFillColor( rOStm, Color(), 0 );
2170 ImplWritePolyPolyAction( rOStm, rPolyPoly );
2172 ImplWritePopAction( rOStm );
2174 nCount += 15;
2177 nCount++;
2179 break;
2181 case( META_FLOATTRANSPARENT_ACTION ):
2183 const MetaFloatTransparentAction* pA = (MetaFloatTransparentAction*) pAction;
2184 const GDIMetaFile& rTransMtf = pA->GetGDIMetaFile();
2185 const Point& rPos = pA->GetPoint();
2186 const Size& rSize = pA->GetSize();
2187 const Gradient& rGradient = pA->GetGradient();
2188 sal_uLong nOldPos, nNewPos;
2190 // write RefPoint comment
2191 rOStm << (sal_Int16) GDI_FLOATTRANSPARENT_COMMENT;
2193 // we'll write the ActionSize later
2194 nOldPos = rOStm.Tell();
2195 rOStm.SeekRel( 4 );
2197 // write comment data
2198 rOStm << rTransMtf << rPos << rSize << rGradient;
2200 // calculate and write ActionSize of comment
2201 nNewPos = rOStm.Tell();
2202 rOStm.Seek( nOldPos );
2203 rOStm << (sal_Int32) ( nNewPos - nOldPos + 4 );
2204 rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
2207 // write actions for float transparence
2208 sal_uLong nAddCount;
2209 GDIMetaFile aMtf( rTransMtf );
2210 const Size aSrcSize( rTransMtf.GetPrefSize() );
2211 Point aSrcPt( rTransMtf.GetPrefMapMode().GetOrigin() );
2212 const double fScaleX = aSrcSize.Width() ? (double) rSize.Width() / aSrcSize.Width() : 1.0;
2213 const double fScaleY = aSrcSize.Height() ? (double) rSize.Height() / aSrcSize.Height() : 1.0;
2214 long nMoveX, nMoveY;
2216 if( fScaleX != 1.0 || fScaleY != 1.0 )
2218 aMtf.Scale( fScaleX, fScaleY );
2219 aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
2222 nMoveX = rPos.X() - aSrcPt.X(), nMoveY = rPos.Y() - aSrcPt.Y();
2224 if( nMoveX || nMoveY )
2225 aMtf.Move( nMoveX, nMoveY );
2227 nAddCount = ImplWriteActions( rOStm, aMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
2228 nNewPos = rOStm.Tell();
2229 rOStm.Seek( nOldPos );
2230 rOStm << (sal_Int32) nAddCount;
2231 rOStm.Seek( nNewPos );
2233 nCount += nAddCount;
2236 nCount++;
2238 break;
2240 case( META_HATCH_ACTION ):
2242 const MetaHatchAction* pA = (MetaHatchAction*) pAction;
2243 const PolyPolygon& rPolyPoly = pA->GetPolyPolygon();
2244 const Hatch& rHatch = pA->GetHatch();
2245 sal_uLong nOldPos, nNewPos, nAddCount;
2247 // write hatch comment
2248 rOStm << (sal_Int16) GDI_HATCH_COMMENT;
2250 // we'll write the ActionSize later
2251 nOldPos = rOStm.Tell();
2252 rOStm.SeekRel( 4 );
2254 // write comment data
2255 rOStm << rPolyPoly;
2256 rOStm << rHatch;
2258 // calculate and write ActionSize of comment
2259 nNewPos = rOStm.Tell();
2260 rOStm.Seek( nOldPos );
2261 rOStm << (sal_Int32) ( nNewPos - nOldPos + 4 );
2262 rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
2265 // write actions for hatch
2266 VirtualDevice aVDev;
2267 GDIMetaFile aTmpMtf;
2269 aVDev.AddHatchActions( rPolyPoly, rHatch, aTmpMtf );
2270 nAddCount = ImplWriteActions( rOStm, aTmpMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
2271 nNewPos = rOStm.Tell();
2272 rOStm.Seek( nOldPos );
2273 rOStm << (sal_Int32) nAddCount;
2274 rOStm.Seek( nNewPos );
2276 nCount += nAddCount;
2279 nCount++;
2281 break;
2283 case( META_REFPOINT_ACTION ):
2285 const MetaRefPointAction* pA = (MetaRefPointAction*) pAction;
2286 const Point& rRefPoint = pA->GetRefPoint();
2287 const sal_Bool bSet = pA->IsSetting();
2288 sal_uLong nOldPos, nNewPos;
2290 // write RefPoint comment
2291 rOStm << (sal_Int16) GDI_REFPOINT_COMMENT;
2293 // we'll write the ActionSize later
2294 nOldPos = rOStm.Tell();
2295 rOStm.SeekRel( 4 );
2297 // write data
2298 rOStm << rRefPoint << bSet;
2299 rOStm << (sal_Int32) 0; // number of actions that follow this comment
2301 // calculate and write ActionSize of comment
2302 nNewPos = rOStm.Tell();
2303 rOStm.Seek( nOldPos );
2304 rOStm << (sal_Int32) ( nNewPos - nOldPos );
2305 rOStm.Seek( nNewPos );
2307 nCount++;
2309 break;
2311 case( META_TEXTLINECOLOR_ACTION ):
2313 const MetaTextLineColorAction* pA = (MetaTextLineColorAction*) pAction;
2314 const Color& rColor = pA->GetColor();
2315 const sal_Bool bSet = pA->IsSetting();
2316 sal_uLong nOldPos, nNewPos;
2318 // write RefPoint comment
2319 rOStm << (sal_Int16) GDI_TEXTLINECOLOR_COMMENT;
2321 // we'll write the ActionSize later
2322 nOldPos = rOStm.Tell();
2323 rOStm.SeekRel( 4 );
2325 // write data
2326 rOStm << rColor << bSet;
2327 rOStm << (sal_Int32) 0; // number of actions that follow this comment
2329 // calculate and write ActionSize of comment
2330 nNewPos = rOStm.Tell();
2331 rOStm.Seek( nOldPos );
2332 rOStm << (sal_Int32) ( nNewPos - nOldPos );
2333 rOStm.Seek( nNewPos );
2335 nCount++;
2337 break;
2339 case( META_TEXTLINE_ACTION ):
2341 const MetaTextLineAction* pA = (MetaTextLineAction*) pAction;
2342 const Point& rStartPt = pA->GetStartPoint();
2343 const sal_Int32 nWidth = (sal_Int32) pA->GetWidth();
2344 const FontStrikeout eStrikeout = pA->GetStrikeout();
2345 const FontUnderline eUnderline = pA->GetUnderline();
2346 sal_uLong nOldPos, nNewPos;
2348 // write RefPoint comment
2349 rOStm << (sal_Int16) GDI_TEXTLINE_COMMENT;
2351 // we'll write the ActionSize later
2352 nOldPos = rOStm.Tell();
2353 rOStm.SeekRel( 4 );
2355 // write data
2356 rOStm << rStartPt << nWidth <<
2357 static_cast<sal_uInt32>(eStrikeout) <<
2358 static_cast<sal_uInt32>(eUnderline);
2359 rOStm << (sal_Int32) 0; // number of actions that follow this comment
2361 // calculate and write ActionSize of comment
2362 nNewPos = rOStm.Tell();
2363 rOStm.Seek( nOldPos );
2364 rOStm << (sal_Int32) ( nNewPos - nOldPos );
2365 rOStm.Seek( nNewPos );
2367 nCount++;
2369 break;
2371 case( META_EPS_ACTION ):
2372 break;
2374 case( META_COMMENT_ACTION ):
2376 const MetaCommentAction* pA = (MetaCommentAction*) pAction;
2377 const sal_uInt32 nDataSize = pA->GetDataSize();
2378 sal_uLong nOldPos, nNewPos;
2380 // write RefPoint comment
2381 rOStm << (sal_Int16) GDI_COMMENT_COMMENT;
2383 // we'll write the ActionSize later
2384 nOldPos = rOStm.Tell();
2385 rOStm.SeekRel( 4 );
2387 // write data
2388 write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStm, pA->GetComment());
2389 rOStm << pA->GetValue() << nDataSize;
2391 if( nDataSize )
2392 rOStm.Write( pA->GetData(), nDataSize );
2394 rOStm << (sal_Int32) 0; // number of actions that follow this comment
2396 // calculate and write ActionSize of comment
2397 nNewPos = rOStm.Tell();
2398 rOStm.Seek( nOldPos );
2399 rOStm << (sal_Int32) ( nNewPos - nOldPos );
2400 rOStm.Seek( nNewPos );
2402 nCount++;
2404 break;
2406 #ifdef DBG_UTIL
2407 default:
2409 OStringBuffer aStr("Missing implementation for Action#: ");
2410 aStr.append(static_cast<sal_Int32>(pAction->GetType()));
2411 aStr.append('!');
2412 OSL_FAIL(aStr.getStr());
2414 break;
2415 #endif
2419 return nCount;
2422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */