sw/qa/core/text/data/clearing-break-start.fodt |   28 +++++++++++++++++++++++
 sw/qa/core/text/text.cxx                       |   30 +++++++++++++++++++++++++
 sw/source/core/text/porlay.cxx                 |   19 +++++++++++++++
 3 files changed, 76 insertions(+), 1 deletion(-)

New commits:
commit 0e496d1f0d3fe884f28ddfe86a1b8462bab2fb56
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Mar 10 08:18:55 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Mar 29 13:34:52 2022 +0200

    sw clearing breaks: fix layout when the line is empty
    
    The break portion's height was not taken into account when the line had
    no text portion ("had no content"). Fix that codepath to also take the
    break portion's height into account, in case that's a clearing break.
    
    (cherry picked from commit cee9b476d51f770fba03cb20b58370762d387e63)
    
    Change-Id: Ib7b338911aa23fee766423897ed131ce4029223c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132258
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/core/text/data/clearing-break-start.fodt 
b/sw/qa/core/text/data/clearing-break-start.fodt
new file mode 100644
index 000000000000..f2df00fadd4f
--- /dev/null
+++ b/sw/qa/core/text/data/clearing-break-start.fodt
@@ -0,0 +1,28 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+  <office:automatic-styles>
+    <style:style style:name="fr1" style:family="graphic">
+      <style:graphic-properties fo:margin-left="0.318cm" 
fo:margin-right="0.318cm" fo:margin-top="0cm" fo:margin-bottom="0cm" 
style:wrap="parallel" style:vertical-pos="from-top" 
style:vertical-rel="paragraph" style:horizontal-pos="from-left" 
style:horizontal-rel="paragraph"/>
+    </style:style>
+  </office:automatic-styles>
+  <office:body>
+    <office:text>
+      <text:p><draw:frame draw:style-name="fr1" draw:name="Picture 1" 
text:anchor-type="char" svg:x="0cm" svg:y="0cm" svg:width="1.806cm" 
svg:height="1.806cm" draw:z-index="0"><draw:image 
draw:mime-type="image/png"><office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAAABGdBTUEAALGPC/xhBQAAAAFz
+       UkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAA
+       AAJiS0dEAACqjSMyAAAACW9GRnMAAAAGAAAAAAAMc1XTAAAACXBIWXMAAA3XAAAN1wFCKJt4
+       AAAACXZwQWcAAABMAAAAQACdMTgbAAABzUlEQVRo3u3ZPU/CQBjA8X+Jxs3ESUDj4iK+LA5+
+       BBfjqBE1cXB2MlFAEqMgxvhNNL4sLsK3UPQL6ObkoAETz+FKW2mxCPRYnucWUu76/OC59C49
+       cGOCKqrD9kHRc6ddPv7oW2WCwMh0nF63Myz7Tm8hPTNu0pgHMER3scepTbgK6enJNND83RLn
+       /878yRaPmgBZFDuMsNLeWB9gmFQHP77MIg9gsYciR50NFKvtjIy10yk84pSZA7DYpwR8scmF
+       QQCMuoQMpzbh0iAARrlnVn90CWHTsZcAiHPPdINQAuqsc2MQAAnKDUKWEhZ10twaBEDSJWQo
+       YlFj7S9CzwEegkXWIbQsRAQASFJhpplwbRAACS+hANRJBxMiAkDcJeQ4sQkBhYgMoJ+Ozlwo
+       2YQ7AJ6CRxyiUGnVy3hVKb0Af9v7hUG2Wy9TEQCUelFTDULB2S+YKYGOMcpM6UIccOQnRA6A
+       cSp6ibfI+wkGADBGpTEd8xz1AaAfTQ7huA8AvUw5hVjuA0D/C5OaMN8XACRZ8F0zCggKAQhA
+       AAIQgAAEIAABCEAAAhCAAAQgAAH4zg3feY4w3Xs44M5+oW0qvCWoGcvaIlM3x/f/ab+O738A
+       hOCNQr34oD4AAAAldEVYdGNyZWF0ZS1kYXRlADIwMTAtMTItMjBUMTc6MDg6MzYrMDE6MDB6
+       5RscAAAAJXRFWHRtb2RpZnktZGF0ZQAyMDEwLTEyLTIwVDE3OjA4OjM3KzAxOjAwgyNmnAAA
+       AABJRU5ErkJggg==
+      </office:binary-data></draw:image></draw:frame>X</text:p>
+    </office:text>
+  </office:body>
+</office:document>
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index f9864cbc722f..9987fac58a3f 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -263,6 +263,36 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testClearingLineBreak)
     assertXPath(pXmlDoc, "//SwParaPortion/SwLineLayout[1]", "height", "1024");
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testClearingLineBreakAtStart)
+{
+    // Given a document with a fly frame and a character wrapped around it:
+    createSwDoc(DATA_DIRECTORY, "clearing-break-start.fodt");
+    // Insert a clearing break before "X":
+    uno::Reference<text::XTextDocument> xDocument(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xDocument->getText();
+    uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+    xCursor->gotoEnd(/*bSelect=*/false);
+    xCursor->goLeft(/*nCount=*/1, /*bSelect=*/false);
+    uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, 
uno::UNO_QUERY);
+    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::ALL);
+    xLineBreakProps->setPropertyValue("Clear", uno::makeAny(eClear));
+    xText->insertTextContent(xCursor, xLineBreak, /*bAbsorb=*/false);
+
+    // When laying out that document:
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+    // Then make sure that the second line "jumps down", below the fly frame:
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1024
+    // - Actual  : 276
+    // i.e. the line height was too small, but only in case the full line was 
a fly and a break
+    // portion, without any real content.
+    assertXPath(pXmlDoc, "//SwParaPortion/SwLineLayout[1]", "height", "1024");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 05619f5591ff..575670c685eb 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -339,6 +339,10 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, 
SwTextFormatInfo &rInf )
     sal_uInt16 nFlyAscent = 0;
     sal_uInt16 nFlyHeight = 0;
     sal_uInt16 nFlyDescent = 0;
+
+    // If this line has a clearing break, then this is the portion's height.
+    sal_uInt16 nBreakHeight = 0;
+
     bool bOnlyPostIts = true;
     SetHanging( false );
 
@@ -455,6 +459,7 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, 
SwTextFormatInfo &rInf )
                 {
                     auto pBreakPortion = static_cast<SwBreakPortion*>(pPos);
                     bClearingBreak = pBreakPortion->GetClear() != 
SwLineBreakClear::NONE;
+                    nBreakHeight = nPosHeight;
                 }
                 if (!(pPos->IsBreakPortion() && !bClearingBreak) || !Height())
                 {
@@ -569,7 +574,19 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, 
SwTextFormatInfo &rInf )
                 if( nFlyDescent > nFlyHeight - nFlyAscent )
                     Height( nFlyHeight + nFlyDescent, false );
                 else
-                    Height( nFlyHeight, false );
+                {
+                    if (nBreakHeight > nFlyHeight)
+                    {
+                        // The line has no content, but it has a clearing 
break: then the line
+                        // height is not only the intersection of the fly and 
line's rectangle, but
+                        // also includes the clearing break's height.
+                        Height(nBreakHeight, false);
+                    }
+                    else
+                    {
+                        Height(nFlyHeight, false);
+                    }
+                }
             }
             else if( nMaxDescent > Height() - mnAscent )
                 Height( nMaxDescent + mnAscent, false );

Reply via email to