summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-01-11 17:18:11 +0100
committerMike Kaganski <mike.kaganski@collabora.com>2022-02-11 09:20:32 +0100
commitc9cf688754ffccd785c8628a2e739e234ed4cd3b (patch)
treed345aac2de89399c0fa7f772459d8b81dc215079 /sw
parent0dbecd2d2ebe18a262cfab96e105637840b5b7fe (diff)
sw: fix swapped inner vs outer border for Word-style left table borders
The minimal DOCX bugdoc has a single cell, the left border style is thinThickMediumGap, the right border style is thickThinMediumGap, which means the doc model already has the left/right mirroring, don't have to do it at layout time. The normal Writer way is to have a single border style and mirror the right/bottom border line. But then looking at the Writer vs Word output, inner vs outer is swapped, so at the end we have to mirror the left border line for Word-style table borders to get compatible output. (cherry picked from commit fc04a84f297b78a1049182b6d8cf745f863ffe61) Change-Id: I10fb95dfac67e466188cfc9ecf35efde806c14b0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129767 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/core/layout/data/double-border-vertical.docxbin0 -> 12253 bytes
-rw-r--r--sw/qa/core/layout/layout.cxx48
-rw-r--r--sw/source/core/layout/paintfrm.cxx7
3 files changed, 55 insertions, 0 deletions
diff --git a/sw/qa/core/layout/data/double-border-vertical.docx b/sw/qa/core/layout/data/double-border-vertical.docx
new file mode 100644
index 000000000000..a4731ebec612
--- /dev/null
+++ b/sw/qa/core/layout/data/double-border-vertical.docx
Binary files differ
diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx
index 2b1dc8be0b3f..0358b2f0f359 100644
--- a/sw/qa/core/layout/layout.cxx
+++ b/sw/qa/core/layout/layout.cxx
@@ -578,6 +578,54 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testInnerCellBorderIntersect)
CPPUNIT_ASSERT_LESS(aBorderStartEnds[0].second, aBorderStartEnds[1].second);
}
+CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testDoubleBorderVertical)
+{
+ // Given a table with a left and right double border, outer is thick, inner is thin:
+ SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "double-border-vertical.docx");
+ SwDocShell* pShell = pDoc->GetDocShell();
+
+ // When rendering that document:
+ std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
+
+ // Then make sure the left border is thick+thin and the right border is thin+thick (from left to
+ // right):
+ MetafileXmlDump dumper;
+ xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
+ // Collect widths of vertical lines.
+ xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "//polyline[@style='solid']/point");
+ xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
+ // Horizontal position -> width.
+ std::map<sal_Int32, sal_Int32> aBorderWidths;
+ for (int i = 0; i < xmlXPathNodeSetGetLength(pXmlNodes); i += 2)
+ {
+ xmlNodePtr pStart = pXmlNodes->nodeTab[i];
+ xmlNodePtr pEnd = pXmlNodes->nodeTab[i + 1];
+ xmlChar* pStartX = xmlGetProp(pStart, BAD_CAST("x"));
+ xmlChar* pEndX = xmlGetProp(pEnd, BAD_CAST("x"));
+ sal_Int32 nStartX = OString(reinterpret_cast<char const*>(pStartX)).toInt32();
+ sal_Int32 nEndX = OString(reinterpret_cast<char const*>(pEndX)).toInt32();
+ if (nStartX != nEndX)
+ {
+ // Horizontal border.
+ continue;
+ }
+ xmlChar* pWidth = xmlGetProp(pStart->parent, BAD_CAST("width"));
+ sal_Int32 nWidth = OString(reinterpret_cast<char const*>(pWidth)).toInt32();
+ aBorderWidths[nStartX] = nWidth;
+ }
+ xmlXPathFreeObject(pXmlObj);
+ std::vector<sal_Int32> aBorderWidthVec;
+ std::transform(aBorderWidths.begin(), aBorderWidths.end(), std::back_inserter(aBorderWidthVec),
+ [](const std::pair<sal_Int32, sal_Int32>& rPair) { return rPair.second; });
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), aBorderWidthVec.size());
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected greater than: 120
+ // - Actual : 60
+ // i.e. the left border was thin+thick, not thick+thin.
+ CPPUNIT_ASSERT_GREATER(aBorderWidthVec[1], aBorderWidthVec[0]);
+ CPPUNIT_ASSERT_GREATER(aBorderWidthVec[2], aBorderWidthVec[3]);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 41cbb9c47e71..00d0000c8b81 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -2861,6 +2861,13 @@ void SwTabFramePainter::Insert(const SwFrame& rFrame, const SvxBoxItem& rBoxItem
// First cell in a row.
bool bOuter = rFrame.IsCellFrame() && rFrame.GetUpper()->GetLower() == &rFrame;
+
+ if (bWordTableCell && bOuter)
+ {
+ // First vs secondary and inner vs outer is the other way around in Word.
+ aL.MirrorSelf();
+ }
+
SwLineEntry aLeft (nLeft, nTop, nBottom, bOuter,
bVert ? aB : (bR2L ? aR : aL));
if (bWordTableCell && rBoxItem.GetLeft())