sw/qa/core/text/text.cxx       |   42 +++++++++++++++++++++++++++++++++++++++++
 sw/source/core/text/porrst.cxx |    8 ++++++-
 2 files changed, 49 insertions(+), 1 deletion(-)

New commits:
commit acfd903a583a384341c0f620a8b7a781b44586be
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Jul 27 16:35:13 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Aug 16 10:56:39 2022 +0200

    tdf#148291 sw clearing breaks: fix RTL layout
    
    The bugreport has two documents that show clear=left and clear=right is
    basically ignored in Word in the RTL paragraph case, while clear=none
    and clear=all work as expected.
    
    There was no special-casing for RTL in SwBreakPortion::Format()
    previously, as the OOXML spec does talk about left/right even in case of
    RTL, i.e. no expected mirroring is documented as the behavior. Looking
    at [MS-OI29500], "2.1.528 Part 1 Section 17.18.3, ST_BrClear" does say
    that the Word "behaves unpredictably" in the normal (non-web) layout.
    
    Fix the problem by handling clear=left and clear=right as clear=none in
    the RTL case, this fixes the rendering differences for both
    bugdocuments.
    
    If later we do want the mirrored layout, then such mirroring could be
    done in SwTextFly::GetMaxBottom().
    
    (cherry picked from commit 4e329f50e42c91704b84b1fc583d6815ab22adab)
    
    Change-Id: I6265e64540fa9e5b893cfbea146152854416dce2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138338
    Tested-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index 68a8230a7bfc..17234c9ec2c0 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -12,6 +12,7 @@
 #include <memory>
 
 #include <com/sun/star/text/BibliographyDataType.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
 
 #include <vcl/gdimtf.hxx>
 #include <vcl/filter/PDFiumLibrary.hxx>
@@ -349,6 +350,47 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, 
testClearingLineBreakLeft)
     assertXPath(pXmlDoc, "//SwParaPortion/SwLineLayout[1]", "height", "2837");
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testClearingLineBreakLeftRTL)
+{
+    // Given a document with an anchored object in an RTL para and a clearing 
break (type=left):
+    loadURL("private:factory/swriter", nullptr);
+    uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<text::XTextDocument> xDocument(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xDocument->getText();
+    uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+    uno::Reference<beans::XPropertySet> xCursorProps(xCursor, uno::UNO_QUERY);
+    xCursorProps->setPropertyValue("WritingMode", 
uno::Any(text::WritingMode2::RL_TB));
+    {
+        uno::Reference<drawing::XShape> xShape(
+            xFactory->createInstance("com.sun.star.drawing.RectangleShape"), 
uno::UNO_QUERY);
+        xShape->setSize(awt::Size(5000, 5000));
+        uno::Reference<beans::XPropertySet> xShapeProps(xShape, 
uno::UNO_QUERY);
+        xShapeProps->setPropertyValue("AnchorType",
+                                      
uno::Any(text::TextContentAnchorType_AT_CHARACTER));
+        uno::Reference<text::XTextContent> xShapeContent(xShape, 
uno::UNO_QUERY);
+        xText->insertTextContent(xCursor, xShapeContent, /*bAbsorb=*/false);
+    }
+    uno::Reference<text::XTextContent> xLineBreak(
+        xFactory->createInstance("com.sun.star.text.LineBreak"), 
uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xLineBreakProps(xLineBreak, 
uno::UNO_QUERY);
+    auto eClear = static_cast<sal_Int16>(SwLineBreakClear::RIGHT);
+    xLineBreakProps->setPropertyValue("Clear", uno::Any(eClear));
+    xText->insertString(xCursor, "foo", /*bAbsorb=*/false);
+    xText->insertTextContent(xCursor, xLineBreak, /*bAbsorb=*/false);
+    xText->insertString(xCursor, "bar", /*bAbsorb=*/false);
+
+    // When laying out that document:
+    calcLayout();
+
+    // Then make sure the "bar" does not jump down (due to type=left && RTL):
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 276
+    // - Actual  : 2837
+    // i.e. left/right was not ignored in the RTL case.
+    assertXPath(pXmlDoc, "//SwParaPortion/SwLineLayout[1]", "height", "276");
+}
+
 CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testClearingLineBreakHeader)
 {
     // Given a document with a shape in the header and a clearing break in the 
body text:
diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx
index f2d2b0cdd168..961c399ca5c1 100644
--- a/sw/source/core/text/porrst.cxx
+++ b/sw/source/core/text/porrst.cxx
@@ -177,7 +177,13 @@ bool SwBreakPortion::Format( SwTextFormatInfo &rInf )
 
     // See if this is a clearing break. If so, calculate how much we need to 
"jump down" so the next
     // line can again use the full text width.
-    if (m_eClear != SwLineBreakClear::NONE)
+    SwLineBreakClear eClear = m_eClear;
+    if (rInf.GetTextFrame()->IsRightToLeft() && eClear != 
SwLineBreakClear::ALL)
+    {
+        // RTL ignores left/right breaks.
+        eClear = SwLineBreakClear::NONE;
+    }
+    if (eClear != SwLineBreakClear::NONE)
     {
         SwTextFly& rTextFly = rInf.GetTextFly();
         if (rTextFly.IsOn())

Reply via email to