From 66ac8e60896f6306bed8fbb34606fd14474f19ce Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 4 Mar 2021 11:52:58 +0100 Subject: 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 Tested-by: Jenkins --- sw/qa/core/layout/data/vmerge-cell-border.docx | Bin 0 -> 13610 bytes sw/qa/core/layout/layout.cxx | 74 +++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 sw/qa/core/layout/data/vmerge-cell-border.docx (limited to 'sw/qa') diff --git a/sw/qa/core/layout/data/vmerge-cell-border.docx b/sw/qa/core/layout/data/vmerge-cell-border.docx new file mode 100644 index 000000000000..11d7a76d22ec Binary files /dev/null and b/sw/qa/core/layout/data/vmerge-cell-border.docx differ 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 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 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(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 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(pValue)).toInt32(); + aLayoutPositions.push_back(nValue); + } + xmlChar* pValue = xmlGetProp(pXmlNode, BAD_CAST("bottom")); + sal_Int32 nValue = OString(reinterpret_cast(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: */ -- cgit