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="&apos;Liberation Serif&apos;" 
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&apos;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&apos;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&apos;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&apos;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 );

Reply via email to