[Libreoffice-commits] core.git: oox/inc oox/source sc/qa

Szabolcs Toth (via logerrit) logerrit at kemper.freedesktop.org
Thu Sep 24 10:54:57 UTC 2020


 oox/inc/drawingml/textbodyproperties.hxx           |    1 
 oox/source/drawingml/shape.cxx                     |   24 +++++++++--
 oox/source/drawingml/textbodypropertiescontext.cxx |    5 +-
 oox/source/export/drawingml.cxx                    |   37 ++++++++---------
 sc/qa/unit/data/xlsx/tdf106197_import_upright.xlsx |binary
 sc/qa/unit/subsequent_filters-test.cxx             |   45 +++++++++++++++++++++
 6 files changed, 89 insertions(+), 23 deletions(-)

New commits:
commit 8c23be49fb5a9044989532e6e20feb1e3ff64f2b
Author:     Szabolcs Toth <toth.szabolcs at nisz.hu>
AuthorDate: Wed Sep 16 14:41:24 2020 +0200
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Thu Sep 24 12:54:14 2020 +0200

    tdf#106197 XLSX shape import: keep text upright
    
    Handle and grab-bag attribute upright to keep
    text upright regardless of shape rotation, fixing
    the text direction after import and after a round-trip.
    
    Co-authored-by: Balázs Regényi
    
    Change-Id: If4c73aeaebad55af967cea894a94756068ca3766
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102870
    Tested-by: László Németh <nemeth at numbertext.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/oox/inc/drawingml/textbodyproperties.hxx b/oox/inc/drawingml/textbodyproperties.hxx
index 6e5e97fb94ba..26e34ac6a5f7 100644
--- a/oox/inc/drawingml/textbodyproperties.hxx
+++ b/oox/inc/drawingml/textbodyproperties.hxx
@@ -34,6 +34,7 @@ struct TextBodyProperties
     OptValue< sal_Int32 >                           moRotation;
     bool                                            mbAnchorCtr;
     OptValue< sal_Int32 >                           moVert;
+    bool                                            moUpright = false;
     std::optional< sal_Int32 >                    moInsets[4];
     std::optional< sal_Int32 >                    moTextOffUpper;
     std::optional< sal_Int32 >                    moTextOffLeft;
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 02b89312d200..326d90be3ffd 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1409,10 +1409,26 @@ Reference< XShape > const & Shape::createAndInsert(
                 sal_Int32 nTextRotateAngle = static_cast< sal_Int32 >( getTextBody()->getTextProperties().moRotation.get( 0 ) );
 
                 nTextRotateAngle -= mnDiagramRotation;
-                /* OOX measures text rotation clockwise in 1/60000th degrees,
-                   relative to the containing shape. setTextRotateAngle wants
-                   degrees anticlockwise. */
-                mpCustomShapePropertiesPtr->setTextRotateAngle( -1 * nTextRotateAngle / 60000 );
+
+                bool isUpright = getTextBody()->getTextProperties().moUpright;
+                if (isUpright)
+                {
+                    // When upright is set, we want the text without any rotation.
+                    // But if we set 0 here, the text is still rotated if the
+                    // shape containing it is rotated.
+                    // Hence, we rotate the text into the the opposite direction of
+                    // the rotation of the shape, by as much as the shape was rotated.
+                    mpCustomShapePropertiesPtr->setTextRotateAngle(mnRotation / 60000);
+                    // Also put this away in a Gabbag.
+                    putPropertyToGrabBag("Upright", Any(isUpright));
+                }
+                else
+                {
+                    /* OOX measures text rotation clockwise in 1/60000th degrees,
+                       relative to the containing shape. setTextRotateAngle wants
+                       degrees anticlockwise. */
+                    mpCustomShapePropertiesPtr->setTextRotateAngle(-1 * nTextRotateAngle / 60000);
+                }
             }
 
             // Note that the script oox/source/drawingml/customshapes/generatePresetsData.pl looks
diff --git a/oox/source/drawingml/textbodypropertiescontext.cxx b/oox/source/drawingml/textbodypropertiescontext.cxx
index b72fa194401a..d3add310097f 100644
--- a/oox/source/drawingml/textbodypropertiescontext.cxx
+++ b/oox/source/drawingml/textbodypropertiescontext.cxx
@@ -94,7 +94,10 @@ TextBodyPropertiesContext::TextBodyPropertiesContext( ContextHandler2Helper cons
     // ST_PositiveCoordinate
 //   sal_Int32 nSpcCol = rAttribs.getInteger( XML_spcCol, 0 );
 //   bool bSpcFirstLastPara = rAttribs.getBool( XML_spcFirstLastPara, 0 );
-//   bool bUpRight = rAttribs.getBool( XML_upright, 0 );
+
+    bool bUpright = rAttribs.getBool(XML_upright, false);
+    if (bUpright)
+        mrTextBodyProp.moUpright = true;
 
     // ST_TextVerticalType
     if( rAttribs.hasAttribute( XML_vert ) ) {
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 8d3cbd23a6a7..8ea8035ea39a 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2932,24 +2932,6 @@ void DrawingML::WriteText(const Reference<XInterface>& rXIface, bool bBodyPr, bo
     else if( bVertical && eHorizontalAlignment == TextHorizontalAdjust_LEFT )
         sVerticalAlignment = "b";
 
-    bool isUpright = false;
-    if (GetProperty(rXPropSet, "InteropGrabBag"))
-    {
-        if (rXPropSet->getPropertySetInfo()->hasPropertyByName("InteropGrabBag"))
-        {
-            uno::Sequence<beans::PropertyValue> aGrabBag;
-            rXPropSet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
-            for (auto& aProp : aGrabBag)
-            {
-                if (aProp.Name == "Upright")
-                {
-                    aProp.Value >>= isUpright;
-                    break;
-                }
-            }
-        }
-    }
-
     bool bHasWrap = false;
     bool bWrap = false;
     // Only custom shapes obey the TextWordWrap option, normal text always wraps.
@@ -2971,6 +2953,25 @@ void DrawingML::WriteText(const Reference<XInterface>& rXIface, bool bBodyPr, bo
             if (xServiceInfo.is() && xServiceInfo->supportsService("com.sun.star.drawing.TextShape"))
                 pWrap = "square";
         }
+
+        bool isUpright = false;
+        if (GetProperty(rXPropSet, "InteropGrabBag"))
+        {
+            if (rXPropSet->getPropertySetInfo()->hasPropertyByName("InteropGrabBag"))
+            {
+                uno::Sequence<beans::PropertyValue> aGrabBag;
+                rXPropSet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
+                for (auto& aProp : aGrabBag)
+                {
+                    if (aProp.Name == "Upright")
+                    {
+                        aProp.Value >>= isUpright;
+                        break;
+                    }
+                }
+            }
+        }
+
         mpFS->startElementNS( (nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr,
                                XML_wrap, pWrap,
                                XML_fromWordArt, sax_fastparser::UseIf("1", bFromWordArt),
diff --git a/sc/qa/unit/data/xlsx/tdf106197_import_upright.xlsx b/sc/qa/unit/data/xlsx/tdf106197_import_upright.xlsx
new file mode 100644
index 000000000000..5ac0a75eabb6
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf106197_import_upright.xlsx differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 203460654d17..4b8d999dc787 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -279,6 +279,7 @@ public:
     void testPreviewMissingObjLink();
     void testShapeRotationImport();
     void testShapeDisplacementOnRotationImport();
+    void testTextBoxBodyUpright();
 
     CPPUNIT_TEST_SUITE(ScFiltersTest);
     CPPUNIT_TEST(testBooleanFormatXLSX);
@@ -448,6 +449,7 @@ public:
     CPPUNIT_TEST(testPreviewMissingObjLink);
     CPPUNIT_TEST(testShapeRotationImport);
     CPPUNIT_TEST(testShapeDisplacementOnRotationImport);
+    CPPUNIT_TEST(testTextBoxBodyUpright);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -4910,6 +4912,49 @@ void ScFiltersTest::testShapeDisplacementOnRotationImport()
     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aRectangle.Y);
 }
 
+void ScFiltersTest::testTextBoxBodyUpright()
+{
+    // tdf#106197 We should import the "upright" attribute of txBody.
+    ScDocShellRef xDocSh = loadDoc("tdf106197_import_upright.", FORMAT_XLSX);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load testTextBoxBodyUpright.xlsx", xDocSh.is());
+
+    uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocSh->GetModel(), uno::UNO_QUERY_THROW);
+    uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW);
+    uno::Reference<drawing::XShape> xShape(xPage->getByIndex(0), uno::UNO_QUERY_THROW);
+    uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY_THROW);
+
+    // Check that we imported "Upright".
+    bool isUpright = false;
+    if (xShapeProperties->getPropertySetInfo()->hasPropertyByName("InteropGrabBag"))
+    {
+        uno::Sequence<beans::PropertyValue> aGrabBag;
+        xShapeProperties->getPropertyValue("InteropGrabBag") >>= aGrabBag;
+        for (auto& aProp : aGrabBag)
+        {
+            if (aProp.Name == "Upright")
+            {
+                aProp.Value >>= isUpright;
+                break;
+            }
+        }
+    }
+    CPPUNIT_ASSERT_EQUAL(true, isUpright);
+
+    // Check the new textRotateAngle.
+    sal_Int32 nAngle;
+    uno::Any aGeom = xShapeProperties->getPropertyValue("CustomShapeGeometry");
+    auto aGeomSeq = aGeom.get<Sequence<beans::PropertyValue>>();
+    for (const auto& aProp : std::as_const(aGeomSeq))
+    {
+        if (aProp.Name == "TextPreRotateAngle")
+        {
+            aProp.Value >>= nAngle;
+            break;
+        }
+    }
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(90), nAngle);
+}
+
 ScFiltersTest::ScFiltersTest()
       : ScBootstrapFixture( "sc/qa/unit/data" )
 {


More information about the Libreoffice-commits mailing list