sw/qa/extras/layout/data/table-in-section-truncated.fodt | 161 +++++++++++++++ sw/qa/extras/layout/layout.cxx | 38 +++ sw/source/core/layout/tabfrm.cxx | 13 + 3 files changed, 210 insertions(+), 2 deletions(-)
New commits: commit 154b58cfd76a8ad670d4aa25874eed66e3398a3e Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Thu Feb 27 19:44:26 2025 +0100 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Fri Feb 28 10:58:27 2025 +0100 sw: layout: fix truncation of table in section There is a table in a section, split across 2 pages; now insert a page break that moves the section to page 2. In SwTabFrame::MakeAll(), on page 2, first the follow is joined, which grows the table frame but shrinks the section frame (removing the follow's height), then the table's upper is grown to LONG_MAX but with bTst=true so it doesn't actually change or invalidate the section frame, then in lcl_RecalcRow() almost no growth happens because the table frame already has accounted for the height of most of the table content. The section frame remains too small for the table, and the content is truncated... this problem can already be reproduced in OOo 3.3. When GetUpper()->Grow() returns some space, invalidate the upper if it's a section frame, then the next round will format the section. (Simply calling Grow() with bTst=false results in an opposite problem, where the section is too large.) Change-Id: I3cb3a5a38fbd7996fa9fcea9a6036f4260451a95 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182331 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/qa/extras/layout/data/table-in-section-truncated.fodt b/sw/qa/extras/layout/data/table-in-section-truncated.fodt new file mode 100644 index 000000000000..238dcd18b1fb --- /dev/null +++ b/sw/qa/extras/layout/data/table-in-section-truncated.fodt @@ -0,0 +1,161 @@ +<?xml version='1.0' encoding='UTF-8'?> +<office:document xmlns:officeooo="http://openoffice.org/2009/office" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:dc="http://purl.org/dc/eleme nts/1.1/" xmlns:ooo="http://openoffice.org/2004/office" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0 " xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:meta><meta:creation-date>2025-02-27T18:20:34.001095028</meta:creation-date><dc:date>2025-02-27T18:27:39.896741375</dc:date><meta:editing-duration>PT6M11S</meta:editing-duration><meta:editing-cycles>4</meta:editing-cycles><meta:generator>CIB_OfficeDev/6.4.0.24$Linux_X86_64 LibreOffice_project/f75130dcf240f3fe0d11d4374e1ad4e36d92e416</meta:generator><meta:document-statistic meta:table-count="1" meta:image-count="0" meta:object-count="0" meta:page-count="2" meta:paragraph-count="4" meta:word-count="10" meta:character-count="53" meta:non-whitespace-character-count="47"/></office:meta> + <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"/> + <style:font-face style:name="Lucida Sans" svg:font-family="'Lucida Sans'" style:font-family-generic="system" style:font-pitch="variable"/> + <style:font-face style:name="Noto Serif CJK SC" svg:font-family="'Noto Serif CJK SC'" style:font-family-generic="system" style:font-pitch="variable"/> + </office:font-face-decls> + <office:styles> + <style:default-style style:family="graphic"> + <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/> + <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:font-independent-line-spacing="false"> + <style:tab-stops/> + </style:paragraph-properties> + <style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lucida Sans" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/> + </style:default-style> + <style:default-style style:family="paragraph"> + <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/> + <style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lucida Sans" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false"/> + </style:default-style> + <style:default-style style:family="table"> + <style:table-properties table:border-model="collapsing"/> + </style:default-style> + <style:default-style style:family="table-row"> + <style:table-row-properties fo:keep-together="auto"/> + </style:default-style> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <text:outline-style style:name="Outline"> + <text:outline-level-style text:level="1" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="2" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="3" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="4" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="5" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="6" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="7" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="8" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="9" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="10" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + </text:outline-style> + <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/> + <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/> + <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/> + </office:styles> + <office:automatic-styles> + <style:style style:name="Table1" style:family="table"> + <style:table-properties style:width="6.5cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:table-column-properties style:column-width="6.5cm" style:rel-column-width="65535*"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:table-cell-properties fo:padding="0.097cm" fo:border="0.05pt solid #000000"/> + </style:style> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:text-properties/> + </style:style> + <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Standard"> + <style:text-properties/> + </style:style> + <style:style style:name="Sect1" style:family="section"> + <style:section-properties style:editable="false"> + <style:columns fo:column-count="1" fo:column-gap="0cm"/> + </style:section-properties> + </style:style> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="10.5cm" fo:page-height="14.801cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0cm"> + <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:page-layout-properties> + <style:header-style/> + <style:footer-style/> + </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"> + <office:forms form:automatic-focus="false" form:apply-design-mode="false"/> + <text:sequence-decls> + <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/> + <text:sequence-decl text:display-outline-level="0" text:name="Table"/> + <text:sequence-decl text:display-outline-level="0" text:name="Text"/> + <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/> + <text:sequence-decl text:display-outline-level="0" text:name="Figure"/> + </text:sequence-decls> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="Standard"/> + <text:p text:style-name="P3">before section</text:p> + <text:section text:style-name="Sect1" text:name="Section1"> + <table:table table:name="Table1" table:style-name="Table1"> + <table:table-column table:style-name="Table1.A"/> + <table:table-row> + <table:table-cell table:style-name="Table1.A1" office:value-type="string"> + <text:p text:style-name="P1">in table in section</text:p> + <text:p text:style-name="P1"><text:soft-page-break/></text:p> + <text:p text:style-name="P1">end table</text:p> + </table:table-cell> + </table:table-row> + </table:table> + <text:p text:style-name="P1">end section</text:p> + </text:section> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 838ab2b5b760..17055fa287ed 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -322,6 +322,44 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTableSplitBug) } } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTableInSectionTruncated) +{ + createSwDoc("table-in-section-truncated.fodt"); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/txt", 20); + assertXPath(pXmlDoc, "/root/page[1]/body/section/txt", 0); + assertXPath(pXmlDoc, "/root/page[1]/body/section/tab/row/cell/txt", 1); + assertXPath(pXmlDoc, "/root/page[2]/body/section/tab/row/cell/txt", 2); + assertXPath(pXmlDoc, "/root/page[2]/body/section/txt", 1); + assertXPath(pXmlDoc, "/root/page[2]/body/txt", 0); + + assertXPath(pXmlDoc, "/root/page[2]/body/section/infos/bounds", "bottom", u"11032"); + } + + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + pWrtShell->Down(false, 19); + dispatchCommand(mxComponent, u".uno:InsertPagebreak"_ustr, {}); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/txt", 20); + assertXPath(pXmlDoc, "/root/page[1]/body/section/txt", 0); + assertXPath(pXmlDoc, "/root/page[1]/body/section/tab/row/cell/txt", 0); + assertXPath(pXmlDoc, "/root/page[2]/body/txt", 1); + assertXPath(pXmlDoc, "/root/page[2]/body/section/tab/row/cell/txt", 3); + assertXPath(pXmlDoc, "/root/page[2]/body/section/txt", 1); + + assertXPath(pXmlDoc, "/root/page[2]/body/section/infos/bounds", "top", u"10369"); + assertXPath(pXmlDoc, "/root/page[2]/body/section/tab/infos/bounds", "top", u"10369"); + assertXPath(pXmlDoc, "/root/page[2]/body/section/tab/infos/bounds", "height", u"940"); + assertXPath(pXmlDoc, "/root/page[2]/body/section/txt/infos/bounds", "bottom", u"11584"); + // problem was that the section bottom did not grow enough (only 11309) + assertXPath(pXmlDoc, "/root/page[2]/body/section/infos/bounds", "bottom", u"11584"); + } +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTableInSectionSplitLoop) { createSwDoc("table-in-section-split-loop.fodt"); diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index f69b94df8a09..f45d7c9b1986 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -2968,8 +2968,17 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) } } if( IsInSct() || GetUpper()->IsInTab() || bFlySplit ) - nDeadLine = aRectFnSet.YInc( nDeadLine, - GetUpper()->Grow( LONG_MAX, true ) ); + { + auto const nGrow{GetUpper()->Grow(LONG_MAX, true)}; + if (nGrow != 0) + { + if (GetUpper()->IsSctFrame()) // what about table cell? + { + GetUpper()->InvalidateSize_(); + } + nDeadLine = aRectFnSet.YInc(nDeadLine, nGrow); + } + } { SwFrameDeleteGuard g(Lower()); // tdf#134965 prevent RemoveFollowFlowLine()