sw/qa/extras/layout/data/multiline-field-in-columnar-section.fodt | 38 ++++++++++ sw/qa/extras/layout/layout5.cxx | 30 +++++++ sw/source/core/text/frmform.cxx | 4 - 3 files changed, 71 insertions(+), 1 deletion(-)
New commits: commit 670c5cee9d08c4ac4696e65ab550b97f8d590e29 Author: Mike Kaganski <[email protected]> AuthorDate: Sat Oct 25 21:47:18 2025 +0500 Commit: Adolfo Jayme Barrientos <[email protected]> CommitDate: Mon Oct 27 10:52:53 2025 +0100 tdf#164718: allow splitting multiline fields in SwTextFrame::FormatAdjust Commit 167be9363ea505b334aa595b273707d7d9217863 (tdf#160526, tdf#160549: fix split conditions at page start, 2024-04-11) had changed a condition to split at a line, disallowing it when the position stored in nEnd is equal to the start of the line. It turned out, that the multiline field portions are special; for all following portions, the line start is the position after the field placeholder character, and the length is zero. This change handles such fields into account. To check if this is a multiline field, it calls SwLineLayout::IsRest. The respective SwLineLayout::SetRest is only called in two places in SwTextFormatter::WhichFirstPortion. SwTextFormatInfo::SetRest is also called there, with nullptr as the argument, which explains why SwTextFormatInfo::GetRest didn't help in the pre-existing code in SwTextFrame::FormatAdjust. The split of the field is correct here. There is a different problem, that this split is undone later at some place, if widow/orphan control is not 0; that should be fixed separately. Change-Id: I3141a4ad4c1e8b3f5437d1fa63f0fd04cffcb297 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192978 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> (cherry picked from commit b5533565c5c7250f1940ba80e03297fdbf78b435) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193016 Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/sw/qa/extras/layout/data/multiline-field-in-columnar-section.fodt b/sw/qa/extras/layout/data/multiline-field-in-columnar-section.fodt new file mode 100644 index 000000000000..83b21b9af5fa --- /dev/null +++ b/sw/qa/extras/layout/data/multiline-field-in-columnar-section.fodt @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:ooow="http://openoffice.org/2004/writer" office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:font-face-decls> + <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/> + </office:font-face-decls> + <office:styles> + <style:default-style style:family="paragraph"> + <style:paragraph-properties fo:orphans="2" fo:widows="2"/> + <style:text-properties style:font-name="Liberation Serif" fo:font-size="12pt"/> + </style:default-style> + </office:styles> + <office:automatic-styles> + <style:style style:name="Sect1" style:family="section"> + <style:section-properties text:dont-balance-text-columns="false" style:editable="false"> + <style:columns fo:column-count="2" fo:column-gap="8mm"> + <style:column style:rel-width="32767*" fo:start-indent="0" fo:end-indent="4mm"/> + <style:column style:rel-width="32768*" fo:start-indent="4mm" fo:end-indent="0"/> + </style:columns> + </style:section-properties> + </style:style> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="210mm" fo:page-height="297mm" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm"/> + </style:page-layout> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-layout-name="pm1"/> + </office:master-styles> + <office:body> + <office:text text:use-soft-page-breaks="true"> + <text:p/> + <text:section text:style-name="Sect1" text:name="Section1"> + <text:p><text:conditional-text text:condition="ooow:1" text:string-value-if-true="He heard quiet steps behind him. That didn't bode well. Who could be following him this late at night and in this deadbeat part of town? And at this particular moment, just after he pulled off the big time and was making off with the greenbacks. Was there another crook who'd had the same idea, and was now watching him and waiting for a chance to grab the fruit of his labor? Or did the steps behind him mean that one of many law officers in town was on to him and just waiting to pounce and snap those cuffs on his wrists? He nervously looked all around." text:string-value-if-false="nothing">He heard quiet steps behind him. That didn't bode well. Who could be following him this late at night and in this deadbeat part of town? And at this particular moment, just after he pulled off the big time and was making off with the greenbacks. Was there another crook who'd had the same idea, a nd was now watching him and waiting for a chance to grab the fruit of his labor? Or did the steps behind him mean that one of many law officers in town was on to him and just waiting to pounce and snap those cuffs on his wrists? He nervously looked all around.</text:conditional-text></text:p> + </text:section> + <text:p/> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/sw/qa/extras/layout/layout5.cxx b/sw/qa/extras/layout/layout5.cxx index a1c5d6c3f79e..59f8ff78b28a 100644 --- a/sw/qa/extras/layout/layout5.cxx +++ b/sw/qa/extras/layout/layout5.cxx @@ -2100,6 +2100,36 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter5, testTdf168858) } } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter5, testTdf164718) +{ + // A 13-line field as the lone content of a paragraph in a two-column section: + createSwDoc("multiline-field-in-columnar-section.fodt"); + Scheduler::ProcessEventsToIdle(); + auto pXmlDoc = parseLayoutDump(); + + // The problem was, that layout refused to split the multiline field across the columns, which + // resulted in a layout loop, ending up in a new page creation, where that section had height + // equal to zero (invisible). The interesting part is, that splitting of the field, which is + // reasonable, is later undone currently; but that is a separate issue (related to orphan and + // widow control). + + // Check that there is only one page, it has the leading paragraph, the section, and the + // trailing paragraph: + assertXPath(pXmlDoc, "//page", 1); + assertXPathChildren(pXmlDoc, "//page/body", 4); + assertXPathNodeName(pXmlDoc, "//page/body/*[1]", "infos"); + assertXPathNodeName(pXmlDoc, "//page/body/*[2]", "txt"); + assertXPathNodeName(pXmlDoc, "//page/body/*[3]", "section"); + assertXPathNodeName(pXmlDoc, "//page/body/*[4]", "txt"); + + // Check that the section's height is not zero (which it was before the fix). Currently, in my + // testing it is 3588. This height is likely to change at some point, when the split will not + // be undone, and lines 8-13 of the field will end up in column 2; then it will be around 1932: + auto height = getXPath(pXmlDoc, "//page/body/section/infos/bounds", "height").toInt32(); + CPPUNIT_ASSERT_GREATER(sal_Int32(1500), height); + CPPUNIT_ASSERT_LESS(sal_Int32(4000), height); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx index 17e55bf5ba48..f0f4de91d2a7 100644 --- a/sw/source/core/text/frmform.cxx +++ b/sw/source/core/text/frmform.cxx @@ -1389,7 +1389,9 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine, if (!bLoneAsCharAnchoredObj && (bHasVisibleNumRule || (nStrLen > TextFrameIndex(0) - && (nEnd != rLine.GetStart() || rInf.GetRest()))) + && (nEnd != rLine.GetStart() || rInf.GetRest() + // tdf#164718: Multiline field? + || rLine.GetCurr()->IsRest()))) ) { SplitFrame( nEnd );
