[ooo-build-commit] .: 18 commits - canvas/source cppcanvas/prj cppcanvas/source cppcanvas/util svtools/source vcl/aqua vcl/inc vcl/source vcl/unx vcl/win
Radek DoulÃk
rodo at kemper.freedesktop.org
Wed Sep 15 08:56:56 PDT 2010
canvas/source/vcl/canvashelper.cxx | 8
cppcanvas/prj/build.lst | 1
cppcanvas/prj/d.lst | 1
cppcanvas/source/inc/implrenderer.hxx | 139 ++
cppcanvas/source/mtfrenderer/emfplus.cxx | 1614 ++++++++++++++++++++++++++
cppcanvas/source/mtfrenderer/implrenderer.cxx | 34
cppcanvas/source/mtfrenderer/makefile.mk | 1
cppcanvas/source/uno/exports.dxp | 3
cppcanvas/source/uno/exports.map | 9
cppcanvas/source/uno/makefile.mk | 62
cppcanvas/source/uno/uno_mtfrenderer.cxx | 80 +
cppcanvas/source/uno/uno_mtfrenderer.hxx | 60
cppcanvas/util/makefile.mk | 2
svtools/source/filter.vcl/wmf/enhwmf.cxx | 194 +++
svtools/source/filter.vcl/wmf/winmtf.cxx | 73 +
svtools/source/filter.vcl/wmf/winmtf.hxx | 49
svtools/source/filter.vcl/wmf/winwmf.cxx | 4
vcl/aqua/inc/salbmp.h | 3
vcl/aqua/source/gdi/salbmp.cxx | 7
vcl/inc/vcl/gdimtf.hxx | 30
vcl/inc/vcl/salbmp.hxx | 5
vcl/source/gdi/gdimtf.cxx | 233 +++
vcl/source/gdi/metaact.cxx | 27
vcl/unx/headless/svpbmp.cxx | 5
vcl/unx/headless/svpbmp.hxx | 3
vcl/unx/inc/salbmp.h | 7
vcl/unx/source/gdi/salbmp.cxx | 71 +
vcl/win/inc/salbmp.h | 3
vcl/win/source/gdi/salbmp.cxx | 7
29 files changed, 2697 insertions(+), 38 deletions(-)
New commits:
commit f4eef390c79e965271541f086d2625a5e209a505
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 12:10:46 2010 +0200
svtools-wmf-clean-warnings.diff: emf+ import - clean the code a bit
to avoid compiler warnings
diff --git a/svtools/source/filter.vcl/wmf/enhwmf.cxx b/svtools/source/filter.vcl/wmf/enhwmf.cxx
index ef6ef5e..f0f1c91 100644
--- a/svtools/source/filter.vcl/wmf/enhwmf.cxx
+++ b/svtools/source/filter.vcl/wmf/enhwmf.cxx
@@ -262,7 +262,7 @@ void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, sal_Bool& bHaveDC)
void *buffer = malloc( length );
- int count = 0, next, pos = pWMF->Tell();
+ int pos = pWMF->Tell();
pOut->PassEMFPlus( buffer, pWMF->Read( buffer, length ) );
pWMF->Seek( pos );
@@ -318,14 +318,10 @@ void EnhWMFReader::ReadGDIComment()
break;
}
case 3: {
- sal_uInt32 x, y, w, h;
-
EMFP_DEBUG(printf ("\t\tENDGROUP\n"));
break;
}
case 0x40000004: {
- sal_uInt32 x, y, w, h;
-
EMFP_DEBUG(printf ("\t\tMULTIFORMATS\n"));
break;
}
@@ -397,10 +393,11 @@ BOOL EnhWMFReader::ReadEnhWMF()
if( id == 0x2B464D45 && nRecSize >= 12 )
ReadEMFPlusComment( length, bHaveDC );
// GDIC comment, doesn't do anything useful yet => enabled only for debug
- else if( id == 0x43494447 && nRecSize >= 12 )
+ else if( id == 0x43494447 && nRecSize >= 12 ) {
EMFP_DEBUG(ReadGDIComment());
- else
+ } else {
EMFP_DEBUG(printf ("\t\tunknown id: 0x%x\n", id));
+ }
}
} else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
@@ -1339,7 +1336,6 @@ BOOL EnhWMFReader::ReadEnhWMF()
case EMR_CREATEDIBPATTERNBRUSHPT :
{
- static int count = 0;
UINT32 nStart = pWMF->Tell() - 8;
Bitmap aBitmap;
diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx
index 019f968..5545da3 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.hxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.hxx
@@ -390,8 +390,8 @@ struct WinMtfFillStyle
};
WinMtfFillStyle( Bitmap& rBmp ) :
- aBmp ( rBmp ),
- aType( FillStylePattern )
+ aType( FillStylePattern ),
+ aBmp ( rBmp )
{
};
commit 86647d4ee808f8c62fc556241bf4bf9647924022
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 12:09:15 2010 +0200
wmf-pattern-brush.diff: emf+ import - added pattern brushes support to wmf
n#232232
diff --git a/svtools/source/filter.vcl/wmf/enhwmf.cxx b/svtools/source/filter.vcl/wmf/enhwmf.cxx
index 58ad0d6..ef6ef5e 100644
--- a/svtools/source/filter.vcl/wmf/enhwmf.cxx
+++ b/svtools/source/filter.vcl/wmf/enhwmf.cxx
@@ -1008,7 +1008,10 @@ BOOL EnhWMFReader::ReadEnhWMF()
Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
aBitmap.Crop( aCropRect );
}
- aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND );
+ /* Pseudocomment to add more context so that make patch.unapply
+ * works better. Ha!
+ */
+ aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ), LIST_APPEND );
}
}
}
@@ -1062,7 +1065,8 @@ BOOL EnhWMFReader::ReadEnhWMF()
Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
aBitmap.Crop( aCropRect );
}
- aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND );
+ /* Another pseudocomment to make make patch.unapply work better */
+ aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ), LIST_APPEND );
}
}
}
@@ -1333,6 +1337,54 @@ BOOL EnhWMFReader::ReadEnhWMF()
}
break;
+ case EMR_CREATEDIBPATTERNBRUSHPT :
+ {
+ static int count = 0;
+ UINT32 nStart = pWMF->Tell() - 8;
+ Bitmap aBitmap;
+
+ *pWMF >> nIndex;
+
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ UINT32 usage, offBmi, cbBmi, offBits, cbBits;
+
+ *pWMF >> usage;
+ *pWMF >> offBmi;
+ *pWMF >> cbBmi;
+ *pWMF >> offBits;
+ *pWMF >> cbBits;
+
+ if ( (cbBits > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBits < cbBmi) )
+ bStatus = FALSE;
+ else if ( offBmi )
+ {
+ UINT32 nSize = cbBmi + cbBits + 14;
+ if ( nSize <= ( nEndPos - nStartPos ) )
+ {
+ char* pBuf = new char[ nSize ];
+
+ SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
+ aTmp.ObjectOwnsMemory( TRUE );
+ aTmp << (BYTE)'B'
+ << (BYTE)'M'
+ << (UINT32)cbBits
+ << (UINT16)0
+ << (UINT16)0
+ << (UINT32)cbBmi + 14;
+ pWMF->Seek( nStart + offBmi );
+ pWMF->Read( pBuf + 14, cbBmi );
+ pWMF->Seek( nStart + offBits );
+ pWMF->Read( pBuf + 14 + cbBmi, cbBits );
+ aTmp.Seek( 0 );
+ aBitmap.Read( aTmp, TRUE );
+ }
+ }
+ }
+
+ pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( aBitmap ) );
+ }
+ break;
#ifdef WIN_MTF_ASSERT
default : WinMtfAssertHandler( "Unknown Meta Action" ); break;
@@ -1352,7 +1404,6 @@ BOOL EnhWMFReader::ReadEnhWMF()
case EMR_ANGLEARC : WinMtfAssertHandler( "AngleArc" ); break;
case EMR_SETCOLORADJUSTMENT : WinMtfAssertHandler( "SetColorAdjustment" ); break;
case EMR_POLYDRAW16 : WinMtfAssertHandler( "PolyDraw16" ); break;
- case EMR_CREATEDIBPATTERNBRUSHPT : WinMtfAssertHandler( "CreateDibPatternBrushPt" ); break;
case EMR_POLYTEXTOUTA : WinMtfAssertHandler( "PolyTextOutA" ); break;
case EMR_POLYTEXTOUTW : WinMtfAssertHandler( "PolyTextOutW" ); break;
case EMR_CREATECOLORSPACE : WinMtfAssertHandler( "CreateColorSpace" ); break;
diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx
index b93acf4..791db60 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.cxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.cxx
@@ -31,6 +31,7 @@
#include "winmtf.hxx"
#include <vcl/metaact.hxx>
+#include <vcl/graphictools.hxx>
#include <vcl/metric.hxx>
#include <rtl/tencinfo.h>
@@ -1041,7 +1042,8 @@ void WinMtfOutput::UpdateFillStyle()
if (!( maLatestFillStyle == maFillStyle ) )
{
maLatestFillStyle = maFillStyle;
- mpGDIMetaFile->AddAction( new MetaFillColorAction( maFillStyle.aFillColor, !maFillStyle.bTransparent ) );
+ if (maFillStyle.aType == FillStyleSolid)
+ mpGDIMetaFile->AddAction( new MetaFillColorAction( maFillStyle.aFillColor, !maFillStyle.bTransparent ) );
}
}
@@ -1369,7 +1371,35 @@ void WinMtfOutput::DrawPolygon( Polygon& rPolygon, sal_Bool bRecordPath )
else
{
UpdateLineStyle();
- mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
+
+ if (maLatestFillStyle.aType != FillStylePattern)
+ mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
+ else {
+ SvtGraphicFill aFill = SvtGraphicFill( PolyPolygon( rPolygon ),
+ Color(),
+ 0.0,
+ SvtGraphicFill::fillNonZero,
+ SvtGraphicFill::fillTexture,
+ SvtGraphicFill::Transform(),
+ true,
+ SvtGraphicFill::hatchSingle,
+ Color(),
+ SvtGraphicFill::gradientLinear,
+ Color(),
+ Color(),
+ 0,
+ Graphic (maLatestFillStyle.aBmp) );
+
+ SvMemoryStream aMemStm;
+
+ aMemStm << aFill;
+
+ mpGDIMetaFile->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_BEGIN", 0,
+ static_cast<const BYTE*>(aMemStm.GetData()),
+ aMemStm.Seek( STREAM_SEEK_TO_END ) ) );
+ mpGDIMetaFile->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_END" ) );
+ }
+
}
}
}
@@ -1712,7 +1742,7 @@ void WinMtfOutput::ResolveBitmapActions( List& rSaveList )
if ( ( nRasterOperation & 0xaa ) != ( ( nRasterOperation & 0x55 ) << 1 ) )
nUsed |= 4; // destination is used
- if ( (nUsed & 1) && (( nUsed & 2 ) == 0) )
+ if ( (nUsed & 1) && (( nUsed & 2 ) == 0) && nWinRop != PATINVERT )
{ // patterns aren't well supported yet
sal_uInt32 nOldRop = SetRasterOp( ROP_OVERPAINT ); // in this case nRasterOperation is either 0 or 0xff
UpdateFillStyle();
diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx
index aed3c93..019f968 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.hxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.hxx
@@ -364,10 +364,17 @@ struct WinMtfFontStyle
// -----------------------------------------------------------------------------
+typedef enum {
+ FillStyleSolid,
+ FillStylePattern
+} WinMtfFillStyleType;
+
struct WinMtfFillStyle
{
- Color aFillColor;
- BOOL bTransparent;
+ Color aFillColor;
+ BOOL bTransparent;
+ WinMtfFillStyleType aType;
+ Bitmap aBmp;
WinMtfFillStyle() :
aFillColor ( Color( COL_BLACK ) ),
@@ -377,16 +384,23 @@ struct WinMtfFillStyle
WinMtfFillStyle( const Color& rColor, BOOL bTrans = FALSE ) :
aFillColor ( rColor ),
- bTransparent( bTrans )
+ bTransparent( bTrans ),
+ aType ( FillStyleSolid )
+ {
+ };
+
+ WinMtfFillStyle( Bitmap& rBmp ) :
+ aBmp ( rBmp ),
+ aType( FillStylePattern )
{
};
BOOL operator==( const WinMtfFillStyle& rStyle )
- { return ( ( aFillColor == rStyle.aFillColor ) && ( bTransparent == rStyle.bTransparent ) ); };
+ { return ( ( aFillColor == rStyle.aFillColor ) && ( bTransparent == rStyle.bTransparent ) && ( aType == rStyle.aType ) ); };
BOOL operator==( WinMtfFillStyle* pStyle )
- { return ( ( aFillColor == pStyle->aFillColor ) && ( bTransparent == pStyle->bTransparent ) ); };
- void operator=( const WinMtfFillStyle& rStyle ) { aFillColor = rStyle.aFillColor; bTransparent = rStyle.bTransparent; };
- void operator=( WinMtfFillStyle* pStyle ) { aFillColor = pStyle->aFillColor; bTransparent = pStyle->bTransparent; };
+ { return ( ( aFillColor == pStyle->aFillColor ) && ( bTransparent == pStyle->bTransparent ) && ( aType == pStyle->aType ) ); };
+ void operator=( const WinMtfFillStyle& rStyle ) { aFillColor = rStyle.aFillColor; bTransparent = rStyle.bTransparent; aBmp = rStyle.aBmp; aType = rStyle.aType; };
+ void operator=( WinMtfFillStyle* pStyle ) { aFillColor = pStyle->aFillColor; bTransparent = pStyle->bTransparent; aBmp = pStyle->aBmp; aType = pStyle->aType; };
};
// -----------------------------------------------------------------------------
@@ -478,12 +492,13 @@ typedef ::boost::shared_ptr< SaveStruct > SaveStructPtr;
struct BSaveStruct
{
- Bitmap aBmp;
- Rectangle aOutRect;
- UINT32 nWinRop;
+ Bitmap aBmp;
+ Rectangle aOutRect;
+ UINT32 nWinRop;
+ WinMtfFillStyle aStyle;
- BSaveStruct( const Bitmap& rBmp, const Rectangle& rOutRect, UINT32 nRop ) :
- aBmp( rBmp ), aOutRect( rOutRect ), nWinRop( nRop ){};
+ BSaveStruct( const Bitmap& rBmp, const Rectangle& rOutRect, UINT32 nRop, WinMtfFillStyle& rStyle ) :
+ aBmp( rBmp ), aOutRect( rOutRect ), nWinRop( nRop ), aStyle ( rStyle ){};
};
// -----------------------------------------------------------------------------
@@ -638,6 +653,7 @@ class WinMtfOutput
void DeleteObject( INT32 nIndex );
void SelectObject( INT32 nIndex );
CharSet GetCharSet(){ return maFont.GetCharSet(); };
+ WinMtfFillStyle& GetFillStyle () { return maFillStyle; }
void SetFont( const Font& rFont );
const Font& GetFont() const;
void SetTextLayoutMode( const sal_uInt32 nLayoutMode );
diff --git a/svtools/source/filter.vcl/wmf/winwmf.cxx b/svtools/source/filter.vcl/wmf/winwmf.cxx
index a549c60..1bad4ec 100644
--- a/svtools/source/filter.vcl/wmf/winwmf.cxx
+++ b/svtools/source/filter.vcl/wmf/winwmf.cxx
@@ -569,7 +569,7 @@ void WMFReader::ReadRecordParams( USHORT nFunc )
aBmp.Crop( aCropRect );
}
Rectangle aDestRect( aPoint, Size( nSxe, nSye ) );
- aBmpSaveList.Insert( new BSaveStruct( aBmp, aDestRect, nWinROP ), LIST_APPEND );
+ aBmpSaveList.Insert( new BSaveStruct( aBmp, aDestRect, nWinROP, pOut->GetFillStyle () ), LIST_APPEND );
}
}
}
@@ -619,7 +619,7 @@ void WMFReader::ReadRecordParams( USHORT nFunc )
Rectangle aCropRect( Point( nSx, nSy ), Size( nSxe, nSye ) );
aBmp.Crop( aCropRect );
}
- aBmpSaveList.Insert( new BSaveStruct( aBmp, aDestRect, nWinROP ), LIST_APPEND );
+ aBmpSaveList.Insert( new BSaveStruct( aBmp, aDestRect, nWinROP, pOut->GetFillStyle () ), LIST_APPEND );
}
}
}
commit 69665388094d8ee9795242ef1d712e4650b8a0b2
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:53:32 2010 +0200
emf+-cppcanvas-replace-poly-factory-and-clean.diff: emf+ import
- replace deprecated polygon factory and clean the code a bit
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index 89c918d..4e2ddb1 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -29,6 +29,7 @@
#include <vcl/metaact.hxx>
#include <svtools/filter.hxx>
#include <basegfx/tools/canvastools.hxx>
+#include <basegfx/tools/gradienttools.hxx>
#include <basegfx/tools/tools.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/point/b2dpoint.hxx>
@@ -44,7 +45,6 @@
#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/rendering/TexturingMode.hpp>
-#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp>
#include <bitmapaction.hxx>
#include <implrenderer.hxx>
@@ -126,7 +126,7 @@ namespace cppcanvas
public:
EMFPPath (sal_Int32 _nPoints, bool bLines = false)
{
- if( _nPoints<0 || _nPoints>SAL_MAX_INT32/(2*sizeof(float)) )
+ if( _nPoints<0 || sal_uInt32(_nPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
_nPoints = SAL_MAX_INT32/(2*sizeof(float));
nPoints = _nPoints;
pPoints = new float [nPoints*2];
@@ -163,8 +163,6 @@ namespace cppcanvas
if (pPointTypes)
for (int i = 0; i < nPoints; i ++) {
- UINT8 pathType;
-
s >> pPointTypes [i];
EMFP_DEBUG (printf ("EMF+\tpoint type: %x\n", pPointTypes [i]));
}
@@ -179,7 +177,6 @@ namespace cppcanvas
::basegfx::B2DPolyPolygon& GetPolygon (ImplRenderer& rR, bool bMapIt = true)
{
::basegfx::B2DPolygon polygon;
- sal_Int32 points = nPoints;
aPolygon.clear ();
@@ -270,7 +267,7 @@ namespace cppcanvas
EMFP_DEBUG (printf ("EMF+\theader: 0x%08x parts: %d\n", header, parts));
if (parts) {
- if( parts<0 || parts>SAL_MAX_INT32/sizeof(sal_Int32) )
+ if( parts<0 || sal_uInt32(parts)>SAL_MAX_INT32/sizeof(sal_Int32) )
parts = SAL_MAX_INT32/sizeof(sal_Int32);
combineMode = new sal_Int32 [parts];
@@ -384,7 +381,7 @@ namespace cppcanvas
s >> surroundColorsNumber;
EMFP_DEBUG (printf ("EMF+\tsurround colors: %d\n", surroundColorsNumber));
- if( surroundColorsNumber<0 || surroundColorsNumber>SAL_MAX_INT32/sizeof(::Color) )
+ if( surroundColorsNumber<0 || sal_uInt32(surroundColorsNumber)>SAL_MAX_INT32/sizeof(::Color) )
surroundColorsNumber = SAL_MAX_INT32/sizeof(::Color);
surroundColors = new ::Color [surroundColorsNumber];
@@ -436,7 +433,7 @@ namespace cppcanvas
if (additionalFlags & 0x08) {
s >> blendPoints;
EMFP_DEBUG (printf ("EMF+\tuse blend, points: %d\n", blendPoints));
- if( blendPoints<0 || blendPoints>SAL_MAX_INT32/(2*sizeof(float)) )
+ if( blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
blendPoints = SAL_MAX_INT32/(2*sizeof(float));
blendPositions = new float [2*blendPoints];
blendFactors = blendPositions + blendPoints;
@@ -453,9 +450,9 @@ namespace cppcanvas
if (additionalFlags & 0x04) {
s >> colorblendPoints;
EMFP_DEBUG (printf ("EMF+\tuse color blend, points: %d\n", colorblendPoints));
- if( colorblendPoints<0 || colorblendPoints>SAL_MAX_INT32/sizeof(float) )
+ if( colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(float) )
colorblendPoints = SAL_MAX_INT32/sizeof(float);
- if( colorblendPoints>SAL_MAX_INT32/sizeof(::Color) )
+ if( sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(::Color) )
colorblendPoints = SAL_MAX_INT32/sizeof(::Color);
colorblendPositions = new float [colorblendPoints];
colorblendColors = new ::Color [colorblendPoints];
@@ -469,9 +466,9 @@ namespace cppcanvas
EMFP_DEBUG (printf ("EMF+\tcolor[%d]: 0x%08x\n", i, color));
}
}
- } else
+ } else {
EMFP_DEBUG (dumpWords (s, 1024));
-
+ }
break;
}
// linear gradient
@@ -511,7 +508,7 @@ namespace cppcanvas
if (additionalFlags & 0x08) {
s >> blendPoints;
EMFP_DEBUG (printf ("EMF+\tuse blend, points: %d\n", blendPoints));
- if( blendPoints<0 || blendPoints>SAL_MAX_INT32/(2*sizeof(float)) )
+ if( blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
blendPoints = SAL_MAX_INT32/(2*sizeof(float));
blendPositions = new float [2*blendPoints];
blendFactors = blendPositions + blendPoints;
@@ -528,10 +525,10 @@ namespace cppcanvas
if (additionalFlags & 0x04) {
s >> colorblendPoints;
EMFP_DEBUG (printf ("EMF+\tuse color blend, points: %d\n", colorblendPoints));
- if( colorblendPoints<0 || colorblendPoints>SAL_MAX_INT32/sizeof(float) )
+ if( colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(float) )
colorblendPoints = SAL_MAX_INT32/sizeof(float);
- if( colorblendPoints>SAL_MAX_INT32/sizeof(::Color) )
- colorblendPoints = SAL_MAX_INT32/sizeof(::Color);
+ if( sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(::Color) )
+ colorblendPoints = sal_uInt32(SAL_MAX_INT32)/sizeof(::Color);
colorblendPositions = new float [colorblendPoints];
colorblendColors = new ::Color [colorblendPoints];
for (int i=0; i < colorblendPoints; i ++) {
@@ -584,7 +581,7 @@ namespace cppcanvas
rStrokeAttributes.StrokeWidth = (rState.mapModeTransform * rR.MapSize (width, 0)).getX ();
}
- void Read (SvStream& s, ImplRenderer& rR, sal_Int32 nHDPI, sal_Int32 nVDPI)
+ void Read (SvStream& s, ImplRenderer& rR, sal_Int32, sal_Int32 )
{
UINT32 header, unknown, penFlags, unknown2;
int i;
@@ -633,7 +630,7 @@ namespace cppcanvas
if (penFlags & 256) {
s >> dashPatternLen;
- if( dashPatternLen<0 || dashPatternLen>SAL_MAX_INT32/sizeof(float) )
+ if( dashPatternLen<0 || sal_uInt32(dashPatternLen)>SAL_MAX_INT32/sizeof(float) )
dashPatternLen = SAL_MAX_INT32/sizeof(float);
dashPattern = new float [dashPatternLen];
for (i = 0; i < dashPatternLen; i++)
@@ -648,7 +645,7 @@ namespace cppcanvas
if (penFlags & 1024) {
s >> compoundArrayLen;
- if( compoundArrayLen<0 || compoundArrayLen>SAL_MAX_INT32/sizeof(float) )
+ if( compoundArrayLen<0 || sal_uInt32(compoundArrayLen)>SAL_MAX_INT32/sizeof(float) )
compoundArrayLen = SAL_MAX_INT32/sizeof(float);
compoundArray = new float [compoundArrayLen];
for (i = 0; i < compoundArrayLen; i++)
@@ -754,7 +751,7 @@ namespace cppcanvas
if( length > 0 && length < 0x4000 ) {
sal_Unicode *chars = (sal_Unicode *) alloca( sizeof( sal_Unicode ) * length );
- for( int i = 0; i < length; i++ )
+ for( sal_uInt32 i = 0; i < length; i++ )
s >> chars[ i ];
family = ::rtl::OUString( chars, length );
@@ -914,10 +911,6 @@ namespace cppcanvas
::basegfx::B2DHomMatrix aWorldTransformation;
::basegfx::B2DHomMatrix aBaseTransformation;
rendering::Texture aTexture;
- double nRotation( 0.0 );
- const ::basegfx::B2DRectangle aBounds( ::basegfx::tools::getRange( localPolygon ) );
- const double nScale( ::basegfx::pruneScaleValue( fabs( aBounds.getHeight()*sin(nRotation) ) +
- fabs( aBounds.getWidth()*cos(nRotation) )));
aWorldTransformation.set (0, 0, aWorldTransform.eM11);
aWorldTransformation.set (0, 1, aWorldTransform.eM21);
@@ -965,10 +958,9 @@ namespace cppcanvas
aTexture.RepeatModeY = rendering::TexturingMode::CLAMP;
aTexture.Alpha = 1.0;
- uno::Reference< rendering::XParametricPolyPolygon2DFactory > xFactory(
- rParms.mrCanvas->getUNOCanvas()->getDevice()->getParametricPolyPolygonFactory() );
+ basegfx::ODFGradientInfo aGradInfo;
+ rtl::OUString aGradientService;
- if( xFactory.is() ) {
const uno::Sequence< double > aStartColor(
::vcl::unotools::colorToDoubleSequence( brush->solidColor,
rParms.mrCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() ) );
@@ -1027,25 +1019,56 @@ namespace cppcanvas
}
EMFP_DEBUG (printf ("EMF+\t\tset gradient\n"));
- if (brush->type == 4)
- aTexture.Gradient = xFactory->createLinearHorizontalGradient( aColors,
- aStops );
- else {
- geometry::RealRectangle2D aBoundsRectangle (0, 0, 1, 1);
- aTexture.Gradient = xFactory->createEllipticalGradient( aColors,
- aStops,
- aBoundsRectangle);
+ basegfx::B2DRange aBoundsRectangle (0, 0, 1, 1);
+ if (brush->type == 4) {
+ aGradientService = rtl::OUString::createFromAscii("LinearGradient");
+ basegfx::tools::createLinearODFGradientInfo( aGradInfo,
+ aBoundsRectangle,
+ aStops.getLength(),
+ 0,
+ 0 );
+
+ } else {
+ aGradientService = rtl::OUString::createFromAscii("EllipticalGradient");
+ basegfx::tools::createEllipticalODFGradientInfo( aGradInfo,
+ aBoundsRectangle,
+ ::basegfx::B2DVector( 0, 0 ),
+ aStops.getLength(),
+ 0,
+ 0 );
}
- }
- ::basegfx::unotools::affineMatrixFromHomMatrix( aTexture.AffineTransform,
- aTextureTransformation );
+ uno::Reference< lang::XMultiServiceFactory > xFactory(
+ rParms.mrCanvas->getUNOCanvas()->getDevice()->getParametricPolyPolygonFactory() );
+
+ if( xFactory.is() ) {
+ uno::Sequence<uno::Any> args( 3 );
+ beans::PropertyValue aProp;
+ aProp.Name = rtl::OUString::createFromAscii( "Colors" );
+ aProp.Value <<= aColors;
+ args[0] <<= aProp;
+ aProp.Name = rtl::OUString::createFromAscii( "Stops" );
+ aProp.Value <<= aStops;
+ args[1] <<= aProp;
+ aProp.Name = rtl::OUString::createFromAscii( "AspectRatio" );
+ aProp.Value <<= static_cast<sal_Int32>(1);
+ args[2] <<= aProp;
+
+ aTexture.Gradient.set(
+ xFactory->createInstanceWithArguments( aGradientService,
+ args ),
+ uno::UNO_QUERY);
+ }
+
+ ::basegfx::unotools::affineMatrixFromHomMatrix( aTexture.AffineTransform,
+ aTextureTransformation );
- pPolyAction =
- ActionSharedPtr ( internal::PolyPolyActionFactory::createPolyPolyAction( localPolygon,
- rParms.mrCanvas,
- rState,
- aTexture ) );
+ if( aTexture.Gradient.is() )
+ pPolyAction =
+ ActionSharedPtr ( internal::PolyPolyActionFactory::createPolyPolyAction( localPolygon,
+ rParms.mrCanvas,
+ rState,
+ aTexture ) );
}
}
@@ -1064,7 +1087,7 @@ namespace cppcanvas
void ImplRenderer::processObjectRecord(SvMemoryStream& rObjectStream, UINT16 flags)
{
- UINT32 objectLen;
+ EMFP_DEBUG (UINT32 objectLen);
sal_uInt32 index;
EMFP_DEBUG (printf ("EMF+ Object slot: %hd flags: %hx\n", flags & 0xff, flags & 0xff00));
@@ -1155,7 +1178,7 @@ namespace cppcanvas
EMFP_DEBUG (printf ("EMF+ record size: %d type: %04hx flags: %04hx data size: %d\n", size, type, flags, dataSize));
- if (type == EmfPlusRecordTypeObject && (mbMultipart && flags & 0x7fff == mMFlags & 0x7fff || flags & 0x8000)) {
+ if (type == EmfPlusRecordTypeObject && ((mbMultipart && (flags & 0x7fff) == (mMFlags & 0x7fff)) || (flags & 0x8000))) {
if (!mbMultipart) {
mbMultipart = true;
mMFlags = flags;
@@ -1254,12 +1277,12 @@ namespace cppcanvas
}
case EmfPlusRecordTypeFillPolygon:
{
- sal_uInt8 index = flags & 0xff;
+ EMFP_DEBUG (sal_uInt8 index = flags & 0xff);
sal_uInt32 brushIndexOrColor;
- sal_Int32 brushIndex;
+ EMFP_DEBUG (sal_Int32 brushIndex);
sal_Int32 points;
- UINT32 color;
- USHORT transparency = 0;
+ EMFP_DEBUG (UINT32 color);
+ EMFP_DEBUG (USHORT transparency = 0);
rMF >> brushIndexOrColor;
rMF >> points;
@@ -1403,8 +1426,9 @@ namespace cppcanvas
rFactoryParms.mrCurrActionIndex += pBmpAction->getActionCount()-1;
}
- } else
+ } else {
EMFP_DEBUG (printf ("EMF+ DrawImagePoints TODO (fixme)\n"));
+ }
}
break;
}
@@ -1484,8 +1508,9 @@ namespace cppcanvas
// reset clip
if (region.parts == 0 && region.initialState == EmfPlusRegionInitialStateInfinite) {
updateClipping (::basegfx::B2DPolyPolygon (), rFactoryParms, false);
- } else
+ } else {
EMFP_DEBUG (printf ("EMF+\tTODO\n"));
+ }
break;
}
case EmfPlusRecordTypeDrawDriverString: {
@@ -1507,12 +1532,12 @@ namespace cppcanvas
float *charsPosX = new float[glyphsCount];
float *charsPosY = new float[glyphsCount];
- for( int i=0; i<glyphsCount; i++) {
+ for( sal_uInt32 i=0; i<glyphsCount; i++) {
rMF >> chars[i];
EMFP_DEBUG (printf ("EMF+\tglyph[%d]: 0x%04x\n",
i, chars[i]));
}
- for( int i=0; i<glyphsCount; i++) {
+ for( sal_uInt32 i=0; i<glyphsCount; i++) {
rMF >> charsPosX[i] >> charsPosY[i];
EMFP_DEBUG (printf ("EMF+\tglyphPosition[%d]: %f, %f\n", i, charsPosX[i], charsPosY[i]));
}
commit 661cb04104bda3f55dc43cd5df16827068bd273f
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:49:33 2010 +0200
emf+-canvas-vcl-clear.diff: emf+ import - fix vcl canvas clearing
of empty canvas
diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx
index c73ab26..f5f8298 100644
--- a/canvas/source/vcl/canvashelper.cxx
+++ b/canvas/source/vcl/canvashelper.cxx
@@ -156,8 +156,8 @@ namespace vclcanvas
tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev );
rOutDev.EnableMapMode( FALSE );
- rOutDev.SetLineColor( COL_WHITE );
- rOutDev.SetFillColor( COL_WHITE );
+ rOutDev.SetLineColor( COL_TRANSPARENT );
+ rOutDev.SetFillColor( COL_TRANSPARENT );
rOutDev.DrawRect( Rectangle( Point(),
rOutDev.GetOutputSizePixel()) );
@@ -167,8 +167,8 @@ namespace vclcanvas
rOutDev2.SetDrawMode( DRAWMODE_DEFAULT );
rOutDev2.EnableMapMode( FALSE );
- rOutDev2.SetLineColor( COL_WHITE );
- rOutDev2.SetFillColor( COL_WHITE );
+ rOutDev2.SetLineColor( COL_TRANSPARENT );
+ rOutDev2.SetFillColor( COL_TRANSPARENT );
rOutDev2.DrawRect( Rectangle( Point(),
rOutDev2.GetOutputSizePixel()) );
rOutDev2.SetDrawMode( DRAWMODE_BLACKLINE | DRAWMODE_BLACKFILL | DRAWMODE_BLACKTEXT |
commit 7ba7fcdc38f03a787252dfe41bded0b97b61365c
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:46:38 2010 +0200
emf+-driver-string.diff: emf+ import - extended string rendering\n\nn#519715
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index 6a881b5..89c918d 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -39,6 +39,8 @@
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <vcl/canvastools.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/alloca.h>
#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/rendering/TexturingMode.hpp>
@@ -48,6 +50,7 @@
#include <implrenderer.hxx>
#include <outdevstate.hxx>
#include <polypolyaction.hxx>
+#include <textaction.hxx>
#define EmfPlusRecordTypeHeader 16385
#define EmfPlusRecordTypeEndOfFile 16386
@@ -727,6 +730,39 @@ namespace cppcanvas
}
};
+ struct EMFPFont : public EMFPObject
+ {
+ sal_uInt32 version;
+ float emSize;
+ sal_uInt32 sizeUnit;
+ sal_Int32 fontFlags;
+ rtl::OUString family;
+
+ void Read (SvMemoryStream &s)
+ {
+ sal_uInt32 header;
+ sal_uInt32 reserved;
+ sal_uInt32 length;
+
+ s >> header >> emSize >> sizeUnit >> fontFlags >> reserved >> length;
+
+ OSL_ASSERT( ( header >> 12 ) == 0xdbc01 );
+
+ EMFP_DEBUG (printf ("EMF+\tfont\nEMF+\theader: 0x%08x version: 0x%08x size: %f unit: 0x%08x\n", header >> 12, header & 0x1fff, emSize, sizeUnit));
+ EMFP_DEBUG (printf ("EMF+\tflags: 0x%08x reserved: 0x%08x length: 0x%08x\n", fontFlags, reserved, length));
+
+ if( length > 0 && length < 0x4000 ) {
+ sal_Unicode *chars = (sal_Unicode *) alloca( sizeof( sal_Unicode ) * length );
+
+ for( int i = 0; i < length; i++ )
+ s >> chars[ i ];
+
+ family = ::rtl::OUString( chars, length );
+ EMFP_DEBUG (printf ("EMF+\tfamily: %s\n", rtl::OUStringToOString( family, RTL_TEXTENCODING_UTF8).getStr()));
+ }
+ }
+ };
+
void ImplRenderer::ReadRectangle (SvStream& s, float& x, float& y, float &width, float& height, sal_uInt32 flags)
{
if (flags & 0x4000) {
@@ -823,10 +859,22 @@ namespace cppcanvas
return ::basegfx::B2DRange (x, y, x + w, y + h);
}
+#define COLOR(x) \
+ ::vcl::unotools::colorToDoubleSequence( ::Color (0xff - (x >> 24), \
+ (x >> 16) & 0xff, \
+ (x >> 8) & 0xff, \
+ x & 0xff), \
+ rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace());
+#define SET_FILL_COLOR(x) \
+ rState.fillColor = COLOR(x);
+#define SET_LINE_COLOR(x) \
+ rState.lineColor = COLOR(x);
+#define SET_TEXT_COLOR(x) \
+ rState.textColor = COLOR(x);
+
void ImplRenderer::EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms,
OutDevState& rState, const CanvasSharedPtr& rCanvas, bool isColor, sal_uInt32 brushIndexOrColor)
{
- sal_uInt8 transparency;
::basegfx::B2DPolyPolygon localPolygon (polygon);
EMFP_DEBUG (printf ("EMF+\tfill polygon\n"));
@@ -838,15 +886,9 @@ namespace cppcanvas
if (isColor) {
EMFP_DEBUG (printf ("EMF+\t\tcolor fill\n"));
- transparency = 0xff - (brushIndexOrColor >> 24);
-
rState.isFillColorSet = true;
rState.isLineColorSet = false;
- rState.fillColor = ::vcl::unotools::colorToDoubleSequence( ::Color (transparency,
- (brushIndexOrColor >> 16) & 0xff,
- (brushIndexOrColor >> 8) & 0xff,
- brushIndexOrColor & 0xff),
- rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace());
+ SET_FILL_COLOR(brushIndexOrColor);
pPolyAction = ActionSharedPtr ( internal::PolyPolyActionFactory::createPolyPolyAction( localPolygon, rParms.mrCanvas, rState ) );
@@ -1080,6 +1122,14 @@ namespace cppcanvas
break;
}
+ case EmfPlusObjectTypeFont:
+ {
+ EMFPFont *font;
+ aObjects [index] = font = new EMFPFont ();
+ font->Read (rObjectStream);
+
+ break;
+ }
default:
EMFP_DEBUG (printf ("EMF+\tObject unhandled flags: 0x%04x\n", flags & 0xff00));
break;
@@ -1438,10 +1488,93 @@ namespace cppcanvas
EMFP_DEBUG (printf ("EMF+\tTODO\n"));
break;
}
- case EmfPlusRecordTypeDrawDriverString:
+ case EmfPlusRecordTypeDrawDriverString: {
EMFP_DEBUG (printf ("EMF+ DrawDriverString, flags: 0x%04x\n", flags));
- EMFP_DEBUG (printf ("EMF+\tTODO\n"));
+ sal_uInt32 brushIndexOrColor;
+ sal_uInt32 optionFlags;
+ sal_uInt32 hasMatrix;
+ sal_uInt32 glyphsCount;
+
+ rMF >> brushIndexOrColor >> optionFlags >> hasMatrix >> glyphsCount;
+
+ EMFP_DEBUG (printf ("EMF+\t%s: 0x%08x\n", (flags & 0x8000) ? "color" : "brush index", brushIndexOrColor));
+ EMFP_DEBUG (printf ("EMF+\toption flags: 0x%08x\n", optionFlags));
+ EMFP_DEBUG (printf ("EMF+\thas matrix: %d\n", hasMatrix));
+ EMFP_DEBUG (printf ("EMF+\tglyphs: %d\n", glyphsCount));
+
+ if( ( optionFlags & 1 ) && glyphsCount > 0 ) {
+ sal_uInt16 *chars = new sal_uInt16[glyphsCount];
+ float *charsPosX = new float[glyphsCount];
+ float *charsPosY = new float[glyphsCount];
+
+ for( int i=0; i<glyphsCount; i++) {
+ rMF >> chars[i];
+ EMFP_DEBUG (printf ("EMF+\tglyph[%d]: 0x%04x\n",
+ i, chars[i]));
+ }
+ for( int i=0; i<glyphsCount; i++) {
+ rMF >> charsPosX[i] >> charsPosY[i];
+ EMFP_DEBUG (printf ("EMF+\tglyphPosition[%d]: %f, %f\n", i, charsPosX[i], charsPosY[i]));
+ }
+
+ XForm transform;
+ if( hasMatrix ) {
+ rMF >> transform;
+ EMFP_DEBUG (printf ("EMF+\tmatrix:: %f, %f, %f, %f, %f, %f\n", transform.eM11, transform.eM12, transform.eM21, transform.eM22, transform.eDx, transform.eDy));
+ }
+
+ // create and add the text action
+ XubString text( chars, glyphsCount );
+
+ EMFPFont *font = (EMFPFont*) aObjects[ flags & 0xff ];
+
+ rendering::FontRequest aFontRequest;
+ aFontRequest.FontDescription.FamilyName = font->family;
+ aFontRequest.CellSize = (rState.mapModeTransform*MapSize( font->emSize, 0 )).getX();
+ rState.xFont = rFactoryParms.mrCanvas->getUNOCanvas()->createFont( aFontRequest,
+ uno::Sequence< beans::PropertyValue >(),
+ geometry::Matrix2D() );
+ if( flags & 0x8000 )
+ SET_TEXT_COLOR(brushIndexOrColor);
+
+ ActionSharedPtr pTextAction(
+ TextActionFactory::createTextAction(
+ ::vcl::unotools::pointFromB2DPoint ( Map( charsPosX[0], charsPosY[0] ) ),
+ ::Size(),
+ ::Color(),
+ ::Size(),
+ ::Color(),
+ text,
+ 0,
+ glyphsCount,
+ NULL,
+ rFactoryParms.mrVDev,
+ rFactoryParms.mrCanvas,
+ rState,
+ rFactoryParms.mrParms,
+ false ) );
+
+ if( pTextAction )
+ {
+ EMFP_DEBUG (printf ("EMF+\t\tadd text action\n"));
+
+ maActions.push_back(
+ MtfAction(
+ pTextAction,
+ rFactoryParms.mrCurrActionIndex ) );
+
+ rFactoryParms.mrCurrActionIndex += pTextAction->getActionCount()-1;
+ }
+
+ delete[] chars;
+ delete[] charsPosX;
+ delete[] charsPosY;
+ } else {
+ EMFP_DEBUG (printf ("EMF+\tTODO: fonts (non-unicode glyphs chars)\n"));
+ }
+
break;
+ }
default:
EMFP_DEBUG (printf ("EMF+ unhandled record type: %d\n", type));
EMFP_DEBUG (printf ("EMF+\tTODO\n"));
commit c2fe2127a24b349e87e62e7b4a2556ee3cffdb05
Author: Thorsten Behrens <tbehrens at novell.com>
Date: Wed Sep 15 11:43:39 2010 +0200
vcl-pluggable-mtf-renderer.diff: emf+ import - checks for valid input
in emf+ renderer, small changes to the patch by Radek (rodo at novell.com)
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index a82aad0..6a881b5 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -123,6 +123,8 @@ namespace cppcanvas
public:
EMFPPath (sal_Int32 _nPoints, bool bLines = false)
{
+ if( _nPoints<0 || _nPoints>SAL_MAX_INT32/(2*sizeof(float)) )
+ _nPoints = SAL_MAX_INT32/(2*sizeof(float));
nPoints = _nPoints;
pPoints = new float [nPoints*2];
if (!bLines)
@@ -265,6 +267,9 @@ namespace cppcanvas
EMFP_DEBUG (printf ("EMF+\theader: 0x%08x parts: %d\n", header, parts));
if (parts) {
+ if( parts<0 || parts>SAL_MAX_INT32/sizeof(sal_Int32) )
+ parts = SAL_MAX_INT32/sizeof(sal_Int32);
+
combineMode = new sal_Int32 [parts];
for (int i = 0; i < parts; i ++) {
@@ -376,6 +381,9 @@ namespace cppcanvas
s >> surroundColorsNumber;
EMFP_DEBUG (printf ("EMF+\tsurround colors: %d\n", surroundColorsNumber));
+ if( surroundColorsNumber<0 || surroundColorsNumber>SAL_MAX_INT32/sizeof(::Color) )
+ surroundColorsNumber = SAL_MAX_INT32/sizeof(::Color);
+
surroundColors = new ::Color [surroundColorsNumber];
for (int i = 0; i < surroundColorsNumber; i++) {
s >> color;
@@ -425,6 +433,8 @@ namespace cppcanvas
if (additionalFlags & 0x08) {
s >> blendPoints;
EMFP_DEBUG (printf ("EMF+\tuse blend, points: %d\n", blendPoints));
+ if( blendPoints<0 || blendPoints>SAL_MAX_INT32/(2*sizeof(float)) )
+ blendPoints = SAL_MAX_INT32/(2*sizeof(float));
blendPositions = new float [2*blendPoints];
blendFactors = blendPositions + blendPoints;
for (int i=0; i < blendPoints; i ++) {
@@ -440,6 +450,10 @@ namespace cppcanvas
if (additionalFlags & 0x04) {
s >> colorblendPoints;
EMFP_DEBUG (printf ("EMF+\tuse color blend, points: %d\n", colorblendPoints));
+ if( colorblendPoints<0 || colorblendPoints>SAL_MAX_INT32/sizeof(float) )
+ colorblendPoints = SAL_MAX_INT32/sizeof(float);
+ if( colorblendPoints>SAL_MAX_INT32/sizeof(::Color) )
+ colorblendPoints = SAL_MAX_INT32/sizeof(::Color);
colorblendPositions = new float [colorblendPoints];
colorblendColors = new ::Color [colorblendPoints];
for (int i=0; i < colorblendPoints; i ++) {
@@ -494,6 +508,8 @@ namespace cppcanvas
if (additionalFlags & 0x08) {
s >> blendPoints;
EMFP_DEBUG (printf ("EMF+\tuse blend, points: %d\n", blendPoints));
+ if( blendPoints<0 || blendPoints>SAL_MAX_INT32/(2*sizeof(float)) )
+ blendPoints = SAL_MAX_INT32/(2*sizeof(float));
blendPositions = new float [2*blendPoints];
blendFactors = blendPositions + blendPoints;
for (int i=0; i < blendPoints; i ++) {
@@ -509,6 +525,10 @@ namespace cppcanvas
if (additionalFlags & 0x04) {
s >> colorblendPoints;
EMFP_DEBUG (printf ("EMF+\tuse color blend, points: %d\n", colorblendPoints));
+ if( colorblendPoints<0 || colorblendPoints>SAL_MAX_INT32/sizeof(float) )
+ colorblendPoints = SAL_MAX_INT32/sizeof(float);
+ if( colorblendPoints>SAL_MAX_INT32/sizeof(::Color) )
+ colorblendPoints = SAL_MAX_INT32/sizeof(::Color);
colorblendPositions = new float [colorblendPoints];
colorblendColors = new ::Color [colorblendPoints];
for (int i=0; i < colorblendPoints; i ++) {
@@ -610,6 +630,8 @@ namespace cppcanvas
if (penFlags & 256) {
s >> dashPatternLen;
+ if( dashPatternLen<0 || dashPatternLen>SAL_MAX_INT32/sizeof(float) )
+ dashPatternLen = SAL_MAX_INT32/sizeof(float);
dashPattern = new float [dashPatternLen];
for (i = 0; i < dashPatternLen; i++)
s >> dashPattern [i];
@@ -623,6 +645,8 @@ namespace cppcanvas
if (penFlags & 1024) {
s >> compoundArrayLen;
+ if( compoundArrayLen<0 || compoundArrayLen>SAL_MAX_INT32/sizeof(float) )
+ compoundArrayLen = SAL_MAX_INT32/sizeof(float);
compoundArray = new float [compoundArrayLen];
for (i = 0; i < compoundArrayLen; i++)
s >> compoundArray [i];
@@ -631,6 +655,8 @@ namespace cppcanvas
if (penFlags & 2048) {
s >> customStartCapLen;
+ if( customStartCapLen<0 )
+ customStartCapLen=0;
customStartCap = new sal_uInt8 [customStartCapLen];
for (i = 0; i < customStartCapLen; i++)
s >> customStartCap [i];
@@ -639,6 +665,8 @@ namespace cppcanvas
if (penFlags & 4096) {
s >> customEndCapLen;
+ if( customEndCapLen<0 )
+ customEndCapLen=0;
customEndCap = new sal_uInt8 [customEndCapLen];
for (i = 0; i < customEndCapLen; i++)
s >> customEndCap [i];
commit d75e9cc6d0f4d1356d35779e3ad9e53fd359f527
Author: Thorsten Behrens <tbehrens at novell.com>
Date: Wed Sep 15 11:40:21 2010 +0200
vcl-pluggable-mtf-renderer.diff: emf+ import - pluggable renderer
Added a way to delegate mtf action rendering to external
services. plan to add a librsvg-based SVG renderer this way.
Limit exposure to arbitrary binary data to zero existing services,
some cleanup.
diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx
index 7928282..0f47d0f 100644
--- a/vcl/inc/vcl/gdimtf.hxx
+++ b/vcl/inc/vcl/gdimtf.hxx
@@ -38,6 +38,7 @@
class OutputDevice;
class ImpLabelList;
class MetaAction;
+class MetaCommentAction;
class SvStream;
class Color;
class BitmapEx;
@@ -137,6 +138,7 @@ private:
const PolyPolygon& rPolyPoly,
const Gradient& rGrad );
SAL_DLLPRIVATE bool ImplPlayWithRenderer( OutputDevice* pOut, const Point& rPos, Size rDestSize );
+ SAL_DLLPRIVATE void ImplDelegate2PluggableRenderer( const MetaCommentAction* pAct, OutputDevice* pOut );
//#endif // __PRIVATE
@@ -251,5 +253,29 @@ public:
void UseCanvas( BOOL _bUseCanvas );
};
+/** Create a special metaaction that delegates rendering to specified
+ service.
+
+ This factory function creates a MetaCommentAction that delegates
+ rendering to the specified services, once played back in the
+ metafile.
+
+ @param rRendererServiceName
+ Renderer service. Gets an awt::XGraphic on instantiation
+
+ @param rGraphicServiceName
+ Graphic service. Gets the raw data on instantiation
+
+ @param pData
+ Raw data. Gets copied
+
+ @param nDataSize
+ Length, in byte, of raw data
+ */
+MetaCommentAction* makePluggableRendererAction( const rtl::OUString& rRendererServiceName,
+ const rtl::OUString& rGraphicServiceName,
+ const void* pData,
+ sal_uInt32 nDataSize );
+
#endif // _SV_GDIMTF_HXX
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index 49e7b1d..097bf9d 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -51,6 +51,10 @@
#include <com/sun/star/rendering/MtfRenderer.hpp>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/awt/XGraphics.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/XGraphicRenderer.hpp>
using namespace com::sun::star;
@@ -474,7 +478,16 @@ void GDIMetaFile::Play( OutputDevice* pOut, ULONG nPos )
{
if( !Hook() )
{
- pAction->Execute( pOut );
+ MetaCommentAction* pCommentAct = static_cast<MetaCommentAction*>(pAction);
+ if( pAction->GetType() == META_COMMENT_ACTION &&
+ pCommentAct->GetComment().Equals("DELEGATE_PLUGGABLE_RENDERER") )
+ {
+ ImplDelegate2PluggableRenderer(pCommentAct, pOut);
+ }
+ else
+ {
+ pAction->Execute( pOut );
+ }
// flush output from time to time
if( i++ > nSyncCount )
@@ -560,6 +573,77 @@ bool GDIMetaFile::ImplPlayWithRenderer( OutputDevice* pOut, const Point& rPos, S
// ------------------------------------------------------------------------
+void GDIMetaFile::ImplDelegate2PluggableRenderer( const MetaCommentAction* pAct, OutputDevice* pOut )
+{
+ OSL_ASSERT( pAct->GetComment().Equals("DELEGATE_PLUGGABLE_RENDERER") );
+
+ // read payload - string of service name, followed by raw render input
+ const BYTE* pData = pAct->GetData();
+ const BYTE* const pEndData = pData + pAct->GetDataSize();
+ if( !pData )
+ return;
+
+ ::rtl::OUStringBuffer aBuffer;
+ while( pData<pEndData && *pData )
+ aBuffer.append(static_cast<sal_Unicode>(*pData++));
+ const ::rtl::OUString aRendererServiceName=aBuffer.makeStringAndClear();
+ ++pData;
+
+ while( pData<pEndData && *pData )
+ aBuffer.append(static_cast<sal_Unicode>(*pData++));
+ const ::rtl::OUString aGraphicServiceName=aBuffer.makeStringAndClear();
+ ++pData;
+
+ uno::Reference< lang::XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory();
+ if( pData<pEndData && xFactory.is() )
+ {
+ try
+ {
+ // instantiate render service
+ uno::Sequence<uno::Any> aRendererArgs(1);
+ aRendererArgs[0] = makeAny(uno::Reference<awt::XGraphics>(pOut->CreateUnoGraphics()));
+ uno::Reference<graphic::XGraphicRenderer> xRenderer(
+ xFactory->createInstanceWithArguments(
+ aRendererServiceName,
+ aRendererArgs),
+ uno::UNO_QUERY );
+
+ // instantiate graphic service
+ uno::Reference<graphic::XGraphic> xGraphic(
+ xFactory->createInstance(
+ aGraphicServiceName),
+ uno::UNO_QUERY );
+
+ uno::Reference<lang::XInitialization> xInit(
+ xGraphic, uno::UNO_QUERY);
+
+ if(xGraphic.is() && xRenderer.is() && xInit.is())
+ {
+ // delay intialization of XGraphic, to only expose
+ // XGraphic-generating services to arbitrary binary data
+ uno::Sequence< sal_Int8 > aSeq(
+ (sal_Int8*)&pData, pEndData-pData );
+ uno::Sequence<uno::Any> aGraphicsArgs(1);
+ aGraphicsArgs[0] = makeAny(aSeq);
+ xInit->initialize(aGraphicsArgs);
+
+ xRenderer->render(xGraphic);
+ }
+ }
+ catch( uno::RuntimeException& )
+ {
+ // runtime errors are fatal
+ throw;
+ }
+ catch( uno::Exception& )
+ {
+ // ignore errors, no way of reporting them here
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos,
const Size& rSize, ULONG nPos )
{
@@ -3125,3 +3209,46 @@ void GDIMetaFile::UseCanvas( BOOL _bUseCanvas )
{
bUseCanvas = _bUseCanvas;
}
+
+// ------------------------------------------------------------------------
+
+MetaCommentAction* makePluggableRendererAction( const rtl::OUString& rRendererServiceName,
+ const rtl::OUString& rGraphicServiceName,
+ const void* _pData,
+ sal_uInt32 nDataSize )
+{
+ const BYTE* pData=(BYTE*)_pData;
+
+ // data gets copied twice, unfortunately
+ rtl::OString aRendererServiceName(
+ rRendererServiceName.getStr(),
+ rRendererServiceName.getLength(),
+ RTL_TEXTENCODING_ASCII_US);
+ rtl::OString aGraphicServiceName(
+ rGraphicServiceName.getStr(),
+ rGraphicServiceName.getLength(),
+ RTL_TEXTENCODING_ASCII_US);
+
+ std::vector<sal_uInt8> aMem(
+ aRendererServiceName.getLength()+
+ aGraphicServiceName.getLength()+2+nDataSize);
+ sal_uInt8* pMem=&aMem[0];
+
+ std::copy(aRendererServiceName.getStr(),
+ aRendererServiceName.getStr()+aRendererServiceName.getLength()+1,
+ pMem);
+ pMem+=aRendererServiceName.getLength()+1;
+ std::copy(aGraphicServiceName.getStr(),
+ aGraphicServiceName.getStr()+aGraphicServiceName.getLength()+1,
+ pMem);
+ pMem+=aGraphicServiceName.getLength()+1;
+
+ std::copy(pData,pData+nDataSize,
+ pMem);
+
+ return new MetaCommentAction(
+ "DELEGATE_PLUGGABLE_RENDERER",
+ 0,
+ &aMem[0],
+ aMem.size());
+}
commit a52ec5e5f67e453c5a9ddf90eb04bd6e06487a55
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:34:17 2010 +0200
emf+-embedded-mf-image.diff: emf+ import - support for embedded MF images
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index 8d22704..a82aad0 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -659,12 +659,10 @@ namespace cppcanvas
Graphic graphic;
- void Read (SvStream &s)
+ void Read (SvMemoryStream &s)
{
sal_uInt32 header, unknown;
- EMFP_DEBUG (dumpWords(s, 16));
-
s >> header >> type;
EMFP_DEBUG (printf ("EMF+\timage\nEMF+\theader: 0x%08x type: 0x%08x\n", header, type));
@@ -679,6 +677,24 @@ namespace cppcanvas
EMFP_DEBUG (printf ("EMF+\tbitmap width: %d height: %d\n", graphic.GetBitmap ().GetSizePixel ().Width (), graphic.GetBitmap ().GetSizePixel ().Height ()));
}
+ } else if (type == 2) {
+ sal_Int32 mfType, mfSize;
+
+ s >> mfType >> mfSize;
+ EMFP_DEBUG (printf ("EMF+\tmetafile type: %d dataSize: %d\n", mfType, mfSize));
+
+ GraphicFilter filter;
+ SvMemoryStream mfStream (((char *)s.GetData()) + s.Tell(), mfSize, STREAM_READ);
+
+ filter.ImportGraphic (graphic, String (), mfStream);
+
+ // debug code - write the stream to debug file /tmp/emf-stream.emf
+ EMFP_DEBUG(mfStream.Seek(0);
+ SvFileStream file( UniString::CreateFromAscii( "/tmp/emf-embedded-stream.emf" ), STREAM_WRITE | STREAM_TRUNC );
+
+ mfStream >> file;
+ file.Flush();
+ file.Close());
}
}
};
@@ -1067,7 +1083,7 @@ namespace cppcanvas
mMFlags = flags;
mMStream.Seek(0);
}
- EMFP_DEBUG (dumpWords(rMF, 16));
+
// 1st 4 bytes are unknown
mMStream.Write (((const char *)rMF.GetData()) + rMF.Tell() + 4, dataSize - 4);
EMFP_DEBUG (printf ("EMF+ read next object part size: %d type: %04hx flags: %04hx data size: %d\n", size, type, flags, dataSize));
diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx b/cppcanvas/source/mtfrenderer/implrenderer.cxx
index f3f68f2..3343e7f 100644
--- a/cppcanvas/source/mtfrenderer/implrenderer.cxx
+++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx
@@ -1818,6 +1818,7 @@ namespace cppcanvas
char *env;
if (env = getenv ("EMF_PLUS_LIMIT")) {
limit = atoi (env);
+ EMFP_DEBUG (printf ("EMF+ records limit: %d\n", limit));
}
}
EMFP_DEBUG (printf ("EMF+ passed to canvas mtf renderer, size: %d\n", pAct->GetDataSize ()));
commit cbf46b7779a5aca70dbd7842c5be3690fa69eb92
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:31:43 2010 +0200
emf+-use-canvas-only-for-emf+.diff: emf+ import
- use canvas rendering only for emf+
diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx
index b333315..b93acf4 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.cxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.cxx
@@ -2230,6 +2230,7 @@ void WinMtfOutput::PassEMFPlusHeaderInfo()
mem << one << zero << zero << one << zero << zero;
mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS_HEADER_INFO", 0, (const BYTE*) mem.GetData(), mem.GetEndOfData() ) );
+ mpGDIMetaFile->UseCanvas( TRUE );
}
void WinMtfOutput::PassEMFPlus( void* pBuffer, UINT32 nLength )
diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx
index e17f3eb..7928282 100644
--- a/vcl/inc/vcl/gdimtf.hxx
+++ b/vcl/inc/vcl/gdimtf.hxx
@@ -107,6 +107,7 @@ private:
ImpLabelList* pLabelList;
BOOL bPause;
BOOL bRecord;
+ BOOL bUseCanvas;
//#if 0 // _SOLAR__PRIVATE
@@ -246,6 +247,8 @@ public:
friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile );
BOOL CreateThumbnail( sal_uInt32 nMaximumExtent, BitmapEx& rBmpEx, const BitmapEx* pOverlay = NULL, const Rectangle* pOverlayRect = NULL ) const;
+
+ void UseCanvas( BOOL _bUseCanvas );
};
#endif // _SV_GDIMTF_HXX
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index 412711b..49e7b1d 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -212,7 +212,8 @@ GDIMetaFile::GDIMetaFile() :
pOutDev ( NULL ),
pLabelList ( NULL ),
bPause ( FALSE ),
- bRecord ( FALSE )
+ bRecord ( FALSE ),
+ bUseCanvas ( FALSE )
{
}
@@ -227,7 +228,8 @@ GDIMetaFile::GDIMetaFile( const GDIMetaFile& rMtf ) :
pNext ( rMtf.pNext ),
pOutDev ( NULL ),
bPause ( FALSE ),
- bRecord ( FALSE )
+ bRecord ( FALSE ),
+ bUseCanvas ( rMtf.bUseCanvas )
{
// RefCount der MetaActions erhoehen
for( void* pAct = First(); pAct; pAct = Next() )
@@ -281,6 +283,7 @@ GDIMetaFile& GDIMetaFile::operator=( const GDIMetaFile& rMtf )
pOutDev = NULL;
bPause = FALSE;
bRecord = FALSE;
+ bUseCanvas = rMtf.bUseCanvas;
if( rMtf.bRecord )
{
@@ -568,7 +571,7 @@ void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos,
{
GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
- if( !pMtf && ImplPlayWithRenderer( pOut, rPos, aDestSize ) )
+ if( bUseCanvas && !pMtf && ImplPlayWithRenderer( pOut, rPos, aDestSize ) )
return;
Size aTmpPrefSize( pOut->LogicToPixel( GetPrefSize(), aDrawMap ) );
@@ -3117,3 +3120,8 @@ BOOL GDIMetaFile::CreateThumbnail( sal_uInt32 nMaximumExtent,
return !rBmpEx.IsEmpty();
}
+
+void GDIMetaFile::UseCanvas( BOOL _bUseCanvas )
+{
+ bUseCanvas = _bUseCanvas;
+}
commit b594d3e1724bfc42b2e13390d421087a48119b2e
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:29:57 2010 +0200
emf+-multipart-objects.diff: emf+ import - support multipart objects
diff --git a/cppcanvas/source/inc/implrenderer.hxx b/cppcanvas/source/inc/implrenderer.hxx
index 3d529c8..4e5f3e8 100644
--- a/cppcanvas/source/inc/implrenderer.hxx
+++ b/cppcanvas/source/inc/implrenderer.hxx
@@ -267,6 +267,7 @@ static float GetSwapFloat( SvStream& rSt )
ActionVector::const_iterator& o_rRangeBegin,
ActionVector::const_iterator& o_rRangeEnd ) const;
+ void processObjectRecord(SvMemoryStream& rObjectStream, UINT16 flags);
void processEMFPlus( MetaCommentAction* pAct, const ActionFactoryParameters& rFactoryParms, OutDevState& rState, const CanvasSharedPtr& rCanvas );
void EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms, OutDevState& rState, const CanvasSharedPtr& rCanvas, bool isColor, sal_uInt32 brushIndexOrColor);
@@ -291,6 +292,10 @@ static float GetSwapFloat( SvStream& rSt )
sal_Int32 nPixY;
sal_Int32 nMmX;
sal_Int32 nMmY;
+ /* multipart object data */
+ bool mbMultipart;
+ UINT16 mMFlags;
+ SvMemoryStream mMStream;
};
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index 699c2d4..8d22704 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -663,6 +663,8 @@ namespace cppcanvas
{
sal_uInt32 header, unknown;
+ EMFP_DEBUG (dumpWords(s, 16));
+
s >> header >> type;
EMFP_DEBUG (printf ("EMF+\timage\nEMF+\theader: 0x%08x type: 0x%08x\n", header, type));
@@ -974,6 +976,72 @@ namespace cppcanvas
}
}
+ void ImplRenderer::processObjectRecord(SvMemoryStream& rObjectStream, UINT16 flags)
+ {
+ UINT32 objectLen;
+ sal_uInt32 index;
+
+ EMFP_DEBUG (printf ("EMF+ Object slot: %hd flags: %hx\n", flags & 0xff, flags & 0xff00));
+
+ index = flags & 0xff;
+ if (aObjects [index] != NULL) {
+ delete aObjects [index];
+ aObjects [index] = NULL;
+ }
+
+ switch (flags & 0x7f00) {
+ case EmfPlusObjectTypeBrush:
+ {
+ EMFPBrush *brush;
+ aObjects [index] = brush = new EMFPBrush ();
+ brush->Read (rObjectStream, *this);
+
+ break;
+ }
+ case EmfPlusObjectTypePen:
+ {
+ EMFPPen *pen;
+ aObjects [index] = pen = new EMFPPen ();
+ pen->Read (rObjectStream, *this, nHDPI, nVDPI);
+
+ break;
+ }
+ case EmfPlusObjectTypePath:
+ sal_uInt32 header, pathFlags;
+ sal_Int32 points;
+
+ rObjectStream >> header >> points >> pathFlags;
+
+ EMFP_DEBUG (printf ("EMF+\tpath\n"));
+ EMFP_DEBUG (printf ("EMF+\theader: 0x%08x points: %d additional flags: 0x%08x\n", header, points, pathFlags));
+
+ EMFPPath *path;
+ aObjects [index] = path = new EMFPPath (points);
+ path->Read (rObjectStream, pathFlags, *this);
+
+ break;
+ case EmfPlusObjectTypeRegion: {
+ EMFPRegion *region;
+
+ aObjects [index] = region = new EMFPRegion ();
+ region->Read (rObjectStream);
+
+ break;
+ }
+ case EmfPlusObjectTypeImage:
+ {
+ EMFPImage *image;
+ aObjects [index] = image = new EMFPImage ();
+ image->Read (rObjectStream);
+
+ break;
+ }
+ default:
+ EMFP_DEBUG (printf ("EMF+\tObject unhandled flags: 0x%04x\n", flags & 0xff00));
+ break;
+ }
+ }
+
void ImplRenderer::processEMFPlus( MetaCommentAction* pAct, const ActionFactoryParameters& rFactoryParms,
OutDevState& rState, const CanvasSharedPtr& rCanvas )
{
@@ -993,6 +1061,26 @@ namespace cppcanvas
EMFP_DEBUG (printf ("EMF+ record size: %d type: %04hx flags: %04hx data size: %d\n", size, type, flags, dataSize));
+ if (type == EmfPlusRecordTypeObject && (mbMultipart && flags & 0x7fff == mMFlags & 0x7fff || flags & 0x8000)) {
+ if (!mbMultipart) {
+ mbMultipart = true;
+ mMFlags = flags;
+ mMStream.Seek(0);
+ }
+ EMFP_DEBUG (dumpWords(rMF, 16));
+ // 1st 4 bytes are unknown
+ mMStream.Write (((const char *)rMF.GetData()) + rMF.Tell() + 4, dataSize - 4);
+ EMFP_DEBUG (printf ("EMF+ read next object part size: %d type: %04hx flags: %04hx data size: %d\n", size, type, flags, dataSize));
+ } else {
+ if (mbMultipart) {
+ EMFP_DEBUG (printf ("EMF+ multipart record flags: %04hx\n", mMFlags));
+ mMStream.Seek (0);
+ processObjectRecord (mMStream, mMFlags);
+ }
+ mbMultipart = false;
+ }
+
+ if (type != EmfPlusRecordTypeObject || !(flags & 0x8000))
switch (type) {
case EmfPlusRecordTypeHeader:
UINT32 header, version;
@@ -1011,73 +1099,8 @@ namespace cppcanvas
EMFP_DEBUG (printf ("EMF+\talready used in svtools wmf/emf filter parser\n"));
break;
case EmfPlusRecordTypeObject:
- {
- UINT32 objectLen;
- sal_uInt32 index;
-
- EMFP_DEBUG (printf ("EMF+ Object slot: %hd flags: %hx\n", flags & 0xff, flags & 0xff00));
-
- index = flags & 0xff;
- if (aObjects [index] != NULL) {
- delete aObjects [index];
- aObjects [index] = NULL;
- }
-
- // not sure yet, what 0x8000 means
- switch (flags & 0x7f00) {
- case EmfPlusObjectTypeBrush:
- {
- EMFPBrush *brush;
- aObjects [index] = brush = new EMFPBrush ();
- brush->Read (rMF, *this);
-
- break;
- }
- case EmfPlusObjectTypePen:
- {
- EMFPPen *pen;
- aObjects [index] = pen = new EMFPPen ();
- pen->Read (rMF, *this, nHDPI, nVDPI);
-
- break;
- }
- case EmfPlusObjectTypePath:
- sal_uInt32 header, pathFlags;
- sal_Int32 points;
-
- rMF >> header >> points >> pathFlags;
-
- EMFP_DEBUG (printf ("EMF+\tpath\n"));
- EMFP_DEBUG (printf ("EMF+\theader: 0x%08x points: %d additional flags: 0x%08x\n", header, points, pathFlags));
-
- EMFPPath *path;
- aObjects [index] = path = new EMFPPath (points);
- path->Read (rMF, pathFlags, *this);
-
- break;
- case EmfPlusObjectTypeRegion: {
- EMFPRegion *region;
-
- aObjects [index] = region = new EMFPRegion ();
- region->Read (rMF);
-
- break;
- }
- case EmfPlusObjectTypeImage:
- {
- EMFPImage *image;
- aObjects [index] = image = new EMFPImage ();
- image->Read (rMF);
-
- break;
- }
- default:
- EMFP_DEBUG (printf ("EMF+\tObject unhandled flags: 0x%04x\n", flags & 0xff00));
- break;
- }
-
- break;
- }
+ processObjectRecord (rMF, flags);
+ break;
case EmfPlusRecordTypeFillPath:
{
sal_uInt32 index = flags & 0xff;
diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx b/cppcanvas/source/mtfrenderer/implrenderer.cxx
index 68abaf3..f3f68f2 100644
--- a/cppcanvas/source/mtfrenderer/implrenderer.cxx
+++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx
@@ -3007,6 +3007,7 @@ namespace cppcanvas
/* EMF+ */
memset (aObjects, 0, sizeof (aObjects));
+ mbMultipart = false;
createActions( const_cast<GDIMetaFile&>(rMtf), // HACK(Q2):
// we're
commit 831622453c1e612a06199929d94872a5814ab48f
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:27:19 2010 +0200
vcl-grey-alpha-unix-sal-bitmap.diff: emf+ import
support 8bit alph bitmaps vcl(unx)
diff --git a/vcl/unx/inc/salbmp.h b/vcl/unx/inc/salbmp.h
index 4f0207e..edd43f0 100644
--- a/vcl/unx/inc/salbmp.h
+++ b/vcl/unx/inc/salbmp.h
@@ -57,7 +57,8 @@ private:
int nScreen,
long nDrawableDepth,
long nX, long nY,
- long nWidth, long nHeight );
+ long nWidth, long nHeight,
+ bool bGrey );
public:
@@ -78,6 +79,7 @@ private:
BitmapBuffer* mpDIB;
ImplSalDDB* mpDDB;
+ bool mbGrey;
public:
diff --git a/vcl/unx/source/gdi/salbmp.cxx b/vcl/unx/source/gdi/salbmp.cxx
index 919945f..63805cb 100644
--- a/vcl/unx/source/gdi/salbmp.cxx
+++ b/vcl/unx/source/gdi/salbmp.cxx
@@ -71,7 +71,8 @@ ULONG X11SalBitmap::mnCacheInstCount = 0;
X11SalBitmap::X11SalBitmap() :
mpDIB( NULL ),
- mpDDB( NULL )
+ mpDDB( NULL ),
+ mbGrey( false )
{
}
@@ -191,7 +192,8 @@ BitmapBuffer* X11SalBitmap::ImplCreateDIB( Drawable aDrawable,
int nScreen,
long nDrawableDepth,
long nX, long nY,
- long nWidth, long nHeight )
+ long nWidth, long nHeight,
+ bool bGrey )
{
BitmapBuffer* pDIB = NULL;
@@ -302,6 +304,21 @@ BitmapBuffer* X11SalBitmap::ImplCreateDIB( Drawable aDrawable,
rPal[ 0 ] = Color( COL_BLACK );
rPal[ 1 ] = Color( COL_WHITE );
}
+ else if( pImage->depth == 8 && bGrey )
+ {
+ rPal.SetEntryCount( 256 );
+ pDstPal = &rPal;
+
+ for( USHORT i = 0; i < 256; i++ )
+ {
+ BitmapColor& rBmpCol = rPal[ i ];
+
+ rBmpCol.SetRed( i );
+ rBmpCol.SetGreen( i );
+ rBmpCol.SetBlue( i );
+ }
+
+ }
else if( aSrcBuf.mnBitCount <= 8 )
{
const SalColormap& rColMap = pSalDisp->GetColormap( nScreen );
@@ -345,7 +362,8 @@ XImage* X11SalBitmap::ImplCreateXImage( SalDisplay *pSalDisp, int nScreen, long
mpDDB->ImplGetDepth(),
0, 0,
mpDDB->ImplGetWidth(),
- mpDDB->ImplGetHeight() );
+ mpDDB->ImplGetHeight(),
+ mbGrey );
}
if( mpDIB && mpDIB->mnWidth && mpDIB->mnHeight )
@@ -428,6 +446,20 @@ XImage* X11SalBitmap::ImplCreateXImage( SalDisplay *pSalDisp, int nScreen, long
(*pPal)[ 0 ] = Color( COL_BLACK );
(*pPal)[ 1 ] = Color( COL_WHITE );
}
+ else if( pImage->depth == 8 && mbGrey )
+ {
+ pPal = new BitmapPalette( 256 );
+
+ for( USHORT i = 0; i < 256; i++ )
+ {
+ BitmapColor& rBmpCol = (*pPal)[ i ];
+
+ rBmpCol.SetRed( i );
+ rBmpCol.SetGreen( i );
+ rBmpCol.SetBlue( i );
+ }
+
+ }
else if( pImage->depth <= 8 )
{
const SalColormap& rColMap = pSalDisp->GetColormap( nScreen );
@@ -592,7 +624,8 @@ ImplSalDDB* X11SalBitmap::ImplGetDDB( Drawable aDrawable,
mpDDB->ImplGetDepth(),
0, 0,
mpDDB->ImplGetWidth(),
- mpDDB->ImplGetHeight() );
+ mpDDB->ImplGetHeight(),
+ mbGrey );
}
delete mpDDB, const_cast<X11SalBitmap*>(this)->mpDDB = NULL;
@@ -755,6 +788,8 @@ bool X11SalBitmap::Create( const ::com::sun::star::uno::Reference< ::com::sun::s
if( xFastPropertySet->getFastPropertyValue(bMask ? 2 : 1) >>= args ) {
if( ( args[1] >>= pixmapHandle ) && ( args[2] >>= depth ) ) {
+
+ mbGrey = bMask;
bool bSuccess = ImplCreateFromDrawable( pixmapHandle, 0, depth, 0, 0, (long) rSize.Width(), (long) rSize.Height() );
bool bFreePixmap;
if( bSuccess && (args[0] >>= bFreePixmap) && bFreePixmap )
@@ -824,7 +859,7 @@ BitmapBuffer* X11SalBitmap::AcquireBuffer( bool )
mpDIB = ImplCreateDIB( mpDDB->ImplGetPixmap(),
mpDDB->ImplGetScreen(),
mpDDB->ImplGetDepth(),
- 0, 0, mpDDB->ImplGetWidth(), mpDDB->ImplGetHeight() );
+ 0, 0, mpDDB->ImplGetWidth(), mpDDB->ImplGetHeight(), mbGrey );
}
return mpDIB;
commit cd9daa72d13a3b059c667d5b60f9f06e2608a180
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:19:07 2010 +0200
emf+-crash-fix.diff: emf+ import - fix crash
n#361534
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index 46f643f..699c2d4 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -810,6 +810,10 @@ namespace cppcanvas
EMFPBrush* brush = (EMFPBrush*) aObjects [brushIndexOrColor];
EMFP_DEBUG (printf ("EMF+\tbrush fill slot: %d (type: %d)\n", brushIndexOrColor, brush->GetType ()));
+ // give up in case something wrong happened
+ if( !brush )
+ return;
+
rState.isFillColorSet = false;
rState.isLineColorSet = false;
@@ -1019,7 +1023,8 @@ namespace cppcanvas
aObjects [index] = NULL;
}
- switch (flags & 0xff00) {
+ // not sure yet, what 0x8000 means
+ switch (flags & 0x7f00) {
case EmfPlusObjectTypeBrush:
{
EMFPBrush *brush;
commit bc78f289c47b54e1f0cbfb00ab6ba40ca1a1423c
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:12:11 2010 +0200
emf+-svtools.diff: emf+ import - parse emf+, pass it along in comments
diff --git a/svtools/source/filter.vcl/wmf/enhwmf.cxx b/svtools/source/filter.vcl/wmf/enhwmf.cxx
index 72b7ce5..58ad0d6 100644
--- a/svtools/source/filter.vcl/wmf/enhwmf.cxx
+++ b/svtools/source/filter.vcl/wmf/enhwmf.cxx
@@ -158,6 +158,8 @@
#define EMR_SETLINKEDUFIS 119
#define EMR_SETTEXTJUSTIFICATION 120
+#define EMFP_DEBUG(x)
+//#define EMFP_DEBUG(x) x
//-----------------------------------------------------------------------------------
@@ -229,6 +231,110 @@ static sal_Bool ImplReadRegion( PolyPolygon& rPolyPoly, SvStream& rSt, sal_uInt3
return bOk;
}
+EMFP_DEBUG(void dumpWords( SvStream& s, int i )
+{
+ sal_uInt32 pos = s.Tell();
+ INT16 data;
+ for( ; i > 0; i -- ) {
+ s >> data;
+ EMFP_DEBUG(printf ("\t\t\tdata: %04hx\n", data));
+ }
+ s.Seek (pos);
+});
+
+void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, sal_Bool& bHaveDC)
+{
+ if (!bEMFPlus) {
+ pOut->PassEMFPlusHeaderInfo();
+
+ // debug code - write the stream to debug file /tmp/emf-stream.emf
+ EMFP_DEBUG(int pos = pWMF->Tell();
+ pWMF->Seek(0);
+ SvFileStream file( UniString::CreateFromAscii( "/tmp/emf-stream.emf" ), STREAM_WRITE | STREAM_TRUNC );
+
+ *pWMF >> file;
+ file.Flush();
+ file.Close();
+
+ pWMF->Seek( pos );)
+ }
+ bEMFPlus = true;
+
+ void *buffer = malloc( length );
+
+ int count = 0, next, pos = pWMF->Tell();
+ pOut->PassEMFPlus( buffer, pWMF->Read( buffer, length ) );
+ pWMF->Seek( pos );
+
+ bHaveDC = false;
+
+ length -= 4;
+
+ while (length > 0) {
+ UINT16 type, flags;
+ UINT32 size, dataSize;
+ sal_uInt32 next;
+
+ *pWMF >> type >> flags >> size >> dataSize;
+
+ EMFP_DEBUG(printf ("\t\tEMF+ record type: %d\n", type));
+
+ // GetDC
+ if( type == 16388 ) {
+ bHaveDC = true;
+ EMFP_DEBUG(printf ("\t\tEMF+ lock DC (device context)\n", type));
+ }
+
+ next = pWMF->Tell() + ( size - 12 );
+
+ length -= size;
+
+ pWMF->Seek( next );
+ }
+
+ free( buffer );
+}
+
+void EnhWMFReader::ReadGDIComment()
+{
+ sal_uInt32 type;
+
+ *pWMF >> type;
+
+ switch( type ) {
+ case 2: {
+ sal_Int32 x, y, r, b;
+
+ EMFP_DEBUG(printf ("\t\tBEGINGROUP\n"));
+
+ *pWMF >> x >> y >> r >> b;
+ EMFP_DEBUG(printf ("\t\tbounding rectangle: %d,%d x %d,%d\n", x, y, r, b));
+
+ sal_uInt32 l;
+
+ *pWMF >> l;
+ EMFP_DEBUG(printf ("\t\tdescription length: %d\n", l));
+
+ break;
+ }
+ case 3: {
+ sal_uInt32 x, y, w, h;
+
+ EMFP_DEBUG(printf ("\t\tENDGROUP\n"));
+ break;
+ }
+ case 0x40000004: {
+ sal_uInt32 x, y, w, h;
+
+ EMFP_DEBUG(printf ("\t\tMULTIFORMATS\n"));
+ break;
+ }
+ default:
+ EMFP_DEBUG(printf ("\t\tunknown GDIComment\n"));
+ EMFP_DEBUG(dumpWords (*pWMF, 16));
+ }
+}
+
BOOL EnhWMFReader::ReadEnhWMF()
{
sal_uInt32 nStretchBltMode = 0;
@@ -239,6 +345,14 @@ BOOL EnhWMFReader::ReadEnhWMF()
sal_Int16 nX16, nY16;
sal_Bool bFlag, bStatus = ReadHeader();
+ sal_Bool bHaveDC = false;
+
+#ifdef UNX
+ static sal_Bool bEnableEMFPlus = ( getenv( "EMF_PLUS_DISABLE" ) == NULL );
+#else
+ // TODO: make it possible to disable emf+ on windows
+ static sal_Bool bEnableEMFPlus = sal_True;
+#endif
while( bStatus && nRecordCount-- )
{
@@ -263,6 +377,33 @@ BOOL EnhWMFReader::ReadEnhWMF()
bFlag = sal_False;
+ EMFP_DEBUG(printf ("0x%04x-0x%04x record type: %d size: %d\n", nNextPos - nRecSize, nNextPos, nRecType, nRecSize));
+
+ if( bEnableEMFPlus && nRecType == EMR_GDICOMMENT ) {
+ sal_uInt32 length;
+
+ *pWMF >> length;
+
+ EMFP_DEBUG(printf ("\tGDI comment\n\t\tlength: %d\n", length));
+
+ if( length >= 4 ) {
+ UINT32 id;
+
+ *pWMF >> id;
+
+ EMFP_DEBUG(printf ("\t\tbegin %c%c%c%c id: 0x%x\n", (char)(id & 0xff), (char)((id & 0xff00) >> 8), (char)((id & 0xff0000) >> 16), (char)((id & 0xff000000) >> 24), id));
+
+ // EMF+ comment (fixme: BE?)
+ if( id == 0x2B464D45 && nRecSize >= 12 )
+ ReadEMFPlusComment( length, bHaveDC );
+ // GDIC comment, doesn't do anything useful yet => enabled only for debug
+ else if( id == 0x43494447 && nRecSize >= 12 )
+ EMFP_DEBUG(ReadGDIComment());
+ else
+ EMFP_DEBUG(printf ("\t\tunknown id: 0x%x\n", id));
+ }
+ } else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
+
switch( nRecType )
{
case EMR_POLYBEZIERTO :
diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx
index d6cb262..b333315 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.cxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.cxx
@@ -38,6 +38,9 @@
#define WIN_MTF_MAX_CLIP_DEPTH 16
+#define EMFP_DEBUG(x)
+//#define EMFP_DEBUG(x) x
+
void WinMtfClipPath::ImpUpdateType()
{
if ( !aPolyPoly.Count() )
@@ -2201,3 +2204,36 @@ void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile )
rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF );
}
+void WinMtfOutput::PassEMFPlusHeaderInfo()
+{
+ EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS header info\n"));
+
+ SvMemoryStream mem;
+ sal_Int32 nLeft, nRight, nTop, nBottom;
+
+ nLeft = mrclFrame.Left();
+ nTop = mrclFrame.Top();
+ nRight = mrclFrame.Right();
+ nBottom = mrclFrame.Bottom();
+
+ // emf header info
+ mem << nLeft << nTop << nRight << nBottom;
+ mem << mnPixX << mnPixY << mnMillX << mnMillY;
+
+ float one, zero;
+
+ one = 1;
+ zero = 0;
+
+ // add transformation matrix to be used in vcl's metaact.cxx for
+ // rotate and scale operations
+ mem << one << zero << zero << one << zero << zero;
+
+ mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS_HEADER_INFO", 0, (const BYTE*) mem.GetData(), mem.GetEndOfData() ) );
+}
+
+void WinMtfOutput::PassEMFPlus( void* pBuffer, UINT32 nLength )
+{
+ EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS comment length %d\n", nLength));
+ mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS", 0, static_cast<const BYTE*>(pBuffer), nLength ) );
+}
diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx
index 4ea701e..aed3c93 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.hxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.hxx
@@ -672,6 +672,9 @@ class WinMtfOutput
void UpdateClipRegion();
void AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile );
+ void PassEMFPlus( void* pBuffer, UINT32 nLength );
+ void PassEMFPlusHeaderInfo();
+
WinMtfOutput( GDIMetaFile& rGDIMetaFile );
virtual ~WinMtfOutput();
};
@@ -710,6 +713,8 @@ class EnhWMFReader : public WinMtf
{
sal_Bool bRecordPath;
sal_Int32 nRecordCount;
+ BOOL bEMFPlus;
+
BOOL ReadHeader();
Rectangle ReadRectangle( INT32, INT32, INT32, INT32 ); // Liesst und konvertiert ein Rechteck
@@ -717,10 +722,12 @@ class EnhWMFReader : public WinMtf
public:
EnhWMFReader( SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, FilterConfigItem* pConfigItem = NULL )
- : WinMtf( new WinMtfOutput( rGDIMetaFile ), rStreamWMF, pConfigItem ), bRecordPath( sal_False ) {};
+ : WinMtf( new WinMtfOutput( rGDIMetaFile ), rStreamWMF, pConfigItem ), bRecordPath( sal_False ), bEMFPlus (FALSE) {};
~EnhWMFReader();
BOOL ReadEnhWMF();
+ void ReadEMFPlusComment(sal_uInt32 length, sal_Bool& bHaveDC);
+ void ReadGDIComment();
};
//============================ WMFReader ==================================
commit c5bc73cb1d50181de339d108e1181aabe6aefad7
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:11:04 2010 +0200
emf+-vcl-renderer.diff: emf+ import - use cppcanvas renderer in vcl
diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx
index 8fa5c17..e17f3eb 100644
--- a/vcl/inc/vcl/gdimtf.hxx
+++ b/vcl/inc/vcl/gdimtf.hxx
@@ -135,6 +135,7 @@ private:
const OutputDevice& rMapDev,
const PolyPolygon& rPolyPoly,
const Gradient& rGrad );
+ SAL_DLLPRIVATE bool ImplPlayWithRenderer( OutputDevice* pOut, const Point& rPos, Size rDestSize );
//#endif // __PRIVATE
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index 22f5f37..412711b 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -35,12 +35,24 @@
#include <vcl/salbtype.hxx>
#include <vcl/outdev.hxx>
#include <vcl/window.hxx>
-#ifndef _SV_CVTSVM_HXX
#include <vcl/cvtsvm.hxx>
-#endif
#include <vcl/virdev.hxx>
+#include <vcl/salbmp.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/svdata.hxx>
+#include <vcl/salinst.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/graphictools.hxx>
+#include <vcl/canvastools.hxx>
+#include <vcl/unohelp.hxx>
+
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/rendering/MtfRenderer.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+using namespace com::sun::star;
// -----------
// - Defines -
@@ -475,6 +487,76 @@ void GDIMetaFile::Play( OutputDevice* pOut, ULONG nPos )
// ------------------------------------------------------------------------
+bool GDIMetaFile::ImplPlayWithRenderer( OutputDevice* pOut, const Point& rPos, Size rDestSize )
+{
+ const Window* win = dynamic_cast <Window*> ( pOut );
+
+ if (!win)
+ win = Application::GetActiveTopWindow();
+ if (!win)
+ win = Application::GetFirstTopLevelWindow();
+
+ if (win) {
+ const uno::Reference<rendering::XCanvas>& xCanvas = win->GetCanvas ();
+ Size aSize (rDestSize.Width () + 1, rDestSize.Height () + 1);
+ const uno::Reference<rendering::XBitmap>& xBitmap = xCanvas->getDevice ()->createCompatibleAlphaBitmap (vcl::unotools::integerSize2DFromSize( aSize));
+ uno::Reference< lang::XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory();
+ if( xFactory.is() && xBitmap.is () ) {
+ uno::Reference< rendering::XMtfRenderer > xMtfRenderer;
+ uno::Sequence< uno::Any > args (1);
+ uno::Reference< rendering::XBitmapCanvas > xBitmapCanvas( xBitmap, uno::UNO_QUERY );
+ if( xBitmapCanvas.is() ) {
+ args[0] = uno::Any( xBitmapCanvas );
+ xMtfRenderer.set( xFactory->createInstanceWithArguments( ::rtl::OUString::createFromAscii( "com.sun.star.rendering.MtfRenderer" ),
+ args ), uno::UNO_QUERY );
+
+ if( xMtfRenderer.is() ) {
+ xBitmapCanvas->clear();
+ uno::Reference< beans::XFastPropertySet > xMtfFastPropertySet( xMtfRenderer, uno::UNO_QUERY );
+ if( xMtfFastPropertySet.is() )
+ // set this metafile to the renderer to
+ // speedup things (instead of copying data to
+ // sequence of bytes passed to renderer)
+ xMtfFastPropertySet->setFastPropertyValue( 0, uno::Any( reinterpret_cast<sal_Int64>( this ) ) );
+
+ xMtfRenderer->draw( rDestSize.Width(), rDestSize.Height() );
+
+ uno::Reference< beans::XFastPropertySet > xFastPropertySet( xBitmapCanvas, uno::UNO_QUERY );
+ if( xFastPropertySet.get() ) {
+ // 0 means get BitmapEx
+ uno::Any aAny = xFastPropertySet->getFastPropertyValue( 0 );
+ BitmapEx* pBitmapEx = (BitmapEx*) *reinterpret_cast<const sal_Int64*>(aAny.getValue());
+ if( pBitmapEx ) {
+ pOut->DrawBitmapEx( rPos, *pBitmapEx );
+ delete pBitmapEx;
+ return true;
+ }
+ }
+
+ SalBitmap* pSalBmp = ImplGetSVData()->mpDefInst->CreateSalBitmap();
+ SalBitmap* pSalMask = ImplGetSVData()->mpDefInst->CreateSalBitmap();
+
+ if( pSalBmp->Create( xBitmapCanvas, aSize ) && pSalMask->Create( xBitmapCanvas, aSize, true ) ) {
+ Bitmap aBitmap( pSalBmp );
+ Bitmap aMask( pSalMask );
+ AlphaMask aAlphaMask( aMask );
+ BitmapEx aBitmapEx( aBitmap, aAlphaMask );
+ pOut->DrawBitmapEx( rPos, aBitmapEx );
+ return true;
+ }
+
+ delete pSalBmp;
+ delete pSalMask;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+// ------------------------------------------------------------------------
+
void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos,
const Size& rSize, ULONG nPos )
{
@@ -484,9 +566,13 @@ void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos,
if( aDestSize.Width() && aDestSize.Height() )
{
- Size aTmpPrefSize( pOut->LogicToPixel( GetPrefSize(), aDrawMap ) );
GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
+ if( !pMtf && ImplPlayWithRenderer( pOut, rPos, aDestSize ) )
+ return;
+
+ Size aTmpPrefSize( pOut->LogicToPixel( GetPrefSize(), aDrawMap ) );
+
if( !aTmpPrefSize.Width() )
aTmpPrefSize.Width() = aDestSize.Width();
diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx
index 99db8a8..b91fd92 100644
--- a/vcl/source/gdi/metaact.cxx
+++ b/vcl/source/gdi/metaact.cxx
@@ -4093,6 +4093,7 @@ void MetaCommentAction::Move( long nXMove, long nYMove )
// SJ: 25.07.06 #i56656# we are not able to mirrorcertain kind of
// comments properly, especially the XPATHSTROKE and XPATHFILL lead to
// problems, so it is better to remove these comments when mirroring
+// FIXME: fake comment to apply the next hunk in the right location
void MetaCommentAction::Scale( double fXScale, double fYScale )
{
if ( ( fXScale != 1.0 ) || ( fYScale != 1.0 ) )
@@ -4126,6 +4127,32 @@ void MetaCommentAction::Scale( double fXScale, double fYScale )
}
delete[] mpData;
ImplInitDynamicData( static_cast<const BYTE*>( aDest.GetData() ), aDest.Tell() );
+ } else if( maComment.Equals( "EMF_PLUS_HEADER_INFO" ) ) {
+ SvMemoryStream aMemStm( (void*)mpData, mnDataSize, STREAM_READ );
+ SvMemoryStream aDest;
+
+ sal_Int32 nLeft, nRight, nTop, nBottom;
+ sal_Int32 nPixX, nPixY, nMillX, nMillY;
+ float m11, m12, m21, m22, mdx, mdy;
+
+ // read data
+ aMemStm >> nLeft >> nTop >> nRight >> nBottom;
+ aMemStm >> nPixX >> nPixY >> nMillX >> nMillY;
+ aMemStm >> m11 >> m12 >> m21 >> m22 >> mdx >> mdy;
+
+ // add scale to the transformation
+ m11 *= fXScale;
+ m12 *= fXScale;
+ m22 *= fYScale;
+ m21 *= fYScale;
+
+ // prepare new data
+ aDest << nLeft << nTop << nRight << nBottom;
+ aDest << nPixX << nPixY << nMillX << nMillY;
+ aDest << m11 << m12 << m21 << m22 << mdx << mdy;
+
+ // save them
+ ImplInitDynamicData( static_cast<const BYTE*>( aDest.GetData() ), aDest.Tell() );
}
}
}
commit 9bf0a742366659d7945383592fc4c59f64579f87
Author: Radek Doulik <rodo at novell.com>
Date: Wed Sep 15 11:02:24 2010 +0200
emf+-vcl-bitmap.diff: emf+ import - create vcl bitmap from XBitmap
diff --git a/vcl/aqua/inc/salbmp.h b/vcl/aqua/inc/salbmp.h
index 1dd2b55..c51582a 100644
--- a/vcl/aqua/inc/salbmp.h
+++ b/vcl/aqua/inc/salbmp.h
@@ -74,6 +74,9 @@ public:
bool Create( const SalBitmap& rSalBmp );
bool Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics );
bool Create( const SalBitmap& rSalBmp, USHORT nNewBitCount );
+ virtual bool Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
+ Size& rSize,
+ bool bMask = false );
void Destroy();
diff --git a/vcl/aqua/source/gdi/salbmp.cxx b/vcl/aqua/source/gdi/salbmp.cxx
index c008d4e..629c618 100644
--- a/vcl/aqua/source/gdi/salbmp.cxx
+++ b/vcl/aqua/source/gdi/salbmp.cxx
@@ -153,6 +153,13 @@ bool AquaSalBitmap::Create( const SalBitmap& rSalBmp, USHORT nNewBitCount )
// ------------------------------------------------------------------
+bool AquaSalBitmap::Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
+{
+ return false;
+}
+
+// ------------------------------------------------------------------
+
void AquaSalBitmap::Destroy()
{
DestroyContext();
diff --git a/vcl/inc/vcl/salbmp.hxx b/vcl/inc/vcl/salbmp.hxx
index 2018023..e48a434 100644
--- a/vcl/inc/vcl/salbmp.hxx
+++ b/vcl/inc/vcl/salbmp.hxx
@@ -33,6 +33,8 @@
#endif
#include <vcl/dllapi.h>
+#include <com/sun/star/rendering/XBitmapCanvas.hpp>
+
struct BitmapBuffer;
class SalGraphics;
class BitmapPalette;
@@ -52,6 +54,9 @@ public:
SalGraphics* pGraphics ) = 0;
virtual bool Create( const SalBitmap& rSalBmp,
USHORT nNewBitCount ) = 0;
+ virtual bool Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
+ Size& rSize,
+ bool bMask = false ) = 0;
virtual void Destroy() = 0;
virtual Size GetSize() const = 0;
virtual USHORT GetBitCount() const = 0;
... etc. - the rest is truncated
More information about the ooo-build-commit
mailing list