diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-03-04 11:52:58 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2021-03-04 12:49:18 +0100 |
commit | 66ac8e60896f6306bed8fbb34606fd14474f19ce (patch) | |
tree | f1da0c8db92a186914ecca40798d3cb3ab0bc70e /sw/qa | |
parent | 8fb25999f428fbc61240295b4065f4e76fd78a75 (diff) |
sw: fix unwanted long vertical border around vertically merged Word cell
In case cells A1 and A2 are vertically merged, they can still specify
different border properties for the two cells. Word draws the border
properties of the covered cells, while Writer ignores the formatting of
A2 in this case and only uses the properties of the covering cell.
Table cell border collapsing rules already differ in Word and Writer, so
SwTabFramePainter::Insert() knows if the table cell's border is
Word-style or not. Extend this code to handle vertically merged cells
better.
In general, this means a cell no longer has a fixed set of 4 borders,
but each edge may have several sub-borders. This commit is a step in
that direction, and handles the case when a vertical (left or right)
border style is set initially, but not set at the end -- as we iterate
through the list of cells in a vertical merge.
Change-Id: I35a05097ce70243099307ce8066766aef61a2bc5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111954
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'sw/qa')
-rw-r--r-- | sw/qa/core/layout/data/vmerge-cell-border.docx | bin | 0 -> 13610 bytes | |||
-rw-r--r-- | sw/qa/core/layout/layout.cxx | 74 |
2 files changed, 74 insertions, 0 deletions
diff --git a/sw/qa/core/layout/data/vmerge-cell-border.docx b/sw/qa/core/layout/data/vmerge-cell-border.docx Binary files differnew file mode 100644 index 000000000000..11d7a76d22ec --- /dev/null +++ b/sw/qa/core/layout/data/vmerge-cell-border.docx diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx index 59af4962263f..7c899aa31d63 100644 --- a/sw/qa/core/layout/layout.cxx +++ b/sw/qa/core/layout/layout.cxx @@ -389,6 +389,80 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testGutterMarginPageBorder) #endif } +CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testVerticallyMergedCellBorder) +{ + // Given a document with a table: 2 columns, 5 rows. B2 -> B5 is merged: + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "vmerge-cell-border.docx"); + SwDocShell* pShell = pDoc->GetDocShell(); + + // When rendering the table: + std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile(); + + // Make sure that B4->B5 has no borders. + MetafileXmlDump dumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile); + // Collect vertical positions of all border points. + xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "//polyline[@style='solid']/point"); + xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval; + std::vector<sal_Int32> aBorderPositions; + for (int i = 0; i < xmlXPathNodeSetGetLength(pXmlNodes); ++i) + { + xmlNodePtr pXmlNode = pXmlNodes->nodeTab[i]; + xmlChar* pValue = xmlGetProp(pXmlNode, BAD_CAST("y")); + sal_Int32 nValue = OString(reinterpret_cast<char const*>(pValue)).toInt32(); + aBorderPositions.push_back(nValue); + } + xmlXPathFreeObject(pXmlObj); + // Collect top and bottom of the B1->B3 rows. + xmlDocUniquePtr pLayout = parseLayoutDump(); + pXmlObj = getXPathNode(pLayout, "//tab/row/infos/bounds"); + pXmlNodes = pXmlObj->nodesetval; + std::vector<sal_Int32> aLayoutPositions; + for (int i = 0; i < 3; ++i) + { + xmlNodePtr pXmlNode = pXmlNodes->nodeTab[i]; + if (i == 0) + { + xmlChar* pValue = xmlGetProp(pXmlNode, BAD_CAST("top")); + sal_Int32 nValue = OString(reinterpret_cast<char const*>(pValue)).toInt32(); + aLayoutPositions.push_back(nValue); + } + xmlChar* pValue = xmlGetProp(pXmlNode, BAD_CAST("bottom")); + sal_Int32 nValue = OString(reinterpret_cast<char const*>(pValue)).toInt32(); + aLayoutPositions.push_back(nValue); + } + xmlXPathFreeObject(pXmlObj); + // Check if any border is outside the B1->B3 range. + for (const auto nBorderPosition : aBorderPositions) + { + bool bFound = false; + for (const auto nLayoutPosition : aLayoutPositions) + { + if (std::abs(nBorderPosition - nLayoutPosition) <= 15) + { + bFound = true; + break; + } + } + std::stringstream ss; + ss << "Bad vertical position for border point: " << nBorderPosition; + ss << " Expected positions: "; + for (size_t i = 0; i < aLayoutPositions.size(); ++i) + { + if (i > 0) + { + ss << ", "; + } + ss << aLayoutPositions[i]; + } + + // Without the accompanying fix in place, this test would have failed with: + // - Bad vertical position for border point: 5624 Expected positions: 3022, 3540, 4059, 4578 + // i.e. the middle vertical border end was the bottom of B5, not bottom of B3. + CPPUNIT_ASSERT_MESSAGE(ss.str(), bFound); + } +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |