[Libreoffice-commits] .: 3 commits - cppcanvas/source svtools/source

Thorsten Behrens thorsten at kemper.freedesktop.org
Tue Oct 26 14:38:46 PDT 2010


 cppcanvas/source/mtfrenderer/implrenderer.cxx |    4 
 svtools/source/filter.vcl/wmf/winmtf.cxx      |  182 +++++++++-----------------
 svtools/source/filter.vcl/wmf/winmtf.hxx      |   38 ++---
 svtools/source/misc/embedhlp.cxx              |    4 
 4 files changed, 90 insertions(+), 138 deletions(-)

New commits:
commit 2f6d56c470e7e2a31d4b2e1d58751bca36222bdb
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Tue Oct 26 23:17:53 2010 +0200

    Speed up wmf clipping
    
    Make use of basegfx rect clipper in wmf import. Greatly speeds
    up reading WMFs with lots of clip actions. Fixes n#535304, applies
    patches/dev300/svtools-wmf-clipperf.diff

diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx
index 33dbdab..007a56e 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.cxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.cxx
@@ -31,8 +31,11 @@
 
 
 #include "winmtf.hxx"
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
 #include <vcl/metaact.hxx>
 #include <vcl/graphictools.hxx>
+#include <vcl/canvastools.hxx>
 #include <vcl/metric.hxx>
 #include <rtl/tencinfo.h>
 
@@ -43,103 +46,56 @@
 #define EMFP_DEBUG(x)
 //#define EMFP_DEBUG(x) x
 
-void WinMtfClipPath::ImpUpdateType()
+void WinMtfClipPath::intersectClipRect( const Rectangle& rRect )
 {
-    if ( !aPolyPoly.Count() )
-        eType = EMPTY;
-    else if ( aPolyPoly.IsRect() )
-        eType = RECTANGLE;
-    else
-        eType = COMPLEX;
-
-    bNeedsUpdate = sal_True;
+    maClip.intersectRange(
+        vcl::unotools::b2DRectangleFromRectangle(rRect));
 }
 
-void WinMtfClipPath::IntersectClipRect( const Rectangle& rRect )
+void WinMtfClipPath::excludeClipRect( const Rectangle& rRect )
 {
-    if ( !aPolyPoly.Count() )
-        aPolyPoly = Polygon( rRect );
-    else if ( nDepth < WIN_MTF_MAX_CLIP_DEPTH )
-    {
-        Polygon aPolygon( rRect );
-        PolyPolygon aIntersection;
-        PolyPolygon aPolyPolyRect( aPolygon );
-        aPolyPoly.GetIntersection( aPolyPolyRect, aIntersection );
-        aPolyPoly = aIntersection;
-        nDepth++;
-    }
-    ImpUpdateType();
+    maClip.subtractRange(
+        vcl::unotools::b2DRectangleFromRectangle(rRect));
 }
 
-void WinMtfClipPath::ExcludeClipRect( const Rectangle& rRect )
+void WinMtfClipPath::setClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode )
 {
-    if ( aPolyPoly.Count() && ( nDepth < WIN_MTF_MAX_CLIP_DEPTH ) )
+    const basegfx::B2DPolyPolygon& rB2DPoly=rPolyPolygon.getB2DPolyPolygon();
+    switch ( nClippingMode )
     {
-        Polygon aPolygon( rRect );
-        PolyPolygon aPolyPolyRect( aPolygon );
-        PolyPolygon aDifference;
-        aPolyPoly.GetDifference( aPolyPolyRect, aDifference );
-        aPolyPoly = aDifference;
-        nDepth++;
-    }
-    ImpUpdateType();
-}
-
-void WinMtfClipPath::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode )
-{
-    if ( !rPolyPolygon.Count() )
-        aPolyPoly = rPolyPolygon;
-    else if ( nDepth < WIN_MTF_MAX_CLIP_DEPTH )
-    {
-        nDepth++;
-
-        PolyPolygon aNewClipPath;
-
-        // #115345# Watch out for empty aPolyPoly here - conceptually,
-        // an empty clip path is a rectangle of infinite size, but it
-        // is represented by an empty aPolyPoly. When intersecting
-        // rPolyPolygon with this _empty_ aPolyPoly, set algebra
-        // guarantees wrong results.
-        switch ( nClippingMode )
-        {
-            case RGN_OR :
-                // #115345# clip stays empty, when ORing an arbitrary
-                // rPolyPolygon. Thus, we can save us the unnecessary
-                // clipper call.
-                if( aPolyPoly.Count() )
-                    aPolyPoly.GetUnion( rPolyPolygon, aNewClipPath );
+        case RGN_OR :
+            maClip.unionPolyPolygon(rB2DPoly);
             break;
-            case RGN_XOR :
-                // TODO:
-                // #115345# Cannot handle this case, for the time being
-                aPolyPoly.GetXOR( rPolyPolygon, aNewClipPath );
+        case RGN_XOR :
+            maClip.xorPolyPolygon(rB2DPoly);
             break;
-            case RGN_DIFF :
-                // TODO:
-                // #115345# Cannot handle this case, for the time being
-                aPolyPoly.GetDifference( rPolyPolygon, aNewClipPath );
+        case RGN_DIFF :
+            maClip.subtractPolyPolygon(rB2DPoly);
             break;
-            case RGN_AND :
-                // #115345# Clip becomes rPolyPolygon, when ANDing
-                // with an arbitrary rPolyPolygon
-                if( aPolyPoly.Count() )
-                    aPolyPoly.GetIntersection( rPolyPolygon, aNewClipPath );
-                else
-                    aNewClipPath = rPolyPolygon;
+        case RGN_AND :
+            maClip.intersectPolyPolygon(rB2DPoly);
             break;
-            case RGN_COPY :
-                aNewClipPath = rPolyPolygon;
+        case RGN_COPY :
+            maClip = basegfx::tools::B2DClipState(rB2DPoly);
             break;
-        }
-        aPolyPoly = aNewClipPath;
     }
-    ImpUpdateType();
 }
 
-void WinMtfClipPath::MoveClipRegion( const Size& rSize )
+void WinMtfClipPath::moveClipRegion( const Size& rSize )
+{
+    // what a weird concept. emulate, don't want this in B2DClipState
+    // API
+    basegfx::B2DPolyPolygon aCurrClip=maClip.getClipPoly();
+    basegfx::B2DHomMatrix aTranslate;
+    aTranslate.translate(rSize.Width(), rSize.Height());
+
+    aCurrClip.transform(aTranslate);
+    maClip = basegfx::tools::B2DClipState( aCurrClip );
+}
+
+basegfx::B2DPolyPolygon WinMtfClipPath::getClipPath() const
 {
-    aPolyPoly.Move( rSize.Width(), rSize.Height() );
-    bNeedsUpdate = sal_True;
+    return maClip.getClipPoly();
 }
 
 // ------------------------------------------------------------------------
@@ -884,31 +840,35 @@ void WinMtfOutput::DeleteObject( sal_Int32 nIndex )
 
 void WinMtfOutput::IntersectClipRect( const Rectangle& rRect )
 {
-    aClipPath.IntersectClipRect( ImplMap( rRect ) );
+    mbClipNeedsUpdate=true;
+    aClipPath.intersectClipRect( ImplMap( rRect ) );
 }
 
 //-----------------------------------------------------------------------------------
 
 void WinMtfOutput::ExcludeClipRect( const Rectangle& rRect )
 {
-    aClipPath.ExcludeClipRect( ImplMap( rRect ) );
+    mbClipNeedsUpdate=true;
+    aClipPath.excludeClipRect( ImplMap( rRect ) );
 }
 
 //-----------------------------------------------------------------------------------
 
 void WinMtfOutput::MoveClipRegion( const Size& rSize )
 {
-    aClipPath.MoveClipRegion( ImplMap( rSize ) );
+    mbClipNeedsUpdate=true;
+    aClipPath.moveClipRegion( ImplMap( rSize ) );
 }
 
 void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode, sal_Bool bIsMapped )
 {
+    mbClipNeedsUpdate=true;
     if ( bIsMapped )
-        aClipPath.SetClipPath( rPolyPolygon, nClippingMode );
+        aClipPath.setClipPath( rPolyPolygon, nClippingMode );
     else
     {
         PolyPolygon aPP( rPolyPolygon );
-        aClipPath.SetClipPath( ImplMap( aPP ), nClippingMode );
+        aClipPath.setClipPath( ImplMap( aPP ), nClippingMode );
     }
 }
 
@@ -930,6 +890,8 @@ WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
     maActPos			( Point() ),
     mbNopMode			( sal_False ),
     mbFillStyleSelected	( sal_False ),
+    mbClipNeedsUpdate   ( true ),
+    mbComplexClip       ( false ),
     mnGfxMode			( GM_COMPATIBLE ),
     mnMapMode           ( MM_TEXT ),
     mnDevOrgX			( 0 ),
@@ -981,31 +943,25 @@ WinMtfOutput::~WinMtfOutput()
 
 void WinMtfOutput::UpdateClipRegion()
 {
-    if ( aClipPath.bNeedsUpdate )
+    if ( mbClipNeedsUpdate )
     {
-        aClipPath.bNeedsUpdate = sal_False;
+        mbClipNeedsUpdate = false;
+        mbComplexClip = false;
 
         mpGDIMetaFile->AddAction( new MetaPopAction() );                    // taking the orignal clipregion
         mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) );  // 
 
-        switch ( aClipPath.GetType() )
+        // skip for 'no clipping at all' case
+        if( !aClipPath.isEmpty() )
         {
-            case RECTANGLE :
-            case COMPLEX :
-            {
-//				we will not generate a RegionClipRegion Action, because this action
-//				cannot be saved to the wmf format - saving to wmf always happens
-//				if the placeholder graphic for ole objects is generated. (SJ)
-
-//				Region aClipRegion( aClipPath.GetClipPath() );
-//				mpGDIMetaFile->AddAction( new MetaISectRegionClipRegionAction( aClipRegion ) );
-
-                Rectangle aClipRect( aClipPath.GetClipPath().GetBoundRect() );
-                mpGDIMetaFile->AddAction( new MetaISectRectClipRegionAction( aClipRect ) );
-            }
-            break;
-            case EMPTY:
-            break;  // -Wall not handled.
+            const basegfx::B2DPolyPolygon& rClipPoly( aClipPath.getClipPath() );
+            mpGDIMetaFile->AddAction(
+                new MetaISectRectClipRegionAction(
+                    vcl::unotools::rectangleFromB2DRectangle(
+                        rClipPoly.getB2DRange())));
+
+            mbComplexClip = rClipPoly.count() > 1
+                || !basegfx::tools::isRectangle(rClipPoly);
         }
     }
 }
@@ -1184,12 +1140,12 @@ void WinMtfOutput::DrawRect( const Rectangle& rRect, BOOL bEdge )
     UpdateClipRegion();
     UpdateFillStyle();
 
-    if ( aClipPath.GetType() == COMPLEX )
+    if ( mbComplexClip )
     {
         Polygon aPoly( ImplMap( rRect ) );
         PolyPolygon aPolyPolyRect( aPoly );
         PolyPolygon aDest;
-        aClipPath.GetClipPath().GetIntersection( aPolyPolyRect, aDest );
+        PolyPolygon(aClipPath.getClipPath()).GetIntersection( aPolyPolyRect, aDest );
         ImplDrawClippedPolyPolygon( aDest );
     }
     else
@@ -1344,11 +1300,11 @@ void WinMtfOutput::DrawPolygon( Polygon& rPolygon, sal_Bool bRecordPath )
     {
         UpdateFillStyle();
 
-        if ( aClipPath.GetType() == COMPLEX )
+        if ( mbComplexClip )
         {
             PolyPolygon aPolyPoly( rPolygon );
             PolyPolygon aDest;
-            aClipPath.GetClipPath().GetIntersection( aPolyPoly, aDest );
+            PolyPolygon(aClipPath.getClipPath()).GetIntersection( aPolyPoly, aDest );
             ImplDrawClippedPolyPolygon( aDest );
         }
         else
@@ -1420,10 +1376,10 @@ void WinMtfOutput::DrawPolyPolygon( PolyPolygon& rPolyPolygon, sal_Bool bRecordP
     {
         UpdateFillStyle();
 
-        if ( aClipPath.GetType() == COMPLEX )
+        if ( mbComplexClip )
         {
             PolyPolygon aDest;
-            aClipPath.GetClipPath().GetIntersection( rPolyPolygon, aDest );	
+            PolyPolygon(aClipPath.getClipPath()).GetIntersection( rPolyPolygon, aDest );
             ImplDrawClippedPolyPolygon( aDest );
         }
         else
@@ -1658,7 +1614,7 @@ void WinMtfOutput::DrawText( Point& rPosition, String& rText, sal_Int32* pDXArry
 void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const BitmapEx rBitmap )
 {
     BitmapEx aBmpEx( rBitmap );
-    if ( aClipPath.GetType() == COMPLEX )
+    if ( mbComplexClip )
     {
         VirtualDevice aVDev;
         MapMode aMapMode( MAP_100TH_MM );
@@ -1673,7 +1629,7 @@ void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const B
         aVDev.SetMapMode( aMapMode );
         aVDev.SetOutputSizePixel( aSizePixel );
         aVDev.SetFillColor( Color( COL_BLACK ) );
-        const PolyPolygon aClip( aClipPath.GetClipPath() );
+        const PolyPolygon aClip( aClipPath.getClipPath() );
         aVDev.DrawPolyPolygon( aClip );
         const Point aEmptyPoint;
 
@@ -2222,7 +2178,7 @@ void WinMtfOutput::Pop()
         if ( ! ( aClipPath == pSave->aClipPath ) )
         {
             aClipPath = pSave->aClipPath;
-            aClipPath.bNeedsUpdate = sal_True;
+            mbClipNeedsUpdate = true;
         }
         if ( meLatestRasterOp != meRasterOp )
             mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx
index e09cb0c..9f2a1b3 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.hxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.hxx
@@ -42,6 +42,7 @@
 #include <vcl/graph.hxx>
 #include <vcl/virdev.hxx>
 #include <tools/poly.hxx>
+#include <basegfx/tools/b2dclipstate.hxx>
 #include <vcl/font.hxx>
 #include <vcl/bmpacc.hxx>
 #include <vcl/lineinfo.hxx>
@@ -305,35 +306,26 @@ struct LOGFONTW
 void WinMtfAssertHandler( const sal_Char*, sal_uInt32 nFlags = WIN_MTF_ASSERT_MIFE );
 #endif 
 
-enum WinMtfClipPathType{ EMPTY, RECTANGLE, COMPLEX };
-
 class WinMtfClipPath
 {
-        PolyPolygon			aPolyPoly;
-        WinMtfClipPathType	eType;
-        sal_Int32			nDepth;
-
-        void		ImpUpdateType();
-
-    public :
+    basegfx::tools::B2DClipState maClip;
 
-        sal_Bool	bNeedsUpdate;
+public :
+    WinMtfClipPath(): maClip() {};
 
-                    WinMtfClipPath(): eType(EMPTY), nDepth( 0 ), bNeedsUpdate( sal_False ){};
+    void		setClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode );
+    void		intersectClipRect( const Rectangle& rRect );
+    void		excludeClipRect( const Rectangle& rRect );
+    void		moveClipRegion( const Size& rSize );
 
-        void		SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode );
-        void		IntersectClipRect( const Rectangle& rRect );
-        void		ExcludeClipRect( const Rectangle& rRect );
-        void		MoveClipRegion( const Size& rSize );
+    bool isEmpty() const { return maClip.isCleared(); }
 
-        WinMtfClipPathType GetType() const { return eType; };
-        const PolyPolygon& GetClipPath() const { return aPolyPoly; };
+    basegfx::B2DPolyPolygon getClipPath() const;
 
-        sal_Bool operator==( const WinMtfClipPath& rPath )
-        {
-            return  ( rPath.eType == eType ) &&
-                    ( rPath.aPolyPoly == aPolyPoly );
-        };
+    bool operator==( const WinMtfClipPath& rPath ) const
+    {
+        return maClip == rPath.maClip;
+    };
 };
 
 class WinMtfPathObj : public PolyPolygon
@@ -579,6 +571,8 @@ class WinMtfOutput
         sal_uInt32          mnRop;
         sal_Bool            mbNopMode;
         sal_Bool			mbFillStyleSelected;
+        sal_Bool            mbClipNeedsUpdate;
+        sal_Bool            mbComplexClip;
 
         std::vector< SaveStructPtr > vSaveStack;
 
commit 9d56280e616424294c35af504eccd429fdd182be
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Tue Oct 26 22:25:56 2010 +0200

    Fix refresh of OLE object previews
    
    A fix for n#411855, to make preview object refresh in all cases.
    Applied patch svtools-update-ole.diff

diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
index 5e614cb..23805a4 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -180,7 +180,9 @@ void SAL_CALL EmbedEventListener_Impl::modified( const lang::EventObject& ) thro
             else
                 pObject->UpdateReplacement();
         }
-        else if ( nState == embed::EmbedStates::UI_ACTIVE || nState == embed::EmbedStates::INPLACE_ACTIVE )
+        else if ( nState == embed::EmbedStates::ACTIVE ||
+                  nState == embed::EmbedStates::UI_ACTIVE ||
+                  nState == embed::EmbedStates::INPLACE_ACTIVE )
         {
             // in case the object is inplace or UI active the replacement image should be updated on demand
             pObject->UpdateReplacementOnDemand();
commit 896a69c1053be0a686acc4ae13f4958e6c856586
Author: Radek Doulik <rodo at novell.com>
Date:   Tue Oct 26 22:19:52 2010 +0200

    Fix round corner bug in canvas
    
     * cppcanvas/source/mtfrenderer/implrenderer.cxx: fixed round
       corners rectangle drawing (basegfx tools use portion of width and
       height to specify the corners width and height)

diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx b/cppcanvas/source/mtfrenderer/implrenderer.cxx
index ddb7ce0..4429ece 100644
--- a/cppcanvas/source/mtfrenderer/implrenderer.cxx
+++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx
@@ -2020,8 +2020,8 @@ namespace cppcanvas
                                     ::vcl::unotools::b2DPointFromPoint( rRect.TopLeft() ),
                                     ::vcl::unotools::b2DPointFromPoint( rRect.BottomRight() ) +
                                     ::basegfx::B2DPoint(1,1) ),
-                                static_cast<MetaRoundRectAction*>(pCurrAct)->GetHorzRound(),
-                                static_cast<MetaRoundRectAction*>(pCurrAct)->GetVertRound() ));
+                                ( (double) static_cast<MetaRoundRectAction*>(pCurrAct)->GetHorzRound() ) / rRect.GetWidth(),
+                                ( (double) static_cast<MetaRoundRectAction*>(pCurrAct)->GetVertRound() ) / rRect.GetHeight() ) );
                         aPoly.transform( getState( rStates ).mapModeTransform );
 
                         createFillAndStroke( aPoly,


More information about the Libreoffice-commits mailing list