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 );

Reply via email to