Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sd / qa / unit / ShapeImportExportTest.cxx
blobb1008702ad22fa0b766a24e36f16e570db1630a0
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 "sdmodeltestbase.hxx"
12 #include <com/sun/star/uno/Reference.hxx>
14 #include <com/sun/star/drawing/XShapes.hpp>
16 #include <svx/svdpage.hxx>
17 #include <svx/svdotext.hxx>
19 using namespace css;
21 /// Shape / SdrObject import and export tests
22 class ShapeImportExportTest : public SdModelTestBase
24 public:
25 ShapeImportExportTest()
26 : SdModelTestBase("/sd/qa/unit/data/")
30 void testTextDistancesOOXML();
31 void testTextDistancesOOXML_LargerThanTextAreaSpecialCase();
32 void testTextDistancesOOXML_Export();
33 void testTextDistancesODP_OOXML_Export();
35 CPPUNIT_TEST_SUITE(ShapeImportExportTest);
36 CPPUNIT_TEST(testTextDistancesOOXML);
37 CPPUNIT_TEST(testTextDistancesOOXML_LargerThanTextAreaSpecialCase);
38 CPPUNIT_TEST(testTextDistancesOOXML_Export);
39 CPPUNIT_TEST(testTextDistancesODP_OOXML_Export);
40 CPPUNIT_TEST_SUITE_END();
43 namespace
45 SdrObject* searchObject(SdrPage const* pPage, std::u16string_view rName)
47 for (size_t i = 0; i < pPage->GetObjCount(); ++i)
49 SdrObject* pCurrent = pPage->GetObj(i);
50 if (pCurrent->GetName() == rName)
51 return pCurrent;
53 return nullptr;
57 /* Test text distances (insets) */
58 void ShapeImportExportTest::testTextDistancesOOXML()
60 createSdImpressDoc("TextDistancesInsets1.pptx");
62 SdrPage const* pPage = GetPage(1);
63 // Bottom Margin = 4cm
65 std::array<std::u16string_view, 3> aObjectDesc = {
66 u"T, BM - 4cm",
67 u"M, BM - 4cm",
68 u"B, BM - 4cm",
71 for (auto const& rString : aObjectDesc)
73 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rString));
74 CPPUNIT_ASSERT(pTextObj);
75 CPPUNIT_ASSERT_EQUAL(tools::Long(-1292), pTextObj->GetTextUpperDistance());
76 CPPUNIT_ASSERT_EQUAL(tools::Long(2708), pTextObj->GetTextLowerDistance());
80 // Bottom Margin = 1cm
82 std::array<std::u16string_view, 3> aObjectDesc = {
83 u"T, BM - 1cm",
84 u"M, BM - 1cm",
85 u"B, BM - 1cm",
88 for (auto const& rString : aObjectDesc)
90 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rString));
91 CPPUNIT_ASSERT(pTextObj);
92 CPPUNIT_ASSERT_EQUAL(tools::Long(0), pTextObj->GetTextUpperDistance());
93 CPPUNIT_ASSERT_EQUAL(tools::Long(1000), pTextObj->GetTextLowerDistance());
97 // Top + Bottom Margin = 1cm
99 std::array<std::u16string_view, 3> aObjectDesc = {
100 u"T, TM+BM - 1cm",
101 u"M, TM+BM - 1cm",
102 u"B, TM+BM - 1cm",
105 for (auto const& rString : aObjectDesc)
107 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rString));
108 CPPUNIT_ASSERT(pTextObj);
109 CPPUNIT_ASSERT_EQUAL(tools::Long(708), pTextObj->GetTextUpperDistance());
110 CPPUNIT_ASSERT_EQUAL(tools::Long(708), pTextObj->GetTextLowerDistance());
114 // No margin - Top + Bottom = 0cm
116 std::array<std::u16string_view, 3> aObjectDesc = {
117 u"T",
118 u"M",
119 u"B",
122 for (auto const& rString : aObjectDesc)
124 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rString));
125 CPPUNIT_ASSERT(pTextObj);
126 CPPUNIT_ASSERT_EQUAL(tools::Long(0), pTextObj->GetTextUpperDistance());
127 CPPUNIT_ASSERT_EQUAL(tools::Long(0), pTextObj->GetTextLowerDistance());
131 // Top Margin = 1cm
133 std::array<std::u16string_view, 3> aObjectDesc = {
134 u"T, TM - 1cm",
135 u"M, TM - 1cm",
136 u"B, TM - 1cm",
139 for (auto const& rString : aObjectDesc)
141 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rString));
142 CPPUNIT_ASSERT(pTextObj);
143 CPPUNIT_ASSERT_EQUAL(tools::Long(1000), pTextObj->GetTextUpperDistance());
144 CPPUNIT_ASSERT_EQUAL(tools::Long(0), pTextObj->GetTextLowerDistance());
148 // Top Margin = 4cm
150 std::array<std::u16string_view, 3> aObjectDesc = {
151 u"T, TM - 4cm",
152 u"M, TM - 4cm",
153 u"B, TM - 4cm",
156 for (auto const& rString : aObjectDesc)
158 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rString));
159 CPPUNIT_ASSERT(pTextObj);
160 CPPUNIT_ASSERT_EQUAL(tools::Long(2708), pTextObj->GetTextUpperDistance());
161 CPPUNIT_ASSERT_EQUAL(tools::Long(-1292), pTextObj->GetTextLowerDistance());
166 /* Test text distances (insets) variants where top+bottom margin > text area*/
167 void ShapeImportExportTest::testTextDistancesOOXML_LargerThanTextAreaSpecialCase()
169 createSdImpressDoc("TextDistancesInsets2.pptx");
171 SdrPage const* pPage = GetPage(1);
173 // Top/Bottom 0cm/3cm, 1cm/4cm, 4cm/7cm - all should be converted to the same value in LO
175 std::array<std::u16string_view, 9> aObjectNames = {
176 u"T_0_3", u"M_0_3", u"B_0_3", u"T_1_4", u"M_1_4",
177 u"B_1_4", u"T_4_7", u"M_4_7", u"B_4_7",
180 for (auto const& rName : aObjectNames)
182 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rName));
183 CPPUNIT_ASSERT(pTextObj);
184 CPPUNIT_ASSERT_EQUAL(tools::Long(-792), pTextObj->GetTextUpperDistance());
185 CPPUNIT_ASSERT_EQUAL(tools::Long(2208), pTextObj->GetTextLowerDistance());
189 // Top/Bottom 0cm/2cm, 1cm/3cm, 4cm/6cm - all should be converted to the same value in LO
191 std::array<std::u16string_view, 9> aObjectNames = {
192 u"T_0_2", u"M_0_2", u"B_0_2", u"T_1_3", u"M_1_3",
193 u"B_1_3", u"T_4_6", u"M_4_6", u"B_4_6",
196 for (auto const& rName : aObjectNames)
198 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rName));
199 CPPUNIT_ASSERT(pTextObj);
200 CPPUNIT_ASSERT_EQUAL(tools::Long(-292), pTextObj->GetTextUpperDistance());
201 CPPUNIT_ASSERT_EQUAL(tools::Long(1708), pTextObj->GetTextLowerDistance());
205 // Top/Bottom 2cm/2cm, 3cm/3cm, 4cm/4cm - all should be converted to the same value in LO
207 std::array<std::u16string_view, 9> aObjectNames = {
208 u"T_2_2", u"M_2_2", u"B_2_2", u"T_3_3", u"M_3_3",
209 u"B_3_3", u"T_4_4", u"M_4_4", u"B_4_4",
212 for (auto const& rName : aObjectNames)
214 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rName));
215 CPPUNIT_ASSERT(pTextObj);
216 CPPUNIT_ASSERT_EQUAL(tools::Long(708), pTextObj->GetTextUpperDistance());
217 CPPUNIT_ASSERT_EQUAL(tools::Long(708), pTextObj->GetTextLowerDistance());
221 // Top/Bottom 2cm/0cm, 3cm/1cm, 6cm/4cm - all should be converted to the same value in LO
223 std::array<std::u16string_view, 9> aObjectNames = {
224 u"T_2_0", u"M_2_0", u"B_2_0", u"T_3_1", u"M_3_1",
225 u"B_3_1", u"T_6_4", u"M_6_4", u"B_6_4",
228 for (auto const& rName : aObjectNames)
230 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rName));
231 CPPUNIT_ASSERT(pTextObj);
232 CPPUNIT_ASSERT_EQUAL(tools::Long(1708), pTextObj->GetTextUpperDistance());
233 CPPUNIT_ASSERT_EQUAL(tools::Long(-292), pTextObj->GetTextLowerDistance());
237 // Top/Bottom 3cm/0cm, 4cm/1cm, 7cm/4cm - all should be converted to the same value in LO
239 std::array<std::u16string_view, 9> aObjectNames = {
240 u"T_3_0", u"M_3_0", u"B_3_0", u"T_4_1", u"M_4_1",
241 u"B_4_1", u"T_7_4", u"M_7_4", u"B_7_4",
244 for (auto const& rName : aObjectNames)
246 auto* pTextObj = DynCastSdrTextObj(searchObject(pPage, rName));
247 CPPUNIT_ASSERT(pTextObj);
248 CPPUNIT_ASSERT_EQUAL(tools::Long(2208), pTextObj->GetTextUpperDistance());
249 CPPUNIT_ASSERT_EQUAL(tools::Long(-792), pTextObj->GetTextLowerDistance());
254 /* Test export of text distances (insets) - conversion back of special case */
255 void ShapeImportExportTest::testTextDistancesOOXML_Export()
257 createSdImpressDoc("TextDistancesInsets3.pptx");
259 save("Impress Office Open XML");
260 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
261 CPPUNIT_ASSERT(pXmlDoc);
263 //Check shape Top/Bottom - 0cm, 4cm
264 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[1]/p:nvSpPr/p:cNvPr", "name", "Text_TB_0_4");
265 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[1]/p:txBody/a:bodyPr",
266 { { "tIns", "-360000" }, { "bIns", "1079640" } });
268 //Check shape Top/Bottom - 4cm, 0cm
269 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:nvSpPr/p:cNvPr", "name", "Text_TB_4_0");
270 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:bodyPr",
271 { { "tIns", "1079640" }, { "bIns", "-360000" } });
273 //Check shape Top/Bottom - 0cm, 3cm
274 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[3]/p:nvSpPr/p:cNvPr", "name", "Text_TB_0_3");
275 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[3]/p:txBody/a:bodyPr",
276 { { "tIns", "-180000" }, { "bIns", "899640" } });
278 //Check shape Top/Bottom - 2cm, 1cm
279 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[4]/p:nvSpPr/p:cNvPr", "name", "Text_TB_2_1");
280 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[4]/p:txBody/a:bodyPr",
281 { { "tIns", "540000" }, { "bIns", "180000" } });
283 //Check shape Top/Bottom - 0cm, 2.5cm
284 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[5]/p:nvSpPr/p:cNvPr", "name",
285 "Text_TB_0_2.5");
286 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[5]/p:txBody/a:bodyPr",
287 { { "tIns", "-90000" }, { "bIns", "809640" } });
289 //Check shape Top/Bottom - 0cm, 2cm
290 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[6]/p:nvSpPr/p:cNvPr", "name", "Text_TB_0_2");
291 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[6]/p:txBody/a:bodyPr",
292 { { "tIns", "0" }, { "bIns", "720000" } });
294 //Check shape Top/Bottom - 0cm, 1.5cm
295 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[7]/p:nvSpPr/p:cNvPr", "name",
296 "Text_TB_0_1.5");
297 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[7]/p:txBody/a:bodyPr",
298 { { "tIns", "0" }, { "bIns", "540000" } });
300 //Check shape Top/Bottom - 3cm, 0cm
301 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[8]/p:nvSpPr/p:cNvPr", "name", "Text_TB_3_0");
302 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[8]/p:txBody/a:bodyPr",
303 { { "tIns", "899640" }, { "bIns", "-180000" } });
305 //Check shape Top/Bottom - 2.5cm, 0cm
306 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[9]/p:nvSpPr/p:cNvPr", "name",
307 "Text_TB_2.5_0");
308 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[9]/p:txBody/a:bodyPr",
309 { { "tIns", "809640" }, { "bIns", "-90000" } });
311 //Check shape Top/Bottom - 2cm, 0cm
312 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[10]/p:nvSpPr/p:cNvPr", "name", "Text_TB_2_0");
313 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[10]/p:txBody/a:bodyPr",
314 { { "tIns", "720000" }, { "bIns", "0" } });
316 //Check shape Top/Bottom - 1.5cm, 0cm
317 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[11]/p:nvSpPr/p:cNvPr", "name",
318 "Text_TB_1.5_0");
319 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[11]/p:txBody/a:bodyPr",
320 { { "tIns", "540000" }, { "bIns", "0" } });
322 //Check shape Top/Bottom - 1cm, 2cm
323 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[12]/p:nvSpPr/p:cNvPr", "name", "Text_TB_1_2");
324 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[12]/p:txBody/a:bodyPr",
325 { { "tIns", "180000" }, { "bIns", "540000" } });
327 //Check shape Top/Bottom - 2cm, 1.5cm
328 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[13]/p:nvSpPr/p:cNvPr", "name",
329 "Text_TB_2_1.5");
330 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[13]/p:txBody/a:bodyPr",
331 { { "tIns", "450000" }, { "bIns", "270000" } });
333 //Check shape Top/Bottom - 1.5cm, 2cm
334 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[14]/p:nvSpPr/p:cNvPr", "name",
335 "Text_TB_1.5_2");
336 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[14]/p:txBody/a:bodyPr",
337 { { "tIns", "270000" }, { "bIns", "450000" } });
339 //Check shape Top/Bottom - 2cm, 1.75cm
340 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[15]/p:nvSpPr/p:cNvPr", "name",
341 "Text_TB_2_1.75");
342 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[15]/p:txBody/a:bodyPr",
343 { { "tIns", "405000" }, { "bIns", "315000" } });
345 //Check shape Top/Bottom - 1.75cm, 2cm
346 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[16]/p:nvSpPr/p:cNvPr", "name",
347 "Text_TB_1.75_2");
348 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[16]/p:txBody/a:bodyPr",
349 { { "tIns", "315000" }, { "bIns", "405000" } });
351 //Check shape Top/Bottom - 2cm, 2cm
352 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[17]/p:nvSpPr/p:cNvPr", "name", "Text_TB_2_2");
353 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[17]/p:txBody/a:bodyPr",
354 { { "tIns", "360000" }, { "bIns", "360000" } });
356 //Check shape Top/Bottom - 1cm, 1cm
357 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[18]/p:nvSpPr/p:cNvPr", "name", "Text_TB_1_1");
358 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[18]/p:txBody/a:bodyPr",
359 { { "tIns", "360000" }, { "bIns", "360000" } });
361 //Check shape Top/Bottom - 0.5cm, 0.5cm
362 assertXPath(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[19]/p:nvSpPr/p:cNvPr", "name",
363 "Text_TB_0.5_0.5");
364 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[19]/p:txBody/a:bodyPr",
365 { { "tIns", "180000" }, { "bIns", "180000" } });
368 void ShapeImportExportTest::testTextDistancesODP_OOXML_Export()
370 createSdImpressDoc("odp/tdf150966_hugeInset.odp");
371 save("Impress Office Open XML");
372 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
373 CPPUNIT_ASSERT(pXmlDoc);
375 // The text ends 5cm below the top edge of the shape.
376 // Without the fix we exported tIns="3600000" and bIns="5400000".
377 // The text had ended about 3.3cm below the top edge in PowerPoint.
378 assertXPathAttrs(pXmlDoc, "/p:sld/p:cSld/p:spTree/p:sp[1]/p:txBody/a:bodyPr",
379 { { "tIns", "720000" }, { "bIns", "2520000" } });
382 CPPUNIT_TEST_SUITE_REGISTRATION(ShapeImportExportTest);
384 CPPUNIT_PLUGIN_IMPLEMENT();
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */