diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-02-01 15:17:40 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-02-02 09:09:48 +0100 |
commit | 60a1f07049a817d4d3d7beb6c9b9da2571e2463b (patch) | |
tree | 74b58403f9e16374fb4d6a6ff7dbfc77fe0abb4c | |
parent | 74bcd46bbf4cb88112b054e5b192a995f3ef354a (diff) |
sw: fix swapped inner vs outer border for Word-style right/bottom page borders
This is similar to commit cf2690ae76b4250af32be7c8980b8d83b3611591 (sw:
fix swapped inner vs outer border for Word-style bottom table borders,
2022-01-13), but that was for outer table borders, this one is for page
borders.
The explicit mirroring is needed because Writer will automatically
mirror, but Word mirrors in its document model, so we need to "mirror
back" to get the matching rendering.
Change-Id: I38fbf8adbc87ecd217a11b177840b0fede4cdf8c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129281
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/core/layout/data/double-page-border.docx | bin | 0 -> 12053 bytes | |||
-rw-r--r-- | sw/qa/core/layout/layout.cxx | 48 | ||||
-rw-r--r-- | sw/source/core/layout/paintfrm.cxx | 23 |
3 files changed, 66 insertions, 5 deletions
diff --git a/sw/qa/core/layout/data/double-page-border.docx b/sw/qa/core/layout/data/double-page-border.docx Binary files differnew file mode 100644 index 000000000000..a706b327cd05 --- /dev/null +++ b/sw/qa/core/layout/data/double-page-border.docx diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx index 8b8174d76941..a31646704cbd 100644 --- a/sw/qa/core/layout/layout.cxx +++ b/sw/qa/core/layout/layout.cxx @@ -694,6 +694,54 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testParaBorderInCellClip) assertXPath(pXmlDoc, "//clipregion/polygon", 2); } +CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testDoublePageBorder) +{ + // Given a page with a top and bottom double border, outer is thick, inner is thin: + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "double-page-border.docx"); + SwDocShell* pShell = pDoc->GetDocShell(); + + // When rendering that document: + std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile(); + + // Then make sure the top border is thick+thing and the bottom border is thin+thick (from top to + // bottom): + MetafileXmlDump dumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile); + // Collect widths of horizontal lines. + xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "//polyline[@style='solid']/point"); + xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval; + // Vertical 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* pStartY = xmlGetProp(pStart, BAD_CAST("y")); + xmlChar* pEndY = xmlGetProp(pEnd, BAD_CAST("y")); + sal_Int32 nStartY = OString(reinterpret_cast<char const*>(pStartY)).toInt32(); + sal_Int32 nEndY = OString(reinterpret_cast<char const*>(pEndY)).toInt32(); + if (nStartY != nEndY) + { + // Vertical border. + continue; + } + xmlChar* pWidth = xmlGetProp(pStart->parent, BAD_CAST("width")); + sal_Int32 nWidth = OString(reinterpret_cast<char const*>(pWidth)).toInt32(); + aBorderWidths[nStartY] = 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()); + CPPUNIT_ASSERT_GREATER(aBorderWidthVec[1], aBorderWidthVec[0]); + // Without the accompanying fix in place, this test would have failed with: + // - Expected greater than: 60 + // - Actual : 15 + // i.e. the bottom border was thick+thin, not thin+thick. + 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 868817ff5147..82601c6334f6 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -5360,14 +5360,14 @@ void SwFrame::PaintSwFrameShadowAndBorder( pBottomBorder = aAccess.Get()->GetBox().GetBottom(); } - bool bWordTableCell = false; + bool bWordBorder = false; SwViewShell* pShell = getRootFrame()->GetCurrShell(); if (pShell) { const IDocumentSettingAccess& rIDSA = pShell->GetDoc()->getIDocumentSettingAccess(); - bWordTableCell = rIDSA.get(DocumentSettingId::TABLE_ROW_KEEP); + bWordBorder = rIDSA.get(DocumentSettingId::TABLE_ROW_KEEP); } - bool bInWordTableCell = IsContentFrame() && GetUpper()->IsCellFrame() && bWordTableCell; + bool bInWordTableCell = IsContentFrame() && GetUpper()->IsCellFrame() && bWordBorder; if (bInWordTableCell) { // Compat mode: don't paint bottom border if we know the bottom of the content was cut @@ -5387,8 +5387,21 @@ void SwFrame::PaintSwFrameShadowAndBorder( aRect.Width(), aRect.Height(), aRect.Left(), aRect.Top())); const svx::frame::Style aStyleTop(pTopBorder, 1.0); - const svx::frame::Style aStyleRight(pRightBorder, 1.0); - const svx::frame::Style aStyleBottom(pBottomBorder, 1.0); + svx::frame::Style aStyleRight(pRightBorder, 1.0); + + // Right/bottom page borders are always mirrored in Word. + if (IsPageFrame() && bWordBorder) + { + aStyleRight.MirrorSelf(); + } + + svx::frame::Style aStyleBottom(pBottomBorder, 1.0); + + if (IsPageFrame() && bWordBorder) + { + aStyleBottom.MirrorSelf(); + } + const svx::frame::Style aStyleLeft(pLeftBorder, 1.0); drawinglayer::primitive2d::Primitive2DContainer aBorderLineTarget; |