sw/qa/core/layout/paintfrm.cxx     |   10 ++--
 sw/source/core/layout/paintfrm.cxx |   80 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 85 insertions(+), 5 deletions(-)

New commits:
commit 08aea5526c75ff4c5385e960bd940f10ffa19cd5
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Aug 21 08:33:14 2023 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Aug 21 09:36:32 2023 +0200

    tdf#156351 sw floattable: fix missing bottom border in master table
    
    The problem was that the bugdoc has a split floating table, and the
    bottom of the table on the first page was missing its border. The
    borders on the second page were correct.
    
    This happens because the cell itself has no bottom border and the layout
    did not extra effort to mirror the top table margin at the buttom, like
    Word does.
    
    Fix the problem similar to commit
    53798fef2cc0b5b0b9706081a4af5ceca964a41b (Related: tdf#156351 sw
    floattable: fix missing top border in follow table, 2023-08-18), so we
    add a bottom border for master tables at a layout level, similar how a
    top border was already added for follow tables.
    
    Given that this kind of worked already in the past (just top borders,
    just the 1 row case), do this unconditionally; but if needed this could
    be limited to the "Word table cell" case.
    
    Change-Id: Iafdcd90226fdc425be597d36ad97fb69dca5a89a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155884
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx
index 15b9df6a4fb4..2416c6b95f8c 100644
--- a/sw/qa/core/layout/paintfrm.cxx
+++ b/sw/qa/core/layout/paintfrm.cxx
@@ -36,7 +36,8 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitTableBorder)
     // When rendering that document:
     std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
 
-    // Then make sure that the follow table has a top border:
+    // Then make sure that the master table has a bottom border and the follow 
table has a top
+    // border:
     MetafileXmlDump aDumper;
     xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
     xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, 
"//polyline[@style='solid']/point");
@@ -61,10 +62,11 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitTableBorder)
     }
     xmlXPathFreeObject(pXmlObj);
     // Without the accompanying fix in place, this test would have failed with:
-    // - Expected: 3
+    // - Expected: 4
     // - Actual  : 2
-    // i.e. the top border in the follow table was missing.
-    CPPUNIT_ASSERT_EQUAL(3, nHorizontalBorders);
+    // i.e. the bottom border in the master table and the top border in the 
follow table were
+    // missing.
+    CPPUNIT_ASSERT_EQUAL(4, nHorizontalBorders);
 }
 }
 
diff --git a/sw/source/core/layout/paintfrm.cxx 
b/sw/source/core/layout/paintfrm.cxx
index 51dabd080b01..cf9edb359c98 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -2400,6 +2400,9 @@ class SwTabFramePainter
     void InsertFollowTopBorder(const SwFrame& rFrame, const SvxBoxItem& 
rBoxItem,
                                bool bWordTableCell, SwTwips nTop, SwTwips 
nLeft, SwTwips nRight,
                                bool bTopIsOuter);
+    void InsertMasterBottomBorder(const SwFrame& rFrame, const SvxBoxItem& 
rBoxItem,
+                                  bool bWordTableCell, SwTwips nBottom, 
SwTwips nLeft, SwTwips nRight,
+                                  bool bBottomIsOuter);
 
     void HandleFrame(const SwLayoutFrame& rFrame, const SwRect& rPaintArea);
     void FindStylesForLine( Point&,
@@ -2894,7 +2897,7 @@ void SwTabFramePainter::InsertFollowTopBorder(const 
SwFrame& rFrame, const SvxBo
 
     // This is then a first row in a follow table, without repeated headlines.
     auto pLastRow = dynamic_cast<const SwRowFrame*>(mrTabFrame.GetLastLower());
-    if (!pLastRow && pLastRow == pThisRow)
+    if (!pLastRow || pLastRow == pThisRow)
     {
         return;
     }
@@ -2930,6 +2933,79 @@ void SwTabFramePainter::InsertFollowTopBorder(const 
SwFrame& rFrame, const SvxBo
     Insert(aFollowTop, true);
 }
 
+void SwTabFramePainter::InsertMasterBottomBorder(const SwFrame& rFrame, const 
SvxBoxItem& rBoxItem,
+                                              bool bWordTableCell, SwTwips 
nBottom, SwTwips nLeft,
+                                              SwTwips nRight, bool 
bBottomIsOuter)
+{
+    // Figure out which cell to copy.
+    int nCol = 0;
+    const SwFrame* pCell = &rFrame;
+    while (pCell)
+    {
+        if (!pCell->GetPrev())
+        {
+            break;
+        }
+
+        ++nCol;
+        pCell = pCell->GetPrev();
+    }
+
+    auto pThisRow = dynamic_cast<const SwRowFrame*>(rFrame.GetUpper());
+    if (!pThisRow || pThisRow->GetUpper() != &mrTabFrame)
+    {
+        return;
+    }
+
+    if (mrTabFrame.IsFollow() || !mrTabFrame.GetFollow())
+    {
+        return;
+    }
+
+    // This is a master table that is split.
+    if (pThisRow->GetNext() || rBoxItem.GetTop() || rBoxItem.GetBottom())
+    {
+        return;
+    }
+
+    // This is then a last row in a master table.
+    auto pFirstRow = dynamic_cast<const SwRowFrame*>(mrTabFrame.GetLower());
+    if (!pFirstRow || pFirstRow == pThisRow)
+    {
+        return;
+    }
+
+    const SwFrame* pFirstCell = pFirstRow->GetLower();
+    for (int i = 0; i < nCol; ++i)
+    {
+        if (!pFirstCell)
+        {
+            break;
+        }
+
+        pFirstCell = pFirstCell->GetNext();
+    }
+    if (!pFirstCell)
+    {
+        return;
+    }
+
+    SwBorderAttrAccess aAccess(SwFrame::GetCache(), pFirstCell);
+    const SwBorderAttrs& rAttrs = *aAccess.Get();
+    const SvxBoxItem& rFirstBoxItem = rAttrs.GetBox();
+    if (!rFirstBoxItem.GetTop())
+    {
+        return;
+    }
+
+    // The matching (same column) row in the first row has a top border for us.
+    svx::frame::Style aMasterT(rFirstBoxItem.GetTop(), 1.0);
+    aMasterT.SetWordTableCell(bWordTableCell);
+    SwLineEntry aMasterBottom(nBottom, nLeft, nRight, bBottomIsOuter, 
aMasterT);
+    aMasterT.SetRefMode(svx::frame::RefMode::Begin);
+    Insert(aMasterBottom, true);
+}
+
 void SwTabFramePainter::Insert(const SwFrame& rFrame, const SvxBoxItem& 
rBoxItem, const SwRect& rPaintArea)
 {
     // build 4 line entries for the 4 borders:
@@ -3020,6 +3096,8 @@ void SwTabFramePainter::Insert(const SwFrame& rFrame, 
const SvxBoxItem& rBoxItem
     Insert( aTop, true );
     Insert( aBottom, true );
 
+    InsertMasterBottomBorder(rFrame, rBoxItem, bWordTableCell, nBottom, nLeft, 
nRight,
+                             bBottomIsOuter);
     InsertFollowTopBorder(rFrame, rBoxItem, bWordTableCell, nTop, nLeft, 
nRight, bTopIsOuter);
 }
 

Reply via email to