sw/source/core/layout/tabfrm.cxx |   33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

New commits:
commit 223a51801f0b75ae5036a8bcecc6eb81d99b113e
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Sep 18 14:04:45 2024 +0500
Commit:     Mike Kaganski <[email protected]>
CommitDate: Fri Sep 20 04:04:58 2024 +0200

    Optimize rows height calculation a bit
    
    Instead of adding heights in a loop, just get the distance between
    the top of the first row and the bottom of the last.
    
    Change-Id: I2082026c1c525f8230393ee8b59d1019f321fae5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173596
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 46d805a7f441..afbd321ab39b 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -207,16 +207,15 @@ static SwTwips lcl_GetHeightOfRows( const SwFrame* 
pStart, tools::Long nCount )
     if ( !nCount || !pStart)
         return 0;
 
-    SwTwips nRet = 0;
     SwRectFnSet aRectFnSet(pStart);
-    while ( pStart && nCount > 0 )
+    SwTwips nTop = aRectFnSet.GetTop(pStart->getFrameArea());
+    while (pStart->GetNext() && nCount > 1)
     {
-        nRet += aRectFnSet.GetHeight(pStart->getFrameArea());
         pStart = pStart->GetNext();
         --nCount;
     }
 
-    return nRet;
+    return -aRectFnSet.BottomDist(pStart->getFrameArea(), nTop);
 }
 
 // Local helper function to insert a new follow flow line
@@ -1096,18 +1095,25 @@ bool SwTabFrame::Split(const SwTwips nCutPos, bool 
bTryToSplit,
     const sal_uInt16 nRepeat = GetTable()->GetRowsToRepeat();
     sal_uInt16 nRowCount = 0;           // pRow currently points to the first 
row
 
-    SwTwips nRemainingSpaceForLastRow =
-        aRectFnSet.YDiff(nCutPos, aRectFnSet.GetTop(getFrameArea()));
-    nRemainingSpaceForLastRow -= aRectFnSet.GetTopMargin(*this) + 
aRectFnSet.GetBottomMargin(*this);
+    // Due to the comment above, about possibly invalid positions of cells due 
to position changes
+    // of the table, calculate the rows height subtracting last row's bottom 
from first row's top,
+    // and compare with the available height
+    SwTwips nRemainingSpaceForLastRow = aRectFnSet.YDiff(nCutPos, 
aRectFnSet.GetPrtTop(*this));
+    nRemainingSpaceForLastRow -= aRectFnSet.GetBottomMargin(*this);
+    auto getRemainingAfter = [aRectFnSet, nAvailable = 
nRemainingSpaceForLastRow,
+                              nFirstRowTop = 
aRectFnSet.GetTop(pRow->getFrameArea())](SwFrame* p)
+    { return nAvailable + (p ? aRectFnSet.BottomDist(p->getFrameArea(), 
nFirstRowTop) : 0); };
 
     // Make pRow point to the line that does not fit anymore:
-    while( pRow->GetNext() &&
-           nRemainingSpaceForLastRow >= ( 
aRectFnSet.GetHeight(pRow->getFrameArea()) ) )
+    while (pRow->GetNext())
     {
+        SwTwips nNewRemaining = getRemainingAfter(pRow);
+        if (nNewRemaining < 0)
+            break;
         if( bTryToSplit || !pRow->IsRowSpanLine() ||
             0 != aRectFnSet.GetHeight(pRow->getFrameArea()) )
             ++nRowCount;
-        nRemainingSpaceForLastRow -= 
aRectFnSet.GetHeight(pRow->getFrameArea());
+        nRemainingSpaceForLastRow = nNewRemaining;
         pRow = static_cast<SwRowFrame*>(pRow->GetNext());
     }
 
@@ -1384,7 +1390,7 @@ bool SwTabFrame::Split(const SwTwips nCutPos, bool 
bTryToSplit,
             pFollowRow = lcl_InsertNewFollowFlowLine( *this, *pLastRow, true );
     }
 
-    SwTwips nShrink = 0;
+    const SwTwips nShrink = lcl_GetHeightOfRows(pRow, 
std::numeric_limits<tools::Long>::max());
 
     //Optimization: There is no paste needed for the new Follow and the
     //optimized insert can be used (large numbers of rows luckily only occur in
@@ -1396,7 +1402,6 @@ bool SwTabFrame::Split(const SwTwips nCutPos, bool 
bTryToSplit,
         while ( pRow )
         {
             SwFrame* pNxt = pRow->GetNext();
-            nShrink += aRectFnSet.GetHeight(pRow->getFrameArea());
             // The footnotes do not have to be moved, this is done in the
             // MoveFwd of the follow table!!!
             pRow->RemoveFromLayout();
@@ -1415,7 +1420,6 @@ bool SwTabFrame::Split(const SwTwips nCutPos, bool 
bTryToSplit,
         while ( pRow )
         {
             SwFrame* pNxt = pRow->GetNext();
-            nShrink += aRectFnSet.GetHeight(pRow->getFrameArea());
 
             // The footnotes have to be moved:
             lcl_MoveFootnotes( *this, *GetFollow(), *pRow );
commit c1020d1ebb95615b68ffda0adf936f38fb2a06af
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Sep 18 13:01:44 2024 +0500
Commit:     Mike Kaganski <[email protected]>
CommitDate: Fri Sep 20 04:04:47 2024 +0200

    Related: tdf#152298 Consider bottom margin in remaining space calculation
    
    The value passed to lcl_RecalcSplitLine could be too large; then
    the call to rTab.Shrink succeeds, and the height of rTab changes
    as requested;  but then the values of  nDistanceToUpperPrtBottom
    and nDistanceToFootnoteBodyPrtBottom are negative,  resulting in
    failed split and layout loop.
    
    Change-Id: I797baee701b6a07e0c9310ea8cf902795c053642
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173595
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 08a4fa339438..46d805a7f441 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -1098,14 +1098,11 @@ bool SwTabFrame::Split(const SwTwips nCutPos, bool 
bTryToSplit,
 
     SwTwips nRemainingSpaceForLastRow =
         aRectFnSet.YDiff(nCutPos, aRectFnSet.GetTop(getFrameArea()));
-    nRemainingSpaceForLastRow -= aRectFnSet.GetTopMargin(*this);
+    nRemainingSpaceForLastRow -= aRectFnSet.GetTopMargin(*this) + 
aRectFnSet.GetBottomMargin(*this);
 
     // Make pRow point to the line that does not fit anymore:
     while( pRow->GetNext() &&
-           nRemainingSpaceForLastRow >= ( 
aRectFnSet.GetHeight(pRow->getFrameArea()) +
-                                           (IsCollapsingBorders() ?
-                                            pRow->GetBottomLineSize() :
-                                            0 ) ) )
+           nRemainingSpaceForLastRow >= ( 
aRectFnSet.GetHeight(pRow->getFrameArea()) ) )
     {
         if( bTryToSplit || !pRow->IsRowSpanLine() ||
             0 != aRectFnSet.GetHeight(pRow->getFrameArea()) )

Reply via email to