[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - oox/qa oox/source

Daniel Arato (NISZ) (via logerrit) logerrit at kemper.freedesktop.org
Thu Nov 5 16:05:23 UTC 2020


 oox/qa/unit/data/camera-rotation-revolution.docx |binary
 oox/qa/unit/drawingml.cxx                        |   25 +++++++++++++++++
 oox/source/drawingml/shape.cxx                   |    7 +++--
 oox/source/export/drawingml.cxx                  |   32 +++++++++++++++++++++--
 4 files changed, 60 insertions(+), 4 deletions(-)

New commits:
commit a571afa4a1747fe3ab3078ade6e93093526c6807
Author:     Daniel Arato (NISZ) <arato.daniel at nisz.hu>
AuthorDate: Tue Sep 29 16:37:41 2020 +0200
Commit:     Gülşah Köse <gulsah.kose at collabora.com>
CommitDate: Thu Nov 5 17:04:47 2020 +0100

    tdf#133037 OOXML shape import: camera rotation along Z
    
    Instead of implementing proper OOXML 3D rotation (which would be
    an entirely new feature if I understand correctly), I merely
    interpret attribute "rev" of the rotation element a:camera/a:rot
    as a directive to rotate the entire shape the usual 2D way. That
    is already implemented and works well. This isn't the same thing
    Word does, but it might be good enough for now. This is kind of a
    mock solution, but it will be very easy to revert if it turns out
    to cause problems.
    
    Note: the export worked well previously, too (moreover, reloading
    the first LO export fixed the import).
    
    Change-Id: I2a99c119880bbed1c5b6430c4638cfbd10b7ac06
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103627
    Tested-by: László Németh <nemeth at numbertext.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>
    (cherry picked from commit a9c5c0d814a266096483572b84c72875ef8efd77)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105352
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Gülşah Köse <gulsah.kose at collabora.com>

diff --git a/oox/qa/unit/data/camera-rotation-revolution.docx b/oox/qa/unit/data/camera-rotation-revolution.docx
new file mode 100644
index 000000000000..74054aa82b3f
Binary files /dev/null and b/oox/qa/unit/data/camera-rotation-revolution.docx differ
diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx
index dea8461d543f..f17d1050fe85 100644
--- a/oox/qa/unit/drawingml.cxx
+++ b/oox/qa/unit/drawingml.cxx
@@ -274,6 +274,31 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testShapeTextAdjustLeft)
     CPPUNIT_ASSERT_EQUAL(drawing::TextHorizontalAdjust_BLOCK, eAdjust);
 }
 
+CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testCameraRotationRevolution)
+{
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "camera-rotation-revolution.docx";
+    load(aURL);
+
+    uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+                                                 uno::UNO_QUERY);
+    uno::Reference<container::XNamed> xShape0(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+    uno::Reference<container::XNamed> xShape1(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xShapeProps0(xShape0, uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xShapeProps1(xShape1, uno::UNO_QUERY);
+    sal_Int32 nRotateAngle0;
+    sal_Int32 nRotateAngle1;
+    xShapeProps0->getPropertyValue("RotateAngle") >>= nRotateAngle0;
+    xShapeProps1->getPropertyValue("RotateAngle") >>= nRotateAngle1;
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 8000
+    // - Actual  : 0
+    // so the camera rotation would not have been factored into how the shape is displayed
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(8000), nRotateAngle0);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(27000), nRotateAngle1);
+}
+
 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 2ccc1e20917f..668c30a547b0 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1439,11 +1439,14 @@ Reference< XShape > const & Shape::createAndInsert(
         else if( getTextBody() )
             getTextBody()->getTextProperties().pushVertSimulation();
 
+        // tdf#133037: a bit hackish: force Shape to rotate in the opposite direction the camera would rotate
+        const sal_Int32 nCameraRotation = get3DProperties().maCameraRotation.mnRevolution.get(0);
+
         PropertySet aPropertySet(mxShape);
-        if ( !bUseRotationTransform && mnRotation != 0 )
+        if ( !bUseRotationTransform && (mnRotation != 0 || nCameraRotation != 0) )
         {
             // use the same logic for rotation from VML exporter (SimpleShape::implConvertAndInsert at vmlshape.cxx)
-            aPropertySet.setAnyProperty( PROP_RotateAngle, makeAny( sal_Int32( NormAngle36000( mnRotation / -600 ) ) ) );
+            aPropertySet.setAnyProperty( PROP_RotateAngle, makeAny( sal_Int32( NormAngle36000( (mnRotation - nCameraRotation) / -600 ) ) ) );
             aPropertySet.setAnyProperty( PROP_HoriOrientPosition, makeAny( maPosition.X ) );
             aPropertySet.setAnyProperty( PROP_VertOrientPosition, makeAny( maPosition.Y ) );
         }
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index b9c6403caff2..264bf3a5e55f 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1669,7 +1669,8 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa
 {
     SAL_INFO("oox.shape",  "write shape transformation");
 
-    sal_Int32 nRotation=0;
+    sal_Int32 nRotation = 0;
+    sal_Int32 nCameraRotation = 0;
     awt::Point aPos = rXShape->getPosition();
     awt::Size aSize = rXShape->getSize();
 
@@ -1706,6 +1707,33 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa
         uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
         if (xPropertySetInfo->hasPropertyByName("RotateAngle"))
             xPropertySet->getPropertyValue("RotateAngle") >>= nRotation;
+        // tdf#133037: restore original rotate angle before output
+        if (xPropertySetInfo->hasPropertyByName(UNO_NAME_MISC_OBJ_INTEROPGRABBAG))
+        {
+            uno::Sequence<beans::PropertyValue> aGrabBagProps;
+            xPropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBagProps;
+            auto p3DEffectProps = std::find_if(std::cbegin(aGrabBagProps), std::cend(aGrabBagProps),
+                [](const PropertyValue& rProp) { return rProp.Name == "3DEffectProperties"; });
+            if (p3DEffectProps != std::cend(aGrabBagProps))
+            {
+                uno::Sequence<beans::PropertyValue> a3DEffectProps;
+                p3DEffectProps->Value >>= a3DEffectProps;
+                auto pCameraProps = std::find_if(std::cbegin(a3DEffectProps), std::cend(a3DEffectProps),
+                    [](const PropertyValue& rProp) { return rProp.Name == "Camera"; });
+                if (pCameraProps != std::cend(a3DEffectProps))
+                {
+                    uno::Sequence<beans::PropertyValue> aCameraProps;
+                    pCameraProps->Value >>= aCameraProps;
+                    auto pZRotationProp = std::find_if(std::cbegin(aCameraProps), std::cend(aCameraProps),
+                        [](const PropertyValue& rProp) { return rProp.Name == "rotRev"; });
+                    if (pZRotationProp != std::cend(aCameraProps))
+                    {
+                        pZRotationProp->Value >>= nCameraRotation;
+                        nCameraRotation = NormAngle36000(nCameraRotation / -600);
+                    }
+                }
+            }
+        }
     }
 
     // OOXML flips shapes before rotating them.
@@ -1713,7 +1741,7 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa
         nRotation = nRotation * -1 + 36000;
 
     WriteTransformation(tools::Rectangle(Point(aPos.X, aPos.Y), Size(aSize.Width, aSize.Height)), nXmlNamespace,
-            bFlipHWrite, bFlipVWrite, ExportRotateClockwisify(nRotation), IsGroupShape( rXShape ));
+            bFlipHWrite, bFlipVWrite, ExportRotateClockwisify(nRotation + nCameraRotation), IsGroupShape( rXShape ));
 }
 
 void DrawingML::WriteRunProperties( const Reference< XPropertySet >& rRun, bool bIsField, sal_Int32 nElement, bool bCheckDirect,


More information about the Libreoffice-commits mailing list