diff options
author | Armin Le Grand <Armin.Le.Grand@cib.de> | 2017-09-28 10:20:15 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@cib.de> | 2017-10-20 14:13:22 +0200 |
commit | d9b16effeda21488911d1b5035f9d3be05731ca2 (patch) | |
tree | 3c16a374a8bb42c7b0207e0e34bcacd66efb150f /sw | |
parent | 4ddd74e2d119eb7b25df75a65fcb214ce08ec672 (diff) |
RotGrfFlyFrame: Adapt Crop functionality to rotated Graphic
The FlyFrame which may contain a Graphic needs working Crop,
interactive and in core. Adapted this to work with now possible
rotation, changed common code in svx which has to handle cases
for Draw/Impress/Calc and Writer differently. Tried to use as
much in common as possible. Additionally furter adaptions
to rotation itself.
Change-Id: Ia961e9490e2627c74220b186116f5aa4fcabca78
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/doc/notxtfrm.cxx | 51 | ||||
-rw-r--r-- | sw/source/core/draw/dflyobj.cxx | 100 | ||||
-rw-r--r-- | sw/source/core/inc/dflyobj.hxx | 7 | ||||
-rw-r--r-- | sw/source/core/inc/frmtool.hxx | 7 |
4 files changed, 111 insertions, 54 deletions
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx index 42eac79c45ee..6a23088246c4 100644 --- a/sw/source/core/doc/notxtfrm.cxx +++ b/sw/source/core/doc/notxtfrm.cxx @@ -757,53 +757,24 @@ bool paintUsingPrimitivesHelper( return false; } -void paintGraphicUsingPrimitivesHelper(vcl::RenderContext & rOutputDevice, - GraphicObject const& rGrfObj, GraphicAttr const& rGraphicAttr, - SwRect const& rAlignedGrfArea) +void paintGraphicUsingPrimitivesHelper( + vcl::RenderContext & rOutputDevice, + GraphicObject const& rGrfObj, + GraphicAttr const& rGraphicAttr, + SwRect const& rAlignedGrfArea) { - // unify using GraphicPrimitive2D + // RotGrfFlyFrame: unify using GraphicPrimitive2D // -> the primitive handles all crop and mirror stuff // -> the primitive renderer will create the needed pdf export data // -> if bitmap content, it will be cached system-dependent const basegfx::B2DRange aTargetRange( rAlignedGrfArea.Left(), rAlignedGrfArea.Top(), rAlignedGrfArea.Right(), rAlignedGrfArea.Bottom()); - basegfx::B2DHomMatrix aTargetTransform; - - // RotGrfFlyFrame: Take rotation into account. Rotation is in 10th degrees - if(0 != rGraphicAttr.GetRotation()) - { - // Fit rotated graphic to center of available space, keeping page ratio: - // Adapt scaling ratio of unit object and rotate it - const double fRotate(static_cast< double >(-rGraphicAttr.GetRotation()) * (M_PI/1800.0)); - aTargetTransform.scale(1.0, aTargetRange.getHeight() / aTargetRange.getWidth()); - aTargetTransform.rotate(fRotate); - - // get the range to see where we are in unit coordinates - basegfx::B2DRange aFullRange(0.0, 0.0, 1.0, 1.0); - aFullRange.transform(aTargetTransform); - - // detect needed scales in X/Y and choose the smallest for staying inside the - // available space while keeping aspect ratio of the source - const double fScaleX(aTargetRange.getWidth() / aFullRange.getWidth()); - const double fScaleY(aTargetRange.getHeight() / aFullRange.getHeight()); - const double fScaleMin(std::min(fScaleX, fScaleY)); - - // TopLeft to zero, then scale, then move to center of available space - aTargetTransform.translate(-aFullRange.getMinX(), -aFullRange.getMinY()); - aTargetTransform.scale(fScaleMin, fScaleMin); - aTargetTransform.translate( - aTargetRange.getCenterX() - (0.5 * fScaleMin * aFullRange.getWidth()), - aTargetRange.getCenterY() - (0.5 * fScaleMin * aFullRange.getHeight())); - } - else - { - // just scale/translate needed - aTargetTransform *= basegfx::utils::createScaleTranslateB2DHomMatrix( - aTargetRange.getRange(), - aTargetRange.getMinimum()); - } - + const double fRotate(static_cast< double >(-rGraphicAttr.GetRotation()) * (M_PI/1800.0)); + const basegfx::B2DHomMatrix aTargetTransform( + basegfx::utils::createRotateAroundCenterKeepAspectRatioStayInsideRange( + aTargetRange, + fRotate)); drawinglayer::primitive2d::Primitive2DContainer aContent(1); bool bDone(false); diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx index 0696af0e59d1..358085bd2760 100644 --- a/sw/source/core/draw/dflyobj.cxx +++ b/sw/source/core/draw/dflyobj.cxx @@ -59,6 +59,8 @@ #include <drawinglayer/primitive2d/baseprimitive2d.hxx> #include <sw_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <notxtfrm.hxx> using namespace ::com::sun::star; @@ -920,20 +922,96 @@ void SwVirtFlyDrawObj::Crop(const Point& rRef, const Fraction& xFact, const Frac GetFormat()->GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); } -void SwVirtFlyDrawObj::addCropHandles(SdrHdlList& rTarget) const +// RotGrfFlyFrame: Helper to access possible rotation of Graphic contained in FlyFrame +sal_uInt16 SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame() const { - tools::Rectangle aRect(GetSnapRect()); + sal_uInt16 nRetval(0); + const SwNoTextFrame* pNoTx = dynamic_cast< const SwNoTextFrame* >(GetFlyFrame()->Lower()); - if(!aRect.IsEmpty()) + if(pNoTx) { - rTarget.AddHdl(new SdrCropHdl(aRect.TopLeft() , SdrHdlKind::UpperLeft, 0, 0)); - rTarget.AddHdl(new SdrCropHdl(aRect.TopCenter() , SdrHdlKind::Upper, 0, 0)); - rTarget.AddHdl(new SdrCropHdl(aRect.TopRight() , SdrHdlKind::UpperRight, 0, 0)); - rTarget.AddHdl(new SdrCropHdl(aRect.LeftCenter() , SdrHdlKind::Left , 0, 0)); - rTarget.AddHdl(new SdrCropHdl(aRect.RightCenter() , SdrHdlKind::Right, 0, 0)); - rTarget.AddHdl(new SdrCropHdl(aRect.BottomLeft() , SdrHdlKind::LowerLeft, 0, 0)); - rTarget.AddHdl(new SdrCropHdl(aRect.BottomCenter(), SdrHdlKind::Lower, 0, 0)); - rTarget.AddHdl(new SdrCropHdl(aRect.BottomRight() , SdrHdlKind::LowerRight, 0, 0)); + SwNoTextNode& rNoTNd = const_cast< SwNoTextNode& >(*static_cast<const SwNoTextNode*>(pNoTx->GetNode())); + SwGrfNode* pGrfNd = rNoTNd.GetGrfNode(); + + if(nullptr != pGrfNd) + { + const SwAttrSet& rSet = pGrfNd->GetSwAttrSet(); + const SwRotationGrf& rRotation = rSet.GetRotationGrf(); + + nRetval = rRotation.GetValue(); + } + } + + return nRetval; +} + +SdrObject* SwVirtFlyDrawObj::getFullDragClone() const +{ + // call parent + SdrObject* pRetval = SdrVirtObj::getFullDragClone(); + + if(pRetval) + { + // RotGrfFlyFrame: Add transformation to placeholder object + const sal_uInt16 nRotation(SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame()); + + if(0 != nRotation) + { + const double fRotate(static_cast< double >(-nRotation) * (M_PI/1800.0)); + const tools::Rectangle aOutRect(GetFlyFrame()->Frame().SVRect()); + const basegfx::B2DRange aTargetRange( + aOutRect.Left(), aOutRect.Top(), + aOutRect.Right(), aOutRect.Bottom()); + const basegfx::B2DHomMatrix aTargetTransform( + basegfx::utils::createRotateAroundCenterKeepAspectRatioStayInsideRange( + aTargetRange, + fRotate)); + + pRetval->TRSetBaseGeometry(aTargetTransform, basegfx::B2DPolyPolygon()); + } + } + + return pRetval; +} + +void SwVirtFlyDrawObj::addCropHandles(SdrHdlList& rTarget) const +{ + // RotGrfFlyFrame: Adapt to possible rotated Graphic contained in FlyFrame + if(GetFlyFrame()->Frame().HasArea()) + { + const tools::Rectangle aOutRect(GetFlyFrame()->Frame().SVRect()); + const basegfx::B2DRange aTargetRange( + aOutRect.Left(), aOutRect.Top(), + aOutRect.Right(), aOutRect.Bottom()); + + if(!aTargetRange.isEmpty()) + { + const sal_uInt16 nRotation(SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame()); + const double fRotate(static_cast< double >(-nRotation) * (M_PI/1800.0)); + const basegfx::B2DHomMatrix aTargetTransform( + basegfx::utils::createRotateAroundCenterKeepAspectRatioStayInsideRange( + aTargetRange, + fRotate)); + basegfx::B2DPoint aPos; + const double fShearX(0.0); + + aPos = aTargetTransform * basegfx::B2DPoint(0.0, 0.0); + rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperLeft, fShearX, fRotate)); + aPos = aTargetTransform * basegfx::B2DPoint(0.5, 0.0); + rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Upper, fShearX, fRotate)); + aPos = aTargetTransform * basegfx::B2DPoint(1.0, 0.0); + rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperRight, fShearX, fRotate)); + aPos = aTargetTransform * basegfx::B2DPoint(0.0, 0.5); + rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Left , fShearX, fRotate)); + aPos = aTargetTransform * basegfx::B2DPoint(1.0, 0.5); + rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Right, fShearX, fRotate)); + aPos = aTargetTransform * basegfx::B2DPoint(0.0, 1.0); + rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerLeft, fShearX, fRotate)); + aPos = aTargetTransform * basegfx::B2DPoint(0.5, 1.0); + rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Lower, fShearX, fRotate)); + aPos = aTargetTransform * basegfx::B2DPoint(1.0, 1.0); + rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerRight, fShearX, fRotate)); + } } } diff --git a/sw/source/core/inc/dflyobj.hxx b/sw/source/core/inc/dflyobj.hxx index 9368eb893b07..528edc8aff39 100644 --- a/sw/source/core/inc/dflyobj.hxx +++ b/sw/source/core/inc/dflyobj.hxx @@ -58,6 +58,10 @@ class SwVirtFlyDrawObj : public SdrVirtObj private: SwFlyFrame *m_pFlyFrame; + // RotGrfFlyFrame: Helper to acces sthe rotation angle (in 10th degrees, left-handed) + // of a GraphicFrame + sal_uInt16 getPossibleRotationFromFraphicFrame() const; + protected: // AW: Need own sdr::contact::ViewContact since AnchorPos from parent is // not used but something own (top left of new SnapRect minus top left @@ -102,6 +106,9 @@ public: virtual void Crop(const Point& rRef, const Fraction& xFact, const Fraction& yFact) override; virtual void addCropHandles(SdrHdlList& rTarget) const override; + // FullDrag support + virtual SdrObject* getFullDragClone() const override; + const SwFrameFormat *GetFormat() const; SwFrameFormat *GetFormat(); diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx index 305c8ffb5495..f0351fa6de29 100644 --- a/sw/source/core/inc/frmtool.hxx +++ b/sw/source/core/inc/frmtool.hxx @@ -72,10 +72,11 @@ bool DrawFillAttributes( const basegfx::utils::B2DClipState& rClipState, OutputDevice& rOut); +// RotGrfFlyFrame: Adapted to rotation void paintGraphicUsingPrimitivesHelper( - OutputDevice & rOutputDevice, - GraphicObject const& rGraphicObj, GraphicAttr const& rGraphicAttr, - SwRect const& rAlignedGrfArea); + OutputDevice & rOutputDevice, + GraphicObject const& rGraphicObj, GraphicAttr const& rGraphicAttr, + SwRect const& rAlignedGrfArea); // method to align rectangle. // Created declaration here to avoid <extern> declarations |