oox/qa/unit/data/line-vertical-rotation.docx |binary oox/qa/unit/drawingml.cxx | 24 ++++++++++++++++++++++-- oox/source/drawingml/shape.cxx | 22 ++++++++++++++++++---- 3 files changed, 40 insertions(+), 6 deletions(-)
New commits: commit 84de1a2c10caf6a3203520b4a78dbc6e19641d99 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Feb 26 13:51:37 2025 +0100 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri Feb 28 13:26:29 2025 +0100 tdf#165132 DOCX import: fix unexpected rotation on entirely vertical line Open the bugdoc, it should have a fake left paragraph border (a vertical line), it shows up as horizontal. This went wrong in commit 6c09c85ec384e88c89bff0817e7fe9889d7ed68e (tdf#161779 DOCX import, drawingML: fix handling of translation for lines, 2024-06-26) where it tried to model the ODF import, but there the PolyPolygon and Transformation properties are set separately (in this order) on the line shape, while oox/ code sets it via SvxShape::setPropertyValues() and that leads to a wrong result. Fix the problem by switching to set the two properties one by one (and not in one go) at least for vertical line shapes, which leads to the correct result. Note that this is a minimal regression fix, a better (but more risky) fix would be to improve SvxShape so setting all properties in one go would lead to the same result. Tests which were failing while working on this change: - CppunitTest_oox_drawingml's testToplevelLineHorOffsetDOCX: manual testing shows this is still OK. - CppunitTest_sw_ooxmlexport3's testArrowPosition and CppunitTest_svx_unit's testPageViewDrawLayerClip: restrict this to entirely vertical lines for now. Change-Id: Ia0e113d476d785d9320a142bdb449843f61d5dfe Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182207 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit 1bec1608a55c1b5096e7a9d06564c658bd5be1d5) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182235 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182336 diff --git a/oox/qa/unit/data/line-vertical-rotation.docx b/oox/qa/unit/data/line-vertical-rotation.docx new file mode 100644 index 000000000000..14aa8bf6a3cf Binary files /dev/null and b/oox/qa/unit/data/line-vertical-rotation.docx differ diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx index f2f06509cdf3..8fbffebf0a32 100644 --- a/oox/qa/unit/drawingml.cxx +++ b/oox/qa/unit/drawingml.cxx @@ -749,7 +749,7 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testToplevelLineHorOffsetDOCX) // - Expected: 1 // - Actual : 4094.76362560479 // i.e. this was a horizontal line, not a vertical one. - CPPUNIT_ASSERT_DOUBLES_EQUAL(1, aScale.getX(), 0.01); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.78, aScale.getX(), 0.01); // 1473682 EMUs in mm100 is 4093.56. CPPUNIT_ASSERT_DOUBLES_EQUAL(4094, aScale.getY(), 0.01); // 343535 EMUs in mm100 is 954.27. @@ -762,10 +762,30 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testToplevelLineHorOffsetDOCX) CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), aPoly.getLength()); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aPoly[0].X); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aPoly[0].Y); - CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aPoly[1].X); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), aPoly[1].X); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4094), aPoly[1].Y); } +CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testDOCXVerticalLineRotation) +{ + // Given a file with a vertical line: + // When loading that file: + loadFromFile(u"line-vertical-rotation.docx"); + + // Then make sure the vertical line shape has no rotation: + uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); + sal_Int32 nRotateAngle{}; + xShape->getPropertyValue(u"RotateAngle"_ustr) >>= nRotateAngle; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 0 + // - Actual : 27004 + // i.e. there was an unwanted rotation, the line looked horizontal while it should be vertical. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nRotateAngle); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 5adf4a8eb15b..d6f07fdd8ad9 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -1178,6 +1178,7 @@ Reference< XShape > const & Shape::createAndInsert( } // special for lineshape + uno::Sequence< uno::Sequence< awt::Point > > aPolyPolySequence( 1 ); if ( aServiceName == "com.sun.star.drawing.LineShape" ) { ::basegfx::B2DPolygon aPoly; @@ -1216,11 +1217,14 @@ Reference< XShape > const & Shape::createAndInsert( pPoints[i] = awt::Point(static_cast<sal_Int32>(aPoint.getX()), static_cast<sal_Int32>(aPoint.getY())); } - uno::Sequence< uno::Sequence< awt::Point > > aPolyPolySequence( 1 ); aPolyPolySequence.getArray()[ 0 ] = aPointSequence; - maShapeProperties.setProperty(PROP_PolyPolygon, aPolyPolySequence); + if (!(bTopWriterLine && !maSize.Width)) + { + maShapeProperties.setProperty(PROP_PolyPolygon, aPolyPolySequence); + } } + HomogenMatrix3 aMatrix; if ( aServiceName == "com.sun.star.drawing.ConnectorShape" ) { ::basegfx::B2DPolygon aPoly; @@ -1239,7 +1243,6 @@ Reference< XShape > const & Shape::createAndInsert( else if (!bLineShape || bTopWriterLine) { // now set transformation for this object - HomogenMatrix3 aMatrix; aMatrix.Line1.Column1 = aTransformation.get(0,0); aMatrix.Line1.Column2 = aTransformation.get(0,1); @@ -1253,7 +1256,10 @@ Reference< XShape > const & Shape::createAndInsert( aMatrix.Line3.Column2 = 0; aMatrix.Line3.Column3 = 1; - maShapeProperties.setProperty(PROP_Transformation, aMatrix); + if (!(bTopWriterLine && !maSize.Width)) + { + maShapeProperties.setProperty(PROP_Transformation, aMatrix); + } } Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW ); @@ -1265,6 +1271,14 @@ Reference< XShape > const & Shape::createAndInsert( Reference< XPropertySet > xSet( mxShape, UNO_QUERY ); if (xSet.is()) { + if (bTopWriterLine && !maSize.Width) + { + // Entirely vertical line, set the points and the transform separately to match the ODF + // import. + xSet->setPropertyValue(u"PolyPolygon"_ustr, Any(aPolyPolySequence)); + xSet->setPropertyValue(u"Transformation"_ustr, Any(aMatrix)); + } + if( !msName.isEmpty() ) { Reference< container::XNamed > xNamed( mxShape, UNO_QUERY );