sw/qa/extras/layout/data/nested-sections.fodt | 157 ++++++++++++++++++ sw/qa/extras/layout/layout3.cxx | 37 ++++ sw/qa/extras/uiwriter/data/section-table-section.fodt | 139 +++++++++++++++ sw/qa/extras/uiwriter/uiwriter9.cxx | 15 + sw/source/core/inc/sectfrm.hxx | 10 + sw/source/core/layout/calcmove.cxx | 22 +- sw/source/core/layout/sectfrm.cxx | 12 - 7 files changed, 378 insertions(+), 14 deletions(-)
New commits: commit f1c8d38882708134789734010155bed1c7d04e9a Author: Michael Stahl <michael.st...@collabora.com> AuthorDate: Tue Sep 23 16:19:36 2025 +0200 Commit: Michael Stahl <michael.st...@collabora.com> CommitDate: Wed Sep 24 13:55:03 2025 +0200 sw: layout: when positioning SwSectionFrame, ignore dead prev sections The place where it went wrong was in a second layout iteration when after positioning some objects everything was moved down, in SwSectionFrame::SimpleFormat(), where an empty section frame 72 of the 1st outer section was the prev of the 2nd outer section frame 73, and was itself not positioned properly. Apparently this empty section frame is inserted by InsertCnt_() but of course empty section frames can happen in other ways too. (reportedly regression from commit a85bd1bc9305af059d880ee422a656a3d9ce1b0b) Change-Id: I7513a2171fe4f3763f7b73b2e4368032e015c495 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191410 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@collabora.com> (cherry picked from commit 528d5c8e0b9401ba945967e66775aea17aec7d00) diff --git a/sw/qa/extras/layout/data/nested-sections.fodt b/sw/qa/extras/layout/data/nested-sections.fodt new file mode 100644 index 000000000000..cb27f13fd9d8 --- /dev/null +++ b/sw/qa/extras/layout/data/nested-sections.fodt @@ -0,0 +1,157 @@ +<?xml version='1.0' encoding='UTF-8'?> +<office:document 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:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:c alcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext: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:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns: meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" 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"/> + <style:font-face style:name="Lucida Sans1" 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:writing-mode="lr-tb" style:flow-with-text="false"/> + <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" loext:tab-stop-distance="0cm" style:writing-mode="lr-tb" style:font-independent-line-spacing="false"> + <style:tab-stops/> + </style:paragraph-properties> + <style:text-properties style:use-window-font-color="true" loext:opacity="0%" 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 Sans1" 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" fo:hyphenation-keep="auto" loext:hyphenation-keep-type="column" loext:hyphenation-keep-line="false" 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" loext:opacity="0%" 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 Sans1" 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" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/> + </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" loext:num-list-format="%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" loext:num-list-format="%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" loext:num-list-format="%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" loext:num-list-format="%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" loext:num-list-format="%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" loext:num-list-format="%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" loext:num-list-format="%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" loext:num-list-format="%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" loext:num-list-format="%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" loext:num-list-format="%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="Sect1" style:family="section"> + <style:section-properties fo:background-color="#81d41a" style:editable="false"> + <style:columns fo:column-count="1" fo:column-gap="0cm"/> + <style:background-image/> + </style:section-properties> + </style:style> + <style:style style:name="Sect2" style:family="section"> + <style:section-properties fo:background-color="#00a933" style:editable="false"> + <style:columns fo:column-count="1" fo:column-gap="0cm"/> + <style:background-image/> + </style:section-properties> + </style:style> + <style:style style:name="Sect3" style:family="section"> + <style:section-properties fo:background-color="#77caee" style:editable="false"> + <style:columns fo:column-count="1" fo:column-gap="0cm"/> + <style:background-image/> + </style:section-properties> + </style:style> + <style:style style:name="gr1" style:family="graphic"> + <style:graphic-properties draw:textarea-horizontal-align="justify" draw:textarea-vertical-align="middle" draw:auto-grow-height="false" fo:min-height="2.499cm" fo:min-width="3.099cm" loext:decorative="false" style:run-through="foreground" style:wrap="none" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" draw:wrap-influence-on-position="once-concurrent" loext:allow-overlap="true" style:flow-with-text="false"/> + </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" loext:margin-gutter="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> + <style:style style:name="dp1" style:family="drawing-page"> + <style:drawing-page-properties draw:background-size="full"/> + </style:style> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-layout-name="pm1" draw:style-name="dp1"/> + </office:master-styles> + <office:body> + <office:text text:use-soft-page-breaks="true"> + <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:section text:style-name="Sect1" text:name="Section1"> + <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"><draw:custom-shape text:anchor-type="paragraph" draw:z-index="0" draw:name="Shape 1" draw:style-name="gr1" svg:width="3.1cm" svg:height="2.5cm" svg:x="2.559cm" svg:y="0.09cm"> + <text:p/> + <draw:enhanced-geometry svg:viewBox="0 0 21600 21600" draw:type="rectangle" draw:enhanced-path="M 0 0 L 21600 0 21600 21600 0 21600 0 0 Z N"/> + </draw:custom-shape>Outer 1</text:p> + <text:section text:style-name="Sect2" text:name="Section2"> + <text:p text:style-name="Standard">Inner 1</text:p> + <text:p text:style-name="Standard">more</text:p> + </text:section> + </text:section> + <text:section text:style-name="Sect3" text:name="Section4"> + <text:p text:style-name="Standard">Outer 2</text:p> + <text:p text:style-name="Standard"><text:soft-page-break/>more2</text:p> + </text:section> + <text:p text:style-name="Standard"/> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx index f3d233fc722a..080ee9c0d004 100644 --- a/sw/qa/extras/layout/layout3.cxx +++ b/sw/qa/extras/layout/layout3.cxx @@ -139,6 +139,43 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf120287) assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 1); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testNestedSectionOverlap) +{ + createSwDoc("nested-sections.fodt"); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + + SwTwips nOuterSection1Bottom + = getXPath(pXmlDoc, "/root/page[1]/body/section[1]/infos/bounds", "bottom").toInt32(); + SwTwips nInnerSection1Top + = getXPath(pXmlDoc, "/root/page[1]/body/section[2]/infos/bounds", "top").toInt32(); + SwTwips nInnerSection1Bottom + = getXPath(pXmlDoc, "/root/page[1]/body/section[2]/infos/bounds", "bottom").toInt32(); + SwTwips nOuterSection2Top + = getXPath(pXmlDoc, "/root/page[1]/body/section[3]/infos/bounds", "top").toInt32(); + + SwTwips nOuterSection1TextBottom + = getXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt[13]/infos/bounds", "bottom") + .toInt32(); + CPPUNIT_ASSERT_EQUAL(nOuterSection1Bottom, nOuterSection1TextBottom); + + SwTwips nInnerSection1TextTop + = getXPath(pXmlDoc, "/root/page[1]/body/section[2]/txt[1]/infos/bounds", "top").toInt32(); + CPPUNIT_ASSERT_EQUAL(nInnerSection1Top, nInnerSection1TextTop); + SwTwips nInnerSection1TextBottom + = getXPath(pXmlDoc, "/root/page[1]/body/section[2]/txt[2]/infos/bounds", "bottom") + .toInt32(); + CPPUNIT_ASSERT_EQUAL(nInnerSection1Bottom, nInnerSection1TextBottom); + + SwTwips nOuterSection2TextTop + = getXPath(pXmlDoc, "/root/page[1]/body/section[3]/txt[1]/infos/bounds", "top").toInt32(); + CPPUNIT_ASSERT_EQUAL(nOuterSection2Top, nOuterSection2TextTop); + + // the problem was that the outer section 2 was positioned above inner 1 + CPPUNIT_ASSERT_EQUAL(nOuterSection1Bottom + 1, nInnerSection1Top); + CPPUNIT_ASSERT_EQUAL(nInnerSection1Bottom + 1, nOuterSection2Top); +} + static auto getXPathIntAttributeValue(xmlXPathContextPtr pXmlXpathCtx, char const* const pXPath) -> sal_Int32 { diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx index 3debf367f05a..3c5ddb5aee88 100644 --- a/sw/source/core/inc/sectfrm.hxx +++ b/sw/source/core/inc/sectfrm.hxx @@ -186,6 +186,16 @@ inline const SwContentFrame *SwSectionFrame::FindLastContent() const return const_cast<SwSectionFrame*>(this)->FindLastContent(); } +namespace sw { + +/** GetPrev() but ignore dead empty SectionFrames + @param bSectPrev if true, and pFrame is first child of section frame, + get section frame's prev + */ +SwFrame* PrevSkipDead(SwFrame* pFrame, bool bSectPrv); + +} // namespace sw + #endif // INCLUDED_SW_SOURCE_CORE_INC_SECTFRM_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index b4a465ad5e7d..7b7daf9f20e2 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -521,8 +521,10 @@ void SwFrame::PrepareCursor() Calc(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr); } +namespace sw { + // Here we return GetPrev(); however we will ignore empty SectionFrames -static SwFrame* lcl_Prev( SwFrame* pFrame, bool bSectPrv = true ) +SwFrame* PrevSkipDead(SwFrame *const pFrame, bool const bSectPrv) { SwFrame* pRet = pFrame->GetPrev(); if( !pRet && pFrame->GetUpper() && pFrame->GetUpper()->IsSctFrame() && @@ -534,12 +536,14 @@ static SwFrame* lcl_Prev( SwFrame* pFrame, bool bSectPrv = true ) return pRet; } +} // namespace sw + static SwFrame* lcl_NotHiddenPrev( SwFrame* pFrame ) { SwFrame *pRet = pFrame; do { - pRet = lcl_Prev( pRet ); + pRet = ::sw::PrevSkipDead(pRet, true); } while ( pRet && pRet->IsHiddenNow() ); return pRet; } @@ -551,7 +555,7 @@ void SwFrame::MakePos() setFrameAreaPositionValid(true); bool bUseUpper = false; - SwFrame* pPrv = lcl_Prev( this ); + SwFrame* pPrv = ::sw::PrevSkipDead(this, true); if ( pPrv && ( !pPrv->IsContentFrame() || ( static_cast<SwContentFrame*>(pPrv)->GetFollow() != this ) ) @@ -574,7 +578,7 @@ void SwFrame::MakePos() } } - pPrv = lcl_Prev( this, false ); + pPrv = ::sw::PrevSkipDead(this, false); const SwFrameType nMyType = GetType(); SwRectFnSet aRectFnSet((IsCellFrame() && GetUpper() ? GetUpper() : this)); if ( !bUseUpper && pPrv ) @@ -637,7 +641,7 @@ void SwFrame::MakePos() { GetUpper()->Calc(getRootFrame()->GetCurrShell()->GetOut()); } - pPrv = lcl_Prev( this, false ); + pPrv = ::sw::PrevSkipDead(this, false); if ( !bUseUpper && pPrv ) { SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); @@ -1386,7 +1390,7 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) // Also move a paragraph forward, which is the first one inside a table cell. if ( bMoveFwdByObjPos && FindPageFrame()->GetPhyPageNum() < nToPageNum && - ( lcl_Prev( this ) || + ( ::sw::PrevSkipDead(this, true) || GetUpper()->IsCellFrame() || ( GetUpper()->IsSctFrame() && GetUpper()->GetUpper()->IsCellFrame() ) ) && @@ -1399,14 +1403,14 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) // If a Follow sits next to its Master and doesn't fit, we know it can // be moved right now. - if ( lcl_Prev( this ) && static_cast<SwTextFrame*>(this)->IsFollow() && IsMoveable() ) + if (::sw::PrevSkipDead(this, true) && static_cast<SwTextFrame*>(this)->IsFollow() && IsMoveable()) { bMovedFwd = true; // If follow frame is in table, its master will be the last in the // current table cell. Thus, invalidate the printing area of the master. if ( IsInTab() ) { - lcl_Prev( this )->InvalidatePrt(); + ::sw::PrevSkipDead(this, true)->InvalidatePrt(); } MoveFwd( bMakePage, false ); } @@ -1618,7 +1622,7 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) auto const pTemp(GetIndPrev()); auto const bTemp(pTemp && pTemp->isFrameAreaSizeValid() && pTemp->isFramePrintAreaValid()); - if ( !lcl_Prev( this ) && + if ( !::sw::PrevSkipDead(this, true) && !bMovedFwd && ( bMoveable || ( bFly && !bTab ) ) && ( !bFootnote || !GetUpper()->FindFootnoteFrame()->GetPrev() ) diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index 590564615419..fd5c74d1c3ec 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -417,7 +417,7 @@ void SwSectionFrame::Paste( SwFrame* pParent, SwFrame* pSibling ) if (bInserted) { pSect->Init(); - aRectFnSet.MakePos( *pSect, pSect->GetUpper(), pSect->GetPrev(), true); + aRectFnSet.MakePos(*pSect, pSect->GetUpper(), ::sw::PrevSkipDead(pSect, false), true); } if( !static_cast<SwLayoutFrame*>(pParent)->Lower() ) { @@ -560,6 +560,7 @@ SwSectionFrame* SwSectionFrame::SplitSect( SwFrame* pFrameStartAfter, SwFrame* p pNew->InsertBehind( pFramePutAfter->GetUpper(), pFramePutAfter ); pNew->Init(); SwRectFnSet aRectFnSet(this); + assert(!pFramePutAfter->IsSctFrame() || static_cast<SwSectionFrame*>(pFramePutAfter)->GetSection()); // it's not dead aRectFnSet.MakePos( *pNew, nullptr, pFramePutAfter, true ); // OD 25.03.2003 #108339# - restore content: // determine layout frame for restoring content after the initialization @@ -815,7 +816,7 @@ void SwSectionFrame::MakeAll(vcl::RenderContext* pRenderContext) if( GetUpper() ) { SwRectFnSet aRectFnSet(GetUpper()); - aRectFnSet.MakePos( *this, GetUpper(), GetPrev(), false ); + aRectFnSet.MakePos(*this, GetUpper(), ::sw::PrevSkipDead(this, false), false); } if (getFrameArea().Height() == 0) @@ -1252,11 +1253,12 @@ void SwSectionFrame::SimpleFormat() return; LockJoin(); SwRectFnSet aRectFnSet(this); - if( GetPrev() || GetUpper() ) + SwFrame *const pPrev{::sw::PrevSkipDead(this, false)}; + if (pPrev || GetUpper()) { // assure notifications on position changes. const SwLayNotify aNotify( this ); - aRectFnSet.MakePos( *this, GetUpper(), GetPrev(), false ); + aRectFnSet.MakePos(*this, GetUpper(), pPrev, false); setFrameAreaPositionValid(true); } SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*GetUpper()); @@ -2188,7 +2190,7 @@ SwLayoutFrame *SwFrame::GetPrevSctLeaf() pNew->InsertBefore( pLayLeaf, nullptr ); pNew->Init(); SwRectFnSet aRectFnSet(pNew); - aRectFnSet.MakePos( *pNew, pLayLeaf, pNew->GetPrev(), true ); + aRectFnSet.MakePos(*pNew, pLayLeaf, ::sw::PrevSkipDead(pNew, false), true); pLayLeaf = FirstLeaf( pNew ); if( !pNew->Lower() ) // Format single column sections commit dda92446b245eae9a35e50f86da3909183a54704 Author: Michael Stahl <michael.st...@collabora.com> AuthorDate: Thu Sep 18 16:34:45 2025 +0200 Commit: Michael Stahl <michael.st...@collabora.com> CommitDate: Thu Sep 18 18:39:45 2025 +0200 sw: add test for bug fixed in 7a036a64581a96a05e4833611801ac304d75524f Change-Id: I8a665383a2e71678e7ec1b267f8775736d09b2f9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191139 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@collabora.com> (cherry picked from commit c850dd1c3636f1ad8dd5ac3d3b238c9b49acf23d) diff --git a/sw/qa/extras/uiwriter/data/section-table-section.fodt b/sw/qa/extras/uiwriter/data/section-table-section.fodt new file mode 100644 index 000000000000..81f5cf1e0ed8 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/section-table-section.fodt @@ -0,0 +1,139 @@ +<?xml version='1.0' encoding='UTF-8'?> +<office:document 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:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:c alcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext: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:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns: meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:meta><meta:initial-creator>gcc</meta:initial-creator><meta:creation-date>2025-09-18T15:59:15.280114841</meta:creation-date><dc:date>2025-09-18T16:00:17.409875094</dc:date><dc:creator>gcc</dc:creator><meta:editing-duration>PT1M3S</meta:editing-duration><meta:editing-cycles>1</meta:editing-cycles><meta:document-statistic meta:table-count="1" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="0" meta:word-count="0" meta:character-count="0" meta:non-whitespace-character-count="0"/><meta:generator>LibreOfficeDev/26.2.0.0.alpha0$Linux_X86_64 LibreOffice_project/7954f6cb07c7219cff788ad9e6c4809ceef8f690</meta:generator></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 Sans1" 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" loext:tab-stop-distance="0cm" style:writing-mode="lr-tb" style:font-independent-line-spacing="false"> + <style:tab-stops/> + </style:paragraph-properties> + <style:text-properties style:use-window-font-color="true" loext:opacity="0%" 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 Sans1" 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" fo:hyphenation-keep="auto" loext:hyphenation-keep-type="column" loext:hyphenation-keep-line="false" 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" loext:opacity="0%" 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 Sans1" 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" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/> + </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"/> + <style:style style:name="Table_20_Contents" style:display-name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:paragraph-properties fo:orphans="0" fo:widows="0" text:number-lines="false" text:line-number="0"/> + </style:style> + <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="17cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:table-column-properties style:column-width="17cm" 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.5pt solid #000000"/> + </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="21.001cm" fo:page-height="29.7cm" 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:footnote-max-height="0cm" loext:margin-gutter="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: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: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:section text:style-name="Sect1" text:name="Section2"> + <text:p text:style-name="Table_20_Contents"/> + </text:section> + <text:p text:style-name="Table_20_Contents"/> + </table:table-cell> + </table:table-row> + </table:table> + <text:p text:style-name="Standard"/> + </text:section> + <text:p text:style-name="Standard"/> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx b/sw/qa/extras/uiwriter/uiwriter9.cxx index 4dca09e83e48..3b53a1a3ae1a 100644 --- a/sw/qa/extras/uiwriter/uiwriter9.cxx +++ b/sw/qa/extras/uiwriter/uiwriter9.cxx @@ -180,6 +180,21 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testSetStringDeletesShape) CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM)); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testPDFExportCrash) +{ + createSwDoc("section-table-section.fodt"); + + uno::Sequence<beans::PropertyValue> aFilterData( + comphelper::InitPropertySequence({ { "PDFUACompliance", uno::Any(true) } })); + uno::Sequence<beans::PropertyValue> aDescriptor( + comphelper::InitPropertySequence({ { "FilterName", uno::Any(u"writer_pdf_Export"_ustr) }, + { "FilterData", uno::Any(aFilterData) }, + { "URL", uno::Any(maTempFile.GetURL()) } })); + + // Without the fix in place, this test would have crashed here + dispatchCommand(mxComponent, u".uno:ExportToPDF"_ustr, aDescriptor); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159049) { // The document contains a shape which has a text with a line break. When copying the text to