summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2013-05-17 16:29:11 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-06-17 15:39:48 +0100
commit3a8dbb63197c5b9298015cbd5b15e607ec9a3705 (patch)
treed7edd0ed73a7d7ebafd449c924bd54ea0aad9065
parent997cc4804d947fdd751e457fda47f95ecf3ac909 (diff)
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
-rw-r--r--drawinglayer/source/primitive2d/cropprimitive2d.cxx2
-rw-r--r--drawinglayer/source/primitive2d/graphicprimitive2d.cxx48
-rw-r--r--include/svtools/grfmgr.hxx11
-rw-r--r--include/svx/svdhdl.hxx36
-rw-r--r--svtools/source/graphic/grfmgr.cxx107
-rw-r--r--svx/source/svdraw/svdhdl.cxx203
-rw-r--r--svx/source/svdraw/svdmrkv.cxx51
-rw-r--r--svx/source/unodraw/UnoGraphicExporter.cxx3
8 files changed, 403 insertions, 58 deletions
diff --git a/drawinglayer/source/primitive2d/cropprimitive2d.cxx b/drawinglayer/source/primitive2d/cropprimitive2d.cxx
index 8ce933afffe2..042710c516e3 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 778245ff12bc..df69a36cdd94 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 9a3bd8c1d1ff..0523cc24d804 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 207b3f494967..ce8dad2712f1 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 136aa578e961..6577c0ef1d89 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 5a03983b0c64..323deaf76a6d 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 ff27728c1d09..cefe73b1cf8b 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 fb9e790bd308..69ac409fe9e3 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;
}