summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-03-10 08:18:55 +0100
committerMiklos Vajna <vmiklos@collabora.com>2022-03-10 09:20:28 +0100
commitcee9b476d51f770fba03cb20b58370762d387e63 (patch)
tree2161a228a687fd1f323e9e4c037baf9eea393df6
parent0dc4cbe342d93ce27b92c5a408adcb009b39b48f (diff)
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. Change-Id: Ib7b338911aa23fee766423897ed131ce4029223c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131297 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--sw/qa/core/text/data/clearing-break-start.fodt28
-rw-r--r--sw/qa/core/text/text.cxx30
-rw-r--r--sw/source/core/text/porlay.cxx19
3 files changed, 76 insertions, 1 deletions
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 39e33e01a580..317139c5ec37 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -290,6 +290,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 dcab6f1db4e9..84c6837d56c1 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 );