summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svx/svdopath.hxx7
-rw-r--r--svx/qa/unit/svdraw.cxx82
-rw-r--r--svx/source/svdraw/svdopath.cxx7
-rw-r--r--svx/source/unodraw/unoshape.cxx15
-rw-r--r--xmloff/source/draw/shapeimport.cxx6
5 files changed, 116 insertions, 1 deletions
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));
+ }
}
}