sw/qa/core/layout/layout.cxx       |   63 +++++++++++++++++++++++++++++++++++++
 sw/source/core/layout/paintfrm.cxx |    9 ++++-
 2 files changed, 71 insertions(+), 1 deletion(-)

New commits:
commit 1f373260cf25ca2f36a929e1a27fde00641e5c09
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Feb 6 14:48:37 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Feb 6 16:02:09 2023 +0000

    tdf#152669 sw: fix missing table borders in the non-Word-table-cell case
    
    A 4x4 table had partially missing inner borders when the page's writing
    mode was set to vertical, for a newly created document.
    
    This went wrong with commit 526c8bdb54eff942d5213030d1455f97720a1ba7
    (sw: fix too long inner borders intersecting with outer borders for Word
    cells, 2022-01-06), which forgot to make changes in
    SwTabFramePainter::Insert() conditional on bWordTableCell.
    
    Fix the problem by making the SwTabFramePainter::Insert() changes
    conditional, similar to how SwTabFramePainter::FindStylesForLine()
    already did this.
    
    Note how the DocumentSettingId::TABLE_ROW_KEEP compat setting is off for
    new documents.
    
    Change-Id: Ie29d1613251d869e7ae78ea7dab3e75f0e6de229
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146585
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx
index b413b1390e3f..829492c45cd9 100644
--- a/sw/qa/core/layout/layout.cxx
+++ b/sw/qa/core/layout/layout.cxx
@@ -16,6 +16,7 @@
 #include <o3tl/string_view.hxx>
 #include <sfx2/viewfrm.hxx>
 #include <sfx2/dispatch.hxx>
+#include <editeng/frmdiritem.hxx>
 
 #include <wrtsh.hxx>
 #include <docsh.hxx>
@@ -604,6 +605,68 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, 
testInnerCellBorderIntersect)
     CPPUNIT_ASSERT_LESS(aBorderStartEnds[0].second, 
aBorderStartEnds[1].second);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testInnerCellBorderNocompatIntersect)
+{
+    // Given a table with both outer and inner borders:
+    createSwDoc();
+    SwDocShell* pShell = getSwDocShell();
+    SwDoc* pDoc = pShell->GetDoc();
+    // Set the default page style's writing direction to vertical:
+    SwPageDesc aStandard(pDoc->GetPageDesc(0));
+    SvxFrameDirectionItem aDirection(SvxFrameDirection::Vertical_RL_TB, 
RES_FRAMEDIR);
+    aStandard.GetMaster().SetFormatAttr(aDirection);
+    pDoc->ChgPageDesc(0, aStandard);
+    // Insert a 4x4 table:
+    SwWrtShell* pWrtShell = pShell->GetWrtShell();
+    SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0);
+    pWrtShell->InsertTable(aTableOptions, 4, 4);
+
+    // When rendering table borders:
+    std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
+
+    // Then make sure that all horizontal lines have the same length:
+    MetafileXmlDump dumper;
+    xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
+    // Collect start/end (vertical) positions of horizontal borders.
+    xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, 
"//polyline[@style='solid']/point");
+    xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
+    std::vector<std::pair<sal_Int32, sal_Int32>> aBorderStartEnds;
+    for (int i = 0; i < xmlXPathNodeSetGetLength(pXmlNodes); i += 2)
+    {
+        xmlNodePtr pStart = pXmlNodes->nodeTab[i];
+        xmlNodePtr pEnd = pXmlNodes->nodeTab[i + 1];
+        xmlChar* pStartY = xmlGetProp(pStart, BAD_CAST("y"));
+        xmlChar* pEndY = xmlGetProp(pEnd, BAD_CAST("y"));
+        sal_Int32 nStartY = o3tl::toInt32(reinterpret_cast<char 
const*>(pStartY));
+        sal_Int32 nEndY = o3tl::toInt32(reinterpret_cast<char const*>(pEndY));
+        if (nStartY != nEndY)
+        {
+            // Vertical border.
+            continue;
+        }
+        xmlChar* pStartX = xmlGetProp(pStart, BAD_CAST("x"));
+        xmlChar* pEndX = xmlGetProp(pEnd, BAD_CAST("x"));
+        sal_Int32 nStartX = o3tl::toInt32(reinterpret_cast<char 
const*>(pStartX));
+        sal_Int32 nEndX = o3tl::toInt32(reinterpret_cast<char const*>(pEndX));
+        aBorderStartEnds.emplace_back(nStartX, nEndX);
+    }
+    xmlXPathFreeObject(pXmlObj);
+    // We have 5 lines: top of 4 cells + bottom.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(5), aBorderStartEnds.size());
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 9719
+    // - Actual  : 10064
+    // i.e. the 2nd line started later than the first one, which is incorrect.
+    CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].first, aBorderStartEnds[1].first);
+    CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].first, aBorderStartEnds[2].first);
+    CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].first, aBorderStartEnds[3].first);
+    CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].first, aBorderStartEnds[4].first);
+    CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].second, 
aBorderStartEnds[1].second);
+    CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].second, 
aBorderStartEnds[2].second);
+    CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].second, 
aBorderStartEnds[3].second);
+    CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].second, 
aBorderStartEnds[4].second);
+}
+
 CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testDoubleBorderVertical)
 {
     // Given a table with a left and right double border, outer is thick, 
inner is thin:
diff --git a/sw/source/core/layout/paintfrm.cxx 
b/sw/source/core/layout/paintfrm.cxx
index f8a0e62b7808..ad609ae5972a 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -2918,11 +2918,18 @@ void SwTabFramePainter::Insert( SwLineEntry& rNew, bool 
bHori )
     }
     SwLineEntrySet::iterator aIter = pLineSet->begin();
 
+    bool bWordTableCell = false;
+    SwViewShell* pShell = mrTabFrame.getRootFrame()->GetCurrShell();
+    if (pShell)
+    {
+        const IDocumentSettingAccess& rIDSA = 
pShell->GetDoc()->getIDocumentSettingAccess();
+        bWordTableCell = rIDSA.get(DocumentSettingId::TABLE_ROW_KEEP);
+    }
     while ( aIter != pLineSet->end() && rNew.mnStartPos < rNew.mnEndPos )
     {
         const SwLineEntry& rOld = *aIter;
 
-        if (rOld.mnLimitedEndPos || rOld.mbOuter != rNew.mbOuter)
+        if (rOld.mnLimitedEndPos || (bWordTableCell && (rOld.mbOuter != 
rNew.mbOuter)))
         {
             // Don't merge with this line entry as it ends sooner than 
mnEndPos.
             ++aIter;

Reply via email to