diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-03-10 08:18:55 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-03-10 09:20:28 +0100 |
commit | cee9b476d51f770fba03cb20b58370762d387e63 (patch) | |
tree | 2161a228a687fd1f323e9e4c037baf9eea393df6 | |
parent | 0dc4cbe342d93ce27b92c5a408adcb009b39b48f (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.fodt | 28 | ||||
-rw-r--r-- | sw/qa/core/text/text.cxx | 30 | ||||
-rw-r--r-- | sw/source/core/text/porlay.cxx | 19 |
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 ); |