sw/qa/extras/layout/data/i94666.odt |binary sw/qa/extras/layout/layout.cxx | 46 ++++++++++++++++++++++++++++++++++++ sw/source/core/layout/wsfrm.cxx | 5 +++ sw/source/uibase/inc/wrtsh.hxx | 2 - 4 files changed, 51 insertions(+), 2 deletions(-)
New commits: commit a984eea00bf3102294e9e860b9d8b9e5ccc34292 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Thu Sep 19 12:37:35 2024 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri Oct 4 09:33:26 2024 +0200 i#94666 sw: layout: fix problem with WIDOW_MAGIC in sections This was already fixed in CWS sw301bf03 with commit 5559afee02fc2be18cded35a17a03aa8191b08f5 but then broken again, perhaps by commit f2e3655255db4032738849cd4b77ce67a6e2c984 "Avoid -fsanitize=signed-integer-overflow", which changed a magic constant, effectively disabling the fix. The problem (in a different document than attached at the bug) is that the first text frame 128 in a section frame 258 gets its height set to WIDOW_MAGIC in CalcPreps(), which grows the section frame to the maximum allowed by its upper, and then when the real size of the text frame is set it shrinks the section frame to be far too small, so the last text frames and the whole table remain formatted at a position on the page but are not painted because the paint is cut off at the (wrong) bottom of the section frame. (On master, the problem with the internal document cannot be reproduced due to some other change which causes the text frame at the cut-off position to have mbFramePrintAreaValid=false which causes it to MoveFwd and that calls SwSectionFrame::SimpleFormat() which fixes the height, but that all looks accidental.) Change-Id: If13d993a0cab5701f45223a70b2c5c8b0690ebeb (cherry picked from commit d77d3af9e4983edd7cd1cac5faecd8253db1a6ee) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173672 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> Tested-by: Jenkins (cherry picked from commit 5725374d6286653fbcdd50ec4999606e4932824d) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173640 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/qa/extras/layout/data/i94666.odt b/sw/qa/extras/layout/data/i94666.odt new file mode 100644 index 000000000000..2652e89570a5 Binary files /dev/null and b/sw/qa/extras/layout/data/i94666.odt differ diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index ea03eef254de..bfbbc4f0aee2 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -852,6 +852,52 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testFieldHideSection) discardDumpedLayout(); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestI94666) +{ + createSwDoc("i94666.odt"); + SwDoc* pDoc = getSwDoc(); + CPPUNIT_ASSERT(pDoc); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page"_ostr, 2); + assertXPath( + pXmlDoc, + "/root/page[2]/body/section/txt[1]/SwParaPortion/SwLineLayout[1]/SwLinePortion[1]"_ostr, + "portion"_ostr, "pulled off "); + discardDumpedLayout(); + } + + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->GotoPage(2, false); + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 11, /*bBasicCall=*/false); + pWrtShell->SetMark(); + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 11, /*bBasicCall=*/false); + pWrtShell->DelToEndOfPara(); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + // the problem was that the last paragraph moved to page 3 + assertXPath( + pXmlDoc, + "/root/page[2]/body/section/txt[1]/SwParaPortion/SwLineLayout[1]/SwLinePortion[1]"_ostr, + "portion"_ostr, + "Widows & orphans He heard quiet steps behind him. That didn't bode well. Who could be " + "following"); + assertXPath( + pXmlDoc, + "/root/page[2]/body/section/txt[1]/SwParaPortion/SwLineLayout[3]/SwLinePortion[1]"_ostr, + "portion"_ostr, "pulled off "); + assertXPath( + pXmlDoc, + "/root/page[2]/body/section/txt[2]/SwParaPortion/SwLineLayout[1]/SwParaPortion[1]"_ostr, + "portion"_ostr, "Moved paragraph"); + assertXPath(pXmlDoc, "/root/page[2]//txt"_ostr, 3); + assertXPath(pXmlDoc, "/root/page"_ostr, 2); + discardDumpedLayout(); + } +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf134272) { createSwDoc("tdf134472.odt"); diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index 225416da96af..db42935339c8 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -2279,7 +2279,10 @@ SwTwips SwContentFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo ) if( nRstHeight < 0 ) { SwTwips nNextHeight = 0; - if( GetUpper()->IsSctFrame() && nDist > LONG_MAX/2 ) + // i#94666 if WIDOW_MAGIC was set as height, nDist is wrong, need + // to take into account all the frames in the section. + if (GetUpper()->IsSctFrame() + && sw::WIDOW_MAGIC - 20000 - getFrameArea().Top() < nDist) { SwFrame *pNxt = GetNext(); while( pNxt ) diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx index 2412c7749bb2..66f2ad2f730f 100644 --- a/sw/source/uibase/inc/wrtsh.hxx +++ b/sw/source/uibase/inc/wrtsh.hxx @@ -291,7 +291,7 @@ typedef bool (SwWrtShell::*FNSimpleMove)(); // also deletes the frame or sets the cursor in the frame when bDelFrame == false SW_DLLPUBLIC bool DelRight(bool isReplaceHeuristic = false); - void DelToEndOfPara(); + SW_DLLPUBLIC void DelToEndOfPara(); void DelToStartOfPara(); SW_DLLPUBLIC bool DelToEndOfSentence(); void DelToStartOfSentence();