oox/qa/unit/data/tdf149538_upright.pptx |binary
 oox/qa/unit/export.cxx                  |   16 ++++++++++++++++
 oox/source/export/drawingml.cxx         |   30 +++++++++++++++++++++---------
 3 files changed, 37 insertions(+), 9 deletions(-)

New commits:
commit 3ade0a5fb1d39360b76c7d62eebee5a18d3f4196
Author:     Regina Henschel <rb.hensc...@t-online.de>
AuthorDate: Fri Jul 22 17:54:02 2022 +0200
Commit:     Regina Henschel <rb.hensc...@t-online.de>
CommitDate: Sat Jul 23 14:33:13 2022 +0200

    tdf#149538 no text area rotation if upright exported
    
    This is a followup to commit 7e23cbdb. With that commit the attribute
    'upright' is correctly emulated by a rotation of the text area
    rectangle. But I forgot to remove this rotation when the 'upright'
    attribute is used on export.
    
    Change-Id: I46d0f421be8ef6b44537134c73dc1e4326ba7e1d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137368
    Tested-by: Jenkins
    Reviewed-by: Regina Henschel <rb.hensc...@t-online.de>

diff --git a/oox/qa/unit/data/tdf149538_upright.pptx 
b/oox/qa/unit/data/tdf149538_upright.pptx
new file mode 100644
index 000000000000..a477b3b1215e
Binary files /dev/null and b/oox/qa/unit/data/tdf149538_upright.pptx differ
diff --git a/oox/qa/unit/export.cxx b/oox/qa/unit/export.cxx
index be4fb81fa0bf..1bc71da5e039 100644
--- a/oox/qa/unit/export.cxx
+++ b/oox/qa/unit/export.cxx
@@ -792,6 +792,22 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf149551VertPadding)
         assertXPathNoAttribute(pXmlDoc, sElement, "rot");
     }
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf149538upright)
+{
+    // The document has a shape with attribute upright="1" in the bodyPr 
element. On import it is
+    // emulatated by rotating the text area rectangle. On export there should 
be an upright="1"
+    // attribute but no 'rot' attribute. Without the fix the 'rot' attribute 
with values from
+    // the emulation was written out.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"tdf149538_upright.pptx";
+    loadAndSave(aURL, "Impress Office Open XML");
+
+    // Verify the markup. The values must be the same as in the original file.
+    std::unique_ptr<SvStream> pStream = parseExportStream(getTempFile(), 
"ppt/slides/slide1.xml");
+    xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get());
+    assertXPath(pXmlDoc, "//p:spTree/p:sp/p:txBody/a:bodyPr", "upright", "1");
+    assertXPathNoAttribute(pXmlDoc, "//p:spTree/p:sp/p:txBody/a:bodyPr", 
"rot");
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 392ce6f4d6aa..e4d0ed7ddc4e 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -3452,7 +3452,6 @@ void DrawingML::WriteText(const Reference<XInterface>& 
rXIface, bool bBodyPr, bo
                         && ( sPresetWarp == "textArchDown" || sPresetWarp == 
"textArchUp"
                             || sPresetWarp == "textButton" || sPresetWarp == 
"textCircle");
 
-
     if (bUpright)
     {
         Degree100 nShapeRotateAngleDeg100(0_deg100);
@@ -3460,24 +3459,37 @@ void DrawingML::WriteText(const Reference<XInterface>& 
rXIface, bool bBodyPr, bo
             nShapeRotateAngleDeg100 = Degree100(mAny.get<sal_Int32>());
         // Depending on shape rotation, the import has made 90deg changes to 
properties
         // "TextPreRotateAngle" and "TextRotateAngle". Revert it.
-        if ((nShapeRotateAngleDeg100 > 4500_deg100 && nShapeRotateAngleDeg100 
<= 13500_deg100)
-            || (nShapeRotateAngleDeg100 > 22500_deg100 && 
nShapeRotateAngleDeg100 <= 31500_deg100))
+        bool bWasAngleChanged
+            = (nShapeRotateAngleDeg100 > 4500_deg100 && 
nShapeRotateAngleDeg100 <= 13500_deg100)
+              || (nShapeRotateAngleDeg100 > 22500_deg100
+                  && nShapeRotateAngleDeg100 <= 31500_deg100);
+        if (bWasAngleChanged)
         {
             nTextRotateAngleDeg100 = nTextRotateAngleDeg100.value_or(0_deg100) 
+ 9000_deg100;
             nTextPreRotateAngle -= 90;
         }
         // If text is no longer upright, user has changed something. Do not 
write 'upright' then.
+        // This try to detect the case assumes, that the text area rotation 
was 0 in the original
+        // MS Office document. That is likely because MS Office has no UI to 
set it and the
+        // predefined SmartArt shapes, which use it, do not use 'upright'.
         Degree100 nAngleSum = nShapeRotateAngleDeg100 + 
nTextRotateAngleDeg100.value_or(0_deg100);
-        if (abs(NormAngle18000(nAngleSum)) >= 100_deg100) // consider 
inaccuracy from rounding
+        if (abs(NormAngle18000(nAngleSum)) < 100_deg100) // consider 
inaccuracy from rounding
+        {
+            nTextRotateAngleDeg100.reset(); // 'upright' does not overrule 
text area rotation.
+        }
+        else
         {
+            // User changes. Keep current angles.
             isUpright.reset();
+            if (bWasAngleChanged)
+            {
+                nTextPreRotateAngle += 90;
+                nTextRotateAngleDeg100 = 
nTextRotateAngleDeg100.value_or(0_deg100) - 9000_deg100;
+            }
         }
     }
 
-    // Evaluate "TextPreRotateAngle". It is used to simulate not yet 
implemented writing modes and it
-    // is used to simulate the 'rot' attribute from diagram <dgm:txXfrm> 
element. When we are here
-    // and export a diagram it is in fact an export of a group of shapes. For 
them a text rotation
-    // inside the text area rectangle is only possible by the "vert" attribute.
+    // Evaluate "TextPreRotateAngle". It is used to simulate not yet 
implemented writing modes.
     if (nTextPreRotateAngle != 0 && !sWritingMode)
     {
         if (nTextPreRotateAngle == -90 || nTextPreRotateAngle == 270)
@@ -3485,7 +3497,7 @@ void DrawingML::WriteText(const Reference<XInterface>& 
rXIface, bool bBodyPr, bo
             sWritingMode = "vert";
             bVertical = true;
             // Our TextPreRotation includes padding, MSO vert does not include 
padding. Therefore set
-            // padding so, that is looks the same in MSO.
+            // padding so, that is looks the same in MSO as in LO.
             sal_Int32 nHelp = nLeft;
             nLeft = nBottom;
             nBottom = nRight;

Reply via email to