[Libreoffice-commits] core.git: 2 commits - drawinglayer/source include/drawinglayer include/svtools include/svx svtools/source svx/source

Armin Le Grand alg at apache.org
Mon Jun 17 07:40:08 PDT 2013


 drawinglayer/source/primitive2d/cropprimitive2d.cxx     |    2 
 drawinglayer/source/primitive2d/graphicprimitive2d.cxx  |   58 +---
 include/drawinglayer/primitive2d/graphicprimitive2d.hxx |    3 
 include/svtools/grfmgr.hxx                              |   11 
 include/svx/svdhdl.hxx                                  |   36 ++
 svtools/source/graphic/grfmgr.cxx                       |  107 ++++++--
 svx/source/svdraw/svdhdl.cxx                            |  203 +++++++++++++++-
 svx/source/svdraw/svdmrkv.cxx                           |   51 ++++
 svx/source/unodraw/UnoGraphicExporter.cxx               |    3 
 9 files changed, 416 insertions(+), 58 deletions(-)

New commits:
commit 3a8dbb63197c5b9298015cbd5b15e607ec9a3705
Author: Armin Le Grand <alg at apache.org>
Date:   Fri May 17 16:29:11 2013 +0000

    Resolves: #i74211# Correct crop of bitmap data when...
    
    logical size and MapMode do not match real pixel size
    
    (cherry picked from commit a24965371f7e881671182bc51432c08cbf667b56)
    
    Conflicts:
    	svtools/inc/svtools/grfmgr.hxx
    	svtools/source/graphic/grfmgr.cxx
    	svx/inc/svx/svdhdl.hxx
    	svx/inc/svx/svdograf.hxx
    	svx/source/svdraw/svdhdl.cxx
    
    Change-Id: Icfb9091b55e50081e8daf697c9f00f5b5a10531a

diff --git a/drawinglayer/source/primitive2d/cropprimitive2d.cxx b/drawinglayer/source/primitive2d/cropprimitive2d.cxx
index 8ce933a..042710c 100644
--- a/drawinglayer/source/primitive2d/cropprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/cropprimitive2d.cxx
@@ -85,7 +85,7 @@ namespace drawinglayer
                 // with getSmallValue here, the original which uses rtl::math::approxEqual
                 // is too correct here. Maybe this changes with enhanced precision in aw080
                 // to the better so that this can be reduced to the more precise call again
-                if(basegfx::fTools::equal(fRotate, F_PI, 0.000000001))
+                if(basegfx::fTools::equal(fabs(fRotate), F_PI, 0.000000001))
                 {
                     aScale.setX(aScale.getX() * -1.0);
                     aScale.setY(aScale.getY() * -1.0);
diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
index 778245ff..df69a36 100644
--- a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
@@ -85,47 +85,25 @@ namespace drawinglayer
                     {
                         // calculate scalings between real image size and logic object size. This
                         // is necessary since the crop values are relative to original bitmap size
-                        double fFactorX(1.0);
-                        double fFactorY(1.0);
-
-                        {
-                            const MapMode aMapMode100thmm(MAP_100TH_MM);
-                            Size aBitmapSize(rGraphicObject.GetPrefSize());
-
-                            // #i95968# better support PrefMapMode; special for MAP_PIXEL was missing
-                            if(MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit())
-                            {
-                                aBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aBitmapSize, aMapMode100thmm);
-                            }
-                            else
-                            {
-                                aBitmapSize = Application::GetDefaultDevice()->LogicToLogic(aBitmapSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm);
-                            }
-
-                            const double fDivX(aBitmapSize.Width() - getGraphicAttr().GetLeftCrop() - getGraphicAttr().GetRightCrop());
-                            const double fDivY(aBitmapSize.Height() - getGraphicAttr().GetTopCrop() - getGraphicAttr().GetBottomCrop());
-                            const basegfx::B2DVector aScale(aTransform * basegfx::B2DVector(1.0, 1.0));
-
-                            if(!basegfx::fTools::equalZero(fDivX))
-                            {
-                                fFactorX = fabs(aScale.getX()) / fDivX;
-                            }
-
-                            if(!basegfx::fTools::equalZero(fDivY))
-                            {
-                                fFactorY = fabs(aScale.getY()) / fDivY;
-                            }
-                        }
+                        const basegfx::B2DVector aObjectScale(aTransform * basegfx::B2DVector(1.0, 1.0));
+                        const basegfx::B2DVector aCropScaleFactor(
+                            rGraphicObject.calculateCropScaling(
+                                aObjectScale.getX(),
+                                aObjectScale.getY(),
+                                getGraphicAttr().GetLeftCrop(),
+                                getGraphicAttr().GetTopCrop(),
+                                getGraphicAttr().GetRightCrop(),
+                                getGraphicAttr().GetBottomCrop()));
 
                         // embed content in cropPrimitive
                         Primitive2DReference xPrimitive(
                             new CropPrimitive2D(
                                 aRetval,
                                 aTransform,
-                                getGraphicAttr().GetLeftCrop() * fFactorX,
-                                getGraphicAttr().GetTopCrop() * fFactorY,
-                                getGraphicAttr().GetRightCrop() * fFactorX,
-                                getGraphicAttr().GetBottomCrop() * fFactorY));
+                                getGraphicAttr().GetLeftCrop() * aCropScaleFactor.getX(),
+                                getGraphicAttr().GetTopCrop() * aCropScaleFactor.getY(),
+                                getGraphicAttr().GetRightCrop() * aCropScaleFactor.getX(),
+                                getGraphicAttr().GetBottomCrop() * aCropScaleFactor.getY()));
 
                         aRetval = Primitive2DSequence(&xPrimitive, 1);
                     }
diff --git a/include/svtools/grfmgr.hxx b/include/svtools/grfmgr.hxx
index 9a3bd8c..0523cc2 100644
--- a/include/svtools/grfmgr.hxx
+++ b/include/svtools/grfmgr.hxx
@@ -493,6 +493,17 @@ public:
     // will cater for XNameContainer objects and deepinspect any containees
     // if they exist
     static void InspectForGraphicObjectImageURL( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIf, std::vector< OUString >& rvEmbedImgUrls );
+
+    // create CropScaling information
+    // fWidth, fHeight: object size
+    // f*Crop: crop values relative to original bitmap size
+    basegfx::B2DVector calculateCropScaling(
+        double fWidth,
+        double fHeight,
+        double fLeftCrop,
+        double fTopCrop,
+        double fRightCrop,
+        double fBottomCrop) const;
 };
 
 typedef ::std::vector< GraphicObject* > GraphicObjectList_impl;
diff --git a/include/svx/svdhdl.hxx b/include/svx/svdhdl.hxx
index 207b3f4..ce8dad2 100644
--- a/include/svx/svdhdl.hxx
+++ b/include/svx/svdhdl.hxx
@@ -28,6 +28,8 @@
 
 #include <svx/xpoly.hxx>
 #include <svx/svdoedge.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <svx/sdgcpitm.hxx>
 #include <svx/sdr/overlay/overlayobjectlist.hxx>
 #include "svx/svxdllapi.h"
 
@@ -512,6 +514,40 @@ protected:
     static BitmapEx GetHandlesBitmap();
 };
 
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SVX_DLLPUBLIC SdrCropViewHdl : public SdrHdl
+{
+private:
+    basegfx::B2DHomMatrix       maObjectTransform;
+    Graphic                     maGraphic;
+    double                      mfCropLeft;
+    double                      mfCropTop;
+    double                      mfCropRight;
+    double                      mfCropBottom;
+
+    // Argh! The old geometry stuff expresses Y-Mirror using 180 degree rotaton
+    // and the bMirrored bool at the SdrGrafObj, so for now I have to give
+    // this info here. I am sooo looking forward to aw080 and real transformations :-(
+    bool                        mbExtraMirrorXFromGraphic;
+
+public:
+    SdrCropViewHdl(
+        const basegfx::B2DHomMatrix& rObjectTransform,
+        const Graphic& rGraphic,
+        double fCropLeft,
+        double fCropTop,
+        double fCropRight,
+        double fCropBottom,
+        bool bExtraMirrorXFromGraphic);
+
+protected:
+    // create marker for this kind
+    virtual void CreateB2dIAObject();
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
 #endif //_SVDHDL_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/graphic/grfmgr.cxx b/svtools/source/graphic/grfmgr.cxx
index 136aa57..6577c0e 100644
--- a/svtools/source/graphic/grfmgr.cxx
+++ b/svtools/source/graphic/grfmgr.cxx
@@ -842,24 +842,53 @@ Graphic GraphicObject::GetTransformedGraphic( const Size& rDestSize, const MapMo
     }
     else if( GRAPHIC_BITMAP == eType )
     {
-        BitmapEx    aBitmapEx( aTransGraphic.GetBitmapEx() );
-
-        // convert crops to pixel
-        aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetLeftCrop(),
-                                                                            rAttr.GetTopCrop() ),
-                                                                      aMap100 );
-        aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetRightCrop(),
-                                                                                rAttr.GetBottomCrop() ),
-                                                                          aMap100 );
+        BitmapEx aBitmapEx( aTransGraphic.GetBitmapEx() );
+        Rectangle aCropRect;
 
-        // convert from prefmapmode to pixel
-        const Size aSrcSizePixel( Application::GetDefaultDevice()->LogicToPixel( aSrcSize,
-                                                                                 aMapGraph ) );
+        // convert crops to pixel (crops are always in GraphicObject units)
+        if(rAttr.IsCropped())
+        {
+            aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel(
+                Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
+                aMapGraph);
+            aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel(
+                Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
+                aMapGraph);
+
+            // convert from prefmapmode to pixel
+            Size aSrcSizePixel(
+                Application::GetDefaultDevice()->LogicToPixel(
+                    aSrcSize,
+                    aMapGraph));
+
+            if(rAttr.IsCropped()
+                && (aSrcSizePixel.Width() != aBitmapEx.GetSizePixel().Width() || aSrcSizePixel.Height() != aBitmapEx.GetSizePixel().Height())
+                && aSrcSizePixel.Width())
+            {
+                // the size in pixels calculated from Graphic's internal MapMode (aTransGraphic.GetPrefMapMode())
+                // and it's internal size (aTransGraphic.GetPrefSize()) is different from it's real pixel size.
+                // This can be interpreted as this values to be set wrong, but needs to be corrected since e.g.
+                // existing cropping is calculated based on this logic values already.
+                // aBitmapEx.Scale(aSrcSizePixel);
+
+                // another possibility is to adapt the values created so far with a factor; this
+                // will keep the original Bitmap untouched and thus quality will not change
+                const double fFactorX(aBitmapEx.GetSizePixel().Width() / aSrcSizePixel.Width());
+                const double fFactorY(aBitmapEx.GetSizePixel().Height() / aSrcSizePixel.Height());
+
+                aCropLeftTop.Width() = basegfx::fround(aCropLeftTop.Width() * fFactorX);
+                aCropLeftTop.Height() = basegfx::fround(aCropLeftTop.Height() * fFactorY);
+                aCropRightBottom.Width() = basegfx::fround(aCropRightBottom.Width() * fFactorX);
+                aCropRightBottom.Height() = basegfx::fround(aCropRightBottom.Height() * fFactorY);
+
+                aSrcSizePixel = aBitmapEx.GetSizePixel();
+            }
 
-        // setup crop rectangle in pixel
-        Rectangle aCropRect( aCropLeftTop.Width(), aCropLeftTop.Height(),
-                             aSrcSizePixel.Width() - aCropRightBottom.Width(),
-                             aSrcSizePixel.Height() - aCropRightBottom.Height() );
+            // setup crop rectangle in pixel
+            aCropRect = Rectangle( aCropLeftTop.Width(), aCropLeftTop.Height(),
+                                 aSrcSizePixel.Width() - aCropRightBottom.Width(),
+                                 aSrcSizePixel.Height() - aCropRightBottom.Height() );
+        }
 
         // #105641# Also crop animations
         if( aTransGraphic.IsAnimated() )
@@ -925,12 +954,10 @@ Graphic GraphicObject::GetTransformedGraphic( const Size& rDestSize, const MapMo
         }
         else
         {
-            BitmapEx aBmpEx( aTransGraphic.GetBitmapEx() );
-
-            ImplTransformBitmap( aBmpEx, rAttr, aCropLeftTop, aCropRightBottom,
+            ImplTransformBitmap( aBitmapEx, rAttr, aCropLeftTop, aCropRightBottom,
                                  aCropRect, rDestSize, sal_True );
 
-            aTransGraphic = aBmpEx;
+            aTransGraphic = aBitmapEx;
         }
 
         aTransGraphic.SetPrefSize( rDestSize );
@@ -1175,4 +1202,44 @@ GraphicObject::InspectForGraphicObjectImageURL( const Reference< XInterface >& x
     }
 }
 
+// calculate scalings between real image size and logic object size. This
+// is necessary since the crop values are relative to original bitmap size
+basegfx::B2DVector GraphicObject::calculateCropScaling(
+    double fWidth,
+    double fHeight,
+    double fLeftCrop,
+    double fTopCrop,
+    double fRightCrop,
+    double fBottomCrop) const
+{
+    const MapMode aMapMode100thmm(MAP_100TH_MM);
+    Size aBitmapSize(GetPrefSize());
+    double fFactorX(1.0);
+    double fFactorY(1.0);
+
+    if(MAP_PIXEL == GetPrefMapMode().GetMapUnit())
+    {
+        aBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aBitmapSize, aMapMode100thmm);
+    }
+    else
+    {
+        aBitmapSize = Application::GetDefaultDevice()->LogicToLogic(aBitmapSize, GetPrefMapMode(), aMapMode100thmm);
+    }
+
+    const double fDivX(aBitmapSize.Width() - fLeftCrop - fRightCrop);
+    const double fDivY(aBitmapSize.Height() - fTopCrop - fBottomCrop);
+
+    if(!basegfx::fTools::equalZero(fDivX))
+    {
+        fFactorX = fabs(fWidth) / fDivX;
+    }
+
+    if(!basegfx::fTools::equalZero(fDivY))
+    {
+        fFactorY = fabs(fHeight) / fDivY;
+    }
+
+    return basegfx::B2DVector(fFactorX,fFactorY);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdhdl.cxx b/svx/source/svdraw/svdhdl.cxx
index 5a03983..323deaf 100644
--- a/svx/source/svdraw/svdhdl.cxx
+++ b/svx/source/svdraw/svdhdl.cxx
@@ -57,6 +57,13 @@
 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
 #include <vcl/lazydelete.hxx>
 
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
+#include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // #i15222#
 // Due to the resource problems in Win95/98 with bitmap resources I
@@ -2329,6 +2336,200 @@ void SdrCropHdl::CreateB2dIAObject()
     }
 }
 
-// --------------------------------------------------------------------
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrCropViewHdl::SdrCropViewHdl(
+    const basegfx::B2DHomMatrix& rObjectTransform,
+    const Graphic& rGraphic,
+    double fCropLeft,
+    double fCropTop,
+    double fCropRight,
+    double fCropBottom,
+    bool bExtraMirrorXFromGraphic)
+:   SdrHdl(Point(), HDL_USER),
+    maObjectTransform(rObjectTransform),
+    maGraphic(rGraphic),
+    mfCropLeft(fCropLeft),
+    mfCropTop(fCropTop),
+    mfCropRight(fCropRight),
+    mfCropBottom(fCropBottom),
+    mbExtraMirrorXFromGraphic(bExtraMirrorXFromGraphic)
+{
+}
+
+void SdrCropViewHdl::CreateB2dIAObject()
+{
+    GetRidOfIAObject();
+    SdrMarkView* pView = pHdlList ? pHdlList->GetView() : 0;
+    SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0;
+
+    if(pPageView && pView->areMarkHandlesHidden())
+    {
+        return;
+    }
+
+    // decompose to have current translate and scale
+    basegfx::B2DVector aScale, aTranslate;
+    double fRotate, fShearX;
+
+    maObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
+
+    if(aScale.equalZero())
+    {
+        return;
+    }
+
+    // detect 180 degree rotation, this is the same as mirrored in X and Y,
+    // thus change to mirroring. Prefer mirroring here. Use the equal call
+    // with getSmallValue here, the original which uses rtl::math::approxEqual
+    // is too correct here. Maybe this changes with enhanced precision in aw080
+    // to the better so that this can be reduced to the more precise call again
+    if(basegfx::fTools::equal(fabs(fRotate), F_PI, 0.000000001))
+    {
+        aScale.setX(aScale.getX() * -1.0);
+        aScale.setY(aScale.getY() * -1.0);
+        fRotate = 0.0;
+    }
+
+    // remember mirroring, reset at Scale and adapt crop values for usage;
+    // mirroring can stay in the object transformation, so do not have to
+    // cope with it here (except later for the CroppedImage transformation,
+    // see below)
+    const bool bMirroredX(aScale.getX() < 0.0);
+    const bool bMirroredY(aScale.getY() < 0.0);
+    double fCropLeft(mfCropLeft);
+    double fCropTop(mfCropTop);
+    double fCropRight(mfCropRight);
+    double fCropBottom(mfCropBottom);
+
+    if(bMirroredX)
+    {
+        aScale.setX(-aScale.getX());
+        fCropLeft = mfCropRight;
+        fCropRight = mfCropLeft;
+    }
+
+    if(bMirroredY)
+    {
+        aScale.setY(-aScale.getY());
+        fCropTop = mfCropBottom;
+        fCropBottom = mfCropTop;
+    }
+
+    // create target translate and scale
+    const basegfx::B2DVector aTargetScale(
+        aScale.getX() + fCropRight + fCropLeft,
+        aScale.getY() + fCropBottom + fCropTop);
+    const basegfx::B2DVector aTargetTranslate(
+        aTranslate.getX() - fCropLeft,
+        aTranslate.getY() - fCropTop);
+
+    // create ranges to make comparisons
+    const basegfx::B2DRange aCurrentForCompare(
+        aTranslate.getX(), aTranslate.getY(),
+        aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
+    basegfx::B2DRange aCropped(
+        aTargetTranslate.getX(), aTargetTranslate.getY(),
+        aTargetTranslate.getX() + aTargetScale.getX(), aTargetTranslate.getY() + aTargetScale.getY());
+
+    if(aCropped.isEmpty())
+    {
+        // nothing to return since cropped content is completely empty
+        return;
+    }
+
+    if(aCurrentForCompare.equal(aCropped))
+    {
+        // no crop at all
+        return;
+    }
+
+    // back-transform to have values in unit coordinates
+    basegfx::B2DHomMatrix aBackToUnit;
+    aBackToUnit.translate(-aTranslate.getX(), -aTranslate.getY());
+    aBackToUnit.scale(
+        basegfx::fTools::equalZero(aScale.getX()) ? 1.0 : 1.0 / aScale.getX(),
+        basegfx::fTools::equalZero(aScale.getY()) ? 1.0 : 1.0 / aScale.getY());
+
+    // transform cropped back to unit coordinates
+    aCropped.transform(aBackToUnit);
+
+    // prepare crop PolyPolygon
+    basegfx::B2DPolyPolygon aCropPolyPolygon(
+        basegfx::tools::createPolygonFromRect(
+            aCropped));
+
+    // current range is unit range
+    basegfx::B2DRange aOverlap(0.0, 0.0, 1.0, 1.0);
+
+    aOverlap.intersect(aCropped);
+
+    if(!aOverlap.isEmpty())
+    {
+        aCropPolyPolygon.append(
+            basegfx::tools::createPolygonFromRect(
+                aOverlap));
+    }
+
+    // transform to object coordinates to prepare for clip
+    aCropPolyPolygon.transform(maObjectTransform);
+
+    // create cropped transformation
+    basegfx::B2DHomMatrix aCroppedTransform;
+    const bool bCombinedMirrorX(mbExtraMirrorXFromGraphic || bMirroredX);
+
+    aCroppedTransform.scale(
+        bCombinedMirrorX ? -aCropped.getWidth() : aCropped.getWidth(),
+        bMirroredY ? -aCropped.getHeight() : aCropped.getHeight());
+    aCroppedTransform.translate(
+        bCombinedMirrorX ? aCropped.getMaxX() : aCropped.getMinX(),
+        bMirroredY ? aCropped.getMaxY() : aCropped.getMinY());
+    aCroppedTransform = maObjectTransform * aCroppedTransform;
+
+    // prepare graphic primitive (tranformed)
+    const drawinglayer::primitive2d::Primitive2DReference aGraphic(
+        new drawinglayer::primitive2d::GraphicPrimitive2D(
+            aCroppedTransform,
+            maGraphic));
+
+    // embed to MaskPrimitive2D
+    const drawinglayer::primitive2d::Primitive2DReference aMaskedGraphic(
+        new drawinglayer::primitive2d::MaskPrimitive2D(
+            aCropPolyPolygon,
+            drawinglayer::primitive2d::Primitive2DSequence(&aGraphic, 1)));
+
+    // embed to UnifiedTransparencePrimitive2D
+    const drawinglayer::primitive2d::Primitive2DReference aTransparenceMaskedGraphic(
+        new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+            drawinglayer::primitive2d::Primitive2DSequence(&aMaskedGraphic, 1),
+            0.8));
+
+    const drawinglayer::primitive2d::Primitive2DSequence aSequence(&aTransparenceMaskedGraphic, 1);
+
+    for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+    {
+        // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
+        const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+        if(rPageWindow.GetPaintWindow().OutputToWindow())
+        {
+            rtl::Reference< ::sdr::overlay::OverlayManager > xManager = rPageWindow.GetOverlayManager();
+            if(xManager.is())
+            {
+                ::sdr::overlay::OverlayObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence);
+                DBG_ASSERT(pNew, "Got NO new IAO!");
+
+                if(pNew)
+                {
+                    // only informative object, no hit
+                    pNew->setHittable(false);
+
+                    xManager->add(*pNew);
+                    maOverlayGroup.append(*pNew);
+                }
+            }
+        }
+    }
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx
index ff27728..cefe73b 100644
--- a/svx/source/svdraw/svdmrkv.cxx
+++ b/svx/source/svdraw/svdmrkv.cxx
@@ -48,6 +48,7 @@
 #include <svx/sdrpagewindow.hxx>
 #include <svx/sdrhittesthelper.hxx>
 #include <svx/svdocapt.hxx>
+#include <svx/svdograf.hxx>
 
 #include <editeng/editdata.hxx>
 
@@ -667,6 +668,56 @@ void SdrMarkView::SetMarkHandles()
                 }
                 else if( eDragMode==SDRDRAG_CROP )
                 {
+                    const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pMarkedObj);
+
+                    if(pSdrGrafObj)
+                    {
+                        const SdrGrafCropItem& rCrop = static_cast< const SdrGrafCropItem& >(pSdrGrafObj->GetMergedItem(SDRATTR_GRAFCROP));
+
+                        if(rCrop.GetLeft() || rCrop.GetTop() || rCrop.GetRight() ||rCrop.GetBottom())
+                        {
+                            basegfx::B2DHomMatrix aMatrix;
+                            basegfx::B2DPolyPolygon aPolyPolygon;
+
+                            pSdrGrafObj->TRGetBaseGeometry(aMatrix, aPolyPolygon);
+
+                            // decompose to have current translate and scale
+                            basegfx::B2DVector aScale, aTranslate;
+                            double fRotate, fShearX;
+
+                            aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+
+                            if(!aScale.equalZero())
+                            {
+                                // get crop scale
+                                const basegfx::B2DVector aCropScaleFactor(
+                                    pSdrGrafObj->GetGraphicObject().calculateCropScaling(
+                                        aScale.getX(),
+                                        aScale.getY(),
+                                        rCrop.GetLeft(),
+                                        rCrop.GetTop(),
+                                        rCrop.GetRight(),
+                                        rCrop.GetBottom()));
+
+                                // apply crop scale
+                                const double fCropLeft(rCrop.GetLeft() * aCropScaleFactor.getX());
+                                const double fCropTop(rCrop.GetTop() * aCropScaleFactor.getY());
+                                const double fCropRight(rCrop.GetRight() * aCropScaleFactor.getX());
+                                const double fCropBottom(rCrop.GetBottom() * aCropScaleFactor.getY());
+
+                                aHdl.AddHdl(
+                                    new SdrCropViewHdl(
+                                        aMatrix,
+                                        pSdrGrafObj->GetGraphicObject().GetGraphic(),
+                                        fCropLeft,
+                                        fCropTop,
+                                        fCropRight,
+                                        fCropBottom,
+                                        pSdrGrafObj->IsMirrored()));
+                            }
+                        }
+                    }
+
                     aHdl.AddHdl(new SdrCropHdl(aRect.TopLeft()     ,HDL_UPLFT));
                     aHdl.AddHdl(new SdrCropHdl(aRect.TopCenter()   ,HDL_UPPER));
                     aHdl.AddHdl(new SdrCropHdl(aRect.TopRight()    ,HDL_UPRGT));
diff --git a/svx/source/unodraw/UnoGraphicExporter.cxx b/svx/source/unodraw/UnoGraphicExporter.cxx
index fb9e790..69ac409 100644
--- a/svx/source/unodraw/UnoGraphicExporter.cxx
+++ b/svx/source/unodraw/UnoGraphicExporter.cxx
@@ -822,7 +822,8 @@ bool GraphicExporter::GetGraphic( ExportSettings& rSettings, Graphic& aGraphic,
                               ( rSettings.mnHeight != aSizePixel.Height() ) ) )
                         {
                             BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
-                            aBmpEx.Scale( Size( rSettings.mnWidth, rSettings.mnHeight ) );
+                            // export: use highest quality
+                            aBmpEx.Scale( Size( rSettings.mnWidth, rSettings.mnHeight ), BMP_SCALE_LANCZOS );
                             aGraphic = aBmpEx;
                         }
 
commit 997cc4804d947fdd751e457fda47f95ecf3ac909
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Jun 17 15:05:53 2013 +0100

    restore now needed ctor
    
    partial revert of bb61f56d71b699dfbe422bac37a3151767e6a40f now
    that we need it again
    
    Change-Id: Iffaf72b96b237101b4bbb65efd32d6c5f18eb212

diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
index 865d52f..778245ff 100644
--- a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
@@ -146,6 +146,16 @@ namespace drawinglayer
         {
         }
 
+        GraphicPrimitive2D::GraphicPrimitive2D(
+            const basegfx::B2DHomMatrix& rTransform,
+            const GraphicObject& rGraphicObject)
+        :   BufferedDecompositionPrimitive2D(),
+            maTransform(rTransform),
+            maGraphicObject(rGraphicObject),
+            maGraphicAttr()
+        {
+        }
+
         bool GraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
         {
             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
diff --git a/include/drawinglayer/primitive2d/graphicprimitive2d.hxx b/include/drawinglayer/primitive2d/graphicprimitive2d.hxx
index 23afdbb..27fa8ff 100644
--- a/include/drawinglayer/primitive2d/graphicprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/graphicprimitive2d.hxx
@@ -69,6 +69,9 @@ namespace drawinglayer
                 const basegfx::B2DHomMatrix& rTransform,
                 const GraphicObject& rGraphicObject,
                 const GraphicAttr& rGraphicAttr);
+            GraphicPrimitive2D(
+                const basegfx::B2DHomMatrix& rTransform,
+                const GraphicObject& rGraphicObject);
 
             /// data read access
             const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }


More information about the Libreoffice-commits mailing list