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 );