blob: 466b7b9492b2b1ad428b80dcae6468ddc7279270 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#define ENABLE_BYTESTRING_STREAM_OPERATORS
#include <algorithm>
#include <string.h>
#include <tools/stack.hxx>
#include <tools/debug.hxx>
#include <tools/stream.hxx>
#include <vcl/virdev.hxx>
#include <vcl/graph.hxx>
#include <vcl/lineinfo.hxx>
#include <vcl/salbtype.hxx>
#include <vcl/cvtsvm.hxx>
#include <vcl/dibtools.hxx>
// -----------
// - Defines -
// -----------
#define CVTSVM_WRITE_SUBACTIONCOUNT 1
// -----------
// - Inlines -
// -----------
void ImplReadRect( SvStream& rIStm, Rectangle& rRect )
{
Point aTL;
Point aBR;
rIStm >> aTL;
rIStm >> aBR;
rRect = Rectangle( aTL, aBR );
}
// ------------------------------------------------------------------------
void ImplWriteRect( SvStream& rOStm, const Rectangle& rRect )
{
rOStm << rRect.TopLeft();
rOStm << rRect.BottomRight();
}
// ------------------------------------------------------------------------
void ImplReadPoly( SvStream& rIStm, Polygon& rPoly )
{
sal_Int32 nSize;
rIStm >> nSize;
rPoly = Polygon( (sal_uInt16) nSize );
for( sal_uInt16 i = 0; i < (sal_uInt16) nSize; i++ )
rIStm >> rPoly[ i ];
}
// ------------------------------------------------------------------------
void ImplReadPolyPoly( SvStream& rIStm, PolyPolygon& rPolyPoly )
{
Polygon aPoly;
sal_Int32 nPolyCount;
rIStm >> nPolyCount;
for( sal_uInt16 i = 0; i < (sal_uInt16) nPolyCount; i++ )
{
ImplReadPoly( rIStm, aPoly );
rPolyPoly.Insert( aPoly );
}
}
// ------------------------------------------------------------------------
void ImplWritePolyPolyAction( SvStream& rOStm, const PolyPolygon& rPolyPoly )
{
const sal_uInt16 nPoly = rPolyPoly.Count();
sal_uInt16 nPoints = 0;
sal_uInt16 n;
for( n = 0; n < nPoly; n++ )
nPoints = sal::static_int_cast<sal_uInt16>(nPoints + rPolyPoly[ n ].GetSize());
rOStm << (sal_Int16) GDI_POLYPOLYGON_ACTION;
rOStm << (sal_Int32) ( 8 + ( nPoly << 2 ) + ( nPoints << 3 ) );
rOStm << (sal_Int32) nPoly;
for( n = 0; n < nPoly; n++ )
{
// #i102224# Here the evtl. curved nature of Polygon was
// ignored (for all those Years). Adapted to at least write
// a polygon representing the curve as good as possible
Polygon aSimplePoly;
rPolyPoly[n].AdaptiveSubdivide(aSimplePoly);
const sal_uInt16 nSize(aSimplePoly.GetSize());
rOStm << (sal_Int32) nSize;
for( sal_uInt16 j = 0; j < nSize; j++ )
rOStm << aSimplePoly[ j ];
}
}
// ------------------------------------------------------------------------
void ImplReadColor( SvStream& rIStm, Color& rColor )
{
sal_Int16 nVal;
rIStm >> nVal; rColor.SetRed( sal::static_int_cast<sal_uInt8>((sal_uInt16)nVal >> 8) );
rIStm >> nVal; rColor.SetGreen( sal::static_int_cast<sal_uInt8>((sal_uInt16)nVal >> 8) );
rIStm >> nVal; rColor.SetBlue( sal::static_int_cast<sal_uInt8>((sal_uInt16)nVal >> 8) );
}
// ------------------------------------------------------------------------
void ImplWriteColor( SvStream& rOStm, const Color& rColor )
{
sal_Int16 nVal;
nVal = ( (sal_Int16) rColor.GetRed() << 8 ) | rColor.GetRed();
rOStm << nVal;
nVal = ( (sal_Int16) rColor.GetGreen() << 8 ) | rColor.GetGreen();
rOStm << nVal;
nVal = ( (sal_Int16) rColor.GetBlue() << 8 ) | rColor.GetBlue();
rOStm << nVal;
}
// ------------------------------------------------------------------------
void ImplReadMapMode( SvStream& rIStm, MapMode& rMapMode )
{
Point aOrg;
sal_Int32 nXNum;
sal_Int32 nXDenom;
sal_Int32 nYNum;
sal_Int32 nYDenom;
sal_Int16 nUnit;
rIStm >> nUnit >> aOrg >> nXNum >> nXDenom >> nYNum >> nYDenom;
rMapMode = MapMode( (MapUnit) nUnit, aOrg, Fraction( nXNum, nXDenom ), Fraction( nYNum, nYDenom ) );
}
// ------------------------------------------------------------------------
void ImplWriteMapMode( SvStream& rOStm, const MapMode& rMapMode )
{
rOStm << (sal_Int16) rMapMode.GetMapUnit();
rOStm << rMapMode.GetOrigin();
rOStm << (sal_Int32) rMapMode.GetScaleX().GetNumerator();
rOStm << (sal_Int32) rMapMode.GetScaleX().GetDenominator();
rOStm << (sal_Int32) rMapMode.GetScaleY().GetNumerator();
rOStm << (sal_Int32) rMapMode.GetScaleY().GetDenominator();
}
// ------------------------------------------------------------------------
void ImplWritePushAction( SvStream& rOStm )
{
rOStm << (sal_Int16) GDI_PUSH_ACTION;
rOStm << (sal_Int32) 4;
}
// ------------------------------------------------------------------------
void ImplWritePopAction( SvStream& rOStm )
{
rOStm << (sal_Int16) GDI_POP_ACTION;
rOStm << (sal_Int32) 4;
}
// ------------------------------------------------------------------------
void ImplWriteLineColor( SvStream& rOStm, const Color& rColor, sal_Int16 nStyle, sal_Int32 nWidth = 0L )
{
if( rColor.GetTransparency() > 127 )
nStyle = 0;
rOStm << (sal_Int16) GDI_PEN_ACTION;
rOStm << (sal_Int32) 16;
ImplWriteColor( rOStm, rColor );
rOStm << nWidth;
rOStm << nStyle;
}
// ------------------------------------------------------------------------
void ImplWriteFillColor( SvStream& rOStm, const Color& rColor, sal_Int16 nStyle )
{
rOStm << (sal_Int16) GDI_FILLBRUSH_ACTION;
rOStm << (sal_Int32) 20;
ImplWriteColor( rOStm, rColor );
if( rColor.GetTransparency() > 127 )
nStyle = 0;
if( nStyle > 1 )
{
ImplWriteColor( rOStm, COL_WHITE );
rOStm << nStyle;
rOStm << (sal_Int16) 1;
}
else
{
ImplWriteColor( rOStm, COL_BLACK );
rOStm << nStyle;
rOStm << (sal_Int16) 0;
}
}
// ------------------------------------------------------------------------
void ImplWriteFont( SvStream& rOStm, const Font& rFont,
rtl_TextEncoding& rActualCharSet )
{
char aName[32];
short nWeight;
ByteString aByteName( rFont.GetName(), rOStm.GetStreamCharSet() );
strncpy( aName, aByteName.GetBuffer(), 32 );
switch ( rFont.GetWeight() )
{
case WEIGHT_THIN:
case WEIGHT_ULTRALIGHT:
case WEIGHT_LIGHT:
nWeight = 1;
break;
case WEIGHT_NORMAL:
case WEIGHT_MEDIUM:
nWeight = 2;
break;
case WEIGHT_BOLD:
case WEIGHT_ULTRABOLD:
case WEIGHT_BLACK:
nWeight = 3;
break;
default:
nWeight = 0;
break;
}
rOStm << (sal_Int16) GDI_FONT_ACTION;
rOStm << (sal_Int32) 78;
rActualCharSet = GetStoreCharSet( rFont.GetCharSet() );
ImplWriteColor( rOStm, rFont.GetColor() );
ImplWriteColor( rOStm, rFont.GetFillColor() );
rOStm.Write( aName, 32 );
rOStm << rFont.GetSize();
rOStm << (sal_Int16) 0; // no character orientation anymore
rOStm << (sal_Int16) rFont.GetOrientation();
rOStm << (sal_Int16) rActualCharSet;
rOStm << (sal_Int16) rFont.GetFamily();
rOStm << (sal_Int16) rFont.GetPitch();
rOStm << (sal_Int16) rFont.GetAlign();
rOStm << (sal_Int16) nWeight;
rOStm << (sal_Int16) rFont.GetUnderline();
rOStm << (sal_Int16) rFont.GetStrikeout();
rOStm << (sal_Bool) ( rFont.GetItalic() != ITALIC_NONE );
rOStm << rFont.IsOutline();
rOStm << rFont.IsShadow();
rOStm << rFont.IsTransparent();
if ( rActualCharSet == RTL_TEXTENCODING_DONTKNOW )
rActualCharSet = gsl_getSystemTextEncoding();
}
// ------------------------------------------------------------------------
void ImplWriteRasterOpAction( SvStream& rOStm, sal_Int16 nRasterOp )
{
rOStm << (sal_Int16) GDI_RASTEROP_ACTION << (sal_Int32) 6 << nRasterOp;
}
// ------------------------------------------------------------------------
sal_Bool ImplWriteUnicodeComment( SvStream& rOStm, const String& rString )
{
xub_StrLen i, nStringLen = rString.Len();
if ( nStringLen )
{
sal_uInt32 nSize = ( nStringLen << 1 ) + 4;
sal_uInt16 nType = GDI_UNICODE_COMMENT;
rOStm << nType << nSize;
for ( i = 0; i < nStringLen; i++ )
{
sal_Unicode nUni = rString.GetChar( i );
rOStm << nUni;
}
}
return nStringLen != 0;
}
// ------------------------------------------------------------------------
void ImplReadUnicodeComment( sal_uInt32 nStrmPos, SvStream& rIStm, String& rString )
{
sal_uInt32 nOld = rIStm.Tell();
if ( nStrmPos )
{
sal_uInt16 nType;
sal_uInt32 nActionSize;
xub_StrLen nStringLen;
rIStm.Seek( nStrmPos );
rIStm >> nType
>> nActionSize;
nStringLen = sal::static_int_cast<xub_StrLen>(( nActionSize - 4 ) >> 1);
if ( nStringLen && ( nType == GDI_UNICODE_COMMENT ) )
{
sal_Unicode* pBuffer = rString.AllocBuffer( nStringLen );
while ( nStringLen-- )
rIStm >> *pBuffer++;
}
}
rIStm.Seek( nOld );
}
// ------------------------------------------------------------------------
void ImplSkipActions( SvStream& rIStm, sal_uLong nSkipCount )
{
sal_Int32 nActionSize;
sal_Int16 nType;
for( sal_uLong i = 0UL; i < nSkipCount; i++ )
{
rIStm >> nType >> nActionSize;
rIStm.SeekRel( nActionSize - 4L );
}
}
// ------------------------------------------------------------------------
bool ImplWriteExtendedPolyPolygonAction(SvStream& rOStm, const PolyPolygon& rPolyPolygon, bool bOnlyWhenCurve)
{
const sal_uInt16 nPolygonCount(rPolyPolygon.Count());
if(nPolygonCount)
{
sal_uInt32 nAllPolygonCount(0);
sal_uInt32 nAllPointCount(0);
sal_uInt32 nAllFlagCount(0);
sal_uInt16 a(0);
for(a = 0; a < nPolygonCount; a++)
{
const Polygon& rCandidate = rPolyPolygon.GetObject(a);
const sal_uInt16 nPointCount(rCandidate.GetSize());
if(nPointCount)
{
nAllPolygonCount++;
nAllPointCount += nPointCount;
if(rCandidate.HasFlags())
{
nAllFlagCount += nPointCount;
}
}
}
if((bOnlyWhenCurve && nAllFlagCount) || (!bOnlyWhenCurve && nAllPointCount))
{
rOStm << (sal_Int16) GDI_EXTENDEDPOLYGON_ACTION;
const sal_Int32 nActionSize(
4 + // Action size
2 + // PolygonCount
(nAllPolygonCount * 2) + // Points per polygon
(nAllPointCount << 3) + // Points themselves
nAllPolygonCount + // Bool if (when poly has points) it has flags, too
nAllFlagCount); // Flags themselves
rOStm << nActionSize;
rOStm << (sal_uInt16)nAllPolygonCount;
for(a = 0; a < nPolygonCount; a++)
{
const Polygon& rCandidate = rPolyPolygon.GetObject(a);
const sal_uInt16 nPointCount(rCandidate.GetSize());
if(nPointCount)
{
rOStm << nPointCount;
for(sal_uInt16 b(0); b < nPointCount; b++)
{
rOStm << rCandidate[b];
}
if(rCandidate.HasFlags())
{
rOStm << (sal_uInt8)true;
for(sal_uInt16 c(0); c < nPointCount; c++)
{
rOStm << (sal_uInt8)rCandidate.GetFlags(c);
}
}
else
{
rOStm << (sal_uInt8)false;
}
}
}
return true;
}
}
return false;
}
// ------------------------------------------------------------------------
void ImplReadExtendedPolyPolygonAction(SvStream& rIStm, PolyPolygon& rPolyPoly)
{
rPolyPoly.Clear();
sal_uInt16 nPolygonCount(0);
rIStm >> nPolygonCount;
for(sal_uInt16 a(0); a < nPolygonCount; a++)
{
sal_uInt16 nPointCount(0);
rIStm >> nPointCount;
Polygon aCandidate(nPointCount);
if(nPointCount)
{
for(sal_uInt16 b(0); b < nPointCount; b++)
{
rIStm >> aCandidate[b];
}
sal_uInt8 bHasFlags(false);
rIStm >> bHasFlags;
if(bHasFlags)
{
sal_uInt8 aPolyFlags(0);
for(sal_uInt16 c(0); c < nPointCount; c++)
{
rIStm >> aPolyFlags;
aCandidate.SetFlags(c, (PolyFlags)aPolyFlags);
}
}
}
rPolyPoly.Insert(aCandidate);
}
}
// ----------------
// - SVMConverter -
// ----------------
SVMConverter::SVMConverter( SvStream& rStm, GDIMetaFile& rMtf, sal_uLong nConvertMode )
{
if( !rStm.GetError() )
{
if( CONVERT_FROM_SVM1 == nConvertMode )
ImplConvertFromSVM1( rStm, rMtf );
else if( CONVERT_TO_SVM1 == nConvertMode )
ImplConvertToSVM1( rStm, rMtf );
}
}
// ------------------------------------------------------------------------
void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf )
{
const sal_uLong nPos = rIStm.Tell();
const sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt();
rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
char aCode[ 5 ];
Size aPrefSz;
sal_Int16 nSize;
sal_Int16 nVersion;
// read header
rIStm.Read( (char*) &aCode, sizeof( aCode ) ); // Kennung
rIStm >> nSize; // Size
rIStm >> nVersion; // Version
rIStm >> aPrefSz.Width(); // PrefSize.Width()
rIStm >> aPrefSz.Height(); // PrefSize.Height()
// check header-magic and version
if( rIStm.GetError()
|| ( memcmp( aCode, "SVGDI", sizeof( aCode ) ) != 0 )
|| ( nVersion != 200 ) )
{
rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
rIStm.SetNumberFormatInt( nOldFormat );
rIStm.Seek( nPos );
return;
}
LineInfo aLineInfo( LINE_NONE, 0 );
Stack aLIStack;
VirtualDevice aFontVDev;
rtl_TextEncoding eActualCharSet = gsl_getSystemTextEncoding();
sal_Bool bFatLine = sal_False;
// TODO: fix reindentation below if you can accept being blamed by the SCM
MapMode aMapMode;
Polygon aActionPoly;
Rectangle aRect;
Point aPt, aPt1;
Size aSz;
Color aActionColor;
sal_Int32 nTmp, nTmp1, nActionSize;
sal_Int32 nActions;
sal_Int16 nType;
sal_uInt32 nUnicodeCommentStreamPos = 0;
sal_Int32 nUnicodeCommentActionNumber = 0;
ImplReadMapMode( rIStm, aMapMode ); // MapMode
rIStm >> nActions; // Action count
rMtf.SetPrefSize( aPrefSz );
rMtf.SetPrefMapMode( aMapMode );
sal_uInt32 nLastPolygonAction(0);
for( sal_Int32 i = 0L; i < nActions; i++ )
{
rIStm >> nType;
sal_Int32 nActBegin = rIStm.Tell();
rIStm >> nActionSize;
DBG_ASSERT( ( nType <= 33 ) || ( nType >= 1024 ), "Unknown GDIMetaAction while converting!" );
switch( nType )
{
case( GDI_PIXEL_ACTION ):
{
rIStm >> aPt;
ImplReadColor( rIStm, aActionColor );
rMtf.AddAction( new MetaPixelAction( aPt, aActionColor ) );
}
break;
case( GDI_POINT_ACTION ):
{
rIStm >> aPt;
rMtf.AddAction( new MetaPointAction( aPt ) );
}
break;
case( GDI_LINE_ACTION ):
{
rIStm >> aPt >> aPt1;
rMtf.AddAction( new MetaLineAction( aPt, aPt1, aLineInfo ) );
}
break;
case (GDI_LINEJOIN_ACTION) :
{
sal_Int16 nLineJoin(0);
rIStm >> nLineJoin;
aLineInfo.SetLineJoin((basegfx::B2DLineJoin)nLineJoin);
}
break;
case (GDI_LINECAP_ACTION) :
{
sal_Int16 nLineCap(0);
rIStm >> nLineCap;
aLineInfo.SetLineCap((com::sun::star::drawing::LineCap)nLineCap);
}
break;
case (GDI_LINEDASHDOT_ACTION) :
{
sal_Int16 a(0);
sal_Int32 b(0);
rIStm >> a; aLineInfo.SetDashCount(a);
rIStm >> b; aLineInfo.SetDashLen(b);
rIStm >> a; aLineInfo.SetDotCount(a);
rIStm >> b; aLineInfo.SetDotLen(b);
rIStm >> b; aLineInfo.SetDistance(b);
if(((aLineInfo.GetDashCount() && aLineInfo.GetDashLen())
|| (aLineInfo.GetDotCount() && aLineInfo.GetDotLen()))
&& aLineInfo.GetDistance())
{
aLineInfo.SetStyle(LINE_DASH);
}
}
break;
case (GDI_EXTENDEDPOLYGON_ACTION) :
{
// read the PolyPolygon in every case
PolyPolygon aInputPolyPolygon;
ImplReadExtendedPolyPolygonAction(rIStm, aInputPolyPolygon);
// now check if it can be set somewhere
if(nLastPolygonAction < rMtf.GetActionCount())
{
MetaPolyLineAction* pPolyLineAction = dynamic_cast< MetaPolyLineAction* >(rMtf.GetAction(nLastPolygonAction));
if(pPolyLineAction)
{
// replace MetaPolyLineAction when we have a single polygon. Do not rely on the
// same point count; the originally written GDI_POLYLINE_ACTION may have been
// Subdivided for better quality for older usages
if(1 == aInputPolyPolygon.Count())
{
rMtf.ReplaceAction(
new MetaPolyLineAction(
aInputPolyPolygon.GetObject(0),
pPolyLineAction->GetLineInfo()),
nLastPolygonAction);
pPolyLineAction->Delete();
}
}
else
{
MetaPolyPolygonAction* pPolyPolygonAction = dynamic_cast< MetaPolyPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
if(pPolyPolygonAction)
{
// replace MetaPolyPolygonAction when we have a curved polygon. Do rely on the
// same sub-polygon count
if(pPolyPolygonAction->GetPolyPolygon().Count() == aInputPolyPolygon.Count())
{
rMtf.ReplaceAction(
new MetaPolyPolygonAction(
aInputPolyPolygon),
nLastPolygonAction);
pPolyPolygonAction->Delete();
}
}
else
{
MetaPolygonAction* pPolygonAction = dynamic_cast< MetaPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
if(pPolygonAction)
{
// replace MetaPolygonAction
if(1 == aInputPolyPolygon.Count())
{
rMtf.ReplaceAction(
new MetaPolygonAction(
aInputPolyPolygon.GetObject(0)),
nLastPolygonAction);
pPolygonAction->Delete();
}
}
}
}
}
}
break;
case( GDI_RECT_ACTION ):
{
ImplReadRect( rIStm, aRect );
rIStm >> nTmp >> nTmp1;
if( nTmp || nTmp1 )
rMtf.AddAction( new MetaRoundRectAction( aRect, nTmp, nTmp1 ) );
else
{
rMtf.AddAction( new MetaRectAction( aRect ) );
if( bFatLine )
rMtf.AddAction( new MetaPolyLineAction( aRect, aLineInfo ) );
}
}
break;
case( GDI_ELLIPSE_ACTION ):
{
ImplReadRect( rIStm, aRect );
if( bFatLine )
{
const Polygon aPoly( aRect.Center(), aRect.GetWidth() >> 1, aRect.GetHeight() >> 1 );
rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
rMtf.AddAction( new MetaPolygonAction( aPoly ) );
rMtf.AddAction( new MetaPopAction() );
rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
}
else
rMtf.AddAction( new MetaEllipseAction( aRect ) );
}
break;
case( GDI_ARC_ACTION ):
{
ImplReadRect( rIStm, aRect );
rIStm >> aPt >> aPt1;
if( bFatLine )
{
const Polygon aPoly( aRect, aPt, aPt1, POLY_ARC );
rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
rMtf.AddAction( new MetaPolygonAction( aPoly ) );
rMtf.AddAction( new MetaPopAction() );
rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
}
else
rMtf.AddAction( new MetaArcAction( aRect, aPt, aPt1 ) );
}
break;
case( GDI_PIE_ACTION ):
{
ImplReadRect( rIStm, aRect );
rIStm >> aPt >> aPt1;
if( bFatLine )
{
const Polygon aPoly( aRect, aPt, aPt1, POLY_PIE );
rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
rMtf.AddAction( new MetaPolygonAction( aPoly ) );
rMtf.AddAction( new MetaPopAction() );
rMtf.AddAction( new MetaPolyLineAction( aPoly, aLineInfo ) );
}
else
rMtf.AddAction( new MetaPieAction( aRect, aPt, aPt1 ) );
}
break;
case( GDI_INVERTRECT_ACTION ):
case( GDI_HIGHLIGHTRECT_ACTION ):
{
ImplReadRect( rIStm, aRect );
rMtf.AddAction( new MetaPushAction( PUSH_RASTEROP ) );
rMtf.AddAction( new MetaRasterOpAction( ROP_INVERT ) );
rMtf.AddAction( new MetaRectAction( aRect ) );
rMtf.AddAction( new MetaPopAction() );
}
break;
case( GDI_POLYLINE_ACTION ):
{
ImplReadPoly( rIStm, aActionPoly );
nLastPolygonAction = rMtf.GetActionCount();
if( bFatLine )
rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
else
rMtf.AddAction( new MetaPolyLineAction( aActionPoly ) );
}
break;
case( GDI_POLYGON_ACTION ):
{
ImplReadPoly( rIStm, aActionPoly );
if( bFatLine )
{
rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
rMtf.AddAction( new MetaPopAction() );
rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
}
else
{
nLastPolygonAction = rMtf.GetActionCount();
rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
}
}
break;
case( GDI_POLYPOLYGON_ACTION ):
{
PolyPolygon aPolyPoly;
ImplReadPolyPoly( rIStm, aPolyPoly );
if( bFatLine )
{
rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
rMtf.AddAction( new MetaLineColorAction( COL_TRANSPARENT, sal_False ) );
rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
rMtf.AddAction( new MetaPopAction() );
for( sal_uInt16 nPoly = 0, nCount = aPolyPoly.Count(); nPoly < nCount; nPoly++ )
rMtf.AddAction( new MetaPolyLineAction( aPolyPoly[ nPoly ], aLineInfo ) );
}
else
{
nLastPolygonAction = rMtf.GetActionCount();
rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
}
}
break;
case( GDI_FONT_ACTION ):
{
Font aFont;
char aName[ 32 ];
sal_Int32 nWidth, nHeight;
sal_Int16 nCharSet, nFamily, nPitch, nAlign, nWeight, nUnderline, nStrikeout;
sal_Int16 nCharOrient, nLineOrient;
sal_Bool bItalic, bOutline, bShadow, bTransparent;
ImplReadColor( rIStm, aActionColor ); aFont.SetColor( aActionColor );
ImplReadColor( rIStm, aActionColor ); aFont.SetFillColor( aActionColor );
rIStm.Read( aName, 32 );
aFont.SetName( UniString( aName, rIStm.GetStreamCharSet() ) );
rIStm >> nWidth >> nHeight;
rIStm >> nCharOrient >> nLineOrient;
rIStm >> nCharSet >> nFamily >> nPitch >> nAlign >> nWeight >> nUnderline >> nStrikeout;
rIStm >> bItalic >> bOutline >> bShadow >> bTransparent;
aFont.SetSize( Size( nWidth, nHeight ) );
aFont.SetCharSet( (CharSet) nCharSet );
aFont.SetFamily( (FontFamily) nFamily );
aFont.SetPitch( (FontPitch) nPitch );
aFont.SetAlign( (FontAlign) nAlign );
aFont.SetWeight( ( nWeight == 1 ) ? WEIGHT_LIGHT : ( nWeight == 2 ) ? WEIGHT_NORMAL :
( nWeight == 3 ) ? WEIGHT_BOLD : WEIGHT_DONTKNOW );
aFont.SetUnderline( (FontUnderline) nUnderline );
aFont.SetStrikeout( (FontStrikeout) nStrikeout );
aFont.SetItalic( bItalic ? ITALIC_NORMAL : ITALIC_NONE );
aFont.SetOutline( bOutline );
aFont.SetShadow( bShadow );
aFont.SetOrientation( nLineOrient );
aFont.SetTransparent( bTransparent );
eActualCharSet = aFont.GetCharSet();
if ( eActualCharSet == RTL_TEXTENCODING_DONTKNOW )
eActualCharSet = gsl_getSystemTextEncoding();
rMtf.AddAction( new MetaFontAction( aFont ) );
rMtf.AddAction( new MetaTextAlignAction( aFont.GetAlign() ) );
rMtf.AddAction( new MetaTextColorAction( aFont.GetColor() ) );
rMtf.AddAction( new MetaTextFillColorAction( aFont.GetFillColor(), !aFont.IsTransparent() ) );
// #106172# Track font relevant data in shadow VDev
aFontVDev.SetFont( aFont );
}
break;
case( GDI_TEXT_ACTION ):
{
ByteString aByteStr;
sal_Int32 nIndex, nLen;
rIStm >> aPt >> nIndex >> nLen >> nTmp;
if ( nTmp && ( static_cast< sal_uInt32 >( nTmp ) < ( SAL_MAX_UINT16 - 1 ) ) )
{
rIStm.Read( aByteStr.AllocBuffer( (sal_uInt16)nTmp ), nTmp + 1 );
UniString aStr( aByteStr, eActualCharSet );
if ( nUnicodeCommentActionNumber == i )
ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
rMtf.AddAction( new MetaTextAction( aPt, aStr, (sal_uInt16) nIndex, (sal_uInt16) nLen ) );
}
rIStm.Seek( nActBegin + nActionSize );
}
break;
case( GDI_TEXTARRAY_ACTION ):
{
ByteString aByteStr;
sal_Int32* pDXAry = NULL;
sal_Int32 nIndex, nLen, nAryLen;
rIStm >> aPt >> nIndex >> nLen >> nTmp >> nAryLen;
if ( nTmp && ( static_cast< sal_uInt32 >( nTmp ) < ( SAL_MAX_UINT16 - 1 ) ) )
{
rIStm.Read( aByteStr.AllocBuffer( (sal_uInt16)nTmp ), nTmp + 1 );
UniString aStr( aByteStr, eActualCharSet );
if( nAryLen > 0L )
{
sal_Int32 nStrLen( aStr.Len() );
pDXAry = new sal_Int32[ Max( nAryLen, nStrLen ) ];
for( long j = 0L; j < nAryLen; j++ )
rIStm >> nTmp, pDXAry[ j ] = nTmp;
// #106172# Add last DX array elem, if missing
if( nAryLen != nStrLen )
{
if( nAryLen+1 == nStrLen )
{
sal_Int32* pTmpAry = new sal_Int32[nStrLen];
aFontVDev.GetTextArray( aStr, pTmpAry, (sal_uInt16) nIndex, (sal_uInt16) nLen );
// now, the difference between the
// last and the second last DX array
// is the advancement for the last
// glyph. Thus, to complete our meta
// action's DX array, just add that
// difference to last elem and store
// in very last.
if( nStrLen > 1 )
pDXAry[ nStrLen-1 ] = pDXAry[ nStrLen-2 ] + pTmpAry[ nStrLen-1 ] - pTmpAry[ nStrLen-2 ];
else
pDXAry[ nStrLen-1 ] = pTmpAry[ nStrLen-1 ]; // len=1: 0th position taken to be 0
delete[] pTmpAry;
}
#ifdef DBG_UTIL
else
DBG_ERROR("More than one DX array element missing on SVM import");
#endif
}
}
if ( nUnicodeCommentActionNumber == i )
ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
rMtf.AddAction( new MetaTextArrayAction( aPt, aStr, pDXAry, (sal_uInt16) nIndex, (sal_uInt16) nLen ) );
if( pDXAry )
delete[] pDXAry;
}
rIStm.Seek( nActBegin + nActionSize );
}
break;
case( GDI_STRETCHTEXT_ACTION ):
{
ByteString aByteStr;
sal_Int32 nIndex, nLen, nWidth;
rIStm >> aPt >> nIndex >> nLen >> nTmp >> nWidth;
if ( nTmp && ( static_cast< sal_uInt32 >( nTmp ) < ( SAL_MAX_INT16 - 1 ) ) )
{
rIStm.Read( aByteStr.AllocBuffer( (sal_uInt16)nTmp ), nTmp + 1 );
UniString aStr( aByteStr, eActualCharSet );
if ( nUnicodeCommentActionNumber == i )
ImplReadUnicodeComment( nUnicodeCommentStreamPos, rIStm, aStr );
rMtf.AddAction( new MetaStretchTextAction( aPt, nWidth, aStr, (sal_uInt16) nIndex, (sal_uInt16) nLen ) );
}
rIStm.Seek( nActBegin + nActionSize );
}
break;
case( GDI_BITMAP_ACTION ):
{
Bitmap aBmp;
rIStm >> aPt;
ReadDIB(aBmp, rIStm, true);
rMtf.AddAction( new MetaBmpAction( aPt, aBmp ) );
}
break;
case( GDI_BITMAPSCALE_ACTION ):
{
Bitmap aBmp;
rIStm >> aPt >> aSz;
ReadDIB(aBmp, rIStm, true);
rMtf.AddAction( new MetaBmpScaleAction( aPt, aSz, aBmp ) );
}
break;
case( GDI_BITMAPSCALEPART_ACTION ):
{
Bitmap aBmp;
Size aSz2;
rIStm >> aPt >> aSz >> aPt1 >> aSz2;
ReadDIB(aBmp, rIStm, true);
rMtf.AddAction( new MetaBmpScalePartAction( aPt, aSz, aPt1, aSz2, aBmp ) );
}
break;
case( GDI_PEN_ACTION ):
{
sal_Int32 nPenWidth;
sal_Int16 nPenStyle;
ImplReadColor( rIStm, aActionColor );
rIStm >> nPenWidth >> nPenStyle;
aLineInfo.SetStyle( nPenStyle ? LINE_SOLID : LINE_NONE );
aLineInfo.SetWidth( nPenWidth );
bFatLine = nPenStyle && !aLineInfo.IsDefault();
rMtf.AddAction( new MetaLineColorAction( aActionColor, nPenStyle != 0 ) );
}
break;
case( GDI_FILLBRUSH_ACTION ):
{
sal_Int16 nBrushStyle;
ImplReadColor( rIStm, aActionColor );
rIStm.SeekRel( 6L );
rIStm >> nBrushStyle;
rMtf.AddAction( new MetaFillColorAction( aActionColor, nBrushStyle != 0 ) );
rIStm.SeekRel( 2L );
}
break;
case( GDI_MAPMODE_ACTION ):
{
ImplReadMapMode( rIStm, aMapMode );
rMtf.AddAction( new MetaMapModeAction( aMapMode ) );
// #106172# Track font relevant data in shadow VDev
aFontVDev.SetMapMode( aMapMode );
}
break;
case( GDI_CLIPREGION_ACTION ):
{
Region aRegion;
sal_Int16 nRegType;
sal_Int16 bIntersect;
sal_Bool bClip = sal_False;
rIStm >> nRegType >> bIntersect;
ImplReadRect( rIStm, aRect );
switch( nRegType )
{
case( 0 ):
break;
case( 1 ):
{
Rectangle aRegRect;
ImplReadRect( rIStm, aRegRect );
aRegion = Region( aRegRect );
bClip = sal_True;
}
break;
case( 2 ):
{
ImplReadPoly( rIStm, aActionPoly );
aRegion = Region( aActionPoly );
bClip = sal_True;
}
break;
case( 3 ):
{
PolyPolygon aPolyPoly;
sal_Int32 nPolyCount;
rIStm >> nPolyCount;
for( sal_uInt16 j = 0; j < (sal_uInt16) nPolyCount; j++ )
{
ImplReadPoly( rIStm, aActionPoly );
aPolyPoly.Insert( aActionPoly );
}
aRegion = Region( aPolyPoly );
bClip = sal_True;
}
break;
}
if( bIntersect )
aRegion.Intersect( aRect );
rMtf.AddAction( new MetaClipRegionAction( aRegion, bClip ) );
}
break;
case( GDI_MOVECLIPREGION_ACTION ):
{
rIStm >> nTmp >> nTmp1;
rMtf.AddAction( new MetaMoveClipRegionAction( nTmp, nTmp1 ) );
}
break;
case( GDI_ISECTCLIPREGION_ACTION ):
{
ImplReadRect( rIStm, aRect );
rMtf.AddAction( new MetaISectRectClipRegionAction( aRect ) );
}
break;
case( GDI_RASTEROP_ACTION ):
{
RasterOp eRasterOp;
sal_Int16 nRasterOp;
rIStm >> nRasterOp;
switch( nRasterOp )
{
case( 1 ):
eRasterOp = ROP_INVERT;
break;
case( 4 ):
case( 5 ):
eRasterOp = ROP_XOR;
break;
default:
eRasterOp = ROP_OVERPAINT;
break;
}
rMtf.AddAction( new MetaRasterOpAction( eRasterOp ) );
}
break;
case( GDI_PUSH_ACTION ):
{
aLIStack.Push( new LineInfo( aLineInfo ) );
rMtf.AddAction( new MetaPushAction( PUSH_ALL ) );
// #106172# Track font relevant data in shadow VDev
aFontVDev.Push();
}
break;
case( GDI_POP_ACTION ):
{
LineInfo* pLineInfo = (LineInfo*) aLIStack.Pop();
// restore line info
if( pLineInfo )
{
aLineInfo = *pLineInfo;
delete pLineInfo;
bFatLine = ( LINE_NONE != aLineInfo.GetStyle() ) && !aLineInfo.IsDefault();
}
rMtf.AddAction( new MetaPopAction() );
// #106172# Track font relevant data in shadow VDev
aFontVDev.Pop();
}
break;
case( GDI_GRADIENT_ACTION ):
{
Color aStartCol;
Color aEndCol;
sal_Int16 nStyle;
sal_Int16 nAngle;
sal_Int16 nBorder;
sal_Int16 nOfsX;
sal_Int16 nOfsY;
sal_Int16 nIntensityStart;
sal_Int16 nIntensityEnd;
ImplReadRect( rIStm, aRect );
rIStm >> nStyle;
ImplReadColor( rIStm, aStartCol );
ImplReadColor( rIStm, aEndCol );
rIStm >> nAngle >> nBorder >> nOfsX >> nOfsY >> nIntensityStart >> nIntensityEnd;
Gradient aGrad( (GradientStyle) nStyle, aStartCol, aEndCol );
aGrad.SetAngle( nAngle );
aGrad.SetBorder( nBorder );
aGrad.SetOfsX( nOfsX );
aGrad.SetOfsY( nOfsY );
aGrad.SetStartIntensity( nIntensityStart );
aGrad.SetEndIntensity( nIntensityEnd );
rMtf.AddAction( new MetaGradientAction( aRect, aGrad ) );
}
break;
case( GDI_TRANSPARENT_COMMENT ):
{
PolyPolygon aPolyPoly;
sal_Int32 nFollowingActionCount;
sal_Int16 nTrans;
rIStm >> aPolyPoly >> nTrans >> nFollowingActionCount;
ImplSkipActions( rIStm, nFollowingActionCount );
rMtf.AddAction( new MetaTransparentAction( aPolyPoly, nTrans ) );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
i += nFollowingActionCount;
#endif
}
break;
case( GDI_FLOATTRANSPARENT_COMMENT ):
{
GDIMetaFile aMtf;
Point aPos;
Size aSize;
Gradient aGradient;
sal_Int32 nFollowingActionCount;
rIStm >> aMtf >> aPos >> aSize >> aGradient >> nFollowingActionCount;
ImplSkipActions( rIStm, nFollowingActionCount );
rMtf.AddAction( new MetaFloatTransparentAction( aMtf, aPos, aSize, aGradient ) );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
i += nFollowingActionCount;
#endif
}
break;
case( GDI_HATCH_COMMENT ):
{
PolyPolygon aPolyPoly;
Hatch aHatch;
sal_Int32 nFollowingActionCount;
rIStm >> aPolyPoly >> aHatch >> nFollowingActionCount;
ImplSkipActions( rIStm, nFollowingActionCount );
rMtf.AddAction( new MetaHatchAction( aPolyPoly, aHatch ) );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
i += nFollowingActionCount;
#endif
}
break;
case( GDI_REFPOINT_COMMENT ):
{
Point aRefPoint;
sal_Bool bSet;
sal_Int32 nFollowingActionCount;
rIStm >> aRefPoint >> bSet >> nFollowingActionCount;
ImplSkipActions( rIStm, nFollowingActionCount );
rMtf.AddAction( new MetaRefPointAction( aRefPoint, bSet ) );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
i += nFollowingActionCount;
#endif
// #106172# Track font relevant data in shadow VDev
if( bSet )
aFontVDev.SetRefPoint( aRefPoint );
else
aFontVDev.SetRefPoint();
}
break;
case( GDI_TEXTLINECOLOR_COMMENT ):
{
Color aColor;
sal_Bool bSet;
sal_Int32 nFollowingActionCount;
rIStm >> aColor >> bSet >> nFollowingActionCount;
ImplSkipActions( rIStm, nFollowingActionCount );
rMtf.AddAction( new MetaTextLineColorAction( aColor, bSet ) );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
i += nFollowingActionCount;
#endif
}
break;
case( GDI_TEXTLINE_COMMENT ):
{
Point aStartPt;
long nWidth;
sal_uInt32 nStrikeout;
sal_uInt32 nUnderline;
sal_Int32 nFollowingActionCount;
rIStm >> aStartPt >> nWidth >> nStrikeout >> nUnderline >> nFollowingActionCount;
ImplSkipActions( rIStm, nFollowingActionCount );
rMtf.AddAction( new MetaTextLineAction( aStartPt, nWidth,
(FontStrikeout) nStrikeout,
(FontUnderline) nUnderline,
UNDERLINE_NONE ) );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
i += nFollowingActionCount;
#endif
}
break;
case( GDI_GRADIENTEX_COMMENT ):
{
PolyPolygon aPolyPoly;
Gradient aGradient;
sal_Int32 nFollowingActionCount;
rIStm >> aPolyPoly >> aGradient >> nFollowingActionCount;
ImplSkipActions( rIStm, nFollowingActionCount );
rMtf.AddAction( new MetaGradientExAction( aPolyPoly, aGradient ) );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
i += nFollowingActionCount;
#endif
}
break;
case( GDI_COMMENT_COMMENT ):
{
ByteString aComment;
sal_Int32 nValue;
sal_uInt32 nDataSize;
sal_uInt8* pData;
sal_Int32 nFollowingActionCount;
rIStm >> aComment >> nValue >> nDataSize;
if( nDataSize )
{
pData = new sal_uInt8[ nDataSize ];
rIStm.Read( pData, nDataSize );
}
else
pData = NULL;
rIStm >> nFollowingActionCount;
ImplSkipActions( rIStm, nFollowingActionCount );
rMtf.AddAction( new MetaCommentAction( aComment, nValue, pData, nDataSize ) );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
i += nFollowingActionCount;
#endif
}
break;
case ( GDI_UNICODE_COMMENT ):
{
nUnicodeCommentActionNumber = i + 1;
nUnicodeCommentStreamPos = rIStm.Tell() - 6;
rIStm.SeekRel( nActionSize - 4 );
}
break;
default:
rIStm.SeekRel( nActionSize - 4L );
break;
}
}
// cleanup push-pop stack if neccessary
for( void* pLineInfo = aLIStack.Pop(); pLineInfo; pLineInfo = aLIStack.Pop() )
delete (LineInfo*) pLineInfo;
rIStm.SetNumberFormatInt( nOldFormat );
}
// ------------------------------------------------------------------------
void SVMConverter::ImplConvertToSVM1( SvStream& rOStm, GDIMetaFile& rMtf )
{
sal_uLong nPos;
sal_uLong nCountPos;
Font aSaveFont;
const sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt();
rtl_TextEncoding eActualCharSet = gsl_getSystemTextEncoding();
const Size aPrefSize( rMtf.GetPrefSize() );
sal_Bool bRop_0_1 = sal_False;
VirtualDevice aSaveVDev;
Color aLineCol( COL_BLACK );
Stack aLineColStack;
rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
//MagicCode schreiben
rOStm << "SVGDI"; // Kennung
nPos = rOStm.Tell();
rOStm << (sal_Int16) 42; // HeaderSize
rOStm << (sal_Int16) 200; // VERSION
rOStm << (sal_Int32) aPrefSize.Width();
rOStm << (sal_Int32) aPrefSize.Height();
ImplWriteMapMode( rOStm, rMtf.GetPrefMapMode() );
// ActionCount wird spaeter geschrieben
nCountPos = rOStm.Tell();
rOStm.SeekRel( 4L );
const sal_Int32 nActCount = ImplWriteActions( rOStm, rMtf, aSaveVDev, bRop_0_1, aLineCol, aLineColStack, eActualCharSet );
const sal_uLong nActPos = rOStm.Tell();
rOStm.Seek( nCountPos );
rOStm << nActCount;
rOStm.Seek( nActPos );
rOStm.SetNumberFormatInt( nOldFormat );
// cleanup push-pop stack if neccessary
for( void* pCol = aLineColStack.Pop(); pCol; pCol = aLineColStack.Pop() )
delete (Color*) pCol;
}
// ------------------------------------------------------------------------
sal_uLong SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
VirtualDevice& rSaveVDev, sal_Bool& rRop_0_1,
Color& rLineCol, Stack& rLineColStack,
rtl_TextEncoding& rActualCharSet )
{
sal_uLong nCount = 0;
for( sal_uLong i = 0, nActionCount = rMtf.GetActionCount(); i < nActionCount; i++ )
{
const MetaAction* pAction = rMtf.GetAction( i );
switch( pAction->GetType() )
{
case( META_PIXEL_ACTION ):
{
MetaPixelAction* pAct = (MetaPixelAction*) pAction;
rOStm << (sal_Int16) GDI_PIXEL_ACTION;
rOStm << (sal_Int32) 18;
rOStm << pAct->GetPoint();
ImplWriteColor( rOStm, pAct->GetColor() );
nCount++;
}
break;
case( META_POINT_ACTION ):
{
MetaPointAction* pAct = (MetaPointAction*) pAction;
rOStm << (sal_Int16) GDI_POINT_ACTION;
rOStm << (sal_Int32) 12;
rOStm << pAct->GetPoint();
nCount++;
}
break;
case( META_LINE_ACTION ):
{
MetaLineAction* pAct = (MetaLineAction*) pAction;
const LineInfo& rInfo = pAct->GetLineInfo();
const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
const bool bLineCap(bFatLine && com::sun::star::drawing::LineCap_BUTT != rInfo.GetLineCap());
const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
if( bFatLine )
{
ImplWritePushAction( rOStm );
ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
if(bLineJoin)
{
rOStm << (sal_Int16) GDI_LINEJOIN_ACTION;
rOStm << (sal_Int32) 6;
rOStm << (sal_Int16) rInfo.GetLineJoin();
}
if(bLineCap)
{
rOStm << (sal_Int16) GDI_LINECAP_ACTION;
rOStm << (sal_Int32) 6;
rOStm << (sal_Int16) rInfo.GetLineCap();
}
}
if(bLineDashDot)
{
rOStm << (sal_Int16) GDI_LINEDASHDOT_ACTION;
rOStm << (sal_Int32) 4 + 16;
rOStm << (sal_Int16)rInfo.GetDashCount();
rOStm << (sal_Int32)rInfo.GetDashLen();
rOStm << (sal_Int16)rInfo.GetDotCount();
rOStm << (sal_Int32)rInfo.GetDotLen();
rOStm << (sal_Int32)rInfo.GetDistance();
}
rOStm << (sal_Int16) GDI_LINE_ACTION;
rOStm << (sal_Int32) 20;
rOStm << pAct->GetStartPoint();
rOStm << pAct->GetEndPoint();
nCount++;
if( bFatLine )
{
ImplWritePopAction( rOStm );
nCount += 3;
if(bLineJoin)
{
nCount += 1;
}
if(bLineCap)
{
nCount += 1;
}
}
if(bLineDashDot)
{
nCount += 1;
}
}
break;
case( META_RECT_ACTION ):
{
MetaRectAction* pAct = (MetaRectAction*) pAction;
rOStm << (sal_Int16) GDI_RECT_ACTION;
rOStm << (sal_Int32) 28;
ImplWriteRect( rOStm, pAct->GetRect() );
rOStm << (sal_Int32) 0;
rOStm << (sal_Int32) 0;
nCount++;
}
break;
case( META_ROUNDRECT_ACTION ):
{
MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction;
rOStm << (sal_Int16) GDI_RECT_ACTION;
rOStm << (sal_Int32) 28;
ImplWriteRect( rOStm, pAct->GetRect() );
rOStm << (sal_Int32) pAct->GetHorzRound();
rOStm << (sal_Int32) pAct->GetVertRound();
nCount++;
}
break;
case( META_ELLIPSE_ACTION ):
{
MetaEllipseAction* pAct = (MetaEllipseAction*) pAction;
rOStm << (sal_Int16) GDI_ELLIPSE_ACTION;
rOStm << (sal_Int32) 20;
ImplWriteRect( rOStm, pAct->GetRect() );
nCount++;
}
break;
case( META_ARC_ACTION ):
{
MetaArcAction* pAct = (MetaArcAction*) pAction;
rOStm << (sal_Int16) GDI_ARC_ACTION;
rOStm << (sal_Int32) 36;
ImplWriteRect( rOStm, pAct->GetRect() );
rOStm << pAct->GetStartPoint();
rOStm << pAct->GetEndPoint();
nCount++;
}
break;
case( META_PIE_ACTION ):
{
MetaPieAction* pAct = (MetaPieAction*) pAction;
rOStm << (sal_Int16) GDI_PIE_ACTION;
rOStm << (sal_Int32) 36;
ImplWriteRect( rOStm, pAct->GetRect() );
rOStm << pAct->GetStartPoint();
rOStm << pAct->GetEndPoint();
nCount++;
}
break;
case( META_CHORD_ACTION ):
{
MetaChordAction* pAct = (MetaChordAction*) pAction;
Polygon aChordPoly( pAct->GetRect(), pAct->GetStartPoint(),
pAct->GetEndPoint(), POLY_CHORD );
const sal_uInt16 nPoints = aChordPoly.GetSize();
rOStm << (sal_Int16) GDI_POLYGON_ACTION;
rOStm << (sal_Int32) ( 8 + ( nPoints << 3 ) );
rOStm << (sal_Int32) nPoints;
for( sal_uInt16 n = 0; n < nPoints; n++ )
rOStm << aChordPoly[ n ];
nCount++;
}
break;
case( META_POLYLINE_ACTION ):
{
// #i102224#
MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction;
// #i102224# Here the evtl. curved nature of Polygon was
// ignored (for all those Years). Adapted to at least write
// a polygon representing the curve as good as possible
Polygon aSimplePoly;
pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
const LineInfo& rInfo = pAct->GetLineInfo();
const sal_uInt16 nPoints(aSimplePoly.GetSize());
const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
const bool bLineCap(bFatLine && com::sun::star::drawing::LineCap_BUTT != rInfo.GetLineCap());
const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
if( bFatLine )
{
ImplWritePushAction( rOStm );
ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
if(bLineJoin)
{
rOStm << (sal_Int16) GDI_LINEJOIN_ACTION;
rOStm << (sal_Int32) 6;
rOStm << (sal_Int16) rInfo.GetLineJoin();
}
if(bLineCap)
{
rOStm << (sal_Int16) GDI_LINECAP_ACTION;
rOStm << (sal_Int32) 6;
rOStm << (sal_Int16) rInfo.GetLineCap();
}
}
if(bLineDashDot)
{
rOStm << (sal_Int16) GDI_LINEDASHDOT_ACTION;
rOStm << (sal_Int32) 4 + 16;
rOStm << (sal_Int16)rInfo.GetDashCount();
rOStm << (sal_Int32)rInfo.GetDashLen();
rOStm << (sal_Int16)rInfo.GetDotCount();
rOStm << (sal_Int32)rInfo.GetDotLen();
rOStm << (sal_Int32)rInfo.GetDistance();
}
rOStm << (sal_Int16) GDI_POLYLINE_ACTION;
rOStm << (sal_Int32) ( 8 + ( nPoints << 3 ) );
rOStm << (sal_Int32) nPoints;
for( sal_uInt16 n = 0; n < nPoints; n++ )
{
rOStm << aSimplePoly[ n ];
}
nCount++;
const PolyPolygon aPolyPolygon(pAct->GetPolygon());
if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
{
nCount++;
}
if( bFatLine )
{
ImplWritePopAction( rOStm );
nCount += 3;
if(bLineJoin)
{
nCount += 1;
}
if(bLineCap)
{
nCount += 1;
}
}
if(bLineDashDot)
{
nCount += 1;
}
}
break;
case( META_POLYGON_ACTION ):
{
MetaPolygonAction* pAct = (MetaPolygonAction*)pAction;
// #i102224# Here the evtl. curved nature of Polygon was
// ignored (for all those Years). Adapted to at least write
// a polygon representing the curve as good as possible
Polygon aSimplePoly;
pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
const sal_uInt16 nPoints(aSimplePoly.GetSize());
rOStm << (sal_Int16) GDI_POLYGON_ACTION;
rOStm << (sal_Int32) ( 8 + ( nPoints << 3 ) );
rOStm << (sal_Int32) nPoints;
for( sal_uInt16 n = 0; n < nPoints; n++ )
rOStm << aSimplePoly[ n ];
nCount++;
const PolyPolygon aPolyPolygon(pAct->GetPolygon());
if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
{
nCount++;
}
}
break;
case( META_POLYPOLYGON_ACTION ):
{
MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction;
ImplWritePolyPolyAction( rOStm, pAct->GetPolyPolygon() );
nCount++;
if(ImplWriteExtendedPolyPolygonAction(rOStm, pAct->GetPolyPolygon(), true))
{
nCount++;
}
}
break;
case( META_TEXT_ACTION ):
{
MetaTextAction* pAct = (MetaTextAction*) pAction;
String aUniText( pAct->GetText() );
ByteString aText( aUniText, rActualCharSet );
const sal_uLong nStrLen = aText.Len();
if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
nCount++;
rOStm << (sal_Int16) GDI_TEXT_ACTION;
rOStm << (sal_Int32) ( 24 + ( nStrLen + 1 ) );
rOStm << pAct->GetPoint();
rOStm << (sal_Int32) pAct->GetIndex();
rOStm << (sal_Int32) pAct->GetLen();
rOStm << (sal_Int32) nStrLen;
rOStm.Write( aText.GetBuffer(), nStrLen + 1 );
nCount++;
}
break;
case( META_TEXTARRAY_ACTION ):
{
MetaTextArrayAction* pAct = (MetaTextArrayAction*)pAction;
ByteString aText( pAct->GetText(), rActualCharSet );
String aUniText( pAct->GetText(), pAct->GetIndex(), pAct->GetLen() );
sal_uLong nAryLen;
sal_uLong nLen = pAct->GetLen();
const sal_uLong nTextLen = aText.Len();
sal_Int32* pDXArray = pAct->GetDXArray();
if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
nCount++;
if( ( nLen + pAct->GetIndex() ) > nTextLen )
{
if( pAct->GetIndex() <= nTextLen )
nLen = nTextLen - pAct->GetIndex();
else
nLen = 0UL;
}
if( !pDXArray || !nLen )
nAryLen = 0;
else
nAryLen = nLen; // #105987# Write out all of DX array
rOStm << (sal_Int16) GDI_TEXTARRAY_ACTION;
rOStm << (sal_Int32) ( 28 + ( nLen + 1 ) + ( nAryLen * 4 ) );
rOStm << pAct->GetPoint();
rOStm << (sal_Int32) 0;
rOStm << (sal_Int32) nLen;
rOStm << (sal_Int32) nLen;
rOStm << (sal_Int32) nAryLen;
rOStm.Write( aText.GetBuffer()+pAct->GetIndex(), nLen + 1 );
for( sal_uLong n = 0UL ; n < nAryLen; n++ )
rOStm << (sal_Int32) pDXArray[ n ];
nCount++;
}
break;
case( META_STRETCHTEXT_ACTION ):
{
MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction;
String aUniText( pAct->GetText() );
ByteString aText( aUniText, rActualCharSet );
const sal_uLong nStrLen = aText.Len();
if ( ImplWriteUnicodeComment( rOStm, aUniText ) )
nCount++;
rOStm << (sal_Int16) GDI_STRETCHTEXT_ACTION;
rOStm << (sal_Int32) ( 28 + ( nStrLen + 1 ) );
rOStm << pAct->GetPoint();
rOStm << (sal_Int32) pAct->GetIndex();
rOStm << (sal_Int32) pAct->GetLen();
rOStm << (sal_Int32) nStrLen;
rOStm << (sal_Int32) pAct->GetWidth();
rOStm.Write( aText.GetBuffer(), nStrLen + 1 );
nCount++;
}
break;
case( META_BMP_ACTION ):
{
MetaBmpAction* pAct = (MetaBmpAction*) pAction;
rOStm << (sal_Int16) GDI_BITMAP_ACTION;
rOStm << (sal_Int32) 12;
rOStm << pAct->GetPoint();
WriteDIB(pAct->GetBitmap(), rOStm, false, true);
nCount++;
}
break;
case( META_BMPSCALE_ACTION ):
{
MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
rOStm << (sal_Int16) GDI_BITMAPSCALE_ACTION;
rOStm << (sal_Int32) 20;
rOStm << pAct->GetPoint();
rOStm << pAct->GetSize();
WriteDIB(pAct->GetBitmap(), rOStm, false, true);
nCount++;
}
break;
case( META_BMPSCALEPART_ACTION ):
{
MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
rOStm << (sal_Int16) GDI_BITMAPSCALEPART_ACTION;
rOStm << (sal_Int32) 36;
rOStm << pAct->GetDestPoint();
rOStm << pAct->GetDestSize();
rOStm << pAct->GetSrcPoint();
rOStm << pAct->GetSrcSize();
WriteDIB(pAct->GetBitmap(), rOStm, false, true);
nCount++;
}
break;
case( META_BMPEX_ACTION ):
{
MetaBmpExAction* pAct = (MetaBmpExAction*) pAction;
const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
rOStm << (sal_Int16) GDI_BITMAP_ACTION;
rOStm << (sal_Int32) 12;
rOStm << pAct->GetPoint();
WriteDIB(aBmp, rOStm, false, true);
nCount++;
}
break;
case( META_BMPEXSCALE_ACTION ):
{
MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction;
const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
rOStm << (sal_Int16) GDI_BITMAPSCALE_ACTION;
rOStm << (sal_Int32) 20;
rOStm << pAct->GetPoint();
rOStm << pAct->GetSize();
WriteDIB(aBmp, rOStm, false, true);
nCount++;
}
break;
case( META_BMPEXSCALEPART_ACTION ):
{
MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction;
const Bitmap aBmp( Graphic( pAct->GetBitmapEx() ).GetBitmap() );
rOStm << (sal_Int16) GDI_BITMAPSCALEPART_ACTION;
rOStm << (sal_Int32) 36;
rOStm << pAct->GetDestPoint();
rOStm << pAct->GetDestSize();
rOStm << pAct->GetSrcPoint();
rOStm << pAct->GetSrcSize();
WriteDIB(aBmp, rOStm, false, true);
nCount++;
}
break;
case( META_GRADIENT_ACTION ):
{
MetaGradientAction* pAct = (MetaGradientAction*) pAction;
const Gradient& rGrad = pAct->GetGradient();
rOStm << (sal_Int16) GDI_GRADIENT_ACTION;
rOStm << (sal_Int32) 46;
ImplWriteRect( rOStm, pAct->GetRect() );
rOStm << (sal_Int16) rGrad.GetStyle();
ImplWriteColor( rOStm, rGrad.GetStartColor() );
ImplWriteColor( rOStm, rGrad.GetEndColor() );
rOStm << (sal_Int16) rGrad.GetAngle();
rOStm << (sal_Int16) rGrad.GetBorder();
rOStm << (sal_Int16) rGrad.GetOfsX();
rOStm << (sal_Int16) rGrad.GetOfsY();
rOStm << (sal_Int16) rGrad.GetStartIntensity();
rOStm << (sal_Int16) rGrad.GetEndIntensity();
nCount++;
}
break;
case( META_GRADIENTEX_ACTION ):
{
const MetaGradientExAction* pA = (MetaGradientExAction*) pAction;
sal_uLong nOldPos, nNewPos;
// write RefPoint comment
rOStm << (sal_Int16) GDI_GRADIENTEX_COMMENT;
// we'll write the ActionSize later
nOldPos = rOStm.Tell();
rOStm.SeekRel( 4 );
// write data
rOStm << pA->GetPolyPolygon() << pA->GetGradient();
rOStm << (sal_Int32) 0; // number of actions that follow this comment
// calculate and write ActionSize of comment
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) ( nNewPos - nOldPos );
rOStm.Seek( nNewPos );
nCount++;
}
break;
case( META_WALLPAPER_ACTION ):
{
MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction;
const Color& rColor = pAct->GetWallpaper().GetColor();
ImplWritePushAction( rOStm );
ImplWriteLineColor( rOStm, rColor, 1 );
ImplWriteFillColor( rOStm, rColor, 1 );
rOStm << (sal_Int16) GDI_RECT_ACTION;
rOStm << (sal_Int32) 28;
ImplWriteRect( rOStm, pAct->GetRect() );
rOStm << (sal_Int32) 0;
rOStm << (sal_Int32) 0;
ImplWritePopAction( rOStm );
nCount += 5;
}
break;
case( META_CLIPREGION_ACTION ):
{
MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction;
const Region& rRegion = pAct->GetRegion();
Rectangle aClipRect;
rOStm << (sal_Int16) GDI_CLIPREGION_ACTION;
rOStm << (sal_Int32) 24;
if( pAct->IsClipping() )
{
aClipRect = rRegion.GetBoundRect();
rOStm << (sal_Int16) 1;
}
else
rOStm << (sal_Int16) 0;
rOStm << (sal_Int16) 0;
ImplWriteRect( rOStm, aClipRect );
if( pAct->IsClipping() )
ImplWriteRect( rOStm, aClipRect );
nCount++;
}
break;
case( META_ISECTRECTCLIPREGION_ACTION ):
{
MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction;
rOStm << (sal_Int16) GDI_ISECTCLIPREGION_ACTION;
rOStm << (sal_Int32) 20;
rOStm << pAct->GetRect();
nCount++;
}
break;
case( META_MOVECLIPREGION_ACTION ):
{
MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction;
rOStm << (sal_Int16) GDI_MOVECLIPREGION_ACTION;
rOStm << (sal_Int32) 12;
rOStm << (sal_Int32) pAct->GetHorzMove();
rOStm << (sal_Int32) pAct->GetVertMove();
nCount++;
}
break;
case( META_LINECOLOR_ACTION ):
{
MetaLineColorAction* pAct = (MetaLineColorAction*) pAction;
ImplWriteLineColor( rOStm, rLineCol = pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
nCount++;
}
break;
case( META_FILLCOLOR_ACTION ):
{
MetaFillColorAction* pAct = (MetaFillColorAction*) pAction;
ImplWriteFillColor( rOStm, pAct->GetColor(), pAct->IsSetting() ? 1 : 0 );
nCount++;
}
break;
case( META_FONT_ACTION ):
{
rSaveVDev.SetFont( ( (MetaFontAction*) pAction )->GetFont() );
ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
nCount++;
}
break;
case( META_TEXTCOLOR_ACTION ):
{
Font aSaveFont( rSaveVDev.GetFont() );
aSaveFont.SetColor( ( (MetaTextColorAction*) pAction )->GetColor() );
rSaveVDev.SetFont( aSaveFont );
ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
nCount++;
}
break;
case( META_TEXTFILLCOLOR_ACTION ):
{
MetaTextFillColorAction* pAct = (MetaTextFillColorAction*) pAction;
Font aSaveFont( rSaveVDev.GetFont() );
if( pAct->IsSetting() )
aSaveFont.SetFillColor( pAct->GetColor() );
else
aSaveFont.SetFillColor( Color( COL_TRANSPARENT ) );
rSaveVDev.SetFont( aSaveFont );
ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
nCount++;
}
break;
case( META_TEXTALIGN_ACTION ):
{
Font aSaveFont( rSaveVDev.GetFont() );
aSaveFont.SetAlign( ( (MetaTextAlignAction*) pAction )->GetTextAlign() );
rSaveVDev.SetFont( aSaveFont );
ImplWriteFont( rOStm, rSaveVDev.GetFont(), rActualCharSet );
nCount++;
}
break;
case( META_MAPMODE_ACTION ):
{
MetaMapModeAction* pAct = (MetaMapModeAction*) pAction;
rOStm << (sal_Int16) GDI_MAPMODE_ACTION;
rOStm << (sal_Int32) 30;
ImplWriteMapMode( rOStm, pAct->GetMapMode() );
nCount++;
}
break;
case( META_PUSH_ACTION ):
{
ImplWritePushAction( rOStm );
rLineColStack.Push( new Color( rLineCol ) );
rSaveVDev.Push();
nCount++;
}
break;
case( META_POP_ACTION ):
{
Color* pCol = (Color*) rLineColStack.Pop();
if( pCol )
{
rLineCol = *pCol;
delete pCol;
}
ImplWritePopAction( rOStm );
rSaveVDev.Pop();
nCount++;
}
break;
case( META_RASTEROP_ACTION ):
{
MetaRasterOpAction* pAct = (MetaRasterOpAction*) pAction;
if( ( pAct->GetRasterOp() != ROP_0 ) && ( pAct->GetRasterOp() != ROP_1 ) )
{
sal_Int16 nRasterOp;
// Falls vorher ROP_0/1 gesetzt war, alten
// Zustand durch Pop erst wieder herstellen
if( rRop_0_1 )
{
ImplWritePopAction( rOStm );
rSaveVDev.Pop();
rRop_0_1 = sal_False;
nCount++;
}
switch( pAct->GetRasterOp() )
{
case( ROP_OVERPAINT ) : nRasterOp = 0; break;
case( ROP_XOR ) : nRasterOp = 4; break;
case( ROP_INVERT ): nRasterOp = 1; break;
default: nRasterOp = 0; break;
}
ImplWriteRasterOpAction( rOStm, nRasterOp );
nCount++;
}
else
{
ImplWritePushAction( rOStm );
rSaveVDev.Push();
if( pAct->GetRasterOp() == ROP_0 )
{
ImplWriteLineColor( rOStm, COL_BLACK, 1 );
ImplWriteFillColor( rOStm, COL_BLACK, 1 );
}
else
{
ImplWriteLineColor( rOStm, COL_WHITE, 1 );
ImplWriteFillColor( rOStm, COL_WHITE, 1 );
}
ImplWriteRasterOpAction( rOStm, 0 );
rRop_0_1 = sal_True;
nCount += 4;
}
}
break;
case( META_TRANSPARENT_ACTION ):
{
const PolyPolygon& rPolyPoly = ( (MetaTransparentAction*) pAction )->GetPolyPolygon();
const sal_Int16 nTrans = ( (MetaTransparentAction*) pAction )->GetTransparence();
const sal_Int16 nBrushStyle = ( nTrans < 38 ) ? 8 : ( nTrans < 63 ) ? 9 : 10;
sal_uLong nOldPos, nNewPos;
// write transparence comment
rOStm << (sal_Int16) GDI_TRANSPARENT_COMMENT;
// we'll write the ActionSize later
nOldPos = rOStm.Tell();
rOStm.SeekRel( 4 );
// write comment data
rOStm << rPolyPoly;
rOStm << nTrans;
rOStm << (sal_Int32) 15; // number of actions that follow this comment
// calculate and write ActionSize of comment
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) ( nNewPos - nOldPos );
rOStm.Seek( nNewPos );
{
// write actions for transparence
ImplWritePushAction( rOStm );
{
ImplWriteRasterOpAction( rOStm, 4 );
ImplWritePolyPolyAction( rOStm, rPolyPoly );
ImplWritePushAction( rOStm );
{
ImplWriteRasterOpAction( rOStm, 2 );
ImplWriteFillColor( rOStm, COL_BLACK, nBrushStyle );
ImplWritePolyPolyAction( rOStm, rPolyPoly );
}
ImplWritePopAction( rOStm );
ImplWriteRasterOpAction( rOStm, 4 );
ImplWritePolyPolyAction( rOStm, rPolyPoly );
}
ImplWritePopAction( rOStm );
ImplWritePushAction( rOStm );
{
ImplWriteFillColor( rOStm, Color(), 0 );
ImplWritePolyPolyAction( rOStm, rPolyPoly );
}
ImplWritePopAction( rOStm );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
nCount += 15;
#endif
}
nCount++;
}
break;
case( META_FLOATTRANSPARENT_ACTION ):
{
const MetaFloatTransparentAction* pA = (MetaFloatTransparentAction*) pAction;
const GDIMetaFile& rTransMtf = pA->GetGDIMetaFile();
const Point& rPos = pA->GetPoint();
const Size& rSize = pA->GetSize();
const Gradient& rGradient = pA->GetGradient();
sal_uLong nOldPos, nNewPos;
// write RefPoint comment
rOStm << (sal_Int16) GDI_FLOATTRANSPARENT_COMMENT;
// we'll write the ActionSize later
nOldPos = rOStm.Tell();
rOStm.SeekRel( 4 );
// write comment data
rOStm << rTransMtf << rPos << rSize << rGradient;
// calculate and write ActionSize of comment
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) ( nNewPos - nOldPos + 4 );
rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
{
// write actions for float transparence
sal_uLong nAddCount;
GDIMetaFile aMtf( rTransMtf );
const Size aSrcSize( rTransMtf.GetPrefSize() );
Point aSrcPt( rTransMtf.GetPrefMapMode().GetOrigin() );
const double fScaleX = aSrcSize.Width() ? (double) rSize.Width() / aSrcSize.Width() : 1.0;
const double fScaleY = aSrcSize.Height() ? (double) rSize.Height() / aSrcSize.Height() : 1.0;
long nMoveX, nMoveY;
if( fScaleX != 1.0 || fScaleY != 1.0 )
{
aMtf.Scale( fScaleX, fScaleY );
aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
}
nMoveX = rPos.X() - aSrcPt.X(), nMoveY = rPos.Y() - aSrcPt.Y();
if( nMoveX || nMoveY )
aMtf.Move( nMoveX, nMoveY );
nAddCount = ImplWriteActions( rOStm, aMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) nAddCount;
rOStm.Seek( nNewPos );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
nCount += nAddCount;
#endif
}
nCount++;
}
break;
case( META_HATCH_ACTION ):
{
const MetaHatchAction* pA = (MetaHatchAction*) pAction;
const PolyPolygon& rPolyPoly = pA->GetPolyPolygon();
const Hatch& rHatch = pA->GetHatch();
sal_uLong nOldPos, nNewPos, nAddCount;
// write hatch comment
rOStm << (sal_Int16) GDI_HATCH_COMMENT;
// we'll write the ActionSize later
nOldPos = rOStm.Tell();
rOStm.SeekRel( 4 );
// write comment data
rOStm << rPolyPoly;
rOStm << rHatch;
// calculate and write ActionSize of comment
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) ( nNewPos - nOldPos + 4 );
rOStm.Seek( ( nOldPos = nNewPos ) + 4 );
{
// write actions for hatch
VirtualDevice aVDev;
GDIMetaFile aTmpMtf;
aVDev.AddHatchActions( rPolyPoly, rHatch, aTmpMtf );
nAddCount = ImplWriteActions( rOStm, aTmpMtf, rSaveVDev, rRop_0_1, rLineCol, rLineColStack, rActualCharSet );
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) nAddCount;
rOStm.Seek( nNewPos );
#ifdef CVTSVM_WRITE_SUBACTIONCOUNT
nCount += nAddCount;
#endif
}
nCount++;
}
break;
case( META_REFPOINT_ACTION ):
{
const MetaRefPointAction* pA = (MetaRefPointAction*) pAction;
const Point& rRefPoint = pA->GetRefPoint();
const sal_Bool bSet = pA->IsSetting();
sal_uLong nOldPos, nNewPos;
// write RefPoint comment
rOStm << (sal_Int16) GDI_REFPOINT_COMMENT;
// we'll write the ActionSize later
nOldPos = rOStm.Tell();
rOStm.SeekRel( 4 );
// write data
rOStm << rRefPoint << bSet;
rOStm << (sal_Int32) 0; // number of actions that follow this comment
// calculate and write ActionSize of comment
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) ( nNewPos - nOldPos );
rOStm.Seek( nNewPos );
nCount++;
}
break;
case( META_TEXTLINECOLOR_ACTION ):
{
const MetaTextLineColorAction* pA = (MetaTextLineColorAction*) pAction;
const Color& rColor = pA->GetColor();
const sal_Bool bSet = pA->IsSetting();
sal_uLong nOldPos, nNewPos;
// write RefPoint comment
rOStm << (sal_Int16) GDI_TEXTLINECOLOR_COMMENT;
// we'll write the ActionSize later
nOldPos = rOStm.Tell();
rOStm.SeekRel( 4 );
// write data
rOStm << rColor << bSet;
rOStm << (sal_Int32) 0; // number of actions that follow this comment
// calculate and write ActionSize of comment
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) ( nNewPos - nOldPos );
rOStm.Seek( nNewPos );
nCount++;
}
break;
#if 0
case( META_OVERLINECOLOR_ACTION ):
break;
#endif
case( META_TEXTLINE_ACTION ):
{
const MetaTextLineAction* pA = (MetaTextLineAction*) pAction;
const Point& rStartPt = pA->GetStartPoint();
const long nWidth = pA->GetWidth();
const FontStrikeout eStrikeout = pA->GetStrikeout();
const FontUnderline eUnderline = pA->GetUnderline();
sal_uLong nOldPos, nNewPos;
// write RefPoint comment
rOStm << (sal_Int16) GDI_TEXTLINE_COMMENT;
// we'll write the ActionSize later
nOldPos = rOStm.Tell();
rOStm.SeekRel( 4 );
// write data
rOStm << rStartPt << nWidth <<
static_cast<sal_uInt32>(eStrikeout) <<
static_cast<sal_uInt32>(eUnderline);
rOStm << (sal_Int32) 0; // number of actions that follow this comment
// calculate and write ActionSize of comment
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) ( nNewPos - nOldPos );
rOStm.Seek( nNewPos );
nCount++;
}
break;
case( META_EPS_ACTION ):
break;
case( META_COMMENT_ACTION ):
{
const MetaCommentAction* pA = (MetaCommentAction*) pAction;
const sal_uInt32 nDataSize = pA->GetDataSize();
sal_uLong nOldPos, nNewPos;
// write RefPoint comment
rOStm << (sal_Int16) GDI_COMMENT_COMMENT;
// we'll write the ActionSize later
nOldPos = rOStm.Tell();
rOStm.SeekRel( 4 );
// write data
rOStm << pA->GetComment() << pA->GetValue() << nDataSize;
if( nDataSize )
rOStm.Write( pA->GetData(), nDataSize );
rOStm << (sal_Int32) 0; // number of actions that follow this comment
// calculate and write ActionSize of comment
nNewPos = rOStm.Tell();
rOStm.Seek( nOldPos );
rOStm << (sal_Int32) ( nNewPos - nOldPos );
rOStm.Seek( nNewPos );
nCount++;
}
break;
#ifdef DBG_UTIL
default:
{
ByteString aStr( "Missing implementation for Action#: " );
aStr += ByteString::CreateFromInt32( pAction->GetType() );
aStr += '!';
DBG_ERROR( aStr.GetBuffer() );
}
break;
#endif
/*
case( META_TEXTRECT_ACTION ):
{
MetaTextRectAction* pAct = (MetaTextRectAction*) pAction;
rOStm << ;
rOStm << ;
nCount++;
}
break;
*/
/*
case( META_MASK_ACTION ):
{
MetaMaskAction* pAct = (MetaMaskAction*) pAction;
rOStm << ;
rOStm << ;
nCount++;
}
break;
*/
/*
case( META_MASKSCALE_ACTION ):
{
MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction;
rOStm << ;
rOStm << ;
nCount++;
}
break;
*/
/*
case( META_MASKSCALEPART_ACTION ):
{
MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
rOStm << ;
rOStm << ;
nCount++;
}
break;
*/
/*
case( META_ISECTREGIONCLIPREGION_ACTION ):
{
MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction;
rOStm << ;
rOStm << ;
nCount++;
}
break;
*/
}
}
return nCount;
}