sw/qa/extras/layout/data/i94666.odt |binary
 sw/qa/extras/layout/layout.cxx      |   31 +++++++++++++++++++++++++++++++
 sw/source/core/layout/wsfrm.cxx     |    5 ++++-
 sw/source/core/text/xmldump.cxx     |    3 ++-
 4 files changed, 37 insertions(+), 2 deletions(-)

New commits:
commit d77d3af9e4983edd7cd1cac5faecd8253db1a6ee
Author:     Michael Stahl <[email protected]>
AuthorDate: Thu Sep 19 12:37:35 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Thu Sep 19 13:32:47 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

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 619ff3f27567..5bab734c67fe 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -603,6 +603,37 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testFieldHideSection)
     discardDumpedLayout();
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestI94666)
+{
+    SwDoc* pDoc = createDoc("i94666.odt");
+    CPPUNIT_ASSERT(pDoc);
+
+    {
+        xmlDocPtr pXmlDoc = parseLayoutDump();
+        assertXPath(pXmlDoc, "/root/page", 2);
+        assertXPath(pXmlDoc, "/root/page[2]/body/section/txt[1]/Text[1]", 
"Portion", "pulled off ");
+        discardDumpedLayout();
+    }
+
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    pWrtShell->GotoPage(2, false);
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 11, 
/*bBasicCall=*/false);
+    pWrtShell->SetMark();
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 11, 
/*bBasicCall=*/false);
+    pWrtShell->DelToEndOfPara();
+
+    {
+        xmlDocPtr pXmlDoc = parseLayoutDump();
+        // the problem was that the last paragraph moved to page 3
+        assertXPath(pXmlDoc, "/root/page[2]/body/section/txt[1]/Text[1]", 
"Portion", "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]/Text[4]", 
"Portion", "pulled off ");
+        assertXPath(pXmlDoc, "/root/page[2]/body/section/txt[2]/Text[1]", 
"Portion", "Moved paragraph");
+        assertXPath(pXmlDoc, "/root/page[2]//txt", 3);
+        assertXPath(pXmlDoc, "/root/page", 2);
+        discardDumpedLayout();
+    }
+}
+
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf134272)
 {
     SwDoc* pDoc = createDoc("tdf134472.odt");
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index cfcca29cca23..f46c3987cd3a 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -2195,7 +2195,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 )
commit 841a5a299b2da0fc4d97d3ac1a3353da96709e3c
Author:     Michael Stahl <[email protected]>
AuthorDate: Thu Sep 19 11:02:50 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Thu Sep 19 13:32:24 2024 +0200

    sw: GetSfxViewShell() can be null in SwFrame::dumpAsXml()
    
    Change-Id: I5680f50afcc739e6cfdb4390a68e4640ad58f940

diff --git a/sw/source/core/text/xmldump.cxx b/sw/source/core/text/xmldump.cxx
index 08f9b83bb57b..c652344f32f5 100644
--- a/sw/source/core/text/xmldump.cxx
+++ b/sw/source/core/text/xmldump.cxx
@@ -327,7 +327,8 @@ void SwFrame::dumpAsXml( xmlTextWriterPtr writer ) const
             SwView* pView = static_cast<SwView*>(SfxViewShell::GetFirst(true, 
checkSfxViewShell<SwView>));
             while (pView)
             {
-                if (pView->GetObjectShell() == 
pRootFrame->GetCurrShell()->GetSfxViewShell()->GetObjectShell())
+                if (pRootFrame->GetCurrShell()->GetSfxViewShell() &&
+                    pView->GetObjectShell() == 
pRootFrame->GetCurrShell()->GetSfxViewShell()->GetObjectShell())
                     pView->dumpAsXml(writer);
                 pView = static_cast<SwView*>(SfxViewShell::GetNext(*pView, 
true, checkSfxViewShell<SwView>));
             }

Reply via email to