summaryrefslogtreecommitdiff
path: root/svx/source/svdraw/svdoashp.cxx
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2019-12-21 22:32:55 +0100
committerTomaž Vajngerl <quikee@gmail.com>2020-02-26 12:04:11 +0100
commitb4a6977e05d87fe0a79b266ec30e4f403404f1b4 (patch)
tree969b5d55c1f3ea2dedff31009ae89ff0eec38da5 /svx/source/svdraw/svdoashp.cxx
parent79d396a2a64bec4e6c9aa514af40fdd67a62d8ce (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.cxx65
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() );