[Libreoffice-commits] core.git: include/svx svx/qa svx/source xmloff/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Mon Feb 22 17:00:47 UTC 2021
include/svx/svdopath.hxx | 7 +++
svx/qa/unit/svdraw.cxx | 82 +++++++++++++++++++++++++++++++++++++
svx/source/svdraw/svdopath.cxx | 7 ++-
svx/source/unodraw/unoshape.cxx | 15 ++++++
xmloff/source/draw/shapeimport.cxx | 6 ++
5 files changed, 116 insertions(+), 1 deletion(-)
New commits:
commit 3870198c0d0bf354cddc33da88b4ddd02de40c94
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Feb 22 14:53:05 2021 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Feb 22 18:00:04 2021 +0100
svx: fix unexpected large bezier shapes when created via the UNO API
Regression from commit bc886f523872d4f9845c188c7d525d72a1a60946
(tdf#98584 Correct import draw:transform values skewY and matrix,
2020-01-02), then problem is was that now we handle the transform matrix
for path objects the way ODF likes it, but this breaks UNO API clients
with existing code.
In an attempt to make everyone happy, revert the default to ignore
scaling from the transform matrix, but add a way so that xmloff/ can opt
in to handle it. This way the ODF import result doesn't regression and
UNO API compatibility is not broken, either.
Change-Id: I8d525e56954bf68c42d3629eca87fe9b513de507
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111340
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
Tested-by: Jenkins
diff --git a/include/svx/svdopath.hxx b/include/svx/svdopath.hxx
index b934d74d3e46..be345a850b7d 100644
--- a/include/svx/svdopath.hxx
+++ b/include/svx/svdopath.hxx
@@ -49,6 +49,7 @@ private:
basegfx::B2DPolyPolygon maPathPolygon;
SdrObjKind meKind;
+ bool mbHandleScale = false;
// for isolation of old Drag/Create code
std::unique_ptr<ImpPathForDragAndCreate> mpDAC;
@@ -163,6 +164,12 @@ public:
// If it's an SdrPathObj it will use the provided geometry information. The Polygon has
// to use (0,0) as upper left and will be scaled to the given size in the matrix.
virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon) override;
+
+ /**
+ * Scaling is ignored from the transform matrix by default, to not break compatibility. One can
+ * opt in to handle scaling if matching ODF behavior is more important.
+ */
+ void SetHandleScale(bool bHandleScale);
};
#endif // INCLUDED_SVX_SVDOPATH_HXX
diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx
index c96ccbb7aa97..15c220d53e07 100644
--- a/svx/qa/unit/svdraw.cxx
+++ b/svx/qa/unit/svdraw.cxx
@@ -16,6 +16,10 @@
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/drawing/HomogenMatrix3.hpp>
#include <drawinglayer/tools/primitive2dxmldump.hxx>
#include <rtl/ustring.hxx>
@@ -105,6 +109,84 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testSemiTransparentText)
CPPUNIT_ASSERT_EQUAL(nTransparence,
static_cast<sal_Int16>(basegfx::fround(fTransparence * 100)));
}
+
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testHandlePathObjScale)
+{
+ // Given a path object:
+ getComponent() = loadFromDesktop("private:factory/sdraw");
+ uno::Reference<lang::XMultiServiceFactory> xFactory(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xShape(
+ xFactory->createInstance("com.sun.star.drawing.ClosedBezierShape"), uno::UNO_QUERY);
+
+ // When setting its scale by both using setSize() and scaling in a transform matrix:
+ // Set size and basic properties.
+ xShape->setPosition(awt::Point(2512, 6062));
+ xShape->setSize(awt::Size(112, 112));
+ uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+ xShapeProps->setPropertyValue("FillStyle", uno::makeAny(drawing::FillStyle_SOLID));
+ xShapeProps->setPropertyValue("LineStyle", uno::makeAny(drawing::LineStyle_SOLID));
+ xShapeProps->setPropertyValue("FillColor", uno::makeAny(static_cast<sal_Int32>(0)));
+ // Add it to the draw page.
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY);
+ xDrawPage->add(xShape);
+ // Set polygon coordinates.
+ drawing::PolyPolygonBezierCoords aPolyPolygonBezierCoords;
+ aPolyPolygonBezierCoords.Coordinates = {
+ {
+ awt::Point(2624, 6118),
+ awt::Point(2624, 6087),
+ awt::Point(2599, 6062),
+ awt::Point(2568, 6062),
+ awt::Point(2537, 6062),
+ awt::Point(2512, 6087),
+ awt::Point(2512, 6118),
+ awt::Point(2512, 6149),
+ awt::Point(2537, 6175),
+ awt::Point(2568, 6174),
+ awt::Point(2599, 6174),
+ awt::Point(2625, 6149),
+ awt::Point(2624, 6118),
+ },
+ };
+ aPolyPolygonBezierCoords.Flags = {
+ {
+ drawing::PolygonFlags_NORMAL,
+ drawing::PolygonFlags_CONTROL,
+ drawing::PolygonFlags_CONTROL,
+ drawing::PolygonFlags_NORMAL,
+ drawing::PolygonFlags_CONTROL,
+ drawing::PolygonFlags_CONTROL,
+ drawing::PolygonFlags_NORMAL,
+ drawing::PolygonFlags_CONTROL,
+ drawing::PolygonFlags_CONTROL,
+ drawing::PolygonFlags_NORMAL,
+ drawing::PolygonFlags_CONTROL,
+ drawing::PolygonFlags_CONTROL,
+ drawing::PolygonFlags_NORMAL,
+ },
+ };
+ xShapeProps->setPropertyValue("PolyPolygonBezier", uno::makeAny(aPolyPolygonBezierCoords));
+ drawing::HomogenMatrix3 aMatrix;
+ aMatrix.Line1.Column1 = 56;
+ aMatrix.Line2.Column1 = -97;
+ aMatrix.Line3.Column1 = 0;
+ aMatrix.Line1.Column2 = 97;
+ aMatrix.Line2.Column2 = 56;
+ aMatrix.Line3.Column2 = 0;
+ aMatrix.Line1.Column3 = 3317;
+ aMatrix.Line2.Column3 = 5583;
+ aMatrix.Line3.Column3 = 1;
+ xShapeProps->setPropertyValue("Transformation", uno::makeAny(aMatrix));
+
+ // Then make sure the scaling is only applied once:
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 113
+ // - Actual : 12566
+ // i.e. the scaling was applied twice.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(113), xShape->getSize().Width);
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdopath.cxx b/svx/source/svdraw/svdopath.cxx
index c3b1995e2b16..be0fbf786a11 100644
--- a/svx/source/svdraw/svdopath.cxx
+++ b/svx/source/svdraw/svdopath.cxx
@@ -2877,6 +2877,11 @@ bool SdrPathObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DP
return true;
}
+void SdrPathObj::SetHandleScale(bool bHandleScale)
+{
+ mbHandleScale = bHandleScale;
+}
+
// Sets the base geometry of the object using infos contained in the homogeneous 3x3 matrix.
// If it's an SdrPathObj it will use the provided geometry information. The Polygon has
// to use (0,0) as upper left and will be scaled to the given size in the matrix.
@@ -2929,7 +2934,7 @@ void SdrPathObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const b
// be applied to the polygon too, so aScale cannot be ignored while loading.
// I use "maSnapRect.IsEmpty() && GetPathPoly().count()" to detect this case. Any better
// idea? The behavior in other cases is the same as it was before this fix.
- if (maSnapRect.IsEmpty() && GetPathPoly().count())
+ if (maSnapRect.IsEmpty() && GetPathPoly().count() && mbHandleScale)
{
// In case of a Writer document, the scaling factors were converted to twips. That is not
// correct here, because width and height are already in the points coordinates and aScale
diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx
index 965df6b63cbd..a84795b4b06b 100644
--- a/svx/source/unodraw/unoshape.cxx
+++ b/svx/source/unodraw/unoshape.cxx
@@ -85,6 +85,7 @@
#include <vcl/wmf.hxx>
#include <svx/sdtfsitm.hxx>
#include <svx/svdoutl.hxx>
+#include <svx/svdopath.hxx>
#include <memory>
#include <vector>
@@ -1611,6 +1612,20 @@ void SvxShape::_setPropertyValue( const OUString& rPropertyName, const uno::Any&
return;
}
+ if (rPropertyName == "HandlePathObjScale")
+ {
+ auto pPathObj = dynamic_cast<SdrPathObj*>(GetSdrObject());
+ if (pPathObj)
+ {
+ bool bHandleScale{};
+ if (rVal >>= bHandleScale)
+ {
+ pPathObj->SetHandleScale(bHandleScale);
+ }
+ }
+ return;
+ }
+
if (!pMap)
{
// reduce log noise by ignoring two properties that higher level code queries for on all objects
diff --git a/xmloff/source/draw/shapeimport.cxx b/xmloff/source/draw/shapeimport.cxx
index 69f97973913f..792daaa5db3f 100644
--- a/xmloff/source/draw/shapeimport.cxx
+++ b/xmloff/source/draw/shapeimport.cxx
@@ -471,6 +471,12 @@ void XMLShapeImportHelper::addShape( uno::Reference< drawing::XShape >& rShape,
{
// add new shape to parent
rShapes->add( rShape );
+
+ uno::Reference<beans::XPropertySet> xPropertySet(rShape, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ xPropertySet->setPropertyValue("HandlePathObjScale", uno::makeAny(true));
+ }
}
}
More information about the Libreoffice-commits
mailing list