[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