sw/qa/extras/odfimport/data/chained-boxes-in-min-height-cells.fodt | 101 ++++++++++ sw/qa/extras/odfimport/odfimport.cxx | 8 sw/source/core/inc/frame.hxx | 13 + sw/source/core/layout/flowfrm.cxx | 1 sw/source/core/layout/frmtool.cxx | 1 sw/source/core/layout/sectfrm.cxx | 2 6 files changed, 123 insertions(+), 3 deletions(-)
New commits: commit 6a98a6fde70438fb189418ba722fc1ec907ec5ff Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Tue Jul 1 19:34:48 2025 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Tue Jul 1 22:04:56 2025 +0200 tdf#167329: Make sure to invalidate inf flags properly Since commit b6bcc7ac278e0db22df02707789730ec123bf934 (tdf#166871: drop mnMaxParaPerPage hack, 2025-06-07), an assertion fails in some cases (see https://gerrit.libreoffice.org/c/core/+/186243/3#message-edb2ace35947927748d0bd37a36d95f2ddf67217 ). The call stack is: #19 __assert_fail in /lib64/libc.so.6 #20 FindFrameInBody(SwAnchoredObject const&) at /home/caolan/LibreOffice/core/sw/source/core/layout/objectformattertxtfrm.cxx:605 #21 SwObjectFormatterTextFrame::CheckMovedFwdCondition(SwAnchoredObject&, SwPageFrame const&, bool, unsigned int&, bool&, bool&) at /home/caolan/LibreOffice/core/sw/source/core/layout/objectformattertxtfrm.cxx:723 (discriminator 1) #22 SwFlyAtContentFrame::MakeAll(OutputDevice*) at /home/caolan/LibreOffice/core/sw/source/core/layout/flycnt.cxx:448 (discriminator 1) #23 SwFrame::PrepareMake(OutputDevice*) at /home/caolan/LibreOffice/core/sw/source/core/layout/calcmove.cxx:397 #24 SwFrame::Calc(OutputDevice*) const at /home/caolan/LibreOffice/core/sw/source/core/layout/trvlfrm.cxx:1858 #25 SwFlyFrame::Calc(OutputDevice*) const at /home/caolan/LibreOffice/core/sw/source/core/layout/fly.cxx:3441 #26 SwObjectFormatter::FormatLayout_(SwLayoutFrame&) at /home/caolan/LibreOffice/core/sw/source/core/layout/objectformatter.cxx:210 The problem is, that some frames don't get their flags invalidated on move, and then use some flag state possibly calculated outside of layout. E.g., creation of table in InsertCnt_ would add cells and insert their content in SwCellFrame ctor; during that, the cell has no upper, and any attempt of a lower to calculate its inf flags would set mbInfBody to false. In SwFlowFrame::PasteTree, pStart may also have inf flags inconsistent with the target position. This change makes SwFrame::InvalidateInfFlags also invalidate these flags in lowers (for layout frames), because obviously, when upper neest to update the flags, so should do lowers. This is similar to what was done in lcl_InvalidateInfFlags, which got simplified. Change-Id: Ic4898791bacef46415985b43f44fddfd533051f2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187240 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/sw/qa/extras/odfimport/data/chained-boxes-in-min-height-cells.fodt b/sw/qa/extras/odfimport/data/chained-boxes-in-min-height-cells.fodt new file mode 100644 index 000000000000..887f1c93345e --- /dev/null +++ b/sw/qa/extras/odfimport/data/chained-boxes-in-min-height-cells.fodt @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document 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:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:settings> + <config:config-item-set config:name="ooo:configuration-settings"> + <config:config-item config:name="MinRowHeightInclBorder" config:type="boolean">true</config:config-item> + </config:config-item-set> + </office:settings> + <office:styles> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <style:style style:name="Frame" style:family="graphic"> + <style:graphic-properties text:anchor-type="paragraph" svg:x="0" svg:y="0" fo:margin-left="2mm" fo:margin-right="2mm" fo:margin-top="2mm" fo:margin-bottom="2mm" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" draw:fill="none" fo:padding="1.5mm" fo:border="0.06pt solid #000000"/> + </style:style> + </office:styles> + <office:automatic-styles> + <style:style style:name="Table1" style:family="table"> + <style:table-properties style:width="277mm" style:rel-width="100%" table:align="left" style:writing-mode="lr-tb"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:table-column-properties style:column-width="138.5mm" style:rel-column-width="6746*"/> + </style:style> + <style:style style:name="Table1.1" style:family="table-row"> + <style:table-row-properties style:min-row-height="116mm" fo:keep-together="auto"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:table-cell-properties style:vertical-align="top" fo:padding="4mm" fo:border="none" style:writing-mode="lr-tb"/> + </style:style> + <style:style style:name="Table1.2" style:family="table-row"> + <style:table-row-properties fo:keep-together="auto"/> + </style:style> + <style:style style:name="Table1.A2" style:family="table-cell"> + <style:table-cell-properties style:vertical-align="top" fo:padding-left="6mm" fo:padding-right="6mm" fo:padding-top="0mm" fo:padding-bottom="0mm" fo:border="none" style:writing-mode="lr-tb"/> + </style:style> + <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Frame"> + <style:graphic-properties fo:margin-left="0" fo:margin-right="0" fo:margin-top="0" fo:margin-bottom="0" style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph" fo:background-color="#ffffff" style:background-transparency="100%" draw:fill="solid" draw:fill-color="#ffffff" fo:padding="0.5mm" fo:border="0.06pt solid #000000" style:flow-with-text="true"/> + </style:style> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="297mm" fo:page-height="210mm" style:print-orientation="landscape" fo:margin-top="30mm" fo:margin-bottom="40mm" fo:margin-left="10mm" fo:margin-right="10mm"/> + </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:p/> + <table:table table:name="Table1" table:style-name="Table1"> + <table:table-column table:style-name="Table1.A"/> + <table:table-column table:style-name="Table1.A"/> + <table:table-row table:style-name="Table1.1"> + <table:table-cell table:style-name="Table1.A1"> + <text:p><draw:frame draw:style-name="fr1" draw:name="Frame1" text:anchor-type="char" svg:width="130mm" svg:height="108mm"> + <draw:text-box draw:chain-next-name="Frame4"> + <text:p/> + </draw:text-box> + </draw:frame></text:p> + </table:table-cell> + <table:table-cell table:style-name="Table1.A1"> + <text:p><draw:frame draw:style-name="fr1" draw:name="Frame2" text:anchor-type="char" svg:width="130mm" svg:height="108mm"> + <draw:text-box draw:chain-next-name="Frame3"> + <text:p/> + </draw:text-box> + </draw:frame></text:p> + </table:table-cell> + </table:table-row> + <table:table-row table:style-name="Table1.2"> + <table:table-cell table:style-name="Table1.A2"> + <text:p/> + </table:table-cell> + <table:table-cell table:style-name="Table1.A2"> + <text:p/> + </table:table-cell> + </table:table-row> + <table:table-row table:style-name="Table1.1"> + <table:table-cell table:style-name="Table1.A1"> + <text:p><draw:frame draw:style-name="fr1" draw:name="Frame3" text:anchor-type="char" svg:width="130mm" svg:height="108mm"> + <draw:text-box> + <text:p/> + </draw:text-box> + </draw:frame></text:p> + </table:table-cell> + <table:table-cell table:style-name="Table1.A1"> + <text:p><draw:frame draw:style-name="fr1" draw:name="Frame4" text:anchor-type="char" svg:width="130mm" svg:height="108mm"> + <draw:text-box draw:chain-next-name="Frame2"> + <text:p/> + </draw:text-box> + </draw:frame></text:p> + </table:table-cell> + </table:table-row> + <table:table-row table:style-name="Table1.2"> + <table:table-cell table:style-name="Table1.A2"> + <text:p/> + </table:table-cell> + <table:table-cell table:style-name="Table1.A2"> + <text:p/> + </table:table-cell> + </table:table-row> + </table:table> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx index 7927d4edb46b..551b6f847d58 100644 --- a/sw/qa/extras/odfimport/odfimport.cxx +++ b/sw/qa/extras/odfimport/odfimport.cxx @@ -1661,6 +1661,14 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf163974) CPPUNIT_ASSERT_EQUAL(size_t(1), footnotes.Count()); } +CPPUNIT_TEST_FIXTURE(Test, testTdf167329) +{ + // This used to fail an assertion during loafing, because some inserted frames didn't + // update their inf flags, and still reported to be not in body. + createSwDoc("chained-boxes-in-min-height-cells.fodt"); + // This must succeed +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 4fb8793c7237..c118480e4cdf 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -626,7 +626,7 @@ public: bool IsRetouche() const { return mbRetouche; } SW_DLLPUBLIC void SetInfFlags(); - void InvalidateInfFlags() { mbInfInvalid = true; } + inline void InvalidateInfFlags(); inline bool IsInDocBody() const; // use InfoFlags, determine flags inline bool IsInFootnote() const; // if necessary inline bool IsInTab() const; @@ -978,6 +978,17 @@ public: bool IsCollapseUpper() const; }; +inline void SwFrame::InvalidateInfFlags() +{ + mbInfInvalid = true; + if (IsLayoutFrame()) + { + // If we are not sure about our flags, neither are lowers + for (SwFrame* p = GetLower(); p; p = p->GetNext()) + p->InvalidateInfFlags(); + } +} + inline bool SwFrame::IsInDocBody() const { if ( mbInfInvalid ) diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index f4c21c2ad4ff..f666d80fce27 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -640,6 +640,7 @@ bool SwFlowFrame::PasteTree( SwFrame *pStart, SwLayoutFrame *pParent, SwFrame *p do { pFloat->mpUpper = pParent; pFloat->InvalidateAll_(); + pFloat->InvalidateInfFlags(); pFloat->CheckDirChange(); // I'm a friend of the TextFrame and thus am allowed to do many things. diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index fae999f2ecc3..9ee8e3e4e014 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1707,6 +1707,7 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc& rDoc, } pFrame = pTableNode->MakeFrame( pLay ); + pFrame->InvalidateInfFlags(); // skip tables deleted with track changes if ( !static_cast<SwTabFrame*>(pFrame)->Lower() ) diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index c37dc152dada..e905c81b6678 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -607,8 +607,6 @@ static void lcl_InvalidateInfFlags( SwFrame* pFrame, bool bInva ) pFrame->InvalidateSize_(); pFrame->InvalidatePrt_(); } - if( pFrame->IsLayoutFrame() ) - lcl_InvalidateInfFlags( static_cast<SwLayoutFrame*>(pFrame)->GetLower(), false ); pFrame = pFrame->GetNext(); } }