diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2019-12-21 22:32:55 +0100 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2020-02-26 12:04:11 +0100 |
commit | b4a6977e05d87fe0a79b266ec30e4f403404f1b4 (patch) | |
tree | 969b5d55c1f3ea2dedff31009ae89ff0eec38da5 /svx/source/svdraw/svdoashp.cxx | |
parent | 79d396a2a64bec4e6c9aa514af40fdd67a62d8ce (diff) |
tdf#129532 tdf#98839 fixes for mirror of custom shapes
tdf#98839 In case a sheared custom shape was mirrored, the shear
angle in draw:transform had a wrong sign in the saved file.
tdf#129532 Mirroring given in draw:transform in file or via macro
was wrongly applied. Errors:
1)Mirroring from draw:transform attribute had overwritten already
existing mirroring in the enhanced-geometry.
2)Mirroring from draw:transform attribute was set in enhanced-
geometry attributes but not really applied.
Change-Id: Ifa52f3606b5a33e6492a02d6e19c883d28752da8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/85670
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'svx/source/svdraw/svdoashp.cxx')
-rw-r--r-- | svx/source/svdraw/svdoashp.cxx | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx index 367e6a3ac24f..2412213f2992 100644 --- a/svx/source/svdraw/svdoashp.cxx +++ b/svx/source/svdraw/svdoashp.cxx @@ -2987,21 +2987,29 @@ void SdrObjCustomShape::AdjustToMaxRect(const tools::Rectangle& rMaxRect, bool b void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/) { + // The shape might have already flipping in its enhanced geometry. LibreOffice applies + // such after all transformations. We remove it, but remember it to apply them later. + bool bIsMirroredX = IsMirroredX(); + bool bIsMirroredY = IsMirroredY(); + if (bIsMirroredX || bIsMirroredY) + { + Point aCurrentCenter = GetSnapRect().Center(); + if (bIsMirroredX) // mirror on the y-axis + { + Mirror(aCurrentCenter, Point(aCurrentCenter.X(), aCurrentCenter.Y() + 1000)); + } + if (bIsMirroredY) // mirror on the x-axis + { + Mirror(aCurrentCenter, Point(aCurrentCenter.X() + 1000, aCurrentCenter.Y())); + } + } + // break up matrix basegfx::B2DTuple aScale; basegfx::B2DTuple aTranslate; double fRotate, fShearX; rMatrix.decompose(aScale, aTranslate, fRotate, fShearX); - // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings - // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly - if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0)) - { - aScale.setX(fabs(aScale.getX())); - aScale.setY(fabs(aScale.getY())); - fRotate = fmod(fRotate + F_PI, F_2PI); - } - // reset object shear and rotations fObjectRotation = 0.0; aGeo.nRotationAngle = 0; @@ -3018,14 +3026,19 @@ void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, } } - // build and set BaseRect (use scale) - Size aSize(FRound(aScale.getX()), FRound(aScale.getY())); + // scale + Size aSize(FRound(fabs(aScale.getX())), FRound(fabs(aScale.getY()))); // fdo#47434 We need a valid rectangle here if( !aSize.Height() ) aSize.setHeight( 1 ); if( !aSize.Width() ) aSize.setWidth( 1 ); - tools::Rectangle aBaseRect(Point(), aSize); - SetSnapRect(aBaseRect); + SetLogicRect(aBaseRect); + + // Apply flipping from Matrix, which is a transformation relative to origin + if (basegfx::fTools::less(aScale.getX(), 0.0)) + Mirror(Point(0, 0), Point(0, 1000)); // mirror on the y-axis + if (basegfx::fTools::less(aScale.getY(), 0.0)) + Mirror(Point(0, 0), Point(1000, 0)); // mirror on the x-axis // shear? if(!basegfx::fTools::equalZero(fShearX)) @@ -3057,6 +3070,30 @@ void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, { Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY()))); } + + // Apply flipping from enhanced geometry at center of the shape. + if (bIsMirroredX || bIsMirroredY) + { + // create mathematically matrix for the applied transformations + // aScale was in most cases built from a rectangle including edge + // and is therefore mathematically too large by 1 + if (aScale.getX() > 2.0 && aScale.getY() > 2.0) + aScale -= basegfx::B2DTuple(1.0, 1.0); + basegfx::B2DHomMatrix aMathMat = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix( + aScale, -fShearX, basegfx::fTools::equalZero(fRotate) ? 0.0 : fRotate, + aTranslate); + // Use matrix to get current center + basegfx::B2DPoint aCenter(0.5,0.5); + aCenter = aMathMat * aCenter; + double fCenterX = aCenter.getX(); + double fCenterY = aCenter.getY(); + if (bIsMirroredX) // vertical axis + Mirror(Point(FRound(fCenterX),FRound(fCenterY)), + Point(FRound(fCenterX), FRound(fCenterY + 1000.0))); + if (bIsMirroredY) // horizontal axis + Mirror(Point(FRound(fCenterX),FRound(fCenterY)), + Point(FRound(fCenterX + 1000.0), FRound(fCenterY))); + } } // taking fObjectRotation instead of aGeo.nAngle @@ -3078,6 +3115,7 @@ bool SdrObjCustomShape::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegf if ( bMirroredX ) { + fShearX = -fShearX; tools::Polygon aPol = Rect2Poly(maRect, aNewGeo); tools::Rectangle aBoundRect( aPol.GetBoundRect() ); @@ -3100,6 +3138,7 @@ bool SdrObjCustomShape::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegf } if ( bMirroredY ) { + fShearX = -fShearX; tools::Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) ); tools::Rectangle aBoundRect( aPol.GetBoundRect() ); |