diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2022-02-23 16:45:31 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2022-05-17 15:47:04 +0200 |
commit | c2f39e62d13cd90ddac50de5f77bfc6fd33f2799 (patch) | |
tree | d40d91bf7683b92a20833ac8c64b76823fb99614 | |
parent | d1e74897df54f5bdfdbff3a24434cd284ff7d8a0 (diff) |
sw: prevent footnote frame against delete while it's moved
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130439
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit fe5d3fbfe63fe8b433776bd3a0508dd712b868b0)
sw: really prevent footnote frame against delete while it's moved
This reverts commit fe5d3fbfe63fe8b433776bd3a0508dd712b868b0
It turns out that checking a single column's IsMovingFootnotes() is not
enough - as frames can move both forwards and backwards the entire chain
of columns would need to be checked.
(Most callers of MoveLowerFootnotes() move forwards, but one place in
tabfrm.cxx moves from a follow to master.)
But it turns out that this is probably the wrong way in any case: most
likely the intention in FormatAnchorFrameAndItsPrevs() is to format
previous frames in the same layout environment, so if there is a section
or column inside a footnote then this upper should be formatted, while
if the footnote is inside a section or column this upper should not be
formatted; this should make calls during MoveFootnotes_() safe as it
should prevent the formatting of frames in the footnote boss moving a
footnote that is already being moved.
So tweak the fix in commit fa1bcc22921941b2cd8a0b32fe0d15655d12d607
a little to make it more general.
Also it was previously possible that for a section with columns,
both the section branch and the column branch was taken, which seems
supperfluous.
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130544
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
(cherry picked from commit 3f569ffc9238e6bf2915e78bf21c844ca5f1270d)
add a layout test to exercise UXTSOREL
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130493
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
(cherry picked from commit 10d46c0498b89350645cf45e744a528d3d8f1ac1)
use Bitstream Vera Sans for consistent results with LIBREOFFICE-UXTSOREL.rtf
instead of Palatino Linotype which will typically get substituted
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133460
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
(cherry picked from commit ff27c0e35ebfdbe998c372b7a36df8b5577e1fd4)
Change-Id: I39487640322339fe4d511e845d9c6bced2ba9dad
-rw-r--r-- | sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf | bin | 0 -> 109018 bytes | |||
-rw-r--r-- | sw/qa/extras/layout/layout.cxx | 6 | ||||
-rw-r--r-- | sw/source/core/layout/objectformattertxtfrm.cxx | 53 |
3 files changed, 45 insertions, 14 deletions
diff --git a/sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf b/sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf Binary files differnew file mode 100644 index 000000000000..d37de51622ef --- /dev/null +++ b/sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index cd1a2ae80511..ceb96daa2dd5 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -2302,6 +2302,12 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testRedlineTables) assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1]", "Portion", "foar"); } +// FIXME: apparently infinite loop on Mac +#ifndef MACOSX +//just care it doesn't crash/assert +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testUXTSOREL) { createDoc("LIBREOFFICE-UXTSOREL.rtf"); } +#endif + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/objectformattertxtfrm.cxx b/sw/source/core/layout/objectformattertxtfrm.cxx index f4e9905d21c1..0ad6178fac1b 100644 --- a/sw/source/core/layout/objectformattertxtfrm.cxx +++ b/sw/source/core/layout/objectformattertxtfrm.cxx @@ -799,6 +799,7 @@ static void lcl_FormatContentOfLayoutFrame( SwLayoutFrame* pLayFrame, if ( pLowerFrame->IsLayoutFrame() ) { SwFrameDeleteGuard aCrudeHack(pLowerFrame); // ??? any issue setting this for non-footnote frames? + // prevent moving footnotes by formatting if they are already being moved lcl_FormatContentOfLayoutFrame( static_cast<SwLayoutFrame*>(pLowerFrame), pLastLowerFrame ); } @@ -830,21 +831,46 @@ void SwObjectFormatterTextFrame::FormatAnchorFrameAndItsPrevs( SwTextFrame& _rAn // for follow text frames. if ( !_rAnchorTextFrame.IsFollow() ) { + // In case the anchor frame is in a column or section, format its + // previous frames first - but don't jump out of the current layout + // environment, e.g. from footnotes into the footnote boss. + SwFrame * pSectFrame(nullptr); + SwFrame * pColFrameOfAnchor(nullptr); + for (SwFrame* pUpper = _rAnchorTextFrame.GetUpper(); + pUpper != nullptr; pUpper = pUpper->GetUpper()) + { + if (pUpper->IsCellFrame()) + { + break; // apparently nothing to be done? + } + if (pUpper->IsFootnoteFrame()) + { + SAL_INFO_IF(pColFrameOfAnchor == nullptr && pUpper->FindColFrame(), + "sw.layout", "tdf#122894 skipping column for footnote in column"); + break; // stop: prevent crash in case footnotes are being moved + } + if (pUpper->IsSctFrame()) + { + pColFrameOfAnchor = nullptr; + pSectFrame = pUpper; + break; + } + if (pColFrameOfAnchor != nullptr) + { // parent of column not a section frame => column not in section + break; + } + if (pUpper->IsColumnFrame()) + { + pColFrameOfAnchor = pUpper; + } + } + // if anchor frame is directly inside a section, format this section and // its previous frames. // Note: It's a very simple format without formatting objects. - if ( _rAnchorTextFrame.IsInSct() ) + if (pSectFrame) { - SwFrame* pSectFrame = _rAnchorTextFrame.GetUpper(); - while ( pSectFrame ) - { - if ( pSectFrame->IsSctFrame() || pSectFrame->IsCellFrame() ) - { - break; - } - pSectFrame = pSectFrame->GetUpper(); - } - if ( pSectFrame && pSectFrame->IsSctFrame() ) + assert(pSectFrame->IsSctFrame()); { SwFrameDeleteGuard aDeleteGuard(&_rAnchorTextFrame); // #i44049# @@ -872,10 +898,9 @@ void SwObjectFormatterTextFrame::FormatAnchorFrameAndItsPrevs( SwTextFrame& _rAn // #i40140# - if anchor frame is inside a column, // format the content of the previous columns. // Note: It's a very simple format without formatting objects. - SwFrame* pColFrameOfAnchor = _rAnchorTextFrame.FindColFrame(); - SAL_WARN_IF(pColFrameOfAnchor && _rAnchorTextFrame.IsInFootnote(), "sw.layout", "tdf#122894 skipping anchor in column in footnote"); - if (pColFrameOfAnchor && !_rAnchorTextFrame.IsInFootnote()) + if (pColFrameOfAnchor) { + assert(pColFrameOfAnchor->IsColumnFrame()); // #i44049# _rAnchorTextFrame.LockJoin(); SwFrameDeleteGuard aDeleteGuard(&_rAnchorTextFrame); |