diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2022-02-23 16:45:31 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2022-06-20 11:25:44 +0200 |
commit | 75bc2f75852b800c6f86d743a5de9e24f21cf279 (patch) | |
tree | 1888953ecce502da2dd1f8b608121477e2ff0b2d | |
parent | tdf#122894 skipping anchor in column in footnote (diff) | |
download | core-75bc2f75852b800c6f86d743a5de9e24f21cf279.tar.gz core-75bc2f75852b800c6f86d743a5de9e24f21cf279.zip |
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
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133904
Tested-by: Michael Stahl <michael.stahl@allotropia.de>
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
-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 bb0749a4ac5f..1c91fda59bcd 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -3044,6 +3044,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 8f311463f898..57c3c7680da0 100644 --- a/sw/source/core/layout/objectformattertxtfrm.cxx +++ b/sw/source/core/layout/objectformattertxtfrm.cxx @@ -766,6 +766,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 ); } @@ -811,21 +812,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# @@ -855,10 +881,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(); |