cid#1640468 Dereference after null check
[LibreOffice.git] / sd / qa / unit / layout-tests.cxx
blob57baf576c8c52d4c4f4ab5f8fa2a00921fdc5626
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 */
9 #include <test/unoapixml_test.hxx>
11 #include <sfx2/objsh.hxx>
12 #include <sfx2/sfxbasemodel.hxx>
14 class SdLayoutTest : public UnoApiXmlTest
16 public:
17 SdLayoutTest()
18 : UnoApiXmlTest(u"/sd/qa/unit/data/"_ustr)
22 xmlDocUniquePtr load(const char* pName)
24 loadFromFile(OUString::createFromAscii(pName));
25 SfxBaseModel* pModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
26 CPPUNIT_ASSERT(pModel);
27 SfxObjectShell* pShell = pModel->GetObjectShell();
28 std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
29 MetafileXmlDump dumper;
31 xmlDocUniquePtr pXmlDoc = XmlTestTools::dumpAndParse(dumper, *xMetaFile);
32 CPPUNIT_ASSERT(pXmlDoc);
34 return pXmlDoc;
38 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf104722)
40 xmlDocUniquePtr pXmlDoc = load("pptx/tdf104722.pptx");
42 // Without the fix in place, this would have failed with
43 // - Expected: 2093
44 // - Actual : -10276
45 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]", "x", u"2093");
47 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]", "y", u"9273");
50 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf135843)
52 xmlDocUniquePtr pXmlDoc = load("pptx/tdf135843.pptx");
54 // Without the fix, the test fails with:
55 // - Expected: 21165
56 // - Actual : 4218
57 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[5]/polyline[1]/point[1]", "x", u"21165");
58 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[5]/polyline[1]/point[1]", "y", u"3866");
60 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[5]/polyline[1]/point[2]", "x", u"21165");
61 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[5]/polyline[1]/point[2]", "y", u"5956");
64 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf146876)
66 xmlDocUniquePtr pXmlDoc = load("odp/tdf146876.odp");
68 // Check the shape is inside the (5000,8500) - (11500,12500) area
69 for (size_t i = 2; i < 4; ++i)
71 for (size_t j = 1; j < 6; ++j)
73 const OString xPath = "/metafile/push[1]/push[1]/push[" + OString::number(i)
74 + "]/polyline/point[" + OString::number(j) + "]";
75 const sal_Int32 nX = getXPath(pXmlDoc, xPath, "x").toInt32();
76 const sal_Int32 nY = getXPath(pXmlDoc, xPath, "y").toInt32();
78 // Without the fix in place, this test would have failed with
79 // - Expected greater or equal than: 5000
80 // - Actual : 0
81 CPPUNIT_ASSERT_GREATEREQUAL(sal_Int32(5000), nX);
82 CPPUNIT_ASSERT_LESSEQUAL(sal_Int32(11500), nX);
84 CPPUNIT_ASSERT_GREATEREQUAL(sal_Int32(8500), nY);
85 CPPUNIT_ASSERT_LESSEQUAL(sal_Int32(12500), nY);
90 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf136949)
92 xmlDocUniquePtr pXmlDoc = load("odp/tdf136949.odp");
94 // Without the fix in place, this test would have failed with
95 // - Expected: 13687
96 // - Actual : 2832
97 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[7]/polyline/point[1]", "x", u"13687");
98 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[7]/polyline/point[2]", "x", u"24759");
101 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf128212)
103 xmlDocUniquePtr pXmlDoc = load("pptx/tdf128212.pptx");
105 // Without the fix in place, this test would have failed with
106 // - Expected: 7795
107 // - Actual : 12068
108 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray", "x", u"4523");
109 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray", "y", u"7795");
112 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testColumnsLayout)
114 // This tests a 2-column text box's layout
116 const OUString sText[] = {
117 u"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat mi quis "
118 "pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolor posuere. "
119 "Curabitur dignissim sapien quis cursus egestas. Donec blandit auctor arcu, nec "
120 "pellentesque eros molestie eget. In consectetur aliquam hendrerit. Sed cursus mauris "
121 "vitae ligula pellentesque, non pellentesque urna aliquet. Fusce placerat mauris enim, "
122 "nec rutrum purus semper vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce "
123 "pellentesque est orci."_ustr,
124 u"Integer sodales tincidunt tristique. Sed a metus posuere, adipiscing nunc et, viverra "
125 "odio. Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. Cras sodales "
126 "nisl sed orci mattis iaculis. Nunc eget dolor accumsan, pharetra risus a, vestibulum "
127 "mauris. Nunc vulputate lobortis mollis. Vivamus nec tellus faucibus, tempor magna nec, "
128 "facilisis felis. Donec commodo enim a vehicula pellentesque. Nullam vehicula vestibulum "
129 "est vel ultricies."_ustr,
130 u"Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu "
131 "ut diam tempor luctus. Cum sociis natoque penatibus et magnis dis parturient montes, "
132 "nascetur ridiculus mus. Praesent vitae lacus vel leo sodales pharetra a a nibh. "
133 "Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; "
134 "Nam luctus tempus nibh, fringilla dictum augue consectetur eget. Curabitur at ante sit "
135 "amet tortor pharetra molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin "
136 "molestie, dolor sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est "
137 "elementum, euismod nulla in, mollis nunc."_ustr
140 // sentence#, index, length, x, y
141 const std::tuple<int, int, int, int, int> strings[] = {
142 // Column 1
143 { 0, 0, 40, 3750, 3193 },
144 { 0, 40, 41, 3750, 3587 },
145 { 0, 81, 39, 3750, 3981 },
146 { 0, 120, 33, 3750, 4375 },
147 { 0, 153, 35, 3750, 4769 },
148 { 0, 188, 34, 3750, 5163 },
149 { 0, 222, 38, 3750, 5557 },
150 { 0, 260, 35, 3750, 5951 },
151 { 0, 295, 37, 3750, 6345 },
152 { 0, 332, 31, 3750, 6739 },
153 { 0, 363, 33, 3750, 7133 },
154 { 0, 396, 39, 3750, 7527 },
155 { 0, 435, 37, 3750, 7921 },
156 { 0, 472, 32, 3750, 8315 },
157 { 0, 504, 22, 3750, 8709 },
158 { 1, 0, 43, 3750, 9103 },
159 { 1, 43, 35, 3750, 9497 },
160 { 1, 78, 36, 3750, 9891 },
161 { 1, 114, 41, 3750, 10285 },
162 { 1, 155, 39, 3750, 10679 },
163 { 1, 194, 35, 3750, 11073 },
164 { 1, 229, 37, 3750, 11467 },
165 { 1, 266, 40, 3750, 11861 },
166 { 1, 306, 39, 3750, 12255 },
167 { 1, 345, 38, 3750, 12649 },
168 { 1, 383, 39, 3750, 13043 },
169 { 1, 422, 29, 3750, 13437 },
170 { 2, 0, 42, 3750, 13831 },
171 { 2, 42, 41, 3750, 14225 },
172 { 2, 83, 39, 3750, 14619 },
173 { 2, 122, 32, 3750, 15013 },
174 { 2, 154, 38, 3750, 15407 },
175 { 2, 192, 34, 3750, 15801 },
176 { 2, 226, 38, 3750, 16195 },
177 // Column 2
178 { 2, 264, 42, 10725, 3193 },
179 { 2, 306, 39, 10725, 3587 },
180 { 2, 345, 37, 10725, 3981 },
181 { 2, 382, 37, 10725, 4375 },
182 { 2, 419, 42, 10725, 4769 },
183 { 2, 461, 36, 10725, 5163 },
184 { 2, 497, 36, 10725, 5557 },
185 { 2, 533, 40, 10725, 5951 },
186 { 2, 573, 35, 10725, 6345 },
187 { 2, 608, 30, 10725, 6739 },
190 xmlDocUniquePtr pXmlDoc = load("odg/two_columns.odg");
192 for (size_t i = 0; i < SAL_N_ELEMENTS(strings); ++i)
194 const auto & [ sentence, index, length, x, y ] = strings[i];
195 OString sXPath = "/metafile/push[1]/push[1]/textarray[" + OString::number(i + 1) + "]";
196 assertXPathContent(pXmlDoc, sXPath + "/text", sText[sentence]);
197 assertXPath(pXmlDoc, sXPath, "index", OUString::number(index));
198 assertXPath(pXmlDoc, sXPath, "length", OUString::number(length));
199 assertXPath(pXmlDoc, sXPath, "x", OUString::number(x));
200 assertXPath(pXmlDoc, sXPath, "y", OUString::number(y));
204 CPPUNIT_TEST_FIXTURE(SdLayoutTest, tdf143258_testTbRlLayout)
206 // This tests a 1-column and a 2-column text boxes' layout
208 const OUString sText[] = {
209 u"tb-rl text within a small text box"_ustr, // Box 1
210 u"tb-rl text within a small 2-column text box"_ustr, // Box 2
213 // sentence#, index, length, x, y
214 const std::tuple<int, int, int, int, int> strings[] = {
215 // Box 1
216 { 0, 0, 11, 5346, 3250 },
217 { 0, 11, 9, 4635, 3250 },
218 { 0, 20, 6, 3924, 3250 },
219 { 0, 26, 8, 3213, 3250 },
220 // Box 2 column 1
221 { 1, 0, 6, 5346, 7250 },
222 { 1, 6, 5, 4635, 7250 },
223 { 1, 11, 7, 3924, 7250 },
224 { 1, 18, 8, 3213, 7250 },
225 // Box 2 column 2
226 { 1, 26, 2, 5346, 9600 },
227 { 1, 28, 7, 4635, 9600 },
228 { 1, 35, 5, 3924, 9600 },
229 { 1, 40, 3, 3213, 9600 },
232 xmlDocUniquePtr pXmlDoc = load("odg/tb-rl-textbox.odg");
234 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/font", SAL_N_ELEMENTS(strings));
235 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray", SAL_N_ELEMENTS(strings));
236 for (size_t i = 0; i < SAL_N_ELEMENTS(strings); ++i)
238 const auto & [ sentence, index, length, x, y ] = strings[i];
239 OString sXPath = "/metafile/push[1]/push[1]/font[" + OString::number(i + 1) + "]";
240 assertXPath(pXmlDoc, sXPath, "orientation", u"-900");
241 assertXPath(pXmlDoc, sXPath, "vertical", u"true");
242 sXPath = "/metafile/push[1]/push[1]/textarray[" + OString::number(i + 1) + "]";
243 assertXPathContent(pXmlDoc, sXPath + "/text", sText[sentence]);
244 assertXPath(pXmlDoc, sXPath, "index", OUString::number(index));
245 assertXPath(pXmlDoc, sXPath, "length", OUString::number(length));
247 // Without the fix in place, this would have failed with
248 // - Expected: 5346
249 // - Actual : 503924
250 // - In <>, attribute 'x' of '/metafile/push[1]/push[1]/textarray[1]' incorrect value.
251 assertXPath(pXmlDoc, sXPath, "x", OUString::number(x));
252 assertXPath(pXmlDoc, sXPath, "y", OUString::number(y));
256 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf146731)
258 xmlDocUniquePtr pXmlDoc = load("pptx/tdf146731.pptx");
260 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[3]/polyline[1]", "width", u"187");
261 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[4]/polyline[1]", "width", u"187");
262 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[5]/polyline[1]", "width", u"187");
264 // Without the fix in place, this test would have failed with
265 // - Expected: 30
266 // - Actual : 187
267 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[6]/polyline[1]", "width", u"30");
268 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[7]/polyline[1]", "width", u"187");
271 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf135843_InsideHBorders)
273 xmlDocUniquePtr pXmlDoc = load("pptx/tdf135843_insideH.pptx");
275 // Without the fix, the test fails with:
276 //- Expected: 34
277 //- Actual : 36
278 // We shouldn't see two vertical borders inside the table on ui.
280 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push", 34);
283 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testBnc480256)
285 xmlDocUniquePtr pXmlDoc = load("pptx/bnc480256-2.pptx");
287 // Without the fix, the test fails with:
288 //- Expected: #ff0000
289 //- Actual : #ffffff
290 // We should see the red vertical border inside the table.
292 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[8]/linecolor[1]", "color", u"#ff0000");
295 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testFitToFrameTextFitting)
297 // This test checks that the text fitting is working correctly when
298 // the textbox is set to "fit to frame" by stretching the text to or
299 // near the textbox boundary. The problem is especially complicated
300 // when the font size is set to a higher number (like 999)
302 // The text fitting behaviour when "fit by frame" is enabled is to
303 // always fit the text into the text box (without forcing the text
304 // into new line) by shrinking or expanding the text horizontally
305 // and vertically.
307 xmlDocUniquePtr pXmlDoc = load("odg/FitToFrameText.odg");
309 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]", "x", u"0");
310 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]", "y", u"406");
311 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]/dxarray", "first", u"114");
312 #ifndef _WIN32 // Windows seems to differ in text layouting, so ignore for now
313 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]/dxarray", "last", u"6984");
314 #endif
317 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf156955)
319 xmlDocUniquePtr pXmlDoc = load("odp/tdf156955.odp");
321 // Make sure text box has the right size - without the fix it was 2759.
322 assertXPath(pXmlDoc, "/metafile/push/push/textarray[5]", "y", u"3183");
325 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf148966)
327 // Test related to IgnoreBreakAfterMultilineField compatibility flag.
329 xmlDocUniquePtr pXmlDoc = load("pptx/tdf148966.pptx");
330 // Without the accompanying fix, would fail with:
331 // - Expected: 5952
332 // - Actual : 7814
333 // i.e. Line break after multiline field should have been ignored.
334 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[3]", "y", u"5952");
337 xmlDocUniquePtr pXmlDoc = load("odp/tdf148966-withflag.odp");
338 // Without the accompanying fix, would fail with:
339 // - Expected: 5952
340 // - Actual : 7814
341 // i.e. When IgnoreBreakAfterMultilineField flag is set, line break
342 // after multiline field should have been ignored.
343 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[3]", "y", u"5952");
346 xmlDocUniquePtr pXmlDoc = load("odp/tdf148966-withoutflag.odp");
347 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[3]", "y", u"7814");
351 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTableVerticalText)
353 xmlDocUniquePtr pXmlDoc = load("pptx/tcPr-vert-roundtrip.pptx");
355 // Without the accompanying fix, would fail with:
356 // - Expected: -900
357 // - Actual : 0
358 // - In <>, attribute 'orientation' of '//font[1]' incorrect value.
359 // i.e. table cell text that was supposed to be vertical (rotated 90
360 // degrees) was not vertical.
361 assertXPath(pXmlDoc, "//font[1]", "orientation", u"-900");
362 assertXPath(pXmlDoc, "//font[2]", "orientation", u"900");
365 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf112594)
367 xmlDocUniquePtr pXmlDoc = load("odp/Tdf112594.fodp");
369 // Test that a NNBSP is grouped with the Mongolian characters after it, so
370 // we have two text arrays, one covering the digits, and the other with the rest.
371 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[3]", "index", u"0");
372 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[3]", "length", u"2");
373 assertXPathContent(pXmlDoc, "/metafile/push[1]/push[1]/textarray[3]/text", u"11\u202f\u1824");
374 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[4]", "index", u"2");
375 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[4]", "length", u"2");
376 assertXPathContent(pXmlDoc, "/metafile/push[1]/push[1]/textarray[4]/text", u"11\u202f\u1824");
379 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf152906_AdjustToContour)
381 // Test that the text adjusts to contour properly
383 static constexpr OUString sText
384 = u"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat mi quis "
385 "pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolor posuere. "
386 "Curabitur dignissim sapien quis cursus egestas. Donec blandit auctor arcu, nec "
387 "pellentesque eros molestie eget. In consectetur aliquam hendrerit. Sed cursus mauris "
388 "vitae ligula pellentesque, non pellentesque urna aliquet. Fusce placerat mauris enim, "
389 "nec rutrum purus semper vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce "
390 "pellentesque est orci."_ustr;
392 // index, length, x, y
393 const std::tuple<int, int, int, int> strings[] = {
394 { 0, 6, 9600, 8647 }, // Lorem
395 { 6, 22, 7570, 9358 }, // ipsum dolor sit amet,
396 { 28, 29, 6776, 10069 }, // consectetur adipiscing elit.
397 { 57, 29, 6299, 10780 }, // Vestibulum consequat mi quis
398 { 86, 37, 5453, 11491 }, // pretium semper. Proin luctus orci ac
399 { 123, 36, 5134, 12202 }, // neque venenatis, quis commodo dolor
400 { 159, 41, 4764, 12913 }, // posuere. Curabitur dignissim sapien quis
401 { 200, 43, 4481, 13624 }, // cursus egestas. Donec blandit auctor arcu,
402 { 243, 40, 4975, 14335 }, // nec pellentesque eros molestie eget. In
403 { 283, 42, 4552, 15046 }, // consectetur aliquam hendrerit. Sed cursus
404 { 325, 38, 5363, 15757 }, // mauris vitae ligula pellentesque, non
405 { 363, 42, 4693, 16468 }, // pellentesque urna aliquet. Fusce placerat
406 { 405, 37, 5047, 17179 }, // mauris enim, nec rutrum purus semper
407 { 442, 33, 5963, 17890 }, // vel. Praesent tincidunt neque eu
408 { 475, 29, 6387, 18601 }, // pellentesque pharetra. Fusce
409 { 504, 22, 7499, 19312 }, // pellentesque est orci.
412 xmlDocUniquePtr pXmlDoc = load("odg/adjust-to-contour.fodg");
414 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray", std::size(strings));
415 for (size_t i = 0; i < std::size(strings); ++i)
417 const auto & [ index, length, x, y ] = strings[i];
418 OString sXPath = "/metafile/push[1]/push[1]/textarray[" + OString::number(i + 1) + "]";
419 assertXPathContent(pXmlDoc, sXPath + "/text", sText);
420 assertXPath(pXmlDoc, sXPath, "index", OUString::number(index));
421 assertXPath(pXmlDoc, sXPath, "length", OUString::number(length));
422 assertXPath(pXmlDoc, sXPath, "x", OUString::number(x));
423 assertXPath(pXmlDoc, sXPath, "y", OUString::number(y));
427 CPPUNIT_PLUGIN_IMPLEMENT();
429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */