Upgrade mdds to 3.0.0 and liborcus to 0.20.0
[LibreOffice.git] / sw / qa / core / layout / paintfrm.cxx
blobcddb43f4b80ddb45eeda8e132d39e53106e57918
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <swmodeltestbase.hxx>
12 #include <o3tl/string_view.hxx>
13 #include <svtools/DocumentToGraphicRenderer.hxx>
15 #include <docsh.hxx>
16 #include <unotxdoc.hxx>
18 namespace
20 /// Covers sw/source/core/layout/paintfrm.cxx fixes.
21 class Test : public SwModelTestBase
23 public:
24 Test()
25 : SwModelTestBase(u"/sw/qa/core/layout/data/"_ustr)
30 CPPUNIT_TEST_FIXTURE(Test, testSplitTableBorder)
32 // Given a document with a split table, table borders are defined, but cell borders are not:
33 createSwDoc("split-table-border.odt");
34 SwDocShell* pShell = getSwDocShell();
36 // When rendering that document:
37 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
39 // Then make sure that the master table has a bottom border and the follow table has a top
40 // border:
41 MetafileXmlDump aDumper;
42 xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
43 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "//polyline[@style='solid']/point");
44 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
45 int nHorizontalBorders = 0;
46 // Count the horizontal borders:
47 for (int i = 0; i < xmlXPathNodeSetGetLength(pXmlNodes); i += 2)
49 xmlNodePtr pStart = pXmlNodes->nodeTab[i];
50 xmlNodePtr pEnd = pXmlNodes->nodeTab[i + 1];
51 xmlChar* pStartY = xmlGetProp(pStart, BAD_CAST("y"));
52 xmlChar* pEndY = xmlGetProp(pEnd, BAD_CAST("y"));
53 sal_Int32 nStartY = o3tl::toInt32(reinterpret_cast<char const*>(pStartY));
54 sal_Int32 nEndY = o3tl::toInt32(reinterpret_cast<char const*>(pEndY));
55 if (nStartY != nEndY)
57 // Vertical border.
58 continue;
61 ++nHorizontalBorders;
63 xmlXPathFreeObject(pXmlObj);
64 // Without the accompanying fix in place, this test would have failed with:
65 // - Expected: 4
66 // - Actual : 2
67 // i.e. the bottom border in the master table and the top border in the follow table were
68 // missing.
69 CPPUNIT_ASSERT_EQUAL(4, nHorizontalBorders);
72 CPPUNIT_TEST_FIXTURE(Test, testRTLBorderMerge)
74 // Given a document with an RTL table:
75 createSwDoc("rtl-table.docx");
76 SwDocShell* pShell = getSwDocShell();
78 // When rendering that document:
79 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
81 // Then make sure the 5 columns all have left and right vertical borders:
82 MetafileXmlDump aDumper;
83 xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
84 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "//polyline[@style='solid']/point");
85 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
86 int nVerticalBorders = 0;
87 // Count the vertical borders:
88 for (int i = 0; i < xmlXPathNodeSetGetLength(pXmlNodes); i += 2)
90 xmlNodePtr pStart = pXmlNodes->nodeTab[i];
91 xmlNodePtr pEnd = pXmlNodes->nodeTab[i + 1];
92 xmlChar* pStartY = xmlGetProp(pStart, BAD_CAST("y"));
93 xmlChar* pEndY = xmlGetProp(pEnd, BAD_CAST("y"));
94 sal_Int32 nStartY = o3tl::toInt32(reinterpret_cast<char const*>(pStartY));
95 sal_Int32 nEndY = o3tl::toInt32(reinterpret_cast<char const*>(pEndY));
96 if (nStartY == nEndY)
98 // Horizontal border.
99 continue;
102 ++nVerticalBorders;
104 xmlXPathFreeObject(pXmlObj);
105 // Without the accompanying fix in place, this test would have failed with:
106 // - Expected: 6
107 // - Actual : 4
108 // i.e. the 2nd and 5th vertical border was missing.
109 CPPUNIT_ASSERT_EQUAL(6, nVerticalBorders);
112 CPPUNIT_TEST_FIXTURE(Test, testSplitTableMergedBorder)
114 // Given a document with a split table, first row in frame 1 has merged cells:
115 createSwDoc("split-table-merged-border.odt");
116 SwDocShell* pShell = getSwDocShell();
118 // When rendering that document:
119 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
121 // Then make sure that the master table has a bottom border with the correct widths:
122 MetafileXmlDump aDumper;
123 xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
124 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "//polyline[@style='solid']/point");
125 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
126 std::set<int> aHorizontalBorderStarts;
127 std::set<int> aHorizontalBorderEnds;
128 // Collect the horizontal borders:
129 for (int i = 0; i < xmlXPathNodeSetGetLength(pXmlNodes); i += 2)
131 xmlNodePtr pStart = pXmlNodes->nodeTab[i];
132 xmlNodePtr pEnd = pXmlNodes->nodeTab[i + 1];
133 xmlChar* pStartY = xmlGetProp(pStart, BAD_CAST("y"));
134 xmlChar* pEndY = xmlGetProp(pEnd, BAD_CAST("y"));
135 sal_Int32 nStartY = o3tl::toInt32(reinterpret_cast<char const*>(pStartY));
136 sal_Int32 nEndY = o3tl::toInt32(reinterpret_cast<char const*>(pEndY));
137 if (nStartY != nEndY)
139 // Vertical border.
140 continue;
143 xmlChar* pStartX = xmlGetProp(pStart, BAD_CAST("x"));
144 xmlChar* pEndX = xmlGetProp(pEnd, BAD_CAST("x"));
145 sal_Int32 nStartX = o3tl::toInt32(reinterpret_cast<char const*>(pStartX));
146 sal_Int32 nEndX = o3tl::toInt32(reinterpret_cast<char const*>(pEndX));
147 aHorizontalBorderStarts.insert(nStartX);
148 aHorizontalBorderEnds.insert(nEndX);
150 xmlXPathFreeObject(pXmlObj);
151 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aHorizontalBorderStarts.size());
152 // Without the accompanying fix in place, this test would have failed with:
153 // - Expected: 2
154 // - Actual : 3
155 // i.e. the frame 1 bottom border ended sooner than expected, resulting in a buggy, partial
156 // bottom border.
157 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aHorizontalBorderEnds.size());
160 CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSeparatorPosition)
162 // Given a document with a Word-style endnote separator:
163 createSwDoc("inline-endnote-position.docx");
164 SwDocShell* pDocShell = getSwDocShell();
166 // When rendering that document:
167 std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();
169 // Then make sure the separator upper spacing is 60% of all space, matching Word:
170 MetafileXmlDump aDumper;
171 xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
172 auto nEndnoteSeparatorY = getXPath(pXmlDoc, "//polygon/point[1]", "y").toInt32();
173 // Without the accompanying fix in place, this test would have failed with:
174 // - Expected: 2164
175 // - Actual : 2060
176 // i.e. the upper spacing was too low.
177 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2164), nEndnoteSeparatorY);
179 // Also make sure the separator length is correct:
180 auto nEndnoteSeparatorStart = getXPath(pXmlDoc, "//polygon/point[1]", "x").toInt32();
181 auto nEndnoteSeparatorEnd = getXPath(pXmlDoc, "//polygon/point[2]", "x").toInt32();
182 sal_Int32 nEndnoteSeparatorLength = nEndnoteSeparatorEnd - nEndnoteSeparatorStart;
183 // Without the accompanying fix in place, this test would have failed with:
184 // - Expected: 2880
185 // - Actual : 2340
186 // i.e. the separator wasn't 2 inches long, but was shorter vs Word.
187 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2880), nEndnoteSeparatorLength);
190 CPPUNIT_TEST_FIXTURE(Test, testEndnoteContSeparator)
192 // Given a document with a Word-style endnote continuation separator:
193 createSwDoc("endnote-cont-separator.docx");
195 // When rendering page 2:
196 sal_Int32 nPage = 2;
197 DocumentToGraphicRenderer aRenderer(mxComponent, /*bSelectionOnly=*/false);
198 Size aSize = aRenderer.getDocumentSizeInPixels(nPage);
199 Graphic aGraphic = aRenderer.renderToGraphic(nPage, aSize, aSize, COL_WHITE,
200 /*bExtOutDevData=*/false);
201 auto& xMetaFile = const_cast<GDIMetaFile&>(aGraphic.GetGDIMetaFile());
203 // Then make sure the separator length is correct:
204 MetafileXmlDump aDumper;
205 xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, xMetaFile);
206 auto nEndnoteSeparatorStart = getXPath(pXmlDoc, "//polygon/point[1]", "x").toInt32();
207 auto nEndnoteSeparatorEnd = getXPath(pXmlDoc, "//polygon/point[2]", "x").toInt32();
208 sal_Int32 nEndnoteSeparatorLength = nEndnoteSeparatorEnd - nEndnoteSeparatorStart;
209 // Without the accompanying fix in place, this test would have failed with:
210 // - Expected: 9360 (page print area width)
211 // - Actual : 2880 (2 inches)
212 // i.e. the separator was too short vs Word.
213 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(9360), nEndnoteSeparatorLength);
217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */