[Libreoffice-commits] core.git: svx/source sw/qa vcl/source

Armin Le Grand alg at apache.org
Wed Mar 13 06:41:00 PDT 2013


 svx/source/svdraw/svdfmtf.cxx            |  174 +++++++++++++++++++++++--------
 svx/source/svdraw/svdfmtf.hxx            |   20 ++-
 svx/source/svdraw/svdxcgv.cxx            |   32 ++---
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx |    2 
 vcl/source/gdi/metaact.cxx               |    3 
 vcl/source/gdi/outdev6.cxx               |    3 
 vcl/source/gdi/outmap.cxx                |   11 +
 7 files changed, 180 insertions(+), 65 deletions(-)

New commits:
commit 684c502ed0a6782fe1b9c7d7cd1911a4a88b543a
Author: Armin Le Grand <alg at apache.org>
Date:   Tue May 8 08:27:10 2012 +0000

    Related: #119125# Added usage of the ClipRegion for dismantling Metafiles
    
    to SdrObjects (ImpSdrGDIMetaFileImport) as good as possible with Metafile usage
    
    Conflicts:
    	svx/source/svdraw/svdfmtf.cxx
    	svx/source/svdraw/svdfmtf.hxx
    
    Change-Id: I41422696e97f919e618f7e385c68d4ac737a52c1

diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
index 7e38fc6..1d9b948 100644
--- a/svx/source/svdraw/svdfmtf.cxx
+++ b/svx/source/svdraw/svdfmtf.cxx
@@ -61,6 +61,8 @@
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <svx/xlinjoit.hxx>
 #include <svx/xlndsit.hxx>
+#include <basegfx/polygon/b2dpolygonclipper.hxx>
+#include <svx/xbtmpit.hxx>
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -74,7 +76,11 @@ ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(SdrModel& rModel):
     maDash(XDASH_RECT, 0, 0, 0, 0, 0),
     fScaleX(0.0),fScaleY(0.0),
     bFntDirty(sal_True),
-    bLastObjWasPolyWithoutLine(sal_False),bNoLine(sal_False),bNoFill(sal_False),bLastObjWasLine(sal_False)
+    bLastObjWasPolyWithoutLine(sal_False),
+    bNoLine(sal_False),
+    bNoFill(sal_False),
+    bLastObjWasLine(sal_False),
+    maClip()
 {
     aVD.EnableOutput(sal_False);
 
@@ -87,6 +93,7 @@ ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(SdrModel& rModel):
     pFillAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST);
     pTextAttr=new SfxItemSet(rModel.GetItemPool(),EE_ITEMS_START,EE_ITEMS_END);
     pModel=&rModel;
+    checkClip();
 }
 
 ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
@@ -371,7 +378,7 @@ void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr
     }
 }
 
-void ImpSdrGDIMetaFileImport::InsertObj( SdrObject* pObj, sal_Bool bScale )
+void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, sal_Bool bScale)
 {
     if ( bScale && !aScaleRect.IsEmpty() )
     {
@@ -381,60 +388,123 @@ void ImpSdrGDIMetaFileImport::InsertObj( SdrObject* pObj, sal_Bool bScale )
             pObj->NbcMove( Size( aOfs.X(), aOfs.Y() ) );
     }
 
-    // #i111954# check object for visibility
-    // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
-    bool bVisible(false);
-
-    if(pObj->HasLineStyle())
+    if(isClip())
     {
-        bVisible = true;
-    }
+        const basegfx::B2DPolyPolygon aPoly(pObj->TakeXorPoly());
+        const basegfx::B2DRange aOldRange(aPoly.getB2DRange());
+        const SdrLayerID aOldLayer(pObj->GetLayer());
+        const SfxItemSet aOldItemSet(pObj->GetMergedItemSet());
+        const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
+        BitmapEx aBitmapEx;
+
+        if(pSdrGrafObj)
+        {
+            aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
+        }
 
-    if(!bVisible && pObj->HasFillStyle())
-    {
-        bVisible = true;
+        SdrObject::Free(pObj);
+
+        if(!aOldRange.isEmpty())
+        {
+            // clip against ClipRegion
+            const basegfx::B2DPolyPolygon aNewPoly(
+                basegfx::tools::clipPolyPolygonOnPolyPolygon(
+                    aPoly,
+                    maClip,
+                    true,
+                    aPoly.isClosed() ? false : true));
+            const basegfx::B2DRange aNewRange(aNewPoly.getB2DRange());
+
+            if(!aNewRange.isEmpty())
+            {
+                pObj = new SdrPathObj(
+                    aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN,
+                    aNewPoly);
+
+                pObj->SetLayer(aOldLayer);
+                pObj->SetMergedItemSet(aOldItemSet);
+
+                if(!!aBitmapEx)
+                {
+                    // aNewRange is inside of aOldRange and defines which part of aBitmapEx is used
+                    const double fLclScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
+                    const double fLclScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
+                    basegfx::B2DRange aPixel(aNewRange);
+                    basegfx::B2DHomMatrix aTrans;
+
+                    aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
+                    aTrans.scale(fLclScaleX, fLclScaleY);
+                    aPixel.transform(aTrans);
+
+                    const BitmapEx aClippedBitmap(
+                        aBitmapEx,
+                        Point(floor(std::max(0.0, aPixel.getMinX())), floor(std::max(0.0, aPixel.getMinY()))),
+                        Size(ceil(aPixel.getWidth()), ceil(aPixel.getHeight())));
+
+                    pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP));
+                    pObj->SetMergedItem(XFillBitmapItem(String(), aClippedBitmap.GetBitmap()));
+                }
+            }
+        }
     }
 
-    if(!bVisible)
+    if(pObj)
     {
-        SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
+        // #i111954# check object for visibility
+        // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
+        bool bVisible(false);
 
-        if(pTextObj && pTextObj->HasText())
+        if(pObj->HasLineStyle())
         {
             bVisible = true;
         }
-    }
-
-    if(!bVisible)
-    {
-        SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
 
-        if(pGrafObj)
+        if(!bVisible && pObj->HasFillStyle())
         {
-            // this may be refined to check if the graphic really is visible. It
-            // is here to ensure that graphic objects without fill, line and text
-            // get created
             bVisible = true;
         }
-    }
 
-    if(!bVisible)
-    {
-        SdrObject::Free(pObj);
-    }
-    else
-    {
-        aTmpList.push_back( pObj );
-        if ( HAS_BASE( SdrPathObj, pObj ) )
+        if(!bVisible)
         {
-            bool bClosed=pObj->IsClosedObj();
-            bLastObjWasPolyWithoutLine=bNoLine && bClosed;
-            bLastObjWasLine=!bClosed;
+            SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
+
+            if(pTextObj && pTextObj->HasText())
+            {
+                bVisible = true;
+            }
+        }
+
+        if(!bVisible)
+        {
+            SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
+
+            if(pGrafObj)
+            {
+                // this may be refined to check if the graphic really is visible. It
+                // is here to ensure that graphic objects without fill, line and text
+                // get created
+                bVisible = true;
+            }
+        }
+
+        if(!bVisible)
+        {
+            SdrObject::Free(pObj);
         }
         else
         {
-            bLastObjWasPolyWithoutLine = sal_False;
-            bLastObjWasLine = sal_False;
+            aTmpList.push_back( pObj );
+            if ( HAS_BASE( SdrPathObj, pObj ) )
+            {
+                bool bClosed=pObj->IsClosedObj();
+                bLastObjWasPolyWithoutLine=bNoLine && bClosed;
+                bLastObjWasLine=!bClosed;
+            }
+            else
+            {
+                bLastObjWasPolyWithoutLine = sal_False;
+                bLastObjWasLine = sal_False;
+            }
         }
     }
 }
@@ -651,6 +721,32 @@ bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPo
     return false;
 }
 
+void ImpSdrGDIMetaFileImport::checkClip()
+{
+    if(aVD.IsClipRegion())
+    {
+        Region aRegion(aVD.GetClipRegion());
+
+        maClip = aRegion.ConvertToB2DPolyPolygon();
+
+        if(isClip())
+        {
+            const basegfx::B2DHomMatrix aTransform(
+                basegfx::tools::createScaleTranslateB2DHomMatrix(
+                    fScaleX,
+                    fScaleY,
+                    aOfs.X(),
+                    aOfs.Y()));
+
+            maClip.transform(aTransform);
+        }
+    }
+}
+
+bool ImpSdrGDIMetaFileImport::isClip() const
+{
+    return !maClip.getB2DRange().isEmpty();
+}
 
 void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
 {
@@ -710,7 +806,6 @@ void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
         {
             // #i73407# make sure polygon is closed, it's a filled primitive
             aSource.setClosed(true);
-
             SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
             SetAttributes(pPath);
             InsertObj(pPath, false);
@@ -732,7 +827,6 @@ void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
         {
             // #i73407# make sure polygon is closed, it's a filled primitive
             aSource.setClosed(true);
-
             SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
             SetAttributes(pPath);
             InsertObj(pPath, false);
diff --git a/svx/source/svdraw/svdfmtf.hxx b/svx/source/svdraw/svdfmtf.hxx
index 5f31f58..c1e7d5c 100644
--- a/svx/source/svdraw/svdfmtf.hxx
+++ b/svx/source/svdraw/svdfmtf.hxx
@@ -77,7 +77,15 @@ protected:
     // to optimize multiple lines into a Polyline
     sal_Bool                    bLastObjWasLine;
 
+    // clipregion
+    basegfx::B2DPolyPolygon     maClip;
+
 protected:
+    // check for clip and evtl. fill maClip
+    void checkClip();
+    bool isClip() const;
+
+    // actions
     void DoAction(MetaPixelAction           & rAct) const;
     void DoAction(MetaPointAction           & rAct) const;
     void DoAction(MetaLineAction            & rAct);
@@ -105,13 +113,13 @@ protected:
     void DoAction(MetaTextFillColorAction   & rAct) { rAct.Execute(&aVD); }
     void DoAction(MetaFontAction            & rAct) { rAct.Execute(&aVD); bFntDirty=sal_True; }
     void DoAction(MetaTextAlignAction       & rAct) { rAct.Execute(&aVD); bFntDirty=sal_True; }
-    void DoAction(MetaClipRegionAction      & rAct) { rAct.Execute(&aVD); }
+    void DoAction(MetaClipRegionAction      & rAct) { rAct.Execute(&aVD); checkClip(); }
     void DoAction(MetaRasterOpAction        & rAct) { rAct.Execute(&aVD); }
-    void DoAction(MetaPushAction            & rAct) { rAct.Execute(&aVD); }
-    void DoAction(MetaPopAction             & rAct) { rAct.Execute(&aVD); bFntDirty=sal_True; }
-    void DoAction(MetaMoveClipRegionAction  & rAct) { rAct.Execute(&aVD); }
-    void DoAction(MetaISectRectClipRegionAction& rAct) { rAct.Execute(&aVD); }
-    void DoAction(MetaISectRegionClipRegionAction& rAct) { rAct.Execute(&aVD); }
+    void DoAction(MetaPushAction            & rAct) { rAct.Execute(&aVD); checkClip(); }
+    void DoAction(MetaPopAction             & rAct) { rAct.Execute(&aVD); bFntDirty=sal_True; checkClip(); }
+    void DoAction(MetaMoveClipRegionAction  & rAct) { rAct.Execute(&aVD); checkClip(); }
+    void DoAction(MetaISectRectClipRegionAction& rAct) { rAct.Execute(&aVD); checkClip(); }
+    void DoAction(MetaISectRegionClipRegionAction& rAct) { rAct.Execute(&aVD); checkClip(); }
     void DoAction(MetaCommentAction& rAct, GDIMetaFile* pMtf);
 
     void ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct );
diff --git a/svx/source/svdraw/svdxcgv.cxx b/svx/source/svdraw/svdxcgv.cxx
index df282db6..6256e23 100644
--- a/svx/source/svdraw/svdxcgv.cxx
+++ b/svx/source/svdraw/svdxcgv.cxx
@@ -529,27 +529,27 @@ GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile(bool bNoVDevIfOneMtfMarked) co
 
         if( !aMtf.GetActionSize() )
         {
-            VirtualDevice   aOut;
-            Size            aDummySize( 2, 2 );
-
-            aOut.SetOutputSizePixel( aDummySize );
-            aOut.EnableOutput( sal_False );
-            aOut.SetMapMode( aMap );
+            VirtualDevice aOut;
+            const Size aDummySize(2, 2);
 
+            aOut.SetOutputSizePixel(aDummySize);
+            aOut.EnableOutput(false);
+            aOut.SetMapMode(aMap);
             aMtf.Clear();
-            aMtf.Record( &aOut );
-
-            // Replace offset given formally to DrawMarkedObj and used at XOutDev with relative
-            // MapMode (which was also used in XOutDev in that case). Goal is to paint the object
-            // as if TopLeft point is (0,0)
-            const Fraction aNeutralFraction(1, 1);
-            const MapMode aRelativeMapMode(MAP_RELATIVE, Point(-aBound.Left(), -aBound.Top()), aNeutralFraction, aNeutralFraction);
-            aOut.SetMapMode(aRelativeMapMode);
+            aMtf.Record(&aOut);
 
             DrawMarkedObj(aOut);
 
             aMtf.Stop();
             aMtf.WindStart();
+
+            // moving the result is more reliable then setting a relative MapMode at the VDev (used
+            // before), also see #i99268# in GetObjGraphic() below. Some draw actions at
+            // the OutDev are simply not handled correctly when a MapMode is set at the
+            // target devive, e.g. MetaFloatTransparentAction. Even the Move for this action
+            // was missing the manipulation of the embedded Metafile
+            aMtf.Move(-aBound.Left(), -aBound.Top());
+
             aMtf.SetPrefMapMode( aMap );
 
             // removed PrefSize extension. It is principally wrong to set a reduced size at
@@ -633,8 +633,8 @@ Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject*
 
             // #i99268# replace the original offset from using XOutDev's SetOffset
             // NOT (as tried with #i92760#) with another MapMode which gets recorded
-            // by the Metafile itself (what always leads to problems), but by hardly
-            // moving the result
+            // by the Metafile itself (what always leads to problems), but by
+            // moving the result directly
             aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top());
 
             aMtf.SetPrefMapMode( aMap );
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 0332a0c..5094e79 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -814,7 +814,7 @@ void Test::testN777345()
     Graphic aGraphic(xGraphic);
     // If this changes later, feel free to update it, but make sure it's not
     // the checksum of a white/transparent placeholder rectangle.
-    CPPUNIT_ASSERT_EQUAL(sal_uLong(3816010727U), aGraphic.GetChecksum());
+    CPPUNIT_ASSERT_EQUAL(sal_uLong(2529763117U), aGraphic.GetChecksum());
 }
 
 void Test::testN777337()
diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx
index b63ca2d..f44e14f 100644
--- a/vcl/source/gdi/metaact.cxx
+++ b/vcl/source/gdi/metaact.cxx
@@ -3758,6 +3758,9 @@ MetaAction* MetaFloatTransparentAction::Clone()
 void MetaFloatTransparentAction::Move( long nHorzMove, long nVertMove )
 {
     maPoint.Move( nHorzMove, nVertMove );
+
+    // also neeed to move the content metafile
+    maMtf.Move( nHorzMove, nVertMove );
 }
 
 // ------------------------------------------------------------------------
diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx
index 680a63d..821d9ce 100644
--- a/vcl/source/gdi/outdev6.cxx
+++ b/vcl/source/gdi/outdev6.cxx
@@ -607,7 +607,10 @@ void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
     const Color aBlack( COL_BLACK );
 
     if( mpMetaFile )
+    {
+         // missing here is to map the data using the DeviceTransformation
         mpMetaFile->AddAction( new MetaFloatTransparentAction( rMtf, rPos, rSize, rTransparenceGradient ) );
+    }
 
     if( ( rTransparenceGradient.GetStartColor() == aBlack && rTransparenceGradient.GetEndColor() == aBlack ) ||
         ( mnDrawMode & ( DRAWMODE_NOTRANSPARENCY ) ) )
diff --git a/vcl/source/gdi/outmap.cxx b/vcl/source/gdi/outmap.cxx
index 6d55f18..b1a5e01 100644
--- a/vcl/source/gdi/outmap.cxx
+++ b/vcl/source/gdi/outmap.cxx
@@ -1427,10 +1427,17 @@ Region OutputDevice::PixelToLogic( const Region& rDeviceRegion ) const
         return rDeviceRegion;
 
     Region          aRegion;
-    PolyPolygon*    pPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
+    basegfx::B2DPolyPolygon* pB2DPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpB2DPolyPoly;
+    PolyPolygon* pPolyPoly = pB2DPolyPoly ? 0 : rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
 
-    if ( pPolyPoly )
+    if ( pB2DPolyPoly ) // conversion with B2DPolyPolygon lost polygon-based ClipRegion
+    {
+        aRegion = Region( PixelToLogic( *pB2DPolyPoly ) );
+    }
+    else if ( pPolyPoly )
+    {
         aRegion = Region( PixelToLogic( *pPolyPoly ) );
+    }
     else
     {
         long                nX;


More information about the Libreoffice-commits mailing list