1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include <osl/thread.h>
23 #include <tools/debug.hxx>
24 #include <tools/fract.hxx>
25 #include <tools/stream.hxx>
26 #include <tools/helpers.hxx>
27 #include <vcl/dibtools.hxx>
28 #include <vcl/virdev.hxx>
29 #include <vcl/graph.hxx>
30 #include <vcl/lineinfo.hxx>
31 #include <rtl/strbuf.hxx>
34 #include <boost/scoped_array.hpp>
37 void ImplReadRect( SvStream
& rIStm
, Rectangle
& rRect
)
42 ReadPair( rIStm
, aTL
);
43 ReadPair( rIStm
, aBR
);
45 rRect
= Rectangle( aTL
, aBR
);
48 void ImplWriteRect( SvStream
& rOStm
, const Rectangle
& rRect
)
50 WritePair( rOStm
, rRect
.TopLeft() );
51 WritePair( rOStm
, rRect
.BottomRight() );
54 void ImplReadPoly( SvStream
& rIStm
, Polygon
& rPoly
)
58 rIStm
.ReadInt32( nSize
);
59 rPoly
= Polygon( (sal_uInt16
) nSize
);
61 for( sal_uInt16 i
= 0; i
< (sal_uInt16
) nSize
; i
++ )
62 ReadPair( rIStm
, rPoly
[ i
] );
65 void ImplReadPolyPoly( SvStream
& rIStm
, tools::PolyPolygon
& rPolyPoly
)
70 rIStm
.ReadInt32( nPolyCount
);
72 for( sal_uInt16 i
= 0; i
< (sal_uInt16
) nPolyCount
; i
++ )
74 ImplReadPoly( rIStm
, aPoly
);
75 rPolyPoly
.Insert( aPoly
);
79 void ImplWritePolyPolyAction( SvStream
& rOStm
, const tools::PolyPolygon
& rPolyPoly
)
81 const sal_uInt16 nPoly
= rPolyPoly
.Count();
82 sal_uInt16 nPoints
= 0;
85 for( n
= 0; n
< nPoly
; n
++ )
86 nPoints
= sal::static_int_cast
<sal_uInt16
>(nPoints
+ rPolyPoly
[ n
].GetSize());
88 rOStm
.WriteInt16( GDI_POLYPOLYGON_ACTION
);
89 rOStm
.WriteInt32( 8 + ( nPoly
<< 2 ) + ( nPoints
<< 3 ) );
90 rOStm
.WriteInt32( nPoly
);
92 for( n
= 0; n
< nPoly
; n
++ )
94 // #i102224# Here the possible curved nature of Polygon was
95 // ignored (for all those years). Adapted to at least write
96 // a polygon representing the curve as good as possible
98 rPolyPoly
[n
].AdaptiveSubdivide(aSimplePoly
);
99 const sal_uInt16
nSize(aSimplePoly
.GetSize());
101 rOStm
.WriteInt32( nSize
);
103 for( sal_uInt16 j
= 0; j
< nSize
; j
++ )
104 WritePair( rOStm
, aSimplePoly
[ j
] );
108 void ImplReadColor( SvStream
& rIStm
, Color
& rColor
)
112 rIStm
.ReadInt16( nVal
); rColor
.SetRed( sal::static_int_cast
<sal_uInt8
>((sal_uInt16
)nVal
>> 8) );
113 rIStm
.ReadInt16( nVal
); rColor
.SetGreen( sal::static_int_cast
<sal_uInt8
>((sal_uInt16
)nVal
>> 8) );
114 rIStm
.ReadInt16( nVal
); rColor
.SetBlue( sal::static_int_cast
<sal_uInt8
>((sal_uInt16
)nVal
>> 8) );
117 void ImplWriteColor( SvStream
& rOStm
, const Color
& rColor
)
121 nVal
= ( (sal_Int16
) rColor
.GetRed() << 8 ) | rColor
.GetRed();
122 rOStm
.WriteInt16( nVal
);
124 nVal
= ( (sal_Int16
) rColor
.GetGreen() << 8 ) | rColor
.GetGreen();
125 rOStm
.WriteInt16( nVal
);
127 nVal
= ( (sal_Int16
) rColor
.GetBlue() << 8 ) | rColor
.GetBlue();
128 rOStm
.WriteInt16( nVal
);
131 void ImplReadMapMode( SvStream
& rIStm
, MapMode
& rMapMode
)
140 rIStm
.ReadInt16( nUnit
);
141 ReadPair( rIStm
, aOrg
);
142 rIStm
.ReadInt32( nXNum
).ReadInt32( nXDenom
).ReadInt32( nYNum
).ReadInt32( nYDenom
);
143 rMapMode
= MapMode( (MapUnit
) nUnit
, aOrg
, Fraction( nXNum
, nXDenom
), Fraction( nYNum
, nYDenom
) );
146 void ImplWriteMapMode( SvStream
& rOStm
, const MapMode
& rMapMode
)
148 rOStm
.WriteInt16( rMapMode
.GetMapUnit() );
149 WritePair( rOStm
, rMapMode
.GetOrigin() );
150 rOStm
.WriteInt32( rMapMode
.GetScaleX().GetNumerator() );
151 rOStm
.WriteInt32( rMapMode
.GetScaleX().GetDenominator() );
152 rOStm
.WriteInt32( rMapMode
.GetScaleY().GetNumerator() );
153 rOStm
.WriteInt32( rMapMode
.GetScaleY().GetDenominator() );
156 void ImplWritePushAction( SvStream
& rOStm
)
158 rOStm
.WriteInt16( GDI_PUSH_ACTION
);
159 rOStm
.WriteInt32( 4 );
162 void ImplWritePopAction( SvStream
& rOStm
)
164 rOStm
.WriteInt16( GDI_POP_ACTION
);
165 rOStm
.WriteInt32( 4 );
168 void ImplWriteLineColor( SvStream
& rOStm
, const Color
& rColor
, sal_Int16 nStyle
, sal_Int32 nWidth
= 0 )
170 if( rColor
.GetTransparency() > 127 )
173 rOStm
.WriteInt16( GDI_PEN_ACTION
);
174 rOStm
.WriteInt32( 16 );
175 ImplWriteColor( rOStm
, rColor
);
176 rOStm
.WriteInt32( nWidth
);
177 rOStm
.WriteInt16( nStyle
);
180 void ImplWriteFillColor( SvStream
& rOStm
, const Color
& rColor
, sal_Int16 nStyle
)
182 rOStm
.WriteInt16( GDI_FILLBRUSH_ACTION
);
183 rOStm
.WriteInt32( 20 );
184 ImplWriteColor( rOStm
, rColor
);
186 if( rColor
.GetTransparency() > 127 )
191 ImplWriteColor( rOStm
, COL_WHITE
);
192 rOStm
.WriteInt16( nStyle
);
193 rOStm
.WriteInt16( 1 );
197 ImplWriteColor( rOStm
, COL_BLACK
);
198 rOStm
.WriteInt16( nStyle
);
199 rOStm
.WriteInt16( 0 );
203 void ImplWriteFont( SvStream
& rOStm
, const vcl::Font
& rFont
,
204 rtl_TextEncoding
& rActualCharSet
)
209 OString
aByteName(OUStringToOString(rFont
.GetName(),
210 rOStm
.GetStreamCharSet()));
211 strncpy( aName
, aByteName
.getStr(), 32 );
214 switch ( rFont
.GetWeight() )
217 case WEIGHT_ULTRALIGHT
:
228 case WEIGHT_ULTRABOLD
:
238 rOStm
.WriteInt16( GDI_FONT_ACTION
);
239 rOStm
.WriteInt32( 78 );
241 rActualCharSet
= GetStoreCharSet( rFont
.GetCharSet() );
242 ImplWriteColor( rOStm
, rFont
.GetColor() );
243 ImplWriteColor( rOStm
, rFont
.GetFillColor() );
244 rOStm
.Write( aName
, 32 );
245 WritePair( rOStm
, rFont
.GetSize() );
246 rOStm
.WriteInt16( 0 ); // no character orientation anymore
247 rOStm
.WriteInt16( rFont
.GetOrientation() );
248 rOStm
.WriteInt16( rActualCharSet
);
249 rOStm
.WriteInt16( rFont
.GetFamily() );
250 rOStm
.WriteInt16( rFont
.GetPitch() );
251 rOStm
.WriteInt16( rFont
.GetAlign() );
252 rOStm
.WriteInt16( nWeight
);
253 rOStm
.WriteInt16( rFont
.GetUnderline() );
254 rOStm
.WriteInt16( rFont
.GetStrikeout() );
255 rOStm
.WriteBool( rFont
.GetItalic() != ITALIC_NONE
);
256 rOStm
.WriteBool( rFont
.IsOutline() );
257 rOStm
.WriteBool( rFont
.IsShadow() );
258 rOStm
.WriteBool( rFont
.IsTransparent() );
259 if ( rActualCharSet
== RTL_TEXTENCODING_DONTKNOW
)
260 rActualCharSet
= osl_getThreadTextEncoding();
263 void ImplWriteRasterOpAction( SvStream
& rOStm
, sal_Int16 nRasterOp
)
265 rOStm
.WriteInt16( GDI_RASTEROP_ACTION
).WriteInt32( 6 ).WriteInt16( nRasterOp
);
268 bool ImplWriteUnicodeComment( SvStream
& rOStm
, const OUString
& rString
)
270 sal_Int32 nStringLen
= rString
.getLength();
273 sal_uInt32 nSize
= ( nStringLen
<< 1 ) + 4;
274 sal_uInt16 nType
= GDI_UNICODE_COMMENT
;
276 rOStm
.WriteUInt16( nType
).WriteUInt32( nSize
);
277 write_uInt16s_FromOUString(rOStm
, rString
);
279 return nStringLen
!= 0;
282 void ImplReadUnicodeComment( sal_uInt32 nStrmPos
, SvStream
& rIStm
, OUString
& rString
)
284 sal_uInt32 nOld
= rIStm
.Tell();
288 sal_uInt32 nActionSize
;
291 rIStm
.Seek( nStrmPos
);
292 rIStm
.ReadUInt16( nType
)
293 .ReadUInt32( nActionSize
);
295 nStringLen
= (nActionSize
- 4) >> 1;
297 if ( nStringLen
&& ( nType
== GDI_UNICODE_COMMENT
) )
298 rString
= read_uInt16s_ToOUString(rIStm
, nStringLen
);
303 void ImplSkipActions( SvStream
& rIStm
, sal_uLong nSkipCount
)
305 sal_Int32 nActionSize
;
308 for( sal_uLong i
= 0UL; i
< nSkipCount
; i
++ )
310 rIStm
.ReadInt16( nType
).ReadInt32( nActionSize
);
311 rIStm
.SeekRel( nActionSize
- 4L );
315 bool ImplWriteExtendedPolyPolygonAction(SvStream
& rOStm
, const tools::PolyPolygon
& rPolyPolygon
, bool bOnlyWhenCurve
)
317 const sal_uInt16
nPolygonCount(rPolyPolygon
.Count());
321 sal_uInt32
nAllPolygonCount(0);
322 sal_uInt32
nAllPointCount(0);
323 sal_uInt32
nAllFlagCount(0);
326 for(a
= 0; a
< nPolygonCount
; a
++)
328 const Polygon
& rCandidate
= rPolyPolygon
.GetObject(a
);
329 const sal_uInt16
nPointCount(rCandidate
.GetSize());
334 nAllPointCount
+= nPointCount
;
336 if(rCandidate
.HasFlags())
338 nAllFlagCount
+= nPointCount
;
343 if((bOnlyWhenCurve
&& nAllFlagCount
) || (!bOnlyWhenCurve
&& nAllPointCount
))
345 rOStm
.WriteInt16( GDI_EXTENDEDPOLYGON_ACTION
);
347 const sal_Int32
nActionSize(
350 (nAllPolygonCount
* 2) + // Points per polygon
351 (nAllPointCount
<< 3) + // Points themselves
352 nAllPolygonCount
+ // Bool if (when poly has points) it has flags, too
353 nAllFlagCount
); // Flags themselves
355 rOStm
.WriteInt32( nActionSize
);
356 rOStm
.WriteUInt16( nAllPolygonCount
);
358 for(a
= 0; a
< nPolygonCount
; a
++)
360 const Polygon
& rCandidate
= rPolyPolygon
.GetObject(a
);
361 const sal_uInt16
nPointCount(rCandidate
.GetSize());
365 rOStm
.WriteUInt16( nPointCount
);
367 for(sal_uInt16
b(0); b
< nPointCount
; b
++)
369 WritePair( rOStm
, rCandidate
[b
] );
372 if(rCandidate
.HasFlags())
374 rOStm
.WriteBool( true );
376 for(sal_uInt16
c(0); c
< nPointCount
; c
++)
378 rOStm
.WriteUChar( rCandidate
.GetFlags(c
) );
383 rOStm
.WriteBool( false );
395 void ImplReadExtendedPolyPolygonAction(SvStream
& rIStm
, tools::PolyPolygon
& rPolyPoly
)
398 sal_uInt16
nPolygonCount(0);
399 rIStm
.ReadUInt16( nPolygonCount
);
404 const size_t nMinRecordSize
= sizeof(sal_uInt16
);
405 const size_t nMaxRecords
= rIStm
.remainingSize() / nMinRecordSize
;
406 if (nPolygonCount
> nMaxRecords
)
408 SAL_WARN("vcl.gdi", "Parsing error: " << nMaxRecords
<<
409 " max possible entries, but " << nPolygonCount
<< " claimed, truncating");
410 nPolygonCount
= nMaxRecords
;
413 for(sal_uInt16
a(0); a
< nPolygonCount
; a
++)
415 sal_uInt16
nPointCount(0);
416 rIStm
.ReadUInt16(nPointCount
);
418 const size_t nMinPolygonSize
= sizeof(sal_Int32
) * 2;
419 const size_t nMaxPolygons
= rIStm
.remainingSize() / nMinPolygonSize
;
420 if (nPointCount
> nMaxPolygons
)
422 SAL_WARN("vcl.gdi", "Parsing error: " << nMaxPolygons
<<
423 " max possible entries, but " << nPointCount
<< " claimed, truncating");
424 nPointCount
= nMaxPolygons
;
427 Polygon
aCandidate(nPointCount
);
431 for(sal_uInt16
b(0); b
< nPointCount
; b
++)
433 ReadPair( rIStm
, aCandidate
[b
] );
436 sal_uInt8
bHasFlags(int(false));
437 rIStm
.ReadUChar( bHasFlags
);
441 sal_uInt8
aPolyFlags(0);
443 for(sal_uInt16
c(0); c
< nPointCount
; c
++)
445 rIStm
.ReadUChar( aPolyFlags
);
446 aCandidate
.SetFlags(c
, (PolyFlags
)aPolyFlags
);
451 rPolyPoly
.Insert(aCandidate
);
455 SVMConverter::SVMConverter( SvStream
& rStm
, GDIMetaFile
& rMtf
, sal_uLong nConvertMode
)
457 if( !rStm
.GetError() )
459 if( CONVERT_FROM_SVM1
== nConvertMode
)
460 ImplConvertFromSVM1( rStm
, rMtf
);
461 else if( CONVERT_TO_SVM1
== nConvertMode
)
462 ImplConvertToSVM1( rStm
, rMtf
);
466 void SVMConverter::ImplConvertFromSVM1( SvStream
& rIStm
, GDIMetaFile
& rMtf
)
468 const sal_uLong nPos
= rIStm
.Tell();
469 const SvStreamEndian nOldFormat
= rIStm
.GetEndian();
471 rIStm
.SetEndian( SvStreamEndian::LITTLE
);
479 rIStm
.Read( aCode
, sizeof( aCode
) ); // Identifier
480 rIStm
.ReadInt16( nSize
); // Size
481 rIStm
.ReadInt16( nVersion
); // Version
483 rIStm
.ReadInt32( nTmp32
);
484 aPrefSz
.Width() = nTmp32
; // PrefSize.Width()
485 rIStm
.ReadInt32( nTmp32
);
486 aPrefSz
.Height() = nTmp32
; // PrefSize.Height()
488 // check header-magic and version
490 || ( memcmp( aCode
, "SVGDI", sizeof( aCode
) ) != 0 )
491 || ( nVersion
!= 200 ) )
493 rIStm
.SetError( SVSTREAM_FILEFORMAT_ERROR
);
494 rIStm
.SetEndian( nOldFormat
);
499 LineInfo
aLineInfo( LINE_NONE
, 0 );
500 ::std::stack
< LineInfo
* > aLIStack
;
501 ScopedVclPtrInstance
< VirtualDevice
> aFontVDev
;
502 rtl_TextEncoding eActualCharSet
= osl_getThreadTextEncoding();
503 bool bFatLine
= false;
505 // TODO: fix reindentation below if you can accept being blamed by the SCM
512 sal_Int32 nTmp
, nTmp1
, nActionSize
;
516 sal_uInt32 nUnicodeCommentStreamPos
= 0;
517 sal_Int32 nUnicodeCommentActionNumber
= 0;
519 ImplReadMapMode( rIStm
, aMapMode
); // MapMode
520 rIStm
.ReadInt32( nActions
); // Action count
522 rMtf
.SetPrefSize( aPrefSz
);
523 rMtf
.SetPrefMapMode( aMapMode
);
524 size_t nLastPolygonAction(0);
526 for (sal_Int32 i
= 0; i
< nActions
; ++i
)
528 rIStm
.ReadInt16( nType
);
529 sal_Int32 nActBegin
= rIStm
.Tell();
530 rIStm
.ReadInt32( nActionSize
);
532 DBG_ASSERT( ( nType
<= 33 ) || ( nType
>= 1024 ), "Unknown GDIMetaAction while converting!" );
536 case( GDI_PIXEL_ACTION
):
538 ReadPair( rIStm
, aPt
);
539 ImplReadColor( rIStm
, aActionColor
);
540 rMtf
.AddAction( new MetaPixelAction( aPt
, aActionColor
) );
544 case( GDI_POINT_ACTION
):
546 ReadPair( rIStm
, aPt
);
547 rMtf
.AddAction( new MetaPointAction( aPt
) );
551 case( GDI_LINE_ACTION
):
553 ReadPair( rIStm
, aPt
);
554 ReadPair( rIStm
, aPt1
);
555 rMtf
.AddAction( new MetaLineAction( aPt
, aPt1
, aLineInfo
) );
559 case (GDI_LINEJOIN_ACTION
) :
561 sal_Int16
nLineJoin(0);
562 rIStm
.ReadInt16( nLineJoin
);
563 aLineInfo
.SetLineJoin((basegfx::B2DLineJoin
)nLineJoin
);
567 case (GDI_LINECAP_ACTION
) :
569 sal_Int16
nLineCap(0);
570 rIStm
.ReadInt16( nLineCap
);
571 aLineInfo
.SetLineCap((com::sun::star::drawing::LineCap
)nLineCap
);
575 case (GDI_LINEDASHDOT_ACTION
) :
580 rIStm
.ReadInt16( a
); aLineInfo
.SetDashCount(a
);
581 rIStm
.ReadInt32( b
); aLineInfo
.SetDashLen(b
);
582 rIStm
.ReadInt16( a
); aLineInfo
.SetDotCount(a
);
583 rIStm
.ReadInt32( b
); aLineInfo
.SetDotLen(b
);
584 rIStm
.ReadInt32( b
); aLineInfo
.SetDistance(b
);
586 if(((aLineInfo
.GetDashCount() && aLineInfo
.GetDashLen())
587 || (aLineInfo
.GetDotCount() && aLineInfo
.GetDotLen()))
588 && aLineInfo
.GetDistance())
590 aLineInfo
.SetStyle(LINE_DASH
);
595 case (GDI_EXTENDEDPOLYGON_ACTION
) :
597 // read the tools::PolyPolygon in every case
598 tools::PolyPolygon aInputPolyPolygon
;
599 ImplReadExtendedPolyPolygonAction(rIStm
, aInputPolyPolygon
);
601 // now check if it can be set somewhere
602 if(nLastPolygonAction
< rMtf
.GetActionSize())
604 MetaPolyLineAction
* pPolyLineAction
= dynamic_cast< MetaPolyLineAction
* >(rMtf
.GetAction(nLastPolygonAction
));
608 // replace MetaPolyLineAction when we have a single polygon. Do not rely on the
609 // same point count; the originally written GDI_POLYLINE_ACTION may have been
610 // Subdivided for better quality for older usages
611 if(1 == aInputPolyPolygon
.Count())
613 MetaAction
* pAction
= rMtf
.ReplaceAction(
614 new MetaPolyLineAction(
615 aInputPolyPolygon
.GetObject(0),
616 pPolyLineAction
->GetLineInfo()),
624 MetaPolyPolygonAction
* pPolyPolygonAction
= dynamic_cast< MetaPolyPolygonAction
* >(rMtf
.GetAction(nLastPolygonAction
));
626 if(pPolyPolygonAction
)
628 // replace MetaPolyPolygonAction when we have a curved polygon. Do rely on the
629 // same sub-polygon count
630 if(pPolyPolygonAction
->GetPolyPolygon().Count() == aInputPolyPolygon
.Count())
632 MetaAction
* pAction
= rMtf
.ReplaceAction(
633 new MetaPolyPolygonAction(
642 MetaPolygonAction
* pPolygonAction
= dynamic_cast< MetaPolygonAction
* >(rMtf
.GetAction(nLastPolygonAction
));
646 // replace MetaPolygonAction
647 if(1 == aInputPolyPolygon
.Count())
649 MetaAction
* pAction
= rMtf
.ReplaceAction(
650 new MetaPolygonAction(
651 aInputPolyPolygon
.GetObject(0)),
663 case( GDI_RECT_ACTION
):
665 ImplReadRect( rIStm
, aRect
);
666 rIStm
.ReadInt32( nTmp
).ReadInt32( nTmp1
);
669 rMtf
.AddAction( new MetaRoundRectAction( aRect
, nTmp
, nTmp1
) );
672 rMtf
.AddAction( new MetaRectAction( aRect
) );
675 rMtf
.AddAction( new MetaPolyLineAction( aRect
, aLineInfo
) );
680 case( GDI_ELLIPSE_ACTION
):
682 ImplReadRect( rIStm
, aRect
);
686 const Polygon
aPoly( aRect
.Center(), aRect
.GetWidth() >> 1, aRect
.GetHeight() >> 1 );
688 rMtf
.AddAction( new MetaPushAction( PushFlags::LINECOLOR
) );
689 rMtf
.AddAction( new MetaLineColorAction( COL_TRANSPARENT
, false ) );
690 rMtf
.AddAction( new MetaPolygonAction( aPoly
) );
691 rMtf
.AddAction( new MetaPopAction() );
692 rMtf
.AddAction( new MetaPolyLineAction( aPoly
, aLineInfo
) );
695 rMtf
.AddAction( new MetaEllipseAction( aRect
) );
699 case( GDI_ARC_ACTION
):
701 ImplReadRect( rIStm
, aRect
);
702 ReadPair( rIStm
, aPt
);
703 ReadPair( rIStm
, aPt1
);
707 const Polygon
aPoly( aRect
, aPt
, aPt1
, POLY_ARC
);
709 rMtf
.AddAction( new MetaPushAction( PushFlags::LINECOLOR
) );
710 rMtf
.AddAction( new MetaLineColorAction( COL_TRANSPARENT
, false ) );
711 rMtf
.AddAction( new MetaPolygonAction( aPoly
) );
712 rMtf
.AddAction( new MetaPopAction() );
713 rMtf
.AddAction( new MetaPolyLineAction( aPoly
, aLineInfo
) );
716 rMtf
.AddAction( new MetaArcAction( aRect
, aPt
, aPt1
) );
720 case( GDI_PIE_ACTION
):
722 ImplReadRect( rIStm
, aRect
);
723 ReadPair( rIStm
, aPt
);
724 ReadPair( rIStm
, aPt1
);
728 const Polygon
aPoly( aRect
, aPt
, aPt1
, POLY_PIE
);
730 rMtf
.AddAction( new MetaPushAction( PushFlags::LINECOLOR
) );
731 rMtf
.AddAction( new MetaLineColorAction( COL_TRANSPARENT
, false ) );
732 rMtf
.AddAction( new MetaPolygonAction( aPoly
) );
733 rMtf
.AddAction( new MetaPopAction() );
734 rMtf
.AddAction( new MetaPolyLineAction( aPoly
, aLineInfo
) );
737 rMtf
.AddAction( new MetaPieAction( aRect
, aPt
, aPt1
) );
741 case( GDI_INVERTRECT_ACTION
):
742 case( GDI_HIGHLIGHTRECT_ACTION
):
744 ImplReadRect( rIStm
, aRect
);
745 rMtf
.AddAction( new MetaPushAction( PushFlags::RASTEROP
) );
746 rMtf
.AddAction( new MetaRasterOpAction( ROP_INVERT
) );
747 rMtf
.AddAction( new MetaRectAction( aRect
) );
748 rMtf
.AddAction( new MetaPopAction() );
752 case( GDI_POLYLINE_ACTION
):
754 ImplReadPoly( rIStm
, aActionPoly
);
755 nLastPolygonAction
= rMtf
.GetActionSize();
758 rMtf
.AddAction( new MetaPolyLineAction( aActionPoly
, aLineInfo
) );
760 rMtf
.AddAction( new MetaPolyLineAction( aActionPoly
) );
764 case( GDI_POLYGON_ACTION
):
766 ImplReadPoly( rIStm
, aActionPoly
);
770 rMtf
.AddAction( new MetaPushAction( PushFlags::LINECOLOR
) );
771 rMtf
.AddAction( new MetaLineColorAction( COL_TRANSPARENT
, false ) );
772 rMtf
.AddAction( new MetaPolygonAction( aActionPoly
) );
773 rMtf
.AddAction( new MetaPopAction() );
774 rMtf
.AddAction( new MetaPolyLineAction( aActionPoly
, aLineInfo
) );
778 nLastPolygonAction
= rMtf
.GetActionSize();
779 rMtf
.AddAction( new MetaPolygonAction( aActionPoly
) );
784 case( GDI_POLYPOLYGON_ACTION
):
786 tools::PolyPolygon aPolyPoly
;
788 ImplReadPolyPoly( rIStm
, aPolyPoly
);
792 rMtf
.AddAction( new MetaPushAction( PushFlags::LINECOLOR
) );
793 rMtf
.AddAction( new MetaLineColorAction( COL_TRANSPARENT
, false ) );
794 rMtf
.AddAction( new MetaPolyPolygonAction( aPolyPoly
) );
795 rMtf
.AddAction( new MetaPopAction() );
797 for( sal_uInt16 nPoly
= 0, nCount
= aPolyPoly
.Count(); nPoly
< nCount
; nPoly
++ )
798 rMtf
.AddAction( new MetaPolyLineAction( aPolyPoly
[ nPoly
], aLineInfo
) );
802 nLastPolygonAction
= rMtf
.GetActionSize();
803 rMtf
.AddAction( new MetaPolyPolygonAction( aPolyPoly
) );
808 case( GDI_FONT_ACTION
):
812 sal_Int32 nWidth
, nHeight
;
813 sal_Int16 nCharSet
, nFamily
, nPitch
, nAlign
, nWeight
, nUnderline
, nStrikeout
;
814 sal_Int16 nCharOrient
, nLineOrient
;
815 bool bItalic
, bOutline
, bShadow
, bTransparent
;
817 ImplReadColor( rIStm
, aActionColor
); aFont
.SetColor( aActionColor
);
818 ImplReadColor( rIStm
, aActionColor
); aFont
.SetFillColor( aActionColor
);
819 rIStm
.Read( aName
, 32 );
820 aFont
.SetName( OUString( aName
, strlen(aName
), rIStm
.GetStreamCharSet() ) );
821 rIStm
.ReadInt32( nWidth
).ReadInt32( nHeight
);
822 rIStm
.ReadInt16( nCharOrient
).ReadInt16( nLineOrient
);
823 rIStm
.ReadInt16( nCharSet
).ReadInt16( nFamily
).ReadInt16( nPitch
).ReadInt16( nAlign
).ReadInt16( nWeight
).ReadInt16( nUnderline
).ReadInt16( nStrikeout
);
824 rIStm
.ReadCharAsBool( bItalic
).ReadCharAsBool( bOutline
).ReadCharAsBool( bShadow
).ReadCharAsBool( bTransparent
);
826 aFont
.SetSize( Size( nWidth
, nHeight
) );
827 aFont
.SetCharSet( (rtl_TextEncoding
) nCharSet
);
828 aFont
.SetFamily( (FontFamily
) nFamily
);
829 aFont
.SetPitch( (FontPitch
) nPitch
);
830 aFont
.SetAlign( (FontAlign
) nAlign
);
831 aFont
.SetWeight( ( nWeight
== 1 ) ? WEIGHT_LIGHT
: ( nWeight
== 2 ) ? WEIGHT_NORMAL
:
832 ( nWeight
== 3 ) ? WEIGHT_BOLD
: WEIGHT_DONTKNOW
);
833 aFont
.SetUnderline( (FontUnderline
) nUnderline
);
834 aFont
.SetStrikeout( (FontStrikeout
) nStrikeout
);
835 aFont
.SetItalic( bItalic
? ITALIC_NORMAL
: ITALIC_NONE
);
836 aFont
.SetOutline( bOutline
);
837 aFont
.SetShadow( bShadow
);
838 aFont
.SetOrientation( nLineOrient
);
839 aFont
.SetTransparent( bTransparent
);
841 eActualCharSet
= aFont
.GetCharSet();
842 if ( eActualCharSet
== RTL_TEXTENCODING_DONTKNOW
)
843 eActualCharSet
= osl_getThreadTextEncoding();
845 rMtf
.AddAction( new MetaFontAction( aFont
) );
846 rMtf
.AddAction( new MetaTextAlignAction( aFont
.GetAlign() ) );
847 rMtf
.AddAction( new MetaTextColorAction( aFont
.GetColor() ) );
848 rMtf
.AddAction( new MetaTextFillColorAction( aFont
.GetFillColor(), !aFont
.IsTransparent() ) );
850 // #106172# Track font relevant data in shadow VDev
851 aFontVDev
->SetFont( aFont
);
855 case( GDI_TEXT_ACTION
):
857 sal_Int32 nIndex
, nLen
;
859 ReadPair( rIStm
, aPt
).ReadInt32( nIndex
).ReadInt32( nLen
).ReadInt32( nTmp
);
862 OString aByteStr
= read_uInt8s_ToOString(rIStm
, nTmp
);
863 sal_uInt8 nTerminator
= 0;
864 rIStm
.ReadUChar( nTerminator
);
865 DBG_ASSERT( nTerminator
== 0, "expected string to be NULL terminated" );
867 OUString
aStr(OStringToOUString(aByteStr
, eActualCharSet
));
868 if ( nUnicodeCommentActionNumber
== i
)
869 ImplReadUnicodeComment( nUnicodeCommentStreamPos
, rIStm
, aStr
);
870 rMtf
.AddAction( new MetaTextAction( aPt
, aStr
, nIndex
, nLen
) );
872 rIStm
.Seek( nActBegin
+ nActionSize
);
876 case( GDI_TEXTARRAY_ACTION
):
878 sal_Int32 nIndex
, nLen
, nAryLen
;
880 ReadPair( rIStm
, aPt
).ReadInt32( nIndex
).ReadInt32( nLen
).ReadInt32( nTmp
).ReadInt32( nAryLen
);
883 OString aByteStr
= read_uInt8s_ToOString(rIStm
, nTmp
);
884 sal_uInt8 nTerminator
= 0;
885 rIStm
.ReadUChar( nTerminator
);
886 DBG_ASSERT( nTerminator
== 0, "expected string to be NULL terminated" );
888 OUString
aStr(OStringToOUString(aByteStr
, eActualCharSet
));
890 boost::scoped_array
<long> pDXAry
;
893 sal_Int32
nStrLen( aStr
.getLength() );
895 pDXAry
.reset(new long[ std::max( nAryLen
, nStrLen
) ]);
897 for (sal_Int32 j
= 0; j
< nAryLen
; ++j
)
898 rIStm
.ReadInt32( nTmp
), pDXAry
[ j
] = nTmp
;
900 // #106172# Add last DX array elem, if missing
901 if( nAryLen
!= nStrLen
)
903 if( nAryLen
+1 == nStrLen
)
905 boost::scoped_array
<long> pTmpAry(new long[nStrLen
]);
907 aFontVDev
->GetTextArray( aStr
, pTmpAry
.get(), nIndex
, nLen
);
909 // now, the difference between the
910 // last and the second last DX array
911 // is the advancement for the last
912 // glyph. Thus, to complete our meta
913 // action's DX array, just add that
914 // difference to last elem and store
917 pDXAry
[ nStrLen
-1 ] = pDXAry
[ nStrLen
-2 ] + pTmpAry
[ nStrLen
-1 ] - pTmpAry
[ nStrLen
-2 ];
919 pDXAry
[ nStrLen
-1 ] = pTmpAry
[ nStrLen
-1 ]; // len=1: 0th position taken to be 0
923 OSL_FAIL("More than one DX array element missing on SVM import");
927 if ( nUnicodeCommentActionNumber
== i
)
928 ImplReadUnicodeComment( nUnicodeCommentStreamPos
, rIStm
, aStr
);
929 rMtf
.AddAction( new MetaTextArrayAction( aPt
, aStr
, pDXAry
.get(), nIndex
, nLen
) );
931 rIStm
.Seek( nActBegin
+ nActionSize
);
935 case( GDI_STRETCHTEXT_ACTION
):
937 sal_Int32 nIndex
, nLen
, nWidth
;
939 ReadPair( rIStm
, aPt
).ReadInt32( nIndex
).ReadInt32( nLen
).ReadInt32( nTmp
).ReadInt32( nWidth
);
942 OString aByteStr
= read_uInt8s_ToOString(rIStm
, nTmp
);
943 sal_uInt8 nTerminator
= 0;
944 rIStm
.ReadUChar( nTerminator
);
945 DBG_ASSERT( nTerminator
== 0, "expected string to be NULL terminated" );
947 OUString
aStr(OStringToOUString(aByteStr
, eActualCharSet
));
948 if ( nUnicodeCommentActionNumber
== i
)
949 ImplReadUnicodeComment( nUnicodeCommentStreamPos
, rIStm
, aStr
);
950 rMtf
.AddAction( new MetaStretchTextAction( aPt
, nWidth
, aStr
, nIndex
, nLen
) );
952 rIStm
.Seek( nActBegin
+ nActionSize
);
956 case( GDI_BITMAP_ACTION
):
960 ReadPair( rIStm
, aPt
);
961 ReadDIB(aBmp
, rIStm
, true);
962 rMtf
.AddAction( new MetaBmpAction( aPt
, aBmp
) );
966 case( GDI_BITMAPSCALE_ACTION
):
970 ReadPair( rIStm
, aPt
);
971 ReadPair( rIStm
, aSz
);
972 ReadDIB(aBmp
, rIStm
, true);
973 rMtf
.AddAction( new MetaBmpScaleAction( aPt
, aSz
, aBmp
) );
977 case( GDI_BITMAPSCALEPART_ACTION
):
982 ReadPair( rIStm
, aPt
);
983 ReadPair( rIStm
, aSz
);
984 ReadPair( rIStm
, aPt1
);
985 ReadPair( rIStm
, aSz2
);
986 ReadDIB(aBmp
, rIStm
, true);
987 rMtf
.AddAction( new MetaBmpScalePartAction( aPt
, aSz
, aPt1
, aSz2
, aBmp
) );
991 case( GDI_PEN_ACTION
):
996 ImplReadColor( rIStm
, aActionColor
);
997 rIStm
.ReadInt32( nPenWidth
).ReadInt16( nPenStyle
);
999 aLineInfo
.SetStyle( nPenStyle
? LINE_SOLID
: LINE_NONE
);
1000 aLineInfo
.SetWidth( nPenWidth
);
1001 bFatLine
= nPenStyle
&& !aLineInfo
.IsDefault();
1003 rMtf
.AddAction( new MetaLineColorAction( aActionColor
, nPenStyle
!= 0 ) );
1007 case( GDI_FILLBRUSH_ACTION
):
1009 sal_Int16 nBrushStyle
;
1011 ImplReadColor( rIStm
, aActionColor
);
1012 rIStm
.SeekRel( 6L );
1013 rIStm
.ReadInt16( nBrushStyle
);
1014 rMtf
.AddAction( new MetaFillColorAction( aActionColor
, nBrushStyle
!= 0 ) );
1015 rIStm
.SeekRel( 2L );
1019 case( GDI_MAPMODE_ACTION
):
1021 ImplReadMapMode( rIStm
, aMapMode
);
1022 rMtf
.AddAction( new MetaMapModeAction( aMapMode
) );
1024 // #106172# Track font relevant data in shadow VDev
1025 aFontVDev
->SetMapMode( aMapMode
);
1029 case( GDI_CLIPREGION_ACTION
):
1031 vcl::Region aRegion
;
1033 sal_Int16 bIntersect
;
1036 rIStm
.ReadInt16( nRegType
).ReadInt16( bIntersect
);
1037 ImplReadRect( rIStm
, aRect
);
1048 ImplReadRect( rIStm
, aRegRect
);
1049 aRegion
= vcl::Region( aRegRect
);
1056 ImplReadPoly( rIStm
, aActionPoly
);
1057 aRegion
= vcl::Region( aActionPoly
);
1064 tools::PolyPolygon aPolyPoly
;
1065 sal_Int32 nPolyCount
;
1067 rIStm
.ReadInt32( nPolyCount
);
1069 for( sal_uInt16 j
= 0; j
< (sal_uInt16
) nPolyCount
; j
++ )
1071 ImplReadPoly( rIStm
, aActionPoly
);
1072 aPolyPoly
.Insert( aActionPoly
);
1075 aRegion
= vcl::Region( aPolyPoly
);
1082 aRegion
.Intersect( aRect
);
1084 rMtf
.AddAction( new MetaClipRegionAction( aRegion
, bClip
) );
1088 case( GDI_MOVECLIPREGION_ACTION
):
1090 rIStm
.ReadInt32( nTmp
).ReadInt32( nTmp1
);
1091 rMtf
.AddAction( new MetaMoveClipRegionAction( nTmp
, nTmp1
) );
1095 case( GDI_ISECTCLIPREGION_ACTION
):
1097 ImplReadRect( rIStm
, aRect
);
1098 rMtf
.AddAction( new MetaISectRectClipRegionAction( aRect
) );
1102 case( GDI_RASTEROP_ACTION
):
1105 sal_Int16 nRasterOp
;
1107 rIStm
.ReadInt16( nRasterOp
);
1112 eRasterOp
= ROP_INVERT
;
1117 eRasterOp
= ROP_XOR
;
1121 eRasterOp
= ROP_OVERPAINT
;
1125 rMtf
.AddAction( new MetaRasterOpAction( eRasterOp
) );
1129 case( GDI_PUSH_ACTION
):
1131 aLIStack
.push( new LineInfo( aLineInfo
) );
1132 rMtf
.AddAction( new MetaPushAction( PushFlags::ALL
) );
1134 // #106172# Track font relevant data in shadow VDev
1139 case( GDI_POP_ACTION
):
1142 LineInfo
* pLineInfo
;
1143 if (aLIStack
.empty())
1147 pLineInfo
= aLIStack
.top();
1151 // restore line info
1154 aLineInfo
= *pLineInfo
;
1156 bFatLine
= ( LINE_NONE
!= aLineInfo
.GetStyle() ) && !aLineInfo
.IsDefault();
1159 rMtf
.AddAction( new MetaPopAction() );
1161 // #106172# Track font relevant data in shadow VDev
1166 case( GDI_GRADIENT_ACTION
):
1175 sal_Int16 nIntensityStart
;
1176 sal_Int16 nIntensityEnd
;
1178 ImplReadRect( rIStm
, aRect
);
1179 rIStm
.ReadInt16( nStyle
);
1180 ImplReadColor( rIStm
, aStartCol
);
1181 ImplReadColor( rIStm
, aEndCol
);
1182 rIStm
.ReadInt16( nAngle
).ReadInt16( nBorder
).ReadInt16( nOfsX
).ReadInt16( nOfsY
).ReadInt16( nIntensityStart
).ReadInt16( nIntensityEnd
);
1184 Gradient
aGrad( (GradientStyle
) nStyle
, aStartCol
, aEndCol
);
1186 aGrad
.SetAngle( nAngle
);
1187 aGrad
.SetBorder( nBorder
);
1188 aGrad
.SetOfsX( nOfsX
);
1189 aGrad
.SetOfsY( nOfsY
);
1190 aGrad
.SetStartIntensity( nIntensityStart
);
1191 aGrad
.SetEndIntensity( nIntensityEnd
);
1192 rMtf
.AddAction( new MetaGradientAction( aRect
, aGrad
) );
1196 case( GDI_TRANSPARENT_COMMENT
):
1198 tools::PolyPolygon aPolyPoly
;
1199 sal_Int32 nFollowingActionCount
;
1202 ReadPolyPolygon( rIStm
, aPolyPoly
);
1203 rIStm
.ReadInt16( nTrans
).ReadInt32( nFollowingActionCount
);
1204 ImplSkipActions( rIStm
, nFollowingActionCount
);
1205 rMtf
.AddAction( new MetaTransparentAction( aPolyPoly
, nTrans
) );
1207 i
+= nFollowingActionCount
;
1211 case( GDI_FLOATTRANSPARENT_COMMENT
):
1217 sal_Int32 nFollowingActionCount
;
1219 ReadGDIMetaFile( rIStm
, aMtf
);
1220 ReadPair( rIStm
, aPos
);
1221 ReadPair( rIStm
, aSize
);
1222 ReadGradient( rIStm
, aGradient
);
1223 rIStm
.ReadInt32( nFollowingActionCount
);
1224 ImplSkipActions( rIStm
, nFollowingActionCount
);
1225 rMtf
.AddAction( new MetaFloatTransparentAction( aMtf
, aPos
, aSize
, aGradient
) );
1227 i
+= nFollowingActionCount
;
1231 case( GDI_HATCH_COMMENT
):
1233 tools::PolyPolygon aPolyPoly
;
1235 sal_Int32 nFollowingActionCount
;
1237 ReadPolyPolygon( rIStm
, aPolyPoly
);
1238 ReadHatch( rIStm
, aHatch
);
1239 rIStm
.ReadInt32( nFollowingActionCount
);
1240 ImplSkipActions( rIStm
, nFollowingActionCount
);
1241 rMtf
.AddAction( new MetaHatchAction( aPolyPoly
, aHatch
) );
1243 i
+= nFollowingActionCount
;
1247 case( GDI_REFPOINT_COMMENT
):
1251 sal_Int32 nFollowingActionCount
;
1253 ReadPair( rIStm
, aRefPoint
);
1254 rIStm
.ReadCharAsBool( bSet
).ReadInt32( nFollowingActionCount
);
1255 ImplSkipActions( rIStm
, nFollowingActionCount
);
1256 rMtf
.AddAction( new MetaRefPointAction( aRefPoint
, bSet
) );
1258 i
+= nFollowingActionCount
;
1260 // #106172# Track font relevant data in shadow VDev
1262 aFontVDev
->SetRefPoint( aRefPoint
);
1264 aFontVDev
->SetRefPoint();
1268 case( GDI_TEXTLINECOLOR_COMMENT
):
1272 sal_Int32 nFollowingActionCount
;
1274 ReadColor( rIStm
, aColor
);
1275 rIStm
.ReadCharAsBool( bSet
).ReadInt32( nFollowingActionCount
);
1276 ImplSkipActions( rIStm
, nFollowingActionCount
);
1277 rMtf
.AddAction( new MetaTextLineColorAction( aColor
, bSet
) );
1279 i
+= nFollowingActionCount
;
1283 case( GDI_TEXTLINE_COMMENT
):
1287 sal_uInt32 nStrikeout
;
1288 sal_uInt32 nUnderline
;
1289 sal_Int32 nFollowingActionCount
;
1291 ReadPair( rIStm
, aStartPt
);
1292 rIStm
.ReadInt32( nWidth
).ReadUInt32( nStrikeout
).ReadUInt32( nUnderline
).ReadInt32( nFollowingActionCount
);
1293 ImplSkipActions( rIStm
, nFollowingActionCount
);
1294 rMtf
.AddAction( new MetaTextLineAction( aStartPt
, nWidth
,
1295 (FontStrikeout
) nStrikeout
,
1296 (FontUnderline
) nUnderline
,
1299 i
+= nFollowingActionCount
;
1303 case( GDI_GRADIENTEX_COMMENT
):
1305 tools::PolyPolygon aPolyPoly
;
1307 sal_Int32 nFollowingActionCount
;
1309 ReadPolyPolygon( rIStm
, aPolyPoly
);
1310 ReadGradient( rIStm
, aGradient
);
1311 rIStm
.ReadInt32( nFollowingActionCount
);
1312 ImplSkipActions( rIStm
, nFollowingActionCount
);
1313 rMtf
.AddAction( new MetaGradientExAction( aPolyPoly
, aGradient
) );
1315 i
+= nFollowingActionCount
;
1319 case( GDI_COMMENT_COMMENT
):
1322 sal_uInt32 nDataSize
;
1324 sal_Int32 nFollowingActionCount
;
1326 OString aComment
= read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm
);
1327 rIStm
.ReadInt32( nValue
).ReadUInt32( nDataSize
);
1331 pData
= new sal_uInt8
[ nDataSize
];
1332 rIStm
.Read( pData
, nDataSize
);
1337 rIStm
.ReadInt32( nFollowingActionCount
);
1338 ImplSkipActions( rIStm
, nFollowingActionCount
);
1339 rMtf
.AddAction( new MetaCommentAction( aComment
, nValue
, pData
, nDataSize
) );
1341 i
+= nFollowingActionCount
;
1345 case ( GDI_UNICODE_COMMENT
):
1347 nUnicodeCommentActionNumber
= i
+ 1;
1348 nUnicodeCommentStreamPos
= rIStm
.Tell() - 6;
1349 rIStm
.SeekRel( nActionSize
- 4 );
1354 rIStm
.SeekRel( nActionSize
- 4L );
1359 // cleanup push-pop stack if necessary
1360 while( !aLIStack
.empty() )
1362 delete aLIStack
.top();
1366 rIStm
.SetEndian( nOldFormat
);
1369 void SVMConverter::ImplConvertToSVM1( SvStream
& rOStm
, GDIMetaFile
& rMtf
)
1371 sal_uLong nCountPos
;
1372 vcl::Font aSaveFont
;
1373 const SvStreamEndian nOldFormat
= rOStm
.GetEndian();
1374 rtl_TextEncoding eActualCharSet
= osl_getThreadTextEncoding();
1375 const Size
aPrefSize( rMtf
.GetPrefSize() );
1376 bool bRop_0_1
= false;
1377 ScopedVclPtrInstance
< VirtualDevice
> aSaveVDev
;
1378 Color
aLineCol( COL_BLACK
);
1379 ::std::stack
< Color
* > aLineColStack
;
1381 rOStm
.SetEndian( SvStreamEndian::LITTLE
);
1384 rOStm
.WriteCharPtr( "SVGDI" ); // Identifier
1385 rOStm
.WriteInt16( 42 ); // HeaderSize
1386 rOStm
.WriteInt16( 200 ); // VERSION
1387 rOStm
.WriteInt32( aPrefSize
.Width() );
1388 rOStm
.WriteInt32( aPrefSize
.Height() );
1389 ImplWriteMapMode( rOStm
, rMtf
.GetPrefMapMode() );
1391 // ActionCount will be written later
1392 nCountPos
= rOStm
.Tell();
1393 rOStm
.SeekRel( 4L );
1395 const sal_Int32 nActCount
= ImplWriteActions( rOStm
, rMtf
, *aSaveVDev
.get(), bRop_0_1
, aLineCol
, aLineColStack
, eActualCharSet
);
1396 const sal_uLong nActPos
= rOStm
.Tell();
1398 rOStm
.Seek( nCountPos
);
1399 rOStm
.WriteInt32( nActCount
);
1400 rOStm
.Seek( nActPos
);
1401 rOStm
.SetEndian( nOldFormat
);
1403 // cleanup push-pop stack if necessary
1404 while ( !aLineColStack
.empty() )
1406 delete aLineColStack
.top();
1407 aLineColStack
.pop();
1411 sal_uLong
SVMConverter::ImplWriteActions( SvStream
& rOStm
, GDIMetaFile
& rMtf
,
1412 VirtualDevice
& rSaveVDev
, bool& rRop_0_1
,
1413 Color
& rLineCol
, ::std::stack
< Color
* >& rLineColStack
,
1414 rtl_TextEncoding
& rActualCharSet
)
1416 sal_uLong nCount
= 0;
1417 for( size_t i
= 0, nActionCount
= rMtf
.GetActionSize(); i
< nActionCount
; i
++ )
1419 const MetaAction
* pAction
= rMtf
.GetAction( i
);
1421 switch( pAction
->GetType() )
1423 case( MetaActionType::PIXEL
):
1425 const MetaPixelAction
* pAct
= static_cast<const MetaPixelAction
*>(pAction
);
1427 rOStm
.WriteInt16( GDI_PIXEL_ACTION
);
1428 rOStm
.WriteInt32( 18 );
1429 WritePair( rOStm
, pAct
->GetPoint() );
1430 ImplWriteColor( rOStm
, pAct
->GetColor() );
1435 case( MetaActionType::POINT
):
1437 const MetaPointAction
* pAct
= static_cast<const MetaPointAction
*>(pAction
);
1439 rOStm
.WriteInt16( GDI_POINT_ACTION
);
1440 rOStm
.WriteInt32( 12 );
1441 WritePair( rOStm
, pAct
->GetPoint() );
1446 case( MetaActionType::LINE
):
1448 const MetaLineAction
* pAct
= static_cast<const MetaLineAction
*>(pAction
);
1449 const LineInfo
& rInfo
= pAct
->GetLineInfo();
1450 const bool bFatLine(!rInfo
.IsDefault() && (LINE_NONE
!= rInfo
.GetStyle()));
1451 const bool bLineJoin(bFatLine
&& basegfx::B2DLINEJOIN_ROUND
!= rInfo
.GetLineJoin());
1452 const bool bLineCap(bFatLine
&& com::sun::star::drawing::LineCap_BUTT
!= rInfo
.GetLineCap());
1453 const bool bLineDashDot(LINE_DASH
== rInfo
.GetStyle());
1457 ImplWritePushAction( rOStm
);
1458 ImplWriteLineColor( rOStm
, rLineCol
, 1, rInfo
.GetWidth() );
1462 rOStm
.WriteInt16( GDI_LINEJOIN_ACTION
);
1463 rOStm
.WriteInt32( 6 );
1464 rOStm
.WriteInt16( rInfo
.GetLineJoin() );
1469 rOStm
.WriteInt16( GDI_LINECAP_ACTION
);
1470 rOStm
.WriteInt32( 6 );
1471 rOStm
.WriteInt16( rInfo
.GetLineCap() );
1477 rOStm
.WriteInt16( GDI_LINEDASHDOT_ACTION
);
1478 rOStm
.WriteInt32( 4 + 16 );
1479 rOStm
.WriteInt16( rInfo
.GetDashCount() );
1480 rOStm
.WriteInt32( rInfo
.GetDashLen() );
1481 rOStm
.WriteInt16( rInfo
.GetDotCount() );
1482 rOStm
.WriteInt32( rInfo
.GetDotLen() );
1483 rOStm
.WriteInt32( rInfo
.GetDistance() );
1486 rOStm
.WriteInt16( GDI_LINE_ACTION
);
1487 rOStm
.WriteInt32( 20 );
1488 WritePair( rOStm
, pAct
->GetStartPoint() );
1489 WritePair( rOStm
, pAct
->GetEndPoint() );
1494 ImplWritePopAction( rOStm
);
1515 case( MetaActionType::RECT
):
1517 const MetaRectAction
* pAct
= static_cast<const MetaRectAction
*>(pAction
);
1519 rOStm
.WriteInt16( GDI_RECT_ACTION
);
1520 rOStm
.WriteInt32( 28 );
1521 ImplWriteRect( rOStm
, pAct
->GetRect() );
1522 rOStm
.WriteInt32( 0 );
1523 rOStm
.WriteInt32( 0 );
1528 case( MetaActionType::ROUNDRECT
):
1530 const MetaRoundRectAction
* pAct
= static_cast<const MetaRoundRectAction
*>(pAction
);
1532 rOStm
.WriteInt16( GDI_RECT_ACTION
);
1533 rOStm
.WriteInt32( 28 );
1534 ImplWriteRect( rOStm
, pAct
->GetRect() );
1535 rOStm
.WriteInt32( pAct
->GetHorzRound() );
1536 rOStm
.WriteInt32( pAct
->GetVertRound() );
1541 case( MetaActionType::ELLIPSE
):
1543 const MetaEllipseAction
* pAct
= static_cast<const MetaEllipseAction
*>(pAction
);
1545 rOStm
.WriteInt16( GDI_ELLIPSE_ACTION
);
1546 rOStm
.WriteInt32( 20 );
1547 ImplWriteRect( rOStm
, pAct
->GetRect() );
1552 case( MetaActionType::ARC
):
1554 const MetaArcAction
* pAct
= static_cast<const MetaArcAction
*>(pAction
);
1556 rOStm
.WriteInt16( GDI_ARC_ACTION
);
1557 rOStm
.WriteInt32( 36 );
1558 ImplWriteRect( rOStm
, pAct
->GetRect() );
1559 WritePair( rOStm
, pAct
->GetStartPoint() );
1560 WritePair( rOStm
, pAct
->GetEndPoint() );
1565 case( MetaActionType::PIE
):
1567 const MetaPieAction
* pAct
= static_cast<const MetaPieAction
*>(pAction
);
1569 rOStm
.WriteInt16( GDI_PIE_ACTION
);
1570 rOStm
.WriteInt32( 36 );
1571 ImplWriteRect( rOStm
, pAct
->GetRect() );
1572 WritePair( rOStm
, pAct
->GetStartPoint() );
1573 WritePair( rOStm
, pAct
->GetEndPoint() );
1578 case( MetaActionType::CHORD
):
1580 const MetaChordAction
* pAct
= static_cast<const MetaChordAction
*>(pAction
);
1581 Polygon
aChordPoly( pAct
->GetRect(), pAct
->GetStartPoint(),
1582 pAct
->GetEndPoint(), POLY_CHORD
);
1583 const sal_uInt16 nPoints
= aChordPoly
.GetSize();
1585 rOStm
.WriteInt16( GDI_POLYGON_ACTION
);
1586 rOStm
.WriteInt32( 8 + ( nPoints
<< 3 ) );
1587 rOStm
.WriteInt32( nPoints
);
1589 for( sal_uInt16 n
= 0; n
< nPoints
; n
++ )
1590 WritePair( rOStm
, aChordPoly
[ n
] );
1595 case( MetaActionType::POLYLINE
):
1598 const MetaPolyLineAction
* pAct
= static_cast<const MetaPolyLineAction
*>(pAction
);
1599 // #i102224# Here the possible curved nature of Polygon was
1600 // ignored (for all those years). Adapted to at least write
1601 // a polygon representing the curve as good as possible
1602 Polygon aSimplePoly
;
1603 pAct
->GetPolygon().AdaptiveSubdivide(aSimplePoly
);
1604 const LineInfo
& rInfo
= pAct
->GetLineInfo();
1605 const sal_uInt16
nPoints(aSimplePoly
.GetSize());
1606 const bool bFatLine(!rInfo
.IsDefault() && (LINE_NONE
!= rInfo
.GetStyle()));
1607 const bool bLineJoin(bFatLine
&& basegfx::B2DLINEJOIN_ROUND
!= rInfo
.GetLineJoin());
1608 const bool bLineCap(bFatLine
&& com::sun::star::drawing::LineCap_BUTT
!= rInfo
.GetLineCap());
1609 const bool bLineDashDot(LINE_DASH
== rInfo
.GetStyle());
1613 ImplWritePushAction( rOStm
);
1614 ImplWriteLineColor( rOStm
, rLineCol
, 1, rInfo
.GetWidth() );
1618 rOStm
.WriteInt16( GDI_LINEJOIN_ACTION
);
1619 rOStm
.WriteInt32( 6 );
1620 rOStm
.WriteInt16( rInfo
.GetLineJoin() );
1625 rOStm
.WriteInt16( GDI_LINECAP_ACTION
);
1626 rOStm
.WriteInt32( 6 );
1627 rOStm
.WriteInt16( rInfo
.GetLineCap() );
1633 rOStm
.WriteInt16( GDI_LINEDASHDOT_ACTION
);
1634 rOStm
.WriteInt32( 4 + 16 );
1635 rOStm
.WriteInt16( rInfo
.GetDashCount() );
1636 rOStm
.WriteInt32( rInfo
.GetDashLen() );
1637 rOStm
.WriteInt16( rInfo
.GetDotCount() );
1638 rOStm
.WriteInt32( rInfo
.GetDotLen() );
1639 rOStm
.WriteInt32( rInfo
.GetDistance() );
1642 rOStm
.WriteInt16( GDI_POLYLINE_ACTION
);
1643 rOStm
.WriteInt32( 8 + ( nPoints
<< 3 ) );
1644 rOStm
.WriteInt32( nPoints
);
1646 for( sal_uInt16 n
= 0; n
< nPoints
; n
++ )
1648 WritePair( rOStm
, aSimplePoly
[ n
] );
1653 const tools::PolyPolygon
aPolyPolygon(pAct
->GetPolygon());
1654 if(ImplWriteExtendedPolyPolygonAction(rOStm
, aPolyPolygon
, true))
1661 ImplWritePopAction( rOStm
);
1682 case( MetaActionType::POLYGON
):
1684 const MetaPolygonAction
* pAct
= static_cast<const MetaPolygonAction
*>(pAction
);
1685 // #i102224# Here the possible curved nature of Polygon was
1686 // ignored (for all those years). Adapted to at least write
1687 // a polygon representing the curve as good as possible
1688 Polygon aSimplePoly
;
1689 pAct
->GetPolygon().AdaptiveSubdivide(aSimplePoly
);
1690 const sal_uInt16
nPoints(aSimplePoly
.GetSize());
1692 rOStm
.WriteInt16( GDI_POLYGON_ACTION
);
1693 rOStm
.WriteInt32( 8 + ( nPoints
<< 3 ) );
1694 rOStm
.WriteInt32( nPoints
);
1696 for( sal_uInt16 n
= 0; n
< nPoints
; n
++ )
1697 WritePair( rOStm
, aSimplePoly
[ n
] );
1701 const tools::PolyPolygon
aPolyPolygon(pAct
->GetPolygon());
1702 if(ImplWriteExtendedPolyPolygonAction(rOStm
, aPolyPolygon
, true))
1709 case( MetaActionType::POLYPOLYGON
):
1711 const MetaPolyPolygonAction
* pAct
= static_cast<const MetaPolyPolygonAction
*>(pAction
);
1712 ImplWritePolyPolyAction( rOStm
, pAct
->GetPolyPolygon() );
1715 if(ImplWriteExtendedPolyPolygonAction(rOStm
, pAct
->GetPolyPolygon(), true))
1722 case( MetaActionType::TEXT
):
1724 const MetaTextAction
* pAct
= static_cast<const MetaTextAction
*>(pAction
);
1725 OUString
aUniText( pAct
->GetText() );
1726 OString
aText(OUStringToOString(aUniText
, rActualCharSet
));
1727 const sal_Int32 nStrLen
= aText
.getLength();
1729 if ( ImplWriteUnicodeComment( rOStm
, aUniText
) )
1732 rOStm
.WriteInt16( GDI_TEXT_ACTION
);
1733 rOStm
.WriteInt32( 24 + ( nStrLen
+ 1 ) );
1734 WritePair( rOStm
, pAct
->GetPoint() );
1735 rOStm
.WriteInt32( pAct
->GetIndex() );
1736 rOStm
.WriteInt32( pAct
->GetLen() );
1737 rOStm
.WriteInt32( nStrLen
);
1738 rOStm
.Write( aText
.getStr(), nStrLen
+ 1 );
1743 case( MetaActionType::TEXTARRAY
):
1745 const MetaTextArrayAction
* pAct
= static_cast<const MetaTextArrayAction
*>(pAction
);
1746 OString
aText(OUStringToOString(pAct
->GetText(), rActualCharSet
));
1747 OUString aUniText
= pAct
->GetText().copy(
1749 std::min
<sal_Int32
>(pAct
->GetText().getLength() - pAct
->GetIndex(), pAct
->GetLen()) );
1751 sal_Int32 nLen
= pAct
->GetLen();
1752 const sal_Int32 nTextLen
= aText
.getLength();
1753 long* pDXArray
= pAct
->GetDXArray();
1755 if ( ImplWriteUnicodeComment( rOStm
, aUniText
) )
1758 if( ( nLen
+ pAct
->GetIndex() ) > nTextLen
)
1760 if( pAct
->GetIndex() <= nTextLen
)
1761 nLen
= nTextLen
- pAct
->GetIndex();
1766 if( !pDXArray
|| !nLen
)
1769 nAryLen
= nLen
; // #105987# Write out all of DX array
1771 rOStm
.WriteInt16( GDI_TEXTARRAY_ACTION
);
1772 rOStm
.WriteInt32( 28 + ( nLen
+ 1 ) + ( nAryLen
* 4 ) );
1773 WritePair( rOStm
, pAct
->GetPoint() );
1774 rOStm
.WriteInt32( 0 );
1775 rOStm
.WriteInt32( nLen
);
1776 rOStm
.WriteInt32( nLen
);
1777 rOStm
.WriteInt32( nAryLen
);
1778 rOStm
.Write( aText
.getStr()+pAct
->GetIndex(), nLen
+ 1 );
1780 for (sal_Int32 n
= 0; n
< nAryLen
; ++n
)
1781 rOStm
.WriteInt32( pDXArray
[ n
] );
1787 case( MetaActionType::STRETCHTEXT
):
1789 const MetaStretchTextAction
* pAct
= static_cast<const MetaStretchTextAction
*>(pAction
);
1790 OUString
aUniText( pAct
->GetText() );
1791 OString
aText(OUStringToOString(aUniText
, rActualCharSet
));
1792 const sal_Int32 nStrLen
= aText
.getLength();
1794 if ( ImplWriteUnicodeComment( rOStm
, aUniText
) )
1797 rOStm
.WriteInt16( GDI_STRETCHTEXT_ACTION
);
1798 rOStm
.WriteInt32( 28 + ( nStrLen
+ 1 ) );
1799 WritePair( rOStm
, pAct
->GetPoint() );
1800 rOStm
.WriteInt32( pAct
->GetIndex() );
1801 rOStm
.WriteInt32( pAct
->GetLen() );
1802 rOStm
.WriteInt32( nStrLen
);
1803 rOStm
.WriteInt32( pAct
->GetWidth() );
1804 rOStm
.Write( aText
.getStr(), nStrLen
+ 1 );
1809 case( MetaActionType::BMP
):
1811 const MetaBmpAction
* pAct
= static_cast<const MetaBmpAction
*>(pAction
);
1813 rOStm
.WriteInt16( GDI_BITMAP_ACTION
);
1814 rOStm
.WriteInt32( 12 );
1815 WritePair( rOStm
, pAct
->GetPoint() );
1816 WriteDIB(pAct
->GetBitmap(), rOStm
, false, true);
1821 case( MetaActionType::BMPSCALE
):
1823 const MetaBmpScaleAction
* pAct
= static_cast<const MetaBmpScaleAction
*>(pAction
);
1825 rOStm
.WriteInt16( GDI_BITMAPSCALE_ACTION
);
1826 rOStm
.WriteInt32( 20 );
1827 WritePair( rOStm
, pAct
->GetPoint() );
1828 WritePair( rOStm
, pAct
->GetSize() );
1829 WriteDIB(pAct
->GetBitmap(), rOStm
, false, true);
1834 case( MetaActionType::BMPSCALEPART
):
1836 const MetaBmpScalePartAction
* pAct
= static_cast<const MetaBmpScalePartAction
*>(pAction
);
1838 rOStm
.WriteInt16( GDI_BITMAPSCALEPART_ACTION
);
1839 rOStm
.WriteInt32( 36 );
1840 WritePair( rOStm
, pAct
->GetDestPoint() );
1841 WritePair( rOStm
, pAct
->GetDestSize() );
1842 WritePair( rOStm
, pAct
->GetSrcPoint() );
1843 WritePair( rOStm
, pAct
->GetSrcSize() );
1844 WriteDIB(pAct
->GetBitmap(), rOStm
, false, true);
1849 case( MetaActionType::BMPEX
):
1851 const MetaBmpExAction
* pAct
= static_cast<const MetaBmpExAction
*>(pAction
);
1852 const Bitmap
aBmp( Graphic( pAct
->GetBitmapEx() ).GetBitmap() );
1854 rOStm
.WriteInt16( GDI_BITMAP_ACTION
);
1855 rOStm
.WriteInt32( 12 );
1856 WritePair( rOStm
, pAct
->GetPoint() );
1857 WriteDIB(aBmp
, rOStm
, false, true);
1862 case( MetaActionType::BMPEXSCALE
):
1864 const MetaBmpExScaleAction
* pAct
= static_cast<const MetaBmpExScaleAction
*>(pAction
);
1865 const Bitmap
aBmp( Graphic( pAct
->GetBitmapEx() ).GetBitmap() );
1867 rOStm
.WriteInt16( GDI_BITMAPSCALE_ACTION
);
1868 rOStm
.WriteInt32( 20 );
1869 WritePair( rOStm
, pAct
->GetPoint() );
1870 WritePair( rOStm
, pAct
->GetSize() );
1871 WriteDIB(aBmp
, rOStm
, false, true);
1876 case( MetaActionType::BMPEXSCALEPART
):
1878 const MetaBmpExScalePartAction
* pAct
= static_cast<const MetaBmpExScalePartAction
*>(pAction
);
1879 const Bitmap
aBmp( Graphic( pAct
->GetBitmapEx() ).GetBitmap() );
1881 rOStm
.WriteInt16( GDI_BITMAPSCALEPART_ACTION
);
1882 rOStm
.WriteInt32( 36 );
1883 WritePair( rOStm
, pAct
->GetDestPoint() );
1884 WritePair( rOStm
, pAct
->GetDestSize() );
1885 WritePair( rOStm
, pAct
->GetSrcPoint() );
1886 WritePair( rOStm
, pAct
->GetSrcSize() );
1887 WriteDIB(aBmp
, rOStm
, false, true);
1892 case( MetaActionType::GRADIENT
):
1894 const MetaGradientAction
* pAct
= static_cast<const MetaGradientAction
*>(pAction
);
1895 const Gradient
& rGrad
= pAct
->GetGradient();
1897 rOStm
.WriteInt16( GDI_GRADIENT_ACTION
);
1898 rOStm
.WriteInt32( 46 );
1899 ImplWriteRect( rOStm
, pAct
->GetRect() );
1900 rOStm
.WriteInt16( rGrad
.GetStyle() );
1901 ImplWriteColor( rOStm
, rGrad
.GetStartColor() );
1902 ImplWriteColor( rOStm
, rGrad
.GetEndColor() );
1903 rOStm
.WriteInt16( rGrad
.GetAngle() );
1904 rOStm
.WriteInt16( rGrad
.GetBorder() );
1905 rOStm
.WriteInt16( rGrad
.GetOfsX() );
1906 rOStm
.WriteInt16( rGrad
.GetOfsY() );
1907 rOStm
.WriteInt16( rGrad
.GetStartIntensity() );
1908 rOStm
.WriteInt16( rGrad
.GetEndIntensity() );
1913 case( MetaActionType::GRADIENTEX
):
1915 const MetaGradientExAction
* pA
= static_cast<const MetaGradientExAction
*>(pAction
);
1916 sal_uLong nOldPos
, nNewPos
;
1918 // write RefPoint comment
1919 rOStm
.WriteInt16( GDI_GRADIENTEX_COMMENT
);
1921 // we'll write the ActionSize later
1922 nOldPos
= rOStm
.Tell();
1926 WritePolyPolygon( rOStm
, pA
->GetPolyPolygon() );
1927 WriteGradient( rOStm
, pA
->GetGradient() );
1928 rOStm
.WriteInt32( 0 ); // number of actions that follow this comment
1930 // calculate and write ActionSize of comment
1931 nNewPos
= rOStm
.Tell();
1932 rOStm
.Seek( nOldPos
);
1933 rOStm
.WriteInt32( nNewPos
- nOldPos
);
1934 rOStm
.Seek( nNewPos
);
1940 case( MetaActionType::WALLPAPER
):
1942 const MetaWallpaperAction
* pAct
= static_cast<const MetaWallpaperAction
*>(pAction
);
1943 const Color
& rColor
= pAct
->GetWallpaper().GetColor();
1945 ImplWritePushAction( rOStm
);
1946 ImplWriteLineColor( rOStm
, rColor
, 1 );
1947 ImplWriteFillColor( rOStm
, rColor
, 1 );
1949 rOStm
.WriteInt16( GDI_RECT_ACTION
);
1950 rOStm
.WriteInt32( 28 );
1951 ImplWriteRect( rOStm
, pAct
->GetRect() );
1952 rOStm
.WriteInt32( 0 );
1953 rOStm
.WriteInt32( 0 );
1955 ImplWritePopAction( rOStm
);
1960 case( MetaActionType::CLIPREGION
):
1962 const MetaClipRegionAction
* pAct
= static_cast<const MetaClipRegionAction
*>(pAction
);
1963 const vcl::Region
& rRegion
= pAct
->GetRegion();
1964 Rectangle aClipRect
;
1966 rOStm
.WriteInt16( GDI_CLIPREGION_ACTION
);
1967 rOStm
.WriteInt32( 24 );
1969 if( pAct
->IsClipping() )
1971 aClipRect
= rRegion
.GetBoundRect();
1972 rOStm
.WriteInt16( 1 );
1975 rOStm
.WriteInt16( 0 );
1977 rOStm
.WriteInt16( 0 );
1978 ImplWriteRect( rOStm
, aClipRect
);
1980 if( pAct
->IsClipping() )
1981 ImplWriteRect( rOStm
, aClipRect
);
1987 case( MetaActionType::ISECTRECTCLIPREGION
):
1989 const MetaISectRectClipRegionAction
* pAct
= static_cast<const MetaISectRectClipRegionAction
*>(pAction
);
1991 rOStm
.WriteInt16( GDI_ISECTCLIPREGION_ACTION
);
1992 rOStm
.WriteInt32( 20 );
1993 WriteRectangle( rOStm
, pAct
->GetRect() );
1998 case( MetaActionType::MOVECLIPREGION
):
2000 const MetaMoveClipRegionAction
* pAct
= static_cast<const MetaMoveClipRegionAction
*>(pAction
);
2002 rOStm
.WriteInt16( GDI_MOVECLIPREGION_ACTION
);
2003 rOStm
.WriteInt32( 12 );
2004 rOStm
.WriteInt32( pAct
->GetHorzMove() );
2005 rOStm
.WriteInt32( pAct
->GetVertMove() );
2010 case( MetaActionType::LINECOLOR
):
2012 const MetaLineColorAction
* pAct
= static_cast<const MetaLineColorAction
*>(pAction
);
2013 ImplWriteLineColor( rOStm
, rLineCol
= pAct
->GetColor(), pAct
->IsSetting() ? 1 : 0 );
2018 case( MetaActionType::FILLCOLOR
):
2020 const MetaFillColorAction
* pAct
= static_cast<const MetaFillColorAction
*>(pAction
);
2021 ImplWriteFillColor( rOStm
, pAct
->GetColor(), pAct
->IsSetting() ? 1 : 0 );
2026 case( MetaActionType::FONT
):
2028 rSaveVDev
.SetFont( static_cast<const MetaFontAction
*>(pAction
)->GetFont() );
2029 ImplWriteFont( rOStm
, rSaveVDev
.GetFont(), rActualCharSet
);
2034 case( MetaActionType::TEXTCOLOR
):
2036 vcl::Font
aSaveFont( rSaveVDev
.GetFont() );
2038 aSaveFont
.SetColor( static_cast<const MetaTextColorAction
*>(pAction
)->GetColor() );
2039 rSaveVDev
.SetFont( aSaveFont
);
2040 ImplWriteFont( rOStm
, rSaveVDev
.GetFont(), rActualCharSet
);
2045 case( MetaActionType::TEXTFILLCOLOR
):
2047 const MetaTextFillColorAction
* pAct
= static_cast<const MetaTextFillColorAction
*>(pAction
);
2048 vcl::Font
aSaveFont( rSaveVDev
.GetFont() );
2050 if( pAct
->IsSetting() )
2051 aSaveFont
.SetFillColor( pAct
->GetColor() );
2053 aSaveFont
.SetFillColor( Color( COL_TRANSPARENT
) );
2055 rSaveVDev
.SetFont( aSaveFont
);
2056 ImplWriteFont( rOStm
, rSaveVDev
.GetFont(), rActualCharSet
);
2061 case( MetaActionType::TEXTALIGN
):
2063 vcl::Font
aSaveFont( rSaveVDev
.GetFont() );
2065 aSaveFont
.SetAlign( static_cast<const MetaTextAlignAction
*>(pAction
)->GetTextAlign() );
2066 rSaveVDev
.SetFont( aSaveFont
);
2067 ImplWriteFont( rOStm
, rSaveVDev
.GetFont(), rActualCharSet
);
2072 case( MetaActionType::MAPMODE
):
2074 const MetaMapModeAction
* pAct
= static_cast<const MetaMapModeAction
*>(pAction
);
2076 rOStm
.WriteInt16( GDI_MAPMODE_ACTION
);
2077 rOStm
.WriteInt32( 30 );
2078 ImplWriteMapMode( rOStm
, pAct
->GetMapMode() );
2083 case( MetaActionType::PUSH
):
2085 ImplWritePushAction( rOStm
);
2086 rLineColStack
.push( new Color( rLineCol
) );
2092 case( MetaActionType::POP
):
2095 if (rLineColStack
.empty())
2099 pCol
= rLineColStack
.top();
2100 rLineColStack
.pop();
2109 ImplWritePopAction( rOStm
);
2115 case( MetaActionType::RASTEROP
):
2117 const MetaRasterOpAction
* pAct
= static_cast<const MetaRasterOpAction
*>(pAction
);
2119 if( ( pAct
->GetRasterOp() != ROP_0
) && ( pAct
->GetRasterOp() != ROP_1
) )
2121 sal_Int16 nRasterOp
;
2123 // If ROP_0/1 was set earlier, restore old state
2127 ImplWritePopAction( rOStm
);
2133 switch( pAct
->GetRasterOp() )
2135 case( ROP_OVERPAINT
) : nRasterOp
= 0; break;
2136 case( ROP_XOR
) : nRasterOp
= 4; break;
2137 case( ROP_INVERT
): nRasterOp
= 1; break;
2138 default: nRasterOp
= 0; break;
2141 ImplWriteRasterOpAction( rOStm
, nRasterOp
);
2146 ImplWritePushAction( rOStm
);
2149 if( pAct
->GetRasterOp() == ROP_0
)
2151 ImplWriteLineColor( rOStm
, COL_BLACK
, 1 );
2152 ImplWriteFillColor( rOStm
, COL_BLACK
, 1 );
2156 ImplWriteLineColor( rOStm
, COL_WHITE
, 1 );
2157 ImplWriteFillColor( rOStm
, COL_WHITE
, 1 );
2160 ImplWriteRasterOpAction( rOStm
, 0 );
2167 case( MetaActionType::Transparent
):
2169 const tools::PolyPolygon
& rPolyPoly
= static_cast<const MetaTransparentAction
*>(pAction
)->GetPolyPolygon();
2170 const sal_Int16 nTrans
= static_cast<const MetaTransparentAction
*>(pAction
)->GetTransparence();
2171 const sal_Int16 nBrushStyle
= ( nTrans
< 38 ) ? 8 : ( nTrans
< 63 ) ? 9 : 10;
2172 sal_uLong nOldPos
, nNewPos
;
2174 // write transparence comment
2175 rOStm
.WriteInt16( GDI_TRANSPARENT_COMMENT
);
2177 // we'll write the ActionSize later
2178 nOldPos
= rOStm
.Tell();
2181 // write comment data
2182 WritePolyPolygon( rOStm
, rPolyPoly
);
2183 rOStm
.WriteInt16( nTrans
);
2184 rOStm
.WriteInt32( 15 ); // number of actions that follow this comment
2186 // calculate and write ActionSize of comment
2187 nNewPos
= rOStm
.Tell();
2188 rOStm
.Seek( nOldPos
);
2189 rOStm
.WriteInt32( nNewPos
- nOldPos
);
2190 rOStm
.Seek( nNewPos
);
2193 // write actions for transparence
2194 ImplWritePushAction( rOStm
);
2196 ImplWriteRasterOpAction( rOStm
, 4 );
2197 ImplWritePolyPolyAction( rOStm
, rPolyPoly
);
2199 ImplWritePushAction( rOStm
);
2201 ImplWriteRasterOpAction( rOStm
, 2 );
2202 ImplWriteFillColor( rOStm
, COL_BLACK
, nBrushStyle
);
2203 ImplWritePolyPolyAction( rOStm
, rPolyPoly
);
2205 ImplWritePopAction( rOStm
);
2207 ImplWriteRasterOpAction( rOStm
, 4 );
2208 ImplWritePolyPolyAction( rOStm
, rPolyPoly
);
2210 ImplWritePopAction( rOStm
);
2212 ImplWritePushAction( rOStm
);
2214 ImplWriteFillColor( rOStm
, Color(), 0 );
2215 ImplWritePolyPolyAction( rOStm
, rPolyPoly
);
2217 ImplWritePopAction( rOStm
);
2226 case( MetaActionType::FLOATTRANSPARENT
):
2228 const MetaFloatTransparentAction
* pA
= static_cast<const MetaFloatTransparentAction
*>(pAction
);
2229 const GDIMetaFile
& rTransMtf
= pA
->GetGDIMetaFile();
2230 const Point
& rPos
= pA
->GetPoint();
2231 const Size
& rSize
= pA
->GetSize();
2232 const Gradient
& rGradient
= pA
->GetGradient();
2233 sal_uLong nOldPos
, nNewPos
;
2235 // write RefPoint comment
2236 rOStm
.WriteInt16( GDI_FLOATTRANSPARENT_COMMENT
);
2238 // we'll write the ActionSize later
2239 nOldPos
= rOStm
.Tell();
2242 // write comment data
2243 WriteGDIMetaFile( rOStm
, rTransMtf
);
2244 WritePair( rOStm
, rPos
);
2245 WritePair( rOStm
, rSize
);
2246 WriteGradient( rOStm
, rGradient
);
2248 // calculate and write ActionSize of comment
2249 nNewPos
= rOStm
.Tell();
2250 rOStm
.Seek( nOldPos
);
2251 rOStm
.WriteInt32( nNewPos
- nOldPos
+ 4 );
2252 rOStm
.Seek( ( nOldPos
= nNewPos
) + 4 );
2255 // write actions for float transparence
2256 sal_uLong nAddCount
;
2257 GDIMetaFile
aMtf( rTransMtf
);
2258 const Size
aSrcSize( rTransMtf
.GetPrefSize() );
2259 Point
aSrcPt( rTransMtf
.GetPrefMapMode().GetOrigin() );
2260 const double fScaleX
= aSrcSize
.Width() ? (double) rSize
.Width() / aSrcSize
.Width() : 1.0;
2261 const double fScaleY
= aSrcSize
.Height() ? (double) rSize
.Height() / aSrcSize
.Height() : 1.0;
2262 long nMoveX
, nMoveY
;
2264 if( fScaleX
!= 1.0 || fScaleY
!= 1.0 )
2266 aMtf
.Scale( fScaleX
, fScaleY
);
2267 aSrcPt
.X() = FRound( aSrcPt
.X() * fScaleX
), aSrcPt
.Y() = FRound( aSrcPt
.Y() * fScaleY
);
2270 nMoveX
= rPos
.X() - aSrcPt
.X(), nMoveY
= rPos
.Y() - aSrcPt
.Y();
2272 if( nMoveX
|| nMoveY
)
2273 aMtf
.Move( nMoveX
, nMoveY
);
2275 nAddCount
= ImplWriteActions( rOStm
, aMtf
, rSaveVDev
, rRop_0_1
, rLineCol
, rLineColStack
, rActualCharSet
);
2276 nNewPos
= rOStm
.Tell();
2277 rOStm
.Seek( nOldPos
);
2278 rOStm
.WriteInt32( nAddCount
);
2279 rOStm
.Seek( nNewPos
);
2281 nCount
+= nAddCount
;
2288 case( MetaActionType::HATCH
):
2290 const MetaHatchAction
* pA
= static_cast<const MetaHatchAction
*>(pAction
);
2291 const tools::PolyPolygon
& rPolyPoly
= pA
->GetPolyPolygon();
2292 const Hatch
& rHatch
= pA
->GetHatch();
2293 sal_uLong nOldPos
, nNewPos
, nAddCount
;
2295 // write hatch comment
2296 rOStm
.WriteInt16( GDI_HATCH_COMMENT
);
2298 // we'll write the ActionSize later
2299 nOldPos
= rOStm
.Tell();
2302 // write comment data
2303 WritePolyPolygon( rOStm
, rPolyPoly
);
2304 WriteHatch( rOStm
, rHatch
);
2306 // calculate and write ActionSize of comment
2307 nNewPos
= rOStm
.Tell();
2308 rOStm
.Seek( nOldPos
);
2309 rOStm
.WriteInt32( nNewPos
- nOldPos
+ 4 );
2310 rOStm
.Seek( ( nOldPos
= nNewPos
) + 4 );
2313 // write actions for hatch
2314 ScopedVclPtrInstance
< VirtualDevice
> aVDev
;
2315 GDIMetaFile aTmpMtf
;
2317 aVDev
->AddHatchActions( rPolyPoly
, rHatch
, aTmpMtf
);
2318 nAddCount
= ImplWriteActions( rOStm
, aTmpMtf
, rSaveVDev
, rRop_0_1
, rLineCol
, rLineColStack
, rActualCharSet
);
2319 nNewPos
= rOStm
.Tell();
2320 rOStm
.Seek( nOldPos
);
2321 rOStm
.WriteInt32( nAddCount
);
2322 rOStm
.Seek( nNewPos
);
2324 nCount
+= nAddCount
;
2331 case( MetaActionType::REFPOINT
):
2333 const MetaRefPointAction
* pA
= static_cast<const MetaRefPointAction
*>(pAction
);
2334 const Point
& rRefPoint
= pA
->GetRefPoint();
2335 const bool bSet
= pA
->IsSetting();
2336 sal_uLong nOldPos
, nNewPos
;
2338 // write RefPoint comment
2339 rOStm
.WriteInt16( GDI_REFPOINT_COMMENT
);
2341 // we'll write the ActionSize later
2342 nOldPos
= rOStm
.Tell();
2346 WritePair( rOStm
, rRefPoint
);
2347 rOStm
.WriteBool( bSet
);
2348 rOStm
.WriteInt32( 0 ); // number of actions that follow this comment
2350 // calculate and write ActionSize of comment
2351 nNewPos
= rOStm
.Tell();
2352 rOStm
.Seek( nOldPos
);
2353 rOStm
.WriteInt32( nNewPos
- nOldPos
);
2354 rOStm
.Seek( nNewPos
);
2360 case( MetaActionType::TEXTLINECOLOR
):
2362 const MetaTextLineColorAction
* pA
= static_cast<const MetaTextLineColorAction
*>(pAction
);
2363 const Color
& rColor
= pA
->GetColor();
2364 const bool bSet
= pA
->IsSetting();
2365 sal_uLong nOldPos
, nNewPos
;
2367 // write RefPoint comment
2368 rOStm
.WriteInt16( GDI_TEXTLINECOLOR_COMMENT
);
2370 // we'll write the ActionSize later
2371 nOldPos
= rOStm
.Tell();
2375 WriteColor( rOStm
, rColor
);
2376 rOStm
.WriteBool( bSet
);
2377 rOStm
.WriteInt32( 0 ); // number of actions that follow this comment
2379 // calculate and write ActionSize of comment
2380 nNewPos
= rOStm
.Tell();
2381 rOStm
.Seek( nOldPos
);
2382 rOStm
.WriteInt32( nNewPos
- nOldPos
);
2383 rOStm
.Seek( nNewPos
);
2389 case( MetaActionType::TEXTLINE
):
2391 const MetaTextLineAction
* pA
= static_cast<const MetaTextLineAction
*>(pAction
);
2392 const Point
& rStartPt
= pA
->GetStartPoint();
2393 const sal_Int32 nWidth
= (sal_Int32
) pA
->GetWidth();
2394 const FontStrikeout eStrikeout
= pA
->GetStrikeout();
2395 const FontUnderline eUnderline
= pA
->GetUnderline();
2396 sal_uLong nOldPos
, nNewPos
;
2398 // write RefPoint comment
2399 rOStm
.WriteInt16( GDI_TEXTLINE_COMMENT
);
2401 // we'll write the ActionSize later
2402 nOldPos
= rOStm
.Tell();
2406 WritePair( rOStm
, rStartPt
);
2407 rOStm
.WriteInt32( nWidth
).WriteUInt32( eStrikeout
).WriteUInt32( eUnderline
);
2408 rOStm
.WriteInt32( 0 ); // number of actions that follow this comment
2410 // calculate and write ActionSize of comment
2411 nNewPos
= rOStm
.Tell();
2412 rOStm
.Seek( nOldPos
);
2413 rOStm
.WriteInt32( nNewPos
- nOldPos
);
2414 rOStm
.Seek( nNewPos
);
2420 case( MetaActionType::EPS
):
2423 case( MetaActionType::COMMENT
):
2425 const MetaCommentAction
* pA
= static_cast<const MetaCommentAction
*>(pAction
);
2426 const sal_uInt32 nDataSize
= pA
->GetDataSize();
2427 sal_uLong nOldPos
, nNewPos
;
2429 // write RefPoint comment
2430 rOStm
.WriteInt16( GDI_COMMENT_COMMENT
);
2432 // we'll write the ActionSize later
2433 nOldPos
= rOStm
.Tell();
2437 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStm
, pA
->GetComment());
2438 rOStm
.WriteInt32( pA
->GetValue() ).WriteUInt32( nDataSize
);
2441 rOStm
.Write( pA
->GetData(), nDataSize
);
2443 rOStm
.WriteInt32( 0 ); // number of actions that follow this comment
2445 // calculate and write ActionSize of comment
2446 nNewPos
= rOStm
.Tell();
2447 rOStm
.Seek( nOldPos
);
2448 rOStm
.WriteInt32( nNewPos
- nOldPos
);
2449 rOStm
.Seek( nNewPos
);
2458 OStringBuffer
aStr("Missing implementation for Action#: ");
2459 aStr
.append(static_cast<sal_Int32
>(pAction
->GetType()));
2461 OSL_FAIL(aStr
.getStr());
2471 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */