sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt  |   52 +++
 sw/qa/extras/layout/data/tdf160958_page_break.fodt            |   39 ++
 sw/qa/extras/layout/layout.cxx                                |  161 ++++++++++
 sw/qa/extras/ooxmlexport/data/tdf151704_thinColumnHeight.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx                    |   10 
 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx                     |    8 
 sw/qa/extras/uiwriter/data/table-in-table.fodt                |   29 +
 sw/qa/extras/uiwriter/uiwriter.cxx                            |   14 
 sw/source/core/crsr/crsrsh.cxx                                |   12 
 sw/source/core/inc/frame.hxx                                  |    1 
 sw/source/core/layout/calcmove.cxx                            |    6 
 sw/source/core/layout/flowfrm.cxx                             |   12 
 sw/source/core/layout/sectfrm.cxx                             |   55 +++
 sw/source/core/layout/tabfrm.cxx                              |   15 
 sw/source/core/layout/trvlfrm.cxx                             |   16 
 sw/source/core/layout/wsfrm.cxx                               |   26 +
 sw/source/core/text/frmform.cxx                               |    9 
 17 files changed, 449 insertions(+), 16 deletions(-)

New commits:
commit 29ffbbd2e718db225825cc87bd912c7c6434cbf0
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue Jun 4 10:12:26 2024 +0500
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 5 13:42:25 2024 +0200

    Make sure that the big value doesn't readily overflow
    
    As shown in 
https://gerrit.libreoffice.org/c/core/+/168235/6#message-5e7ed6fecf7fd36dc167193e25c3ec94daa11cb3
    
    > looks like this started to break e.g. CppunitTest_sw_mailmerge2 with
    >
    > /sw/inc/swrect.hxx:251:48: runtime error: signed integer overflow: 13569 
+ 9223372036854775807 cannot be represented in type 'long'
    >     #0 0x7f30b337cb90 in SwRect::Bottom() const /sw/inc/swrect.hxx:251:48
    >     #1 0x7f30b337234f in SwRect::Overlaps(SwRect const&) const 
/sw/inc/swrect.hxx:376:30
    >     #2 0x7f30b699354b in lcl_CheckFlowBack(SwFrame*, SwRect const&) 
/sw/source/core/layout/frmtool.cxx:3316:23
    >     #3 0x7f30b699376f in lcl_CheckFlowBack(SwFrame*, SwRect const&) 
/sw/source/core/layout/frmtool.cxx:3317:17
    >     #4 0x7f30b699376f in lcl_CheckFlowBack(SwFrame*, SwRect const&) 
/sw/source/core/layout/frmtool.cxx:3317:17
    >     #5 0x7f30b698d21e in Notify_Background(SdrObject const*, 
SwPageFrame*, SwRect const&, PrepareHint, bool) 
/sw/source/core/layout/frmtool.cxx:3415:13
    >     #6 0x7f30b5b941b4 in lcl_NotifyBackgroundOfObj(SwDrawContact const&, 
SdrObject const&, tools::Rectangle const*) 
/sw/source/core/draw/dcontact.cxx:955:13
    >     #7 0x7f30b5b7c9b9 in SwDrawContact::DisconnectFromLayout(bool) 
/sw/source/core/draw/dcontact.cxx:1689:9
    >     #8 0x7f30b5ba0cae in SwDrawContact::SwClientNotify(SwModify const&, 
SfxHint const&) /sw/source/core/draw/dcontact.cxx:1544:17
    >     #9 0x7f30b399e3c2 in SwModify::CallSwClientNotify(SfxHint const&) 
const /sw/source/core/attr/calbck.cxx:311:18
    >     #10 0x7f30b399e6c5 in 
sw::BroadcastingModify::CallSwClientNotify(SfxHint const&) const 
/sw/source/core/attr/calbck.cxx:316:15
    >     #11 0x7f30b6656d23 in SwDrawFrameFormat::DelFrames() 
/sw/source/core/layout/atrfrm.cxx:3525:5
    >     #12 0x7f30b51785f8 in 
sw::DocumentLayoutManager::DelLayoutFormat(SwFrameFormat*) 
/sw/source/core/doc/DocumentLayoutManager.cxx:235:14
    >     #13 0x7f30b4df70ac in 
sw::DocumentContentOperationsManager::DelFullPara(SwPaM&) 
/sw/source/core/doc/DocumentContentOperationsManager.cxx:2343:55
    >     #14 0x7f30b42b5701 in SwDoc::RemoveInvisibleContent() 
/sw/source/core/doc/doc.cxx:1576:57
    >     #15 0x7f30ba70c920 in SwDBManager::MergeMailFiles(SwWrtShell*, 
SwMergeDescriptor const&) /sw/source/uibase/dbui/dbmgr.cxx:1468:35
    >     #16 0x7f30ba6f7eff in SwDBManager::Merge(SwMergeDescriptor const&) 
/sw/source/uibase/dbui/dbmgr.cxx:556:20
    >     #17 0x7f30bbe0d561 in 
SwXMailMerge::execute(com::sun::star::uno::Sequence<com::sun::star::beans::NamedValue>
 const&) /sw/source/uibase/uno/unomailmerge.cxx:786:24
    >     #18 0x7f30bbe103ce in non-virtual thunk to 
SwXMailMerge::execute(com::sun::star::uno::Sequence<com::sun::star::beans::NamedValue>
 const&) /sw/source/uibase/uno/unomailmerge.cxx
    >     #19 0x7f30d009b8ed in (anonymous 
namespace)::MMTest2::executeMailMerge(bool) 
/sw/qa/extras/mailmerge/mailmerge2.cxx:195:31
    >     #20 0x7f30d00eb3e5 in (anonymous 
namespace)::testTdf123057_file::verify() 
/sw/qa/extras/mailmerge/mailmerge2.cxx:597:5
    >     #21 0x7f30d00a11eb in (anonymous 
namespace)::MMTest2::executeMailMergeTest(char const*, char const*, char 
const*, char const*, int, char const*) 
/sw/qa/extras/mailmerge/mailmerge2.cxx:99:9
    >     #22 0x7f30d00efc32 in (anonymous 
namespace)::testTdf123057_file::MailMerge() 
/sw/qa/extras/mailmerge/mailmerge2.cxx:594:1
    > (<https://ci.libreoffice.org/job/lo_ubsan/3194/>;)
    
    Change-Id: Ic34ad5c39d3b89c84f124e145a30714ba3752103
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168364
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit ecd42fe1885e8fca0ec302a6d0a666f925fa62d9)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168323
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 160ca02ea1c04b18d7f43c318d9fbfcdcd19209d)

diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index c2140632d8c8..5d7ea3c02a99 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -20,6 +20,7 @@
 #include <memory>
 #include <sal/config.h>
 #include <sal/log.hxx>
+#include <o3tl/safeint.hxx>
 
 #include <bodyfrm.hxx>
 #include <swtable.hxx>
@@ -538,7 +539,7 @@ bool SwFlowFrame::PasteTree( SwFrame *pStart, SwLayoutFrame 
*pParent, SwFrame *p
         else
             bRet = true;
 
-        nGrowVal += aRectFnSet.GetHeight(pFloat->getFrameArea());
+        nGrowVal = o3tl::saturating_add(nGrowVal, 
aRectFnSet.GetHeight(pFloat->getFrameArea()));
         if ( pFloat->GetNext() )
             pFloat = pFloat->GetNext();
         else
diff --git a/sw/source/core/layout/sectfrm.cxx 
b/sw/source/core/layout/sectfrm.cxx
index bc5349360eb0..36f489e4b92c 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -2665,8 +2665,9 @@ void SwSectionFrame::Modify( const SfxPoolItem* pOld, 
const SfxPoolItem * pNew )
         InvalidateObjs(false);
         {
             // Set it to a huge positive value, to make sure a recalculation 
fires
+            constexpr SwTwips HUGE_POSITIVE = 10000 * 1440 / 2.54; // 100m
             SwFrameAreaDefinition::FrameAreaWriteAccess area(*this);
-            SwRectFnSet(this).SetHeight(area, 
std::numeric_limits<sal_uLong>::max());
+            SwRectFnSet(this).SetHeight(area, HUGE_POSITIVE);
         }
 
         for (SwFrame* pLowerFrame = Lower(); pLowerFrame; pLowerFrame = 
pLowerFrame->GetNext())
commit beefaaa193ebac86307f9e085263ec28dcc93914
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu May 30 02:23:02 2024 +0500
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 5 13:42:25 2024 +0200

    tdf#160958: merge hidden section's follows; move first-on-page section back
    
    Change-Id: I6bd6707089dcea58d5df4bef63aa769769d97ea9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168235
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168279
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit f660e0de223741f57d01c30fc7f8ce1bdad0b6e0)

diff --git a/sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt 
b/sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt
new file mode 100644
index 000000000000..1306cfa6226d
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Serif" 
svg:font-family="&apos;Liberation Serif&apos;" 
style:font-family-generic="roman" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="paragraph">
+   <style:paragraph-properties fo:orphans="2" fo:widows="2"/>
+   <style:text-properties style:font-name="Liberation Serif" 
fo:font-size="12pt"/>
+  </style:default-style>
+ </office:styles>
+ <office:automatic-styles>
+  <style:page-layout style:name="pm1">
+   <style:page-layout-properties fo:page-width="21cm" fo:page-height="297mm" 
style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" 
fo:margin-left="2cm" fo:margin-right="2cm"/>
+  </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+  <office:text>
+   <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum 
consequat mi quis pretium semper. Proin luctus orci ac neque venenatis, quis 
commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. Donec 
blandit auctor arcu, nec pellentesque eros molestie eget. In consectetur 
aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, non 
pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus semper 
vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce pellentesque est 
orci.</text:p>
+   <text:p>Integer sodales tincidunt tristique. Sed a metus posuere, 
adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit amet tristique 
lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. Nunc eget 
dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate lobortis 
mollis. Vivamus nec tellus faucibus, tempor magna nec, facilisis felis. Donec 
commodo enim a vehicula pellentesque. Nullam vehicula vestibulum est vel 
ultricies.</text:p>
+   <text:p>Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. 
Donec consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et 
magnis dis parturient montes, nascetur ridiculus mus. Praesent vitae lacus vel 
leo sodales pharetra a a nibh. Vestibulum ante ipsum primis in faucibus orci 
luctus et ultrices posuere cubilia Curae; Nam luctus tempus nibh, fringilla 
dictum augue consectetur eget. Curabitur at ante sit amet tortor pharetra 
molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin molestie, dolor 
sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est 
elementum, euismod nulla in, mollis nunc.</text:p>
+   <text:p>He heard quiet steps behind him. That didn&apos;t bode well. Who 
could be following him this late at night and in this deadbeat part of town? 
And at this particular moment, just after he pulled off the big time and was 
making off with the greenbacks. Was there another crook who&apos;d had the same 
idea, and was now watching him and waiting for a chance to grab the fruit of 
his labor? Or did the steps behind him mean that one of many law officers in 
town was on to him and just waiting to pounce and snap those cuffs on his 
wrists? He nervously looked all around. Suddenly he saw the alley. Like 
lightning he darted off to the left and disappeared between the two warehouses 
almost falling over the trash can lying in the middle of the sidewalk. He tried 
to nervously tap his way along in the inky darkness and suddenly stiffened: it 
was a dead-end, he would have to go back the way he had come. The steps got 
louder and louder, he saw the black outline of a figure coming around the
  corner. Is this the end of the line? he thought pressing himself back against 
the wall trying to make himself invisible in the dark, was all that planning 
and energy wasted? He was dripping with sweat now, cold and wet, he could smell 
the fear coming off his clothes. Suddenly next to him, with a barely noticeable 
squeak, a door swung quietly to and fro in the night&apos;s breeze. Could this 
be the haven he&apos;d prayed for? Slowly he slid toward the door, pressing 
himself more and more into the wall, into the dark, away from his enemy. Would 
this door save his hide?</text:p>
+   <text:p>foo</text:p>
+   <text:p>bar</text:p>
+   <text:p>baz</text:p>
+   <text:p>foo</text:p>
+   <text:p>bar</text:p>
+   <text:p>baz</text:p>
+   <text:p>foo</text:p>
+   <text:p>bar</text:p>
+   <text:p>baz</text:p>
+   <text:p>foo</text:p>
+   <text:p>bar</text:p>
+   <text:p>baz</text:p>
+   <text:p>foo</text:p>
+   <text:p>bar</text:p>
+   <text:p>baz</text:p>
+   <text:p>foo</text:p>
+   <text:p>bar</text:p>
+   <text:section text:name="Section1">
+    <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
Vestibulum consequat mi quis pretium semper. Proin luctus orci ac neque 
venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis cursus 
egestas. Donec blandit auctor arcu, nec pellentesque eros molestie eget. In 
consectetur aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, non 
pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus semper 
vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce pellentesque est 
orci.</text:p>
+    <text:p>Integer sodales tincidunt tristique. Sed a metus posuere, 
adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit amet tristique 
lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. Nunc eget 
dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate lobortis 
mollis. Vivamus nec tellus faucibus, tempor magna nec, facilisis felis. Donec 
commodo enim a vehicula pellentesque. Nullam vehicula vestibulum est vel 
ultricies.</text:p>
+    <text:p>Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. 
Donec consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et 
magnis dis parturient montes, nascetur ridiculus mus. Praesent vitae lacus vel 
leo sodales pharetra a a nibh. Vestibulum ante ipsum primis in faucibus orci 
luctus et ultrices posuere cubilia Curae; Nam luctus tempus nibh, fringilla 
dictum augue consectetur eget. Curabitur at ante sit amet tortor pharetra 
molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin molestie, dolor 
sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est 
elementum, euismod nulla in, mollis nunc.</text:p>
+   </text:section>
+   <text:p>baz</text:p>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/layout/data/tdf160958_page_break.fodt 
b/sw/qa/extras/layout/data/tdf160958_page_break.fodt
new file mode 100644
index 000000000000..1d4d8863b073
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf160958_page_break.fodt
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Serif" 
svg:font-family="&apos;Liberation Serif&apos;" 
style:font-family-generic="roman" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="paragraph">
+   <style:text-properties style:use-window-font-color="true" 
style:font-name="Liberation Serif" fo:font-size="12pt"/>
+  </style:default-style>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:master-page-name="">
+   <style:paragraph-properties style:page-number="auto" 
fo:break-before="page"/>
+  </style:style>
+  <style:page-layout style:name="pm1">
+   <style:page-layout-properties fo:page-width="21cm" fo:page-height="297mm" 
style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" 
fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm"/>
+  </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+  <office:text>
+   <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum 
consequat mi quis pretium semper. Proin luctus orci ac neque venenatis, quis 
commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. Donec 
blandit auctor arcu, nec pellentesque eros molestie eget. In consectetur 
aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, non 
pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus semper 
vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce pellentesque est 
orci.</text:p>
+   <text:section text:name="Section1">
+    <text:p text:style-name="P1"/>
+    <text:p/>
+    <text:p/>
+    <text:p>Integer sodales tincidunt tristique. Sed a metus posuere, 
adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit amet tristique 
lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. Nunc eget 
dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate lobortis 
mollis. <text:soft-page-break/>Vivamus nec tellus faucibus, tempor magna nec, 
facilisis felis. Donec commodo enim a vehicula pellentesque. Nullam vehicula 
vestibulum est vel ultricies.</text:p>
+    <text:p/>
+    <text:p/>
+    <text:p/>
+   </text:section>
+   <text:p>Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. 
Donec consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et 
magnis dis parturient montes, nascetur ridiculus mus. Praesent vitae lacus vel 
leo sodales pharetra a a nibh. Vestibulum ante ipsum primis in faucibus orci 
luctus et ultrices posuere cubilia Curae; Nam luctus tempus nibh, fringilla 
dictum augue consectetur eget. Curabitur at ante sit amet tortor pharetra 
molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin molestie, dolor 
sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est 
elementum, euismod nulla in, mollis nunc.</text:p>
+   <text:p/>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index a5f1906cd8e9..7c78421584d3 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -4219,6 +4219,167 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, 
testPageBreakInHiddenSection)
     assertXPath(pXmlDoc, "//page[4]/body/section/infos/bounds", "height", 
u"0");
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf160958_page_break)
+{
+    // Given a document with a section with the first paragraph having a page 
break
+    createDoc("tdf160958_page_break.fodt");
+    auto pExportDump = parseLayoutDump();
+    assertXPath(pExportDump, "//page", 2);
+    // A single paragraph on the first page, with 6 lines
+    assertXPath(pExportDump, "//page[1]/body/txt", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt/LineBreak", 6);
+    // A section with 7 paragraphs, and two more paragraphs after the section
+    assertXPath(pExportDump, "//page[2]/body/section", 1);
+    assertXPath(pExportDump, "//page[2]/body/section/txt", 7);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[4]/LineBreak", 5);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[5]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[6]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[7]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/txt", 2);
+    assertXPath(pExportDump, "//page[2]/body/txt[1]/LineBreak", 7);
+    assertXPath(pExportDump, "//page[2]/body/txt[2]/SwParaPortion", 0);
+
+    // Hide the section
+    uno::Reference<css::text::XTextSectionsSupplier> 
xTextSectionsSupplier(mxComponent, uno::UNO_QUERY_THROW);
+    auto xSections = xTextSectionsSupplier->getTextSections();
+    CPPUNIT_ASSERT(xSections);
+    uno::Reference<css::beans::XPropertySet> 
xSection(xSections->getByName(u"Section1"), uno::UNO_QUERY_THROW);
+    xSection->setPropertyValue(u"IsVisible", css::uno::Any(false));
+
+    discardDumpedLayout();
+    calcLayout();
+    pExportDump = parseLayoutDump();
+    assertXPath(pExportDump, "//page", 1);
+    // Three paragraphs and a hidden section on the first page
+    assertXPath(pExportDump, "//page/body/txt", 3);
+    assertXPath(pExportDump, "//page/body/section", 1);
+
+    assertXPath(pExportDump, "//page/body/section/infos/bounds", "height", 
"0");
+    assertXPath(pExportDump, "//page/body/txt[1]/LineBreak", 6);
+    assertXPath(pExportDump, "//page/body/section/txt", 7);
+
+    assertXPath(pExportDump, "//page/body/txt[2]/LineBreak", 7);
+    assertXPath(pExportDump, "//page/body/txt[3]/SwParaPortion", 0);
+
+    // Show the section again
+    xSection->setPropertyValue(u"IsVisible", css::uno::Any(true));
+
+    // Check that the layout has been restored
+    discardDumpedLayout();
+    calcLayout();
+    pExportDump = parseLayoutDump();
+    assertXPath(pExportDump, "//page", 2);
+    assertXPath(pExportDump, "//page[1]/body/txt", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt/LineBreak", 6);
+    assertXPath(pExportDump, "//page[2]/body/section", 1);
+    assertXPath(pExportDump, "//page[2]/body/section/txt", 7);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[4]/LineBreak", 5);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[5]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[6]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[7]/SwParaPortion", 0);
+    assertXPath(pExportDump, "//page[2]/body/txt", 2);
+    assertXPath(pExportDump, "//page[2]/body/txt[1]/LineBreak", 7);
+    assertXPath(pExportDump, "//page[2]/body/txt[2]/SwParaPortion", 0);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf160958_orphans)
+{
+    // Given a document with a section which moves to the next page as a 
whole, because of orphans
+    createDoc("tdf160958_orphans_move_section.fodt");
+    auto pExportDump = parseLayoutDump();
+    assertXPath(pExportDump, "//page", 2);
+    // 21 paragraphs on the first page
+    assertXPath(pExportDump, "//page[1]/body/txt", 21);
+    assertXPath(pExportDump, "//page[1]/body/txt[1]/LineBreak", 6);
+    assertXPath(pExportDump, "//page[1]/body/txt[2]/LineBreak", 5);
+    assertXPath(pExportDump, "//page[1]/body/txt[3]/LineBreak", 7);
+    assertXPath(pExportDump, "//page[1]/body/txt[4]/LineBreak", 16);
+    assertXPath(pExportDump, "//page[1]/body/txt[5]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[6]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[7]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[8]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[9]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[10]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[11]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[12]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[13]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[14]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[15]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[16]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[17]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[18]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[19]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[20]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[21]/LineBreak", 1);
+    // A section and one more paragraph after the section
+    assertXPath(pExportDump, "//page[2]/body/section", 1);
+    assertXPath(pExportDump, "//page[2]/body/section/txt", 3);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[1]/LineBreak", 6);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[2]/LineBreak", 5);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[3]/LineBreak", 7);
+    assertXPath(pExportDump, "//page[2]/body/txt", 1);
+    assertXPath(pExportDump, "//page[2]/body/txt[1]/LineBreak", 1);
+
+    // Hide the section
+    uno::Reference<css::text::XTextSectionsSupplier> 
xTextSectionsSupplier(mxComponent, uno::UNO_QUERY_THROW);
+    auto xSections = xTextSectionsSupplier->getTextSections();
+    CPPUNIT_ASSERT(xSections);
+    uno::Reference<css::beans::XPropertySet> 
xSection(xSections->getByName(u"Section1"), uno::UNO_QUERY_THROW);
+    xSection->setPropertyValue(u"IsVisible", css::uno::Any(false));
+
+    discardDumpedLayout();
+    calcLayout();
+    pExportDump = parseLayoutDump();
+    assertXPath(pExportDump, "//page", 1);
+    assertXPath(pExportDump, "//page/body/txt", 22);
+    assertXPath(pExportDump, "//page/body/section", 1);
+    assertXPath(pExportDump, "//page/body/section/infos/bounds", "height", 
"0");
+
+    // Show the section again
+    xSection->setPropertyValue(u"IsVisible", css::uno::Any(true));
+
+    // Check that the layout has been restored
+    discardDumpedLayout();
+    calcLayout();
+    pExportDump = parseLayoutDump();
+    assertXPath(pExportDump, "//page", 2);
+    assertXPath(pExportDump, "//page[1]/body/txt", 21);
+    assertXPath(pExportDump, "//page[1]/body/txt[1]/LineBreak", 6);
+    assertXPath(pExportDump, "//page[1]/body/txt[2]/LineBreak", 5);
+    assertXPath(pExportDump, "//page[1]/body/txt[3]/LineBreak", 7);
+    assertXPath(pExportDump, "//page[1]/body/txt[4]/LineBreak", 16);
+    assertXPath(pExportDump, "//page[1]/body/txt[5]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[6]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[7]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[8]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[9]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[10]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[11]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[12]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[13]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[14]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[15]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[16]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[17]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[18]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[19]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[20]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[1]/body/txt[21]/LineBreak", 1);
+    assertXPath(pExportDump, "//page[2]/body/section", 1);
+    assertXPath(pExportDump, "//page[2]/body/section/txt", 3);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[1]/LineBreak", 6);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[2]/LineBreak", 5);
+    assertXPath(pExportDump, "//page[2]/body/section/txt[3]/LineBreak", 7);
+    assertXPath(pExportDump, "//page[2]/body/txt", 1);
+    assertXPath(pExportDump, "//page[2]/body/txt[1]/LineBreak", 1);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/sectfrm.cxx 
b/sw/source/core/layout/sectfrm.cxx
index 9b7b04a823ee..bc5349360eb0 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -805,6 +805,42 @@ void SwSectionFrame::MakeAll(vcl::RenderContext* 
pRenderContext)
         setFramePrintAreaValid(true);
         return;
     }
+
+    if (!GetPrev() && !IsFollow() && IsInDocBody() && IsHiddenNow())
+    {
+        // This may be the first frame on a page, and it may had moved to that 
page because its
+        // content required that (a page break in the first paragraph, or a 
tall first line, or
+        // "do not break paragraph" setting, or the like). Try to move back, 
to allow following
+        // frames to move back, if possible. Sections cannot move back; 
workaround by a call to
+        // GetPrevSctLeaf(), which may return a candidate upper frame on a 
previous page, or it
+        // may create a new master for this at the end of the previous page. 
Cut and paste this
+        // appropriately; then drop the temporary, if needed.
+        if (SwLayoutFrame* moveBackPos = GetPrevSctLeaf())
+        {
+            SwLayoutFrame* newUpper = moveBackPos;
+            SwFrame* newSibling = nullptr;
+            const bool temporaryMasterCreated = IsFollow();
+            if (temporaryMasterCreated)
+            {
+                assert(moveBackPos == &GetPrecede()->GetFrame());
+                newUpper = moveBackPos->GetUpper();
+                newSibling = moveBackPos->GetNext(); // actually, will be also 
nullptr
+            }
+            if (newUpper != GetUpper())
+            {
+                // Can't use MoveSubTree, because the move needs to fire 
events to re-layout
+                Cut();
+                Paste(newUpper, newSibling);
+            }
+            if (temporaryMasterCreated)
+            {
+                moveBackPos->Cut();
+                DestroyFrame(moveBackPos);
+            }
+            assert(!IsFollow());
+        }
+    }
+
     LockJoin(); // I don't let myself to be destroyed on the way
 
     while( GetNext() && GetNext() == GetFollow() )
@@ -815,6 +851,17 @@ void SwSectionFrame::MakeAll(vcl::RenderContext* 
pRenderContext)
             break;
     }
 
+    if (GetFollow() && IsHiddenNow())
+    {
+        // Merge all the follows of this hidden section
+        while (auto* follow = GetFollow())
+        {
+            MergeNext(follow);
+            if (GetFollow() == follow) // failed to merge
+                break; // avoid endless loop
+        }
+    }
+
     // OD 2004-03-15 #116561# - In online layout join the follows, if section
     // can grow.
     const SwViewShell *pSh = getRootFrame()->GetCurrShell();
@@ -2616,6 +2663,11 @@ void SwSectionFrame::Modify( const SfxPoolItem* pOld, 
const SfxPoolItem * pNew )
     {
         InvalidateAll();
         InvalidateObjs(false);
+        {
+            // Set it to a huge positive value, to make sure a recalculation 
fires
+            SwFrameAreaDefinition::FrameAreaWriteAccess area(*this);
+            SwRectFnSet(this).SetHeight(area, 
std::numeric_limits<sal_uLong>::max());
+        }
 
         for (SwFrame* pLowerFrame = Lower(); pLowerFrame; pLowerFrame = 
pLowerFrame->GetNext())
         {
commit a85cf6704424647a421401df7b3b3eb8cf55518b
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Tue Aug 1 19:45:58 2023 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 5 13:42:24 2024 +0200

    tdf#152307 sw: layout: invalidate more frames when footer grows
    
    While on page 12:
    SwTabFrame::MakeAll() is called on 523 while it's on page 12; there is
    one invalid pos text frame 492 with a fly somewhere before it;
    PrepareMake() of 523 formats prevs 492 then 493 which MoveFwd() taking
    523 with it.
    
    While on page 13:
    TabFrame 523 is valid, and the footer 6651 never formatted (0 height).
    Formatting the footer in SwHeadFootFrame::FormatSize() invalidates the
    body 1031, immediately calls Calc() from SwFrame::MakePos(), where
    ~SwLayNotify() -> SwLayoutFrame::ChgLowersProp() invalidates
    SectionFrame 1034.
    
    Then SectionFrame 1034 is formatted, which via
    SwSectionFrame::CheckClipping() -> SwLayoutFrame::ChgLowersProp()
    invalidates only the last lower frame, because it checks the position of
    the frame and this frame still has a position on a previous page (it
    moved from page 12) and isn't even invalid yet.
    
    So in case there are invalid frames, the positions of the frames
    following these cannot be trusted to be used to optimize invalidations
    in SwLayoutFrame::ChgLowersProp().
    
    (aside: it seems odd to format the body text before the footer text, but
     in this case doing it differently wouldn't have helped because the
     problem was already caused on a previous page)
    
    (regression from commit b9ef71476fd70bc13f50ebe80390e0730d1b7afb)
    
    [note: This is required so the testTdf160958_orphans runs successfully]
    
    Change-Id: I23b35c09af3a373d0913d931a2ba59d45fadf2c0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155196
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 06bbcee6e367d1bc319c1f9cb0e749168e4d890c)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155230
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit c2a86b88e71c0b4291cd813d9a53fa89a29ea8b9)

diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index d8875dbc89cd..cfcca29cca23 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -3043,26 +3043,48 @@ void SwLayoutFrame::ChgLowersProp( const Size& rOldSize 
)
             }
             else
             {
+                SwFrame const* pFirstInvalid(nullptr);
+                for (SwFrame const* pLow = Lower();
+                     pLow && pLow != pLowerFrame; pLow = pLow->GetNext())
+                {
+                    if (!pLow->isFrameAreaDefinitionValid())
+                    {
+                        pFirstInvalid = pLow;
+                        break;
+                    }
+                }
                 // variable size of body|section frame has shrunk. Thus,
                 // invalidate all lowers not matching the new body|section size
                 // and the dedicated new last lower.
                 if( aRectFnSet.IsVert() )
                 {
                     SwTwips nBot = getFrameArea().Left() + 
getFramePrintArea().Left();
-                    while ( pLowerFrame && pLowerFrame->GetPrev() && 
pLowerFrame->getFrameArea().Left() < nBot )
+                    while (pLowerFrame && pLowerFrame->GetPrev()
+                        && (pFirstInvalid != nullptr // tdf#152307 trust 
nothing after invalid frame
+                            || pLowerFrame->getFrameArea().Left() < nBot))
                     {
                         pLowerFrame->InvalidateAll_();
                         pLowerFrame->InvalidatePage( pPage );
+                        if (pLowerFrame == pFirstInvalid)
+                        {
+                            pFirstInvalid = nullptr; // continue checking nBot
+                        }
                         pLowerFrame = pLowerFrame->GetPrev();
                     }
                 }
                 else
                 {
                     SwTwips nBot = getFrameArea().Top() + 
getFramePrintArea().Bottom();
-                    while ( pLowerFrame && pLowerFrame->GetPrev() && 
pLowerFrame->getFrameArea().Top() > nBot )
+                    while (pLowerFrame && pLowerFrame->GetPrev()
+                        && (pFirstInvalid != nullptr // tdf#152307 trust 
nothing after invalid frame
+                            || nBot < pLowerFrame->getFrameArea().Top()))
                     {
                         pLowerFrame->InvalidateAll_();
                         pLowerFrame->InvalidatePage( pPage );
+                        if (pLowerFrame == pFirstInvalid)
+                        {
+                            pFirstInvalid = nullptr; // continue checking nBot
+                        }
                         pLowerFrame = pLowerFrame->GetPrev();
                     }
                 }
commit f73fe207ccc849c4ce259c4d4ee5f9093883d737
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue May 28 09:04:51 2024 +0500
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 5 13:42:24 2024 +0200

    tdf#161202: lowers shouldn't move forward because of lack of space
    
    ... in hidden section. So make sure to set heights of lowers to zero, too.
    testOldComplexMergeTableInTable turned out to be a nice test for this.
    
    Change-Id: I334aaaf2becf0ac1ff61faed2e5f697f344c78d4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168151
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    (cherry picked from commit fc1e6a64bd0517a7e67f08860c29b44d030220eb)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168198
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 6a7a5fad86e5fcb736286ecc01a561bc5f802d23)

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index 696e9c4ee3bd..47393c8dc3ec 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -276,6 +276,14 @@ DECLARE_OOXMLEXPORT_TEST(testOldComplexMergeTableInTable, 
"ooo96040-2.odt")
 
     if (!pXmlDoc)
        return;
+
+    // Check tdf#161202 - this document has all kinds of tables inside hidden 
sections.
+    // The page count must be 13, but for unclear reason, it is 12 in some 
tests on Linux
+    // (maybe the layout hasn't finished?).
+    // Without the fix, it was 52.
+//    CPPUNIT_ASSERT_LESSEQUAL(13, getPages());
+    // is actually 19 in 6.4 branch? but 16 when opened in UI...
+    CPPUNIT_ASSERT_LESSEQUAL(19, getPages());
 }
 
 DECLARE_OOXMLEXPORT_TEST(testHyperlinkContainingPlaceholderField, 
"hyperlink-field.odt")
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index cb5a2418ef21..151f7686aab9 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -862,6 +862,7 @@ public:
     bool IsProtected() const;
 
     virtual bool IsHiddenNow() const;
+    void MakeValidZeroHeight();
 
     bool IsColLocked()  const { return mbColLocked; }
     virtual bool IsDeleteForbidden() const { return mnForbidDelete > 0; }
diff --git a/sw/source/core/layout/calcmove.cxx 
b/sw/source/core/layout/calcmove.cxx
index b889de6689ae..7600522869f0 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -960,6 +960,9 @@ void SwLayoutFrame::MakeAll(vcl::RenderContext* 
/*pRenderContext*/)
     const SwLayNotify aNotify( this );
     bool bVert = IsVertical();
 
+    if (IsHiddenNow())
+        MakeValidZeroHeight();
+
     SwRectFn fnRect = ( IsNeighbourFrame() == bVert )? fnRectHori : ( 
IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert );
 
     std::unique_ptr<SwBorderAttrAccess> pAccess;
@@ -1237,6 +1240,9 @@ void SwContentFrame::MakeAll(vcl::RenderContext* 
/*pRenderContext*/)
         return;
     }
 
+    if (IsHiddenNow())
+        MakeValidZeroHeight();
+
     auto xDeleteGuard = std::make_unique<SwFrameDeleteGuard>(this);
     LockJoin();
     long nFormatCount = 0;
diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index b29909288056..c2140632d8c8 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -1381,6 +1381,9 @@ SwTwips SwFlowFrame::CalcUpperSpace( const SwBorderAttrs 
*pAttrs,
                                    const SwFrame* pPr,
                                    const bool _bConsiderGrid ) const
 {
+    if (m_rThis.IsHiddenNow())
+        return 0;
+
     // OD 2004-03-10 #i11860# - use new method 
<GetPrevFrameForUpperSpaceCalc(..)>
     const SwFrame* pPrevFrame = GetPrevFrameForUpperSpaceCalc_( pPr );
 
@@ -1657,6 +1660,9 @@ SwTwips 
SwFlowFrame::GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid() cons
 */
 SwTwips SwFlowFrame::CalcLowerSpace( const SwBorderAttrs* _pAttrs ) const
 {
+    if (m_rThis.IsHiddenNow())
+        return 0;
+
     SwTwips nLowerSpace = 0;
 
     std::unique_ptr<SwBorderAttrAccess> pAttrAccess;
@@ -1705,6 +1711,9 @@ SwTwips SwFlowFrame::CalcLowerSpace( const SwBorderAttrs* 
_pAttrs ) const
 SwTwips SwFlowFrame::CalcAddLowerSpaceAsLastInTableCell(
                                             const SwBorderAttrs* _pAttrs ) 
const
 {
+    if (m_rThis.IsHiddenNow())
+        return 0;
+
     SwTwips nAdditionalLowerSpace = 0;
 
     IDocumentSettingAccess const& 
rIDSA(m_rThis.GetUpper()->GetFormat()->getIDocumentSettingAccess());
diff --git a/sw/source/core/layout/sectfrm.cxx 
b/sw/source/core/layout/sectfrm.cxx
index 4f4e36ca5711..9b7b04a823ee 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -1183,7 +1183,7 @@ void SwSectionFrame::SimpleFormat()
     SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*GetUpper());
     // OD 22.10.2002 #97265# - call always method <lcl_ColumnRefresh(..)>, in
     // order to get calculated lowers, not only if there space left in its 
upper.
-    if( aRectFnSet.BottomDist( getFrameArea(), nDeadLine ) >= 0 )
+    if (aRectFnSet.BottomDist(getFrameArea(), nDeadLine) >= 0)
     {
         {
             SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index dd0d6bbc9dd5..214932b173f2 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -2105,6 +2105,9 @@ void SwTabFrame::MakeAll(vcl::RenderContext* 
pRenderContext)
         }
     }
 
+    if (IsHiddenNow())
+        MakeValidZeroHeight();
+
     int nUnSplitted = 5; // Just another loop control :-(
     int nThrowAwayValidLayoutLimit = 5; // And another one :-(
     SwRectFnSet aRectFnSet(this);
@@ -2841,6 +2844,18 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
                                long& rLeftOffset,
                                long& rRightOffset ) const
 {
+    if (IsHiddenNow())
+    {
+        rUpper = 0;
+        rLeftOffset = 0;
+        rRightOffset = 0;
+#if 0
+        if (pSpaceBelowBottom)
+            *pSpaceBelowBottom = 0;
+#endif
+        return false;
+    }
+
     bool bInvalidatePrtArea = false;
     const SwPageFrame *pPage = FindPageFrame();
     const SwFlyFrame* pMyFly = FindFlyFrame();
diff --git a/sw/source/core/layout/trvlfrm.cxx 
b/sw/source/core/layout/trvlfrm.cxx
index 3dd5cc223038..5cda95c23aec 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -1693,6 +1693,22 @@ bool SwFrame::IsHiddenNow() const
     return false;
 }
 
+void SwFrame::MakeValidZeroHeight()
+{
+    SwRectFnSet aRectFnSet(this);
+    {
+        SwFrameAreaDefinition::FrameAreaWriteAccess area(*this);
+        aRectFnSet.SetHeight(area, 0);
+    }
+    {
+        SwFrameAreaDefinition::FramePrintAreaWriteAccess area(*this);
+        aRectFnSet.SetHeight(area, 0);
+    }
+    setFrameAreaSizeValid(true);
+    setFramePrintAreaValid(true);
+    setFrameAreaPositionValid(false);
+}
+
 /** @return the physical page number */
 sal_uInt16 SwFrame::GetPhyPageNum() const
 {
commit 5001be4706ab8d9e9637b1b303794d6a3c21f793
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Fri Dec 23 15:49:59 2022 -0500
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 5 13:42:24 2024 +0200

    tdf#151704 sw: don't give random height to text frame
    
    This was introduced forever ago with
    commit 6c3ae34e32539f8493a940666dbe16b23a8ba7b0
    Author: Frank Meies on Tue Nov 20 15:24:54 2001 +0000
        Chg: Vertical Formatting - Growing frames
    
    But why?
    Assuming that anything that NEEDED to set a proper height
    has done so by now. The commit suggests it was added to
    handle vertical layouts.
    
    If this exploratory patch causes problems
    (and it very well might since this is a really generic spot)
    then perhaps it can be limited to verical layout situations?
    
    [note: required for I334aaaf2becf0ac1ff61faed2e5f697f344c78d4
     to format rows that contain only hidden paragraphs with height 0]
    
    Change-Id: Ib6e4a45379e670fd343a2e2d87879e6bb52afebf
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144787
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit cd7f8d895abae28533ec43ed43b2d90947e92b42)

diff --git a/sw/qa/extras/ooxmlexport/data/tdf151704_thinColumnHeight.docx 
b/sw/qa/extras/ooxmlexport/data/tdf151704_thinColumnHeight.docx
new file mode 100644
index 000000000000..7e7cd57e1395
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf151704_thinColumnHeight.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 18a22bbdd30c..d7f9df7eaeb7 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -50,6 +50,16 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf128197)
     CPPUNIT_ASSERT_LESS(nHeight15, nHeight14);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf151704_thinColumnHeight, 
"tdf151704_thinColumnHeight.docx")
+{
+    xmlDocPtr pXmlDoc = parseLayoutDump();
+    sal_Int32 nRowHeightT1 = getXPath(
+        pXmlDoc, "//page[1]/body//tab[1]/row/cell/tab[1]/row[1]/infos/bounds", 
"height").toInt32();
+    sal_Int32 nRowHeightT2 = getXPath(
+        pXmlDoc, "//page[2]/body//tab/row[1]/infos/bounds", 
"height").toInt32();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Same row height in both tables", 
nRowHeightT1, nRowHeightT2);
+}
+
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf78749, "tdf78749.docx")
 {
     //Shape lost the background image before, now check if it still has...
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index 7a1b0ed7e3ff..15be672ac92d 100755
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -1780,7 +1780,6 @@ void SwTextFrame::Format( vcl::RenderContext* 
pRenderContext, const SwBorderAttr
     if( aRectFnSet.GetWidth(getFramePrintArea()) <= 0 )
     {
         // If MustFit is set, we shrink to the Upper's bottom edge if needed.
-        // Else we just take a standard size of 12 Pt. (240 twip).
         SwTextLineAccess aAccess( this );
         long nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
 
@@ -1791,14 +1790,6 @@ void SwTextFrame::Format( vcl::RenderContext* 
pRenderContext, const SwBorderAttr
             if( nDiff > 0 )
                 Shrink( nDiff );
         }
-        else if( 240 < nFrameHeight )
-        {
-            Shrink( nFrameHeight - 240 );
-        }
-        else if( 240 > nFrameHeight )
-        {
-            Grow( 240 - nFrameHeight );
-        }
 
         nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
         const long nTop = aRectFnSet.GetTopMargin(*this);
commit 6978fa6a900da6948e1fd72912194290bfbfce13
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu May 2 09:11:25 2024 +0500
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue Jun 4 14:54:48 2024 +0200

    tdf#160898: check for nullptr
    
    Regression after commit d81379db730a163c5ff75d4f3a3cddbd7b5eddda
    (tdf#154877 sw: generalise ExtendedSelectAll(), 2023-05-09)
    
    Change-Id: I9289171647fca8bd1b696399ff7c43a2ac7b8b30
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166990
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166997
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit e7803234b5609d6ff66ebe79b7409d0fc822b067)

diff --git a/sw/qa/extras/uiwriter/data/table-in-table.fodt 
b/sw/qa/extras/uiwriter/data/table-in-table.fodt
new file mode 100644
index 000000000000..e055d343b847
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/table-in-table.fodt
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:automatic-styles>
+  <style:style style:name="border" style:family="table-cell">
+   <style:table-cell-properties fo:padding="1mm" fo:border="0.5pt solid 
#000000"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:p/>
+   <table:table>
+    <table:table-column/>
+    <table:table-row>
+     <table:table-cell table:style-name="border">
+      <table:table>
+       <table:table-column/>
+       <table:table-row>
+        <table:table-cell table:style-name="border"/>
+       </table:table-row>
+      </table:table>
+      <text:p/>
+     </table:table-cell>
+    </table:table-row>
+   </table:table>
+   <text:p/>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx 
b/sw/qa/extras/uiwriter/uiwriter.cxx
index d1b117f6a467..ccc96d3e58fc 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -8351,6 +8351,20 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf159565)
                          xSelection->getString());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf160898)
+{
+    // Given a document with a 1-cell table in another 1-cell table:
+    createDoc("table-in-table.fodt");
+    SwXTextDocument* pXTextDocument = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwDocShell* pDocShell = pXTextDocument->GetDocShell();
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+
+    // Move to the normally hidden paragraph inside the outer table cell, 
following the inner table
+    pWrtShell->Down(false, 2);
+    // Without the fix, this would crash:
+    pWrtShell->SelAll();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 85e9eb837017..511480102844 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -726,9 +726,15 @@ bool SwCursorShell::MoveStartText()
     *m_pCurrentCursor->GetPoint() = SwPosition(*pStartNode);
     GetDoc()->GetNodes().GoNext(&m_pCurrentCursor->GetPoint()->nNode);
     
m_pCurrentCursor->GetPoint()->nContent.Assign(m_pCurrentCursor->GetPoint()->nNode.GetNode().GetContentNode(),
 0);
-    while (m_pCurrentCursor->GetPoint()->nNode.GetNode().FindTableNode() != 
pTable
-        && (!pTable || pTable->GetIndex() < 
m_pCurrentCursor->GetPoint()->nNode.GetNode().FindTableNode()->GetIndex())
-        && MoveOutOfTable());
+    while (auto* pFoundTable = 
m_pCurrentCursor->GetPoint()->nNode.GetNode().FindTableNode())
+    {
+        if (pFoundTable == pTable)
+            break;
+        if (pTable && pTable->GetIndex() >= pFoundTable->GetIndex())
+            break;
+        if (!MoveOutOfTable())
+            break;
+    }
     
UpdateCursor(SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE|SwCursorShell::READONLY);
     return old != *m_pCurrentCursor->GetPoint();
 }

Reply via email to