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

Armin Le Grand alg at apache.org
Mon Jun 17 06:51:04 PDT 2013


 svx/source/svdraw/svdfmtf.cxx |  177 +++++++++++++++++++++++++++++-------------
 1 file changed, 125 insertions(+), 52 deletions(-)

New commits:
commit e014694623b1516aa47f2012cc038e4c64ed7bea
Author: Armin Le Grand <alg at apache.org>
Date:   Fri May 17 09:58:33 2013 +0000

    Resolves: #i122326# added text clipping, corrected text box distances
    
    (cherry picked from commit 58b44ad7c8d46904da750c4820f4bde675953fa9)
    
    Conflicts:
    	svx/source/svdraw/svdfmtf.cxx
    
    Change-Id: I313c2f50269b8ba97c32a24b92aafafb49f3ca70

diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
index 879e230..a6e27ff 100644
--- a/svx/source/svdraw/svdfmtf.cxx
+++ b/svx/source/svdraw/svdfmtf.cxx
@@ -68,6 +68,9 @@
 #include <svx/xflbmtit.hxx>
 #include <svx/xflbstit.hxx>
 #include <svx/svdpntv.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdogrp.hxx>
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -476,63 +479,130 @@ void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, bool bScale)
         const SdrLayerID aOldLayer(pObj->GetLayer());
         const SfxItemSet aOldItemSet(pObj->GetMergedItemSet());
         const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
-        BitmapEx aBitmapEx;
+        const SdrTextObj* pSdrTextObj = dynamic_cast< SdrTextObj* >(pObj);
 
-        if(pSdrGrafObj)
+        if(pSdrTextObj && pSdrTextObj->HasText())
         {
-            aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
-        }
+            // all text objects are created from ImportText and have no line or fill attributes, so
+            // it is okay to concentrate on the text itself
+            while(true)
+            {
+                const basegfx::B2DPolyPolygon aTextContour(pSdrTextObj->TakeContour());
+                const basegfx::B2DRange aTextRange(aTextContour.getB2DRange());
+                const basegfx::B2DRange aClipRange(maClip.getB2DRange());
+
+                // no overlap -> completely outside
+                if(!aClipRange.overlaps(aTextRange))
+                {
+                    SdrObject::Free(pObj);
+                    break;
+                }
+
+                // when the clip is a rectangle fast check for inside is possible
+                if(basegfx::tools::isRectangle(maClip) && aClipRange.isInside(aTextRange))
+                {
+                    // completely inside ClipRect
+                    break;
+                }
 
-        SdrObject::Free(pObj);
+                // here text needs to be clipped; to do so, convert to SdrObjects with polygons
+                // and add these recursively. Delete original object, do not add in this run
+                SdrObject* pConverted = pSdrTextObj->ConvertToPolyObj(true, true);
+                SdrObject::Free(pObj);
 
-        if(!aOldRange.isEmpty())
+                if(pConverted)
+                {
+                    // recursively add created conversion; per definition this shall not
+                    // contain further SdrTextObjs. Visit only non-group objects
+                    SdrObjListIter aIter(*pConverted, IM_DEEPNOGROUPS);
+
+                    // work with clones; the created conversion may contain group objects
+                    // and when working with the original objects the loop itself could
+                    // break and the cleanup later would be pretty complicated (only delete group
+                    // objects, are these empty, ...?)
+                    while(aIter.IsMore())
+                    {
+                        SdrObject* pCandidate = aIter.Next();
+                        OSL_ENSURE(pCandidate && 0 == dynamic_cast< SdrObjGroup* >(pCandidate), "SdrObjListIter with IM_DEEPNOGROUPS error (!)");
+                        SdrObject* pNewClone = pCandidate->Clone();
+
+                        if(pNewClone)
+                        {
+                            InsertObj(pNewClone, false);
+                        }
+                        else
+                        {
+                            OSL_ENSURE(false, "SdrObject::Clone() failed (!)");
+                        }
+                    }
+
+                    // cleanup temporary conversion objects
+                    SdrObject::Free(pConverted);
+                }
+
+                break;
+            }
+        }
+        else
         {
-            // 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())
+            BitmapEx aBitmapEx;
+
+            if(pSdrGrafObj)
             {
-                pObj = new SdrPathObj(
-                    aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN,
-                    aNewPoly);
+                aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
+            }
 
-                pObj->SetLayer(aOldLayer);
-                pObj->SetMergedItemSet(aOldItemSet);
+            SdrObject::Free(pObj);
 
-                if(!!aBitmapEx)
+            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())
                 {
-                    // 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 Size aOrigSizePixel(aBitmapEx.GetSizePixel());
-                    const Point aClipTopLeft(
-                        basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))),
-                        basegfx::fround(floor(std::max(0.0, aPixel.getMinY()))));
-                    const Size aClipSize(
-                        basegfx::fround(ceil(std::min((double)aOrigSizePixel.Width(), aPixel.getWidth()))),
-                        basegfx::fround(ceil(std::min((double)aOrigSizePixel.Height(), aPixel.getHeight()))));
-                    const BitmapEx aClippedBitmap(
-                        aBitmapEx,
-                        aClipTopLeft,
-                        aClipSize);
-
-                    pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP));
-                    pObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aClippedBitmap)));
-                    pObj->SetMergedItem(XFillBmpTileItem(false));
-                    pObj->SetMergedItem(XFillBmpStretchItem(true));
+                    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 fScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
+                        const double fScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
+                        basegfx::B2DRange aPixel(aNewRange);
+                        basegfx::B2DHomMatrix aTrans;
+
+                        aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
+                        aTrans.scale(fScaleX, fScaleY);
+                        aPixel.transform(aTrans);
+
+                        const Size aOrigSizePixel(aBitmapEx.GetSizePixel());
+                        const Point aClipTopLeft(
+                            basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))),
+                            basegfx::fround(floor(std::max(0.0, aPixel.getMinY()))));
+                        const Size aClipSize(
+                            basegfx::fround(ceil(std::min((double)aOrigSizePixel.Width(), aPixel.getWidth()))),
+                            basegfx::fround(ceil(std::min((double)aOrigSizePixel.Height(), aPixel.getHeight()))));
+                        const BitmapEx aClippedBitmap(
+                            aBitmapEx,
+                            aClipTopLeft,
+                            aClipSize);
+
+                        pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP));
+                        pObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aClippedBitmap)));
+                        pObj->SetMergedItem(XFillBmpTileItem(false));
+                        pObj->SetMergedItem(XFillBmpStretchItem(true));
+                    }
                 }
             }
         }
@@ -948,19 +1018,22 @@ void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rS
     Rectangle aTextRect( aPos, aSize );
     SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
 
+    pText->SetMergedItem ( SdrTextUpperDistItem (0));
+    pText->SetMergedItem ( SdrTextLowerDistItem (0));
+    pText->SetMergedItem ( SdrTextRightDistItem (0));
+    pText->SetMergedItem ( SdrTextLeftDistItem (0));
+
     if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
     {
         pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
         pText->SetMergedItem( SdrTextAutoGrowHeightItem( false ) );
         // don't let the margins eat the space needed for the text
-        pText->SetMergedItem ( SdrTextUpperDistItem (0));
-        pText->SetMergedItem ( SdrTextLowerDistItem (0));
-        pText->SetMergedItem ( SdrTextRightDistItem (0));
-        pText->SetMergedItem ( SdrTextLeftDistItem (0));
         pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
     }
     else
+    {
         pText->SetMergedItem( SdrTextAutoGrowWidthItem( true ) );
+    }
 
     pText->SetModel(mpModel);
     pText->SetLayer(mnLayer);


More information about the Libreoffice-commits mailing list