summaryrefslogtreecommitdiff
path: root/xmloff
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2020-01-02 17:37:32 +0100
committerRegina Henschel <rb.henschel@t-online.de>2020-01-17 18:03:38 +0100
commitbc886f523872d4f9845c188c7d525d72a1a60946 (patch)
tree8677487eb45e619a9dcbc135c9c934e1a8e201d4 /xmloff
parent21a5c7f77dea3c880ee1808f5385205f53271338 (diff)
tdf#98584 Correct import draw:transform values skewY and matrix
Covers tdf#98583 and tdf#98565 too. TRBaseGeomety (API) uses for skewX the same angle orientation as written to file. But that results in mathematically wrong matrices. Change sign where needed. Vertical shearing is converted and written to file by LO as sequence rotation * shear horizontal * scale. Same should happen on reading. Because LO does not write skewY itself, I have used the angle orientation, that was used in OOo1.1.5 and that is used in Scribus 1.5.4. Import generates a transformation matrix from the draw:transform attribute. That is a mathematically correct matrix. It is applied to the shape via TRSetBaseGeometry. But that uses a wrong sign in the shear angle. Therefore conversion of mathematical matrix to TRBaseGeometry matrix is needed. The draw:transform attribute can generate a scaling, which needs to be applied on top of the scaling made from svg:width and svg:height. Such happens on import of skewY() and might happen with matrix(). SdrPathObject puts scaling form svg:width and svg:height directly into the coordinates of its points. It had ignored any additional scaling. I have add a part to detect and apply it. Change-Id: I7636b9feec432cf403e7c6ef8dbd6a769793d144 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86244 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de> Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
Diffstat (limited to 'xmloff')
-rw-r--r--xmloff/source/draw/xexptran.cxx10
-rw-r--r--xmloff/source/draw/ximpshap.cxx53
2 files changed, 47 insertions, 16 deletions
diff --git a/xmloff/source/draw/xexptran.cxx b/xmloff/source/draw/xexptran.cxx
index eb7cb4a634d5..0137166871bc 100644
--- a/xmloff/source/draw/xexptran.cxx
+++ b/xmloff/source/draw/xexptran.cxx
@@ -510,12 +510,18 @@ void SdXMLImExTransform2D::GetFullTransform(::basegfx::B2DHomMatrix& rFullTrans)
}
case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX :
{
- rFullTrans.shearX(tan(static_cast<ImpSdXMLExpTransObj2DSkewX*>(pObj)->mfSkewX));
+ // For to get a mathematical correct matrix from already existing documents,
+ // mirror the value here. ODF spec is unclear about direction.
+ rFullTrans.shearX(-tan(static_cast<ImpSdXMLExpTransObj2DSkewX*>(pObj)->mfSkewX));
break;
}
case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY :
{
- rFullTrans.shearY(tan(static_cast<ImpSdXMLExpTransObj2DSkewY*>(pObj)->mfSkewY));
+ // LibreOffice does not write skewY, OOo neither. Such files are foreign documents
+ // or manually set transformations. OOo had used the value as -tan(value) before
+ // errors were introduced, Scribus 1.5.4 uses it as -tan(value) too, MS Office does
+ // not shear at all. ODF spec is unclear about direction.
+ rFullTrans.shearY(-tan(static_cast<ImpSdXMLExpTransObj2DSkewY*>(pObj)->mfSkewY));
break;
}
case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX :
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index 8bee4b376ba1..3594d1605363 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -575,21 +575,38 @@ void SdXMLShapeContext::SetTransformation()
}
// now set transformation for this object
- drawing::HomogenMatrix3 aMatrix;
- aMatrix.Line1.Column1 = maUsedTransformation.get(0, 0);
- aMatrix.Line1.Column2 = maUsedTransformation.get(0, 1);
- aMatrix.Line1.Column3 = maUsedTransformation.get(0, 2);
+ // maUsedTransformtion contains the mathematical correct matrix, which if
+ // applied to a unit square would generate the transformed shape. But the property
+ // "Transformation" contains a matrix, which can be used in TRSetBaseGeometry
+ // and would be created by TRGetBaseGeometry. And those use a mathematically wrong
+ // sign for the shearing angle. So we need to adapt the matrix here.
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate;
+ double fShearX;
+ maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+ basegfx::B2DHomMatrix aB2DHomMatrix;
+ aB2DHomMatrix = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
+ aScale,
+ basegfx::fTools::equalZero(fShearX) ? 0.0 : -fShearX,
+ basegfx::fTools::equalZero(fRotate) ? 0.0 : fRotate,
+ aTranslate);
+ drawing::HomogenMatrix3 aUnoMatrix;
- aMatrix.Line2.Column1 = maUsedTransformation.get(1, 0);
- aMatrix.Line2.Column2 = maUsedTransformation.get(1, 1);
- aMatrix.Line2.Column3 = maUsedTransformation.get(1, 2);
+ aUnoMatrix.Line1.Column1 = aB2DHomMatrix.get(0, 0);
+ aUnoMatrix.Line1.Column2 = aB2DHomMatrix.get(0, 1);
+ aUnoMatrix.Line1.Column3 = aB2DHomMatrix.get(0, 2);
- aMatrix.Line3.Column1 = maUsedTransformation.get(2, 0);
- aMatrix.Line3.Column2 = maUsedTransformation.get(2, 1);
- aMatrix.Line3.Column3 = maUsedTransformation.get(2, 2);
+ aUnoMatrix.Line2.Column1 = aB2DHomMatrix.get(1, 0);
+ aUnoMatrix.Line2.Column2 = aB2DHomMatrix.get(1, 1);
+ aUnoMatrix.Line2.Column3 = aB2DHomMatrix.get(1, 2);
- xPropSet->setPropertyValue("Transformation", Any(aMatrix));
+ aUnoMatrix.Line3.Column1 = aB2DHomMatrix.get(2, 0);
+ aUnoMatrix.Line3.Column2 = aB2DHomMatrix.get(2, 1);
+ aUnoMatrix.Line3.Column3 = aB2DHomMatrix.get(2, 2);
+
+ xPropSet->setPropertyValue("Transformation", Any(aUnoMatrix));
}
}
}
@@ -1093,9 +1110,9 @@ void SdXMLLineShapeContext::StartElement(const uno::Reference< xml::sax::XAttrib
xPropSet->setPropertyValue("Geometry", Any(aPolyPoly));
}
- // set sizes for transformation
- maSize.Width = o3tl::saturating_sub(aBottomRight.X, aTopLeft.X);
- maSize.Height = o3tl::saturating_sub(aBottomRight.Y, aTopLeft.Y);
+ // Size is included in point coordinates
+ maSize.Width = 1;
+ maSize.Height = 1;
maPosition.X = aTopLeft.X;
maPosition.Y = aTopLeft.Y;
@@ -1322,6 +1339,10 @@ void SdXMLPolygonShapeContext::StartElement(const uno::Reference< xml::sax::XAtt
css::drawing::PointSequenceSequence aPointSequenceSequence;
basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(basegfx::B2DPolyPolygon(aPolygon), aPointSequenceSequence);
xPropSet->setPropertyValue("Geometry", Any(aPointSequenceSequence));
+ // Size is now contained in the point coordinates, adapt maSize for
+ // to use the correct transformation matrix in SetTransformation()
+ maSize.Width = 1;
+ maSize.Height = 1;
}
}
}
@@ -1471,6 +1492,10 @@ void SdXMLPathShapeContext::StartElement(const uno::Reference< xml::sax::XAttrib
}
xPropSet->setPropertyValue("Geometry", aAny);
+ // Size is now contained in the point coordinates, adapt maSize for
+ // to use the correct transformation matrix in SetTransformation()
+ maSize.Width = 1;
+ maSize.Height = 1;
}
// set pos, size, shear and rotate