diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2022-02-23 16:45:31 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2022-05-09 09:50:39 +0200 |
commit | c35737020bf1d83723ac06334a2decb6b7850240 (patch) | |
tree | de468bdf392f0a55cab3eed45329ce5e29f80628 | |
parent | 87ada07d405bd6813d7ad03e66b66bc259988f61 (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 45c22406abd5..b34bd0c99d76 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -2946,6 +2946,12 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint72) { createDoc("forcepoint72 //just care it doesn't crash/assert CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint75) { createDoc("forcepoint75-1.rtf"); } +// 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 + //just care it doesn't crash/assert CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepointFootnoteFrame) { diff --git a/sw/source/core/layout/objectformattertxtfrm.cxx b/sw/source/core/layout/objectformattertxtfrm.cxx index b6057d2f4e9e..3848fd81969a 100644 --- a/sw/source/core/layout/objectformattertxtfrm.cxx +++ b/sw/source/core/layout/objectformattertxtfrm.cxx @@ -641,6 +641,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 ); } @@ -686,21 +687,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# @@ -728,10 +754,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(); SwFrame* pColFrame = pColFrameOfAnchor->GetUpper()->GetLower(); |