oox/source/drawingml/shape.cxx                     |   10 +++--
 oox/source/export/drawingml.cxx                    |   37 +++++++++++++++++++--
 sc/qa/unit/data/xlsx/tdf137000_export_upright.xlsx |binary
 sc/qa/unit/subsequent_export-test.cxx              |   21 +++++++++++
 4 files changed, 61 insertions(+), 7 deletions(-)

New commits:
commit c080b0a44facfbbf4ca9e3ad74a93306df322df6
Author:     Szabolcs Toth <toth.szabo...@nisz.hu>
AuthorDate: Thu Sep 17 11:22:09 2020 +0200
Commit:     Gabor Kelemen <kelemen.gab...@nisz.hu>
CommitDate: Thu Feb 25 15:13:39 2021 +0100

    tdf#137000 XLSX shape export: fix upright
    
    Upright is an XML attribute of xdr:txBody/a:bodyPr. It is set
    in MSO when in a textbox menu we choose "Do not rotate this element".
    LO import uses a text rotation opposite shape rotation to create
    upright text, but when exporting the attribute "upright" we must
    make sure that the text rotation in bodyPr is 0, not the temporary
    opposite value. Otherwise MSO rotates the text.
    
    Note: integer precision of rotation is enough for interoperability,
    because it's possible to rotate the shapes only by whole degrees
    in MSO.
    
    Follow-up of commit 8c23be49fb5a9044989532e6e20feb1e3ff64f2b
    (tdf#106197 XLSX shape import: keep text upright).
    
    Co-authored-by: Balázs Regényi
    
    Change-Id: I0ffae41f83d3fc3a1fa37f413a8fc9fd8ccd9b6b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103094
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111412
    Tested-by: Gabor Kelemen <kelemen.gab...@nisz.hu>
    Reviewed-by: Gabor Kelemen <kelemen.gab...@nisz.hu>

diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 8d15beca453e..a69404094db1 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1430,8 +1430,7 @@ Reference< XShape > const & Shape::createAndInsert(
 
                 nTextRotateAngle -= mnDiagramRotation;
 
-                bool isUpright = getTextBody()->getTextProperties().moUpright;
-                if (isUpright)
+                if (getTextBody()->getTextProperties().moUpright)
                 {
                     // When upright is set, we want the text without any 
rotation.
                     // But if we set 0 here, the text is still rotated if the
@@ -1439,8 +1438,11 @@ Reference< XShape > const & Shape::createAndInsert(
                     // 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));
+
+                    // Also put the initial angles away in a GrabBag.
+                    putPropertyToGrabBag("Upright", Any(true));
+                    putPropertyToGrabBag("nShapeRotationAtImport", 
Any(mnRotation / 60000));
+                    putPropertyToGrabBag("nTextRotationAtImport", 
Any(mnRotation / 60000));
                 }
                 else
                 {
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 1532ce2b2ad2..6a9b4d3f6186 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2863,20 +2863,31 @@ void DrawingML::WriteText( const Reference< XInterface 
>& rXIface, const OUStrin
                 pWrap = "square";
         }
 
-        bool isUpright = false;
         std::optional<OUString> sHorzOverflow;
         std::optional<OUString> sVertOverflow;
+        sal_Int32 nShapeRotateAngle = 0;
+        if (GetProperty(rXPropSet, "RotateAngle"))
+            nShapeRotateAngle = 
rXPropSet->getPropertyValue("RotateAngle").get<sal_Int32>() / 300;
+        Reference< XPropertySet > xTextSet(xXText, UNO_QUERY);
+        sal_Int32 nShapeTextRotateAngle = 0;
+        if (GetProperty(xTextSet, "RotateAngle"))
+            nShapeTextRotateAngle = 
rXPropSet->getPropertyValue("RotateAngle").get<sal_Int32>() / 300;
+        std::optional<OString> isUpright;
         if (GetProperty(rXPropSet, "InteropGrabBag"))
         {
             if 
(rXPropSet->getPropertySetInfo()->hasPropertyByName("InteropGrabBag"))
             {
+                bool bUpright = false;
+                sal_Int32 nOldShapeRotation = 0;
+                sal_Int32 nOldTextRotation = 0;
                 uno::Sequence<beans::PropertyValue> aGrabBag;
                 rXPropSet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
                 for (const auto& aProp : std::as_const(aGrabBag))
                 {
                     if (aProp.Name == "Upright")
                     {
-                        aProp.Value >>= isUpright;
+                        aProp.Value >>= bUpright;
+                        isUpright = OString(bUpright ? "1" : "0");
                     }
                     else if (aProp.Name == "horzOverflow")
                     {
@@ -2891,6 +2902,26 @@ void DrawingML::WriteText( const Reference< XInterface 
>& rXIface, const OUStrin
                         sVertOverflow = sValue;
                     }
                 }
+                if (bUpright)
+                {
+                    for (auto& aProp : aGrabBag)
+                    {
+                        if (aProp.Name == "nShapeRotationAtImport")
+                            aProp.Value >>= nOldShapeRotation;
+                        else if (aProp.Name == "nTextRotationAtImport")
+                            aProp.Value >>= nOldTextRotation;
+                    }
+                    // So our shape with the textbox in it was not rotated.
+                    // Keep upright and make the preRotateAngle 0, it is an 
attribute
+                    // of textBodyPr and must be 0 when upright is true, 
otherwise
+                    // bad rotation happens in MSO.
+                    if (nShapeRotateAngle == nOldShapeRotation && 
nShapeTextRotateAngle == nOldTextRotation)
+                        nTextPreRotateAngle = 0;
+                    // So we rotated the shape, in this case lose upright and 
do
+                    // as LO normally does.
+                    else
+                        isUpright.reset();
+                }
             }
         }
 
@@ -2906,7 +2937,7 @@ void DrawingML::WriteText( const Reference< XInterface >& 
rXIface, const OUStrin
                                XML_anchor, sVerticalAlignment,
                                XML_anchorCtr, sax_fastparser::UseIf("1", 
bHorizontalCenter),
                                XML_vert, sWritingMode,
-                               XML_upright, isUpright ? "1" : "0",
+                               XML_upright, isUpright,
                                XML_rot, 
sax_fastparser::UseIf(oox::drawingml::calcRotationValue((nTextPreRotateAngle + 
nTextRotateAngle) * 100), (nTextPreRotateAngle + nTextRotateAngle) != 0));
         if (bIsFontworkShape)
         {
diff --git a/sc/qa/unit/data/xlsx/tdf137000_export_upright.xlsx 
b/sc/qa/unit/data/xlsx/tdf137000_export_upright.xlsx
new file mode 100644
index 000000000000..5ac0a75eabb6
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf137000_export_upright.xlsx 
differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx 
b/sc/qa/unit/subsequent_export-test.cxx
index b7ac23366e91..70305f238b85 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -267,6 +267,7 @@ public:
     void testTdf123353();
     void testTdf133688_precedents();
     void testTdf91251_missingOverflowRoundtrip();
+    void testTdf137000_handle_upright();
     void testTdf126305_DataValidatyErrorAlert();
     void testTdf129969();
 
@@ -430,6 +431,7 @@ public:
     CPPUNIT_TEST(testTdf123353);
     CPPUNIT_TEST(testTdf133688_precedents);
     CPPUNIT_TEST(testTdf91251_missingOverflowRoundtrip);
+    CPPUNIT_TEST(testTdf137000_handle_upright);
     CPPUNIT_TEST(testTdf126305_DataValidatyErrorAlert);
     CPPUNIT_TEST(testTdf129969);
 
@@ -5460,6 +5462,25 @@ void ScExportTest::testTdf129969()
     xDocSh->DoClose();
 }
 
+void ScExportTest::testTdf137000_handle_upright()
+{
+    // tdf#106197 When exporting the "upright" attribute, we must set
+    // TextPreRotateAngle to 0.
+    // (Upright is an xml attribute of xdr:txBody/a:bodyPr. It is set when
+    // in a textbox menu we choose: do not rotate this element.)
+    ScDocShellRef xShell = loadDoc("tdf137000_export_upright.", FORMAT_XLSX);
+    CPPUNIT_ASSERT(xShell.is());
+
+    std::shared_ptr<utl::TempFile> pXPathFile
+        = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
+    xmlDocUniquePtr pDrawing
+        = XPathHelper::parseExport(pXPathFile, m_xSFactory, 
"xl/drawings/drawing1.xml");
+    CPPUNIT_ASSERT(pDrawing);
+
+    assertXPathNoAttribute(pDrawing, 
"/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:txBody/a:bodyPr",
+                           "rot");
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to