Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / oox / qa / unit / export.cxx
blob3a51c953f484eb6e4612c85795b6c56aefce69e1
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 <test/unoapixml_test.hxx>
12 using namespace ::com::sun::star;
14 namespace
16 /// Covers ooox/source/export/ fixes.
17 class Test : public UnoApiXmlTest
19 public:
20 Test()
21 : UnoApiXmlTest("/oox/qa/unit/data/")
26 CPPUNIT_TEST_FIXTURE(Test, testPolylineConnectorPosition)
28 // Given a document with a group shape and therein a polyline and a connector.
29 loadFromURL(u"tdf141786_PolylineConnectorInGroup.odt");
30 // When saving that to DOCX:
31 save("Office Open XML Text");
33 // Then make sure polyline and connector have the correct position.
34 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
36 // For child elements of groups in Writer the position has to be adapted to be relative
37 // to group instead of being relative to anchor. That was missing for polyline and
38 // connector.
39 // Polyline: Without fix it would have failed with expected: 0, actual: 1800360
40 assertXPath(pXmlDoc, "//wpg:wgp/wps:wsp[1]/wps:spPr/a:xfrm/a:off", "x", "0");
41 // ... failed with expected: 509400, actual: 1229400
42 assertXPath(pXmlDoc, "//wpg:wgp/wps:wsp[1]/wps:spPr/a:xfrm/a:off", "y", "509400");
44 // Connector: Without fix it would have failed with expected: 763200, actual: 2563560
45 assertXPath(pXmlDoc, "//wpg:wgp/wps:wsp[3]/wps:spPr/a:xfrm/a:off", "x", "763200");
46 // ... failed with expected: 0, actual: 720000
47 assertXPath(pXmlDoc, "//wpg:wgp/wps:wsp[3]/wps:spPr/a:xfrm/a:off", "y", "0");
48 // Polyline and connector were shifted 1800360EMU right, 720000EMU down.
51 CPPUNIT_TEST_FIXTURE(Test, testRotatedShapePosition)
53 // Given a document with a group shape and therein a rotated custom shape.
54 loadFromURL(u"tdf141786_RotatedShapeInGroup.odt");
56 // FIXME: validation error in OOXML export: Errors: 3
57 skipValidation();
59 // When saving that to DOCX:
60 save("Office Open XML Text");
62 // Then make sure the rotated child shape has the correct position.
63 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
65 // For a group itself and for shapes outside of groups, the position calculation is done in
66 // DocxSdrExport. For child elements of groups it has to be done in
67 // DrawingML::WriteShapeTransformation(), but was missing.
68 // Without fix it would have failed with expected: 469440, actual: 92160
69 // The shape was about 1cm shifted up and partly outside its group.
70 assertXPath(pXmlDoc, "//wpg:wgp/wps:wsp[1]/wps:spPr/a:xfrm/a:off", "y", "469440");
73 CPPUNIT_TEST_FIXTURE(Test, testDmlGroupshapePolygon)
75 // Given a document with a group shape, containing a single polygon child shape:
76 loadFromURL(u"dml-groupshape-polygon.docx");
78 // FIXME: validation error in OOXML export: Errors: 9
79 skipValidation();
81 // When saving that to DOCX:
82 save("Office Open XML Text");
84 // Then make sure that the group shape, the group shape's child size and the child shape's size
85 // match:
86 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
87 assertXPath(pXmlDoc, "//wpg:grpSpPr/a:xfrm/a:ext", "cx", "5328360");
88 // Without the accompanying fix in place, this test would have failed, the <a:chExt> element was
89 // not written.
90 assertXPath(pXmlDoc, "//wpg:grpSpPr/a:xfrm/a:chExt", "cx", "5328360");
91 assertXPath(pXmlDoc, "//wps:spPr/a:xfrm/a:ext", "cx", "5328360");
94 CPPUNIT_TEST_FIXTURE(Test, testCustomShapeArrowExport)
96 // Given a document with a few different kinds of arrow shapes in it:
97 loadFromURL(u"tdf142602_CustomShapeArrows.odt");
99 // FIXME: validation error in OOXML export: Errors: 11
100 skipValidation();
102 // When saving that to DOCX:
103 save("Office Open XML Text");
105 // Then the shapes should retain their correct control values.
106 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
108 // Without the fix the output OOXML would have no <a:prstGeom> tags in it.
110 // Right arrow
111 assertXPath(pXmlDoc,
112 "//w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
113 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
114 "prst", "rightArrow");
115 assertXPath(pXmlDoc,
116 "//w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
117 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
118 "fmla", "val 50000");
119 assertXPath(pXmlDoc,
120 "//w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
121 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
122 "fmla", "val 46321");
124 // Left arrow
125 assertXPath(pXmlDoc,
126 "//w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
127 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
128 "prst", "leftArrow");
129 assertXPath(pXmlDoc,
130 "//w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
131 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
132 "fmla", "val 50000");
133 assertXPath(pXmlDoc,
134 "//w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
135 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
136 "fmla", "val 52939");
138 // Down arrow
139 assertXPath(pXmlDoc,
140 "//w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
141 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
142 "prst", "downArrow");
143 assertXPath(pXmlDoc,
144 "//w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
145 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
146 "fmla", "val 50000");
147 assertXPath(pXmlDoc,
148 "//w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
149 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
150 "fmla", "val 59399");
152 // Up arrow
153 assertXPath(pXmlDoc,
154 "//w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
155 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
156 "prst", "upArrow");
157 assertXPath(pXmlDoc,
158 "//w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
159 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
160 "fmla", "val 50000");
161 assertXPath(pXmlDoc,
162 "//w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
163 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
164 "fmla", "val 63885");
166 // Left-right arrow
167 assertXPath(pXmlDoc,
168 "//w:r/mc:AlternateContent[5]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
169 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
170 "prst", "leftRightArrow");
171 assertXPath(pXmlDoc,
172 "//w:r/mc:AlternateContent[5]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
173 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
174 "fmla", "val 50000");
175 assertXPath(pXmlDoc,
176 "//w:r/mc:AlternateContent[5]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
177 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
178 "fmla", "val 53522");
180 // Up-down arrow
181 assertXPath(pXmlDoc,
182 "//w:r/mc:AlternateContent[6]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
183 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
184 "prst", "upDownArrow");
185 assertXPath(pXmlDoc,
186 "//w:r/mc:AlternateContent[6]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
187 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
188 "fmla", "val 50000");
189 assertXPath(pXmlDoc,
190 "//w:r/mc:AlternateContent[6]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
191 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
192 "fmla", "val 62743");
194 // Right arrow callout
195 assertXPath(pXmlDoc,
196 "//w:r/mc:AlternateContent[7]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
197 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
198 "prst", "rightArrowCallout");
199 assertXPath(pXmlDoc,
200 "//w:r/mc:AlternateContent[7]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
201 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
202 "fmla", "val 25002");
203 assertXPath(pXmlDoc,
204 "//w:r/mc:AlternateContent[7]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
205 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
206 "fmla", "val 25000");
207 assertXPath(pXmlDoc,
208 "//w:r/mc:AlternateContent[7]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
209 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[3]",
210 "fmla", "val 25052");
211 assertXPath(pXmlDoc,
212 "//w:r/mc:AlternateContent[7]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
213 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[4]",
214 "fmla", "val 66667");
216 // Left arrow callout
217 assertXPath(pXmlDoc,
218 "//w:r/mc:AlternateContent[8]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
219 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
220 "prst", "leftArrowCallout");
221 assertXPath(pXmlDoc,
222 "//w:r/mc:AlternateContent[8]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
223 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
224 "fmla", "val 25002");
225 assertXPath(pXmlDoc,
226 "//w:r/mc:AlternateContent[8]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
227 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
228 "fmla", "val 25000");
229 assertXPath(pXmlDoc,
230 "//w:r/mc:AlternateContent[8]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
231 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[3]",
232 "fmla", "val 25057");
233 assertXPath(pXmlDoc,
234 "//w:r/mc:AlternateContent[8]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
235 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[4]",
236 "fmla", "val 66673");
238 // Down arrow callout
239 assertXPath(pXmlDoc,
240 "//w:r/mc:AlternateContent[9]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
241 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
242 "prst", "downArrowCallout");
243 assertXPath(pXmlDoc,
244 "//w:r/mc:AlternateContent[9]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
245 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
246 "fmla", "val 29415");
247 assertXPath(pXmlDoc,
248 "//w:r/mc:AlternateContent[9]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
249 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
250 "fmla", "val 29413");
251 assertXPath(pXmlDoc,
252 "//w:r/mc:AlternateContent[9]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
253 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[3]",
254 "fmla", "val 16667");
255 assertXPath(pXmlDoc,
256 "//w:r/mc:AlternateContent[9]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
257 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[4]",
258 "fmla", "val 66667");
260 // Up arrow callout
261 assertXPath(pXmlDoc,
262 "//w:r/mc:AlternateContent[10]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
263 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
264 "prst", "upArrowCallout");
265 assertXPath(pXmlDoc,
266 "//w:r/mc:AlternateContent[10]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
267 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[1]",
268 "fmla", "val 31033");
269 assertXPath(pXmlDoc,
270 "//w:r/mc:AlternateContent[10]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
271 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[2]",
272 "fmla", "val 31030");
273 assertXPath(pXmlDoc,
274 "//w:r/mc:AlternateContent[10]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
275 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[3]",
276 "fmla", "val 16667");
277 assertXPath(pXmlDoc,
278 "//w:r/mc:AlternateContent[10]/mc:Choice/w:drawing/wp:anchor/a:graphic/"
279 "a:graphicData/wps:wsp/wps:spPr/a:prstGeom/a:avLst/a:gd[4]",
280 "fmla", "val 66660");
283 CPPUNIT_TEST_FIXTURE(Test, testCameraRevolutionGrabBag)
285 // Given a PPTX file that contains camera revolution (rotation around z axis) applied shapes
286 loadFromURL(u"camera-rotation-revolution-nonwps.pptx");
288 // When saving that document:
289 save("Impress Office Open XML");
291 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
292 // Then make sure the revolution is exported without a problem:
293 // First shape textbox:
294 assertXPath(pXmlDoc, "//p:sp[1]/p:spPr/a:scene3d/a:camera/a:rot", "rev", "5400000");
296 // Second shape rectangle:
297 assertXPath(pXmlDoc, "//p:sp[2]/p:spPr/a:scene3d/a:camera/a:rot", "rev", "18300000");
299 // Make sure Shape3DProperties don't leak under txBody
300 // Without the accompanying fix in place, this test would have failed with:
301 // - Expected: 0
302 // - Actual : 1
303 // - In <>, XPath '//p:sp[1]/p:txBody/a:bodyPr/a:scene3d/a:camera/a:rot' number of nodes is incorrect
304 assertXPath(pXmlDoc, "//p:sp[1]/p:txBody/a:bodyPr/a:scene3d/a:camera/a:rot", 0);
305 assertXPath(pXmlDoc, "//p:sp[2]/p:txBody/a:bodyPr/a:scene3d/a:camera/a:rot", 0);
308 CPPUNIT_TEST_FIXTURE(Test, testReferToTheme)
310 // Given a PPTX file that contains references to a theme:
311 loadFromURL(u"refer-to-theme.pptx");
313 // When saving that document:
314 save("Impress Office Open XML");
316 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
317 // Then make sure the shape text color is a scheme color:
318 // Without the accompanying fix in place, this test would have failed with:
319 // - Expected: 1
320 // - Actual : 0
321 // - XPath '//p:sp/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr' number of nodes is incorrect
322 // i.e. the <a:schemeClr> element was not written.
323 assertXPath(pXmlDoc, "//p:sp[1]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr", "val",
324 "accent1");
325 assertXPath(pXmlDoc, "//p:sp[1]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr/a:lumMod", 0);
326 assertXPath(pXmlDoc, "//p:sp[1]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr/a:lumOff", 0);
328 // Second shape: lighter color:
329 // Without the accompanying fix in place, this test would have failed with:
330 // - Expected: 1
331 // - Actual : 0
332 // - XPath '//p:sp[2]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr' number of nodes is incorrect
333 // i.e. the effects case did not write scheme colors.
334 assertXPath(pXmlDoc, "//p:sp[2]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr", "val",
335 "accent1");
336 assertXPath(pXmlDoc, "//p:sp[2]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr/a:lumMod", "val",
337 "40000");
338 assertXPath(pXmlDoc, "//p:sp[2]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr/a:lumOff", "val",
339 "60000");
341 // Third shape, darker color:
342 assertXPath(pXmlDoc, "//p:sp[3]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr", "val",
343 "accent1");
344 assertXPath(pXmlDoc, "//p:sp[3]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr/a:lumMod", "val",
345 "75000");
346 assertXPath(pXmlDoc, "//p:sp[3]/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr/a:lumOff", 0);
349 CPPUNIT_TEST_FIXTURE(Test, testThemeColor_ShapeFill)
351 // Given an ODP file that contains references to a theme for shape fill:
352 loadFromURL(u"ReferenceShapeFill.fodp");
354 // When saving that document:
355 save("Impress Office Open XML");
357 // Then make sure the shape fill color is a scheme color.
358 // Note that this was already working from PPTX files via grab-bags,
359 //so this test intentionally uses an ODP file as input.
360 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
361 assertXPath(pXmlDoc, "//p:sp[1]/p:spPr/a:solidFill/a:schemeClr", "val", "accent6");
362 assertXPath(pXmlDoc, "//p:sp[1]/p:spPr/a:solidFill/a:schemeClr/a:lumMod", "val", "75000");
365 CPPUNIT_TEST_FIXTURE(Test, testTdf146690_endParagraphRunPropertiesNewLinesTextSize)
367 // Given a PPTX file that contains references to a theme:
368 loadFromURL(u"endParaRPr-newline-textsize.pptx");
370 // When saving that document:
371 save("Impress Office Open XML");
373 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
374 // Make sure the text size is exported correctly:
375 // Without the accompanying fix in place, this test would have failed with:
376 // - Expected: 500
377 // - Actual : 1800
378 // i.e. the endParaRPr 'size' wasn't exported correctly
379 assertXPath(pXmlDoc, "//p:sp[1]/p:txBody/a:p[1]/a:endParaRPr", "sz", "500");
380 assertXPath(pXmlDoc, "//p:sp[1]/p:txBody/a:p[2]/a:endParaRPr", "sz", "500");
381 assertXPath(pXmlDoc, "//p:sp[1]/p:txBody/a:p[3]/a:endParaRPr", "sz", "500");
384 CPPUNIT_TEST_FIXTURE(Test, testTdf147978_endsubpath)
386 // Given an odp file that contains a non-primitive custom shape with command N
387 loadFromURL(u"tdf147978_endsubpath.odp");
389 // When saving that document:
390 save("Impress Office Open XML");
392 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
393 // Then make sure the pathLst has two child elements,
394 // Without the accompanying fix in place, only one element a:path was exported.
395 assertXPathChildren(pXmlDoc, "//a:pathLst", 2);
396 // and make sure first path with no stroke, second with no fill
397 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]", "stroke", "0");
398 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]", "fill", "none");
401 CPPUNIT_TEST_FIXTURE(Test, testTdf147978_commandA)
403 // Given an odp file that contains a non-primitive custom shape with command N
404 loadFromURL(u"tdf147978_enhancedPath_commandA.odp");
406 // When saving that document:
407 save("Impress Office Open XML");
409 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
410 // Then make sure the path has a child element arcTo. Prior to the fix that part of the curve was
411 // not exported at all. In odp it is a command A. Such does not exist in OOXML and is therefore
412 // exported as a:lnTo followed by a:arcTo
413 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:lnTo", 2);
414 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", 1);
415 // And assert its attribute values
416 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", "wR", "7200");
417 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", "hR", "5400");
418 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", "stAng", "7719588");
419 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", "swAng", "-5799266");
422 CPPUNIT_TEST_FIXTURE(Test, testTdf147978_commandT)
424 // The odp file contains a non-primitive custom shape with commands MTZ
425 loadFromURL(u"tdf147978_enhancedPath_commandT.odp");
427 // Export to pptx had only exported the command M and has used a wrong path size
428 save("Impress Office Open XML");
430 // Verify the markup:
431 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
432 // File has draw:viewBox="0 0 216 216"
433 assertXPath(pXmlDoc, "//a:pathLst/a:path", "w", "216");
434 assertXPath(pXmlDoc, "//a:pathLst/a:path", "h", "216");
435 // Command T is exported as lnTo followed by arcTo.
436 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:moveTo", 1);
437 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:lnTo", 1);
438 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", 1);
439 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:close", 1);
440 // And assert its values
441 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:moveTo/a:pt", "x", "108");
442 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:moveTo/a:pt", "y", "162");
443 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:lnTo/a:pt", "x", "138");
444 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:lnTo/a:pt", "y", "110");
445 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", "wR", "108");
446 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", "hR", "54");
447 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", "stAng", "18000000");
448 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo", "swAng", "18000000");
451 CPPUNIT_TEST_FIXTURE(Test, testTdf147978_commandXY)
453 // The odp file contains a non-primitive custom shapes with commands XY
454 loadFromURL(u"tdf147978_enhancedPath_commandXY.odp");
456 // Export to pptx had dropped commands X and Y.
457 save("Impress Office Open XML");
459 // Verify the markup:
460 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
461 // File has draw:viewBox="0 0 10 10"
462 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]", "w", "10");
463 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]", "h", "10");
464 // Shape has M 0 5 Y 5 0 10 5 5 10 F Y 0 5 N M 10 10 X 0 0
465 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:moveTo/a:pt", "x", "0");
466 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:moveTo/a:pt", "y", "5");
467 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[1]", "wR", "5");
468 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[1]", "hR", "5");
469 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[1]", "stAng", "10800000");
470 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[1]", "swAng", "5400000");
471 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[2]", "stAng", "16200000");
472 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[2]", "swAng", "5400000");
473 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[3]", "stAng", "0");
474 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[3]", "swAng", "5400000");
475 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[4]", "stAng", "0");
476 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]/a:arcTo[4]", "swAng", "-5400000");
477 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]/a:moveTo/a:pt", "x", "10");
478 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]/a:moveTo/a:pt", "y", "10");
479 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]/a:arcTo", "wR", "10");
480 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]/a:arcTo", "hR", "10");
481 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]/a:arcTo", "stAng", "5400000");
482 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]/a:arcTo", "swAng", "5400000");
485 CPPUNIT_TEST_FIXTURE(Test, testTdf147978_commandHIJK)
487 // The odp file contains a non-primitive custom shapes with commands H,I,J,K
488 loadFromURL(u"tdf147978_enhancedPath_commandHIJK.odp");
490 // Export to pptx had dropped commands X and Y.
491 save("Impress Office Open XML");
493 // Verify the markup:
494 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
495 // File has draw:viewBox="0 0 80 80"
496 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]", "w", "80");
497 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]", "h", "80");
498 // File uses from back to front J (lighten), I (lightenLess), normal fill, K (darkenLess),
499 // H (darken). New feature, old versions did not export these at all.
500 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]", "fill", "lighten");
501 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]", "fill", "lightenLess");
502 assertXPathNoAttribute(pXmlDoc, "//a:pathLst/a:path[3]", "fill");
503 assertXPath(pXmlDoc, "//a:pathLst/a:path[4]", "fill", "darkenLess");
504 assertXPath(pXmlDoc, "//a:pathLst/a:path[5]", "fill", "darken");
507 CPPUNIT_TEST_FIXTURE(Test, testTdf147978_subpath)
509 // The odp file contains a non-primitive custom shapes with commands H,I,J,K
510 loadFromURL(u"tdf147978_enhancedPath_subpath.pptx");
512 // Export to pptx had dropped the subpaths.
513 save("Impress Office Open XML");
515 // Verify the markup:
516 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
517 // File should have four subpaths with increasing path size
518 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]", "w", "10");
519 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]", "h", "10");
520 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]", "w", "20");
521 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]", "h", "20");
522 assertXPath(pXmlDoc, "//a:pathLst/a:path[3]", "w", "40");
523 assertXPath(pXmlDoc, "//a:pathLst/a:path[3]", "h", "40");
524 assertXPath(pXmlDoc, "//a:pathLst/a:path[4]", "w", "80");
525 assertXPath(pXmlDoc, "//a:pathLst/a:path[4]", "h", "80");
528 CPPUNIT_TEST_FIXTURE(Test, testTdf100391TextAreaRect)
530 // The document has a custom shape of type "non-primitive" to trigger the custGeom export
531 loadFromURL(u"tdf100391_TextAreaRect.odp");
532 // When saving to PPTX the textarea rect was set to default instead of using the actual area
533 save("Impress Office Open XML");
535 // Verify the markup. Without fix the values were l="l", t="t", r="r", b="b"
536 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
537 assertXPath(pXmlDoc, "//a:custGeom/a:rect", "l", "textAreaLeft");
538 assertXPath(pXmlDoc, "//a:custGeom/a:rect", "t", "textAreaTop");
539 assertXPath(pXmlDoc, "//a:custGeom/a:rect", "r", "textAreaRight");
540 assertXPath(pXmlDoc, "//a:custGeom/a:rect", "b", "textAreaBottom");
541 // The values are calculated in guides, for example
542 assertXPath(pXmlDoc, "//a:custGeom/a:gdLst/a:gd[1]", "name", "textAreaLeft");
543 assertXPath(pXmlDoc, "//a:custGeom/a:gdLst/a:gd[1]", "fmla", "*/ 1440000 w 2880000");
544 // The test reflects the state of Apr 2022. It needs to be adapted when export of handles and
545 // guides is implemented.
548 CPPUNIT_TEST_FIXTURE(Test, testTdf109169_OctagonBevel)
550 // The odp file contains an "Octagon Bevel" shape. Such has shading not in commands H,I,J,K
551 // but shading is generated in ctor of EnhancedCustomShape2d from the Type value.
552 loadFromURL(u"tdf109169_OctagonBevel.odt");
554 // FIXME: validation error in OOXML export: Errors: 1
555 skipValidation();
557 // Export to docx had not written a:fill or a:stroke attributes at all.
558 save("Office Open XML Text");
560 // Verify the markup:
561 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
562 // File should have six subpaths, one with stroke and five with fill
563 assertXPath(pXmlDoc, "//a:pathLst/a:path[1]", "stroke", "0");
564 assertXPath(pXmlDoc, "//a:pathLst/a:path[2]", "fill", "darkenLess");
565 assertXPath(pXmlDoc, "//a:pathLst/a:path[3]", "fill", "darken");
566 assertXPath(pXmlDoc, "//a:pathLst/a:path[4]", "fill", "darken");
567 assertXPath(pXmlDoc, "//a:pathLst/a:path[5]", "fill", "lightenLess");
568 assertXPath(pXmlDoc, "//a:pathLst/a:path[6]", "fill", "lighten");
571 CPPUNIT_TEST_FIXTURE(Test, testFaultyPathCommandsAWT)
573 // The odp file contains shapes whose path starts with command A, W, T or L. That is a faulty
574 // path. LO is tolerant and renders it so that is makes a moveTo to the start point of the arc or
575 // the end of the line respectively. Export to OOXML does the same now and writes a moveTo
576 // instead of the normally used lnTo. If a lnTo is written, MS Office shows nothing of the shape.
577 loadFromURL(u"FaultyPathStart.odp");
579 save("Impress Office Open XML");
581 // Verify the markup:
582 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
583 // First child of a:path should be a moveTo in all four shapes.
584 assertXPath(pXmlDoc, "//p:spTree/p:sp[1]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo");
585 assertXPath(pXmlDoc, "//p:spTree/p:sp[2]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo");
586 assertXPath(pXmlDoc, "//p:spTree/p:sp[3]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo");
587 assertXPath(pXmlDoc, "//p:spTree/p:sp[4]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo");
590 CPPUNIT_TEST_FIXTURE(Test, testTdf148784StretchXY)
592 // The document has a custom shapes of type "non-primitive" to trigger the custGeom export.
593 // They use formulas with 'right' and 'bottom'.
594 // When saving to PPTX the attributes stretchpoint-x and stretchpoint-y were not considered. The
595 // line at right and bottom edge were positioned inside as if the shape had a square size.
596 loadFromURL(u"tdf148784_StretchXY.odp");
597 save("Impress Office Open XML");
599 // Verify the markup.
600 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
602 // x-position of last segment should be same as path width. It was 21600 without fix.
603 sal_Int32 nWidth
604 = getXPathContent(pXmlDoc, "//p:spTree/p:sp[1]/p:spPr/a:custGeom/a:pathLst/a:path/@w")
605 .toInt32();
606 sal_Int32 nPosX
607 = getXPathContent(
608 pXmlDoc, "//p:spTree/p:sp[1]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo[4]/a:pt/@x")
609 .toInt32();
610 CPPUNIT_ASSERT_EQUAL_MESSAGE("StretchX", nWidth, nPosX);
612 // y-position of last segment should be same as path height. It was 21600 without fix.
613 sal_Int32 nHeight
614 = getXPathContent(pXmlDoc, "//p:spTree/p:sp[2]/p:spPr/a:custGeom/a:pathLst/a:path/@h")
615 .toInt32();
616 sal_Int32 nPosY
617 = getXPathContent(
618 pXmlDoc, "//p:spTree/p:sp[2]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo[4]/a:pt/@y")
619 .toInt32();
620 CPPUNIT_ASSERT_EQUAL_MESSAGE("StretchY", nHeight, nPosY);
622 // The test reflects the state of Apr 2022. It needs to be adapted when export of handles and
623 // guides is implemented.
626 CPPUNIT_TEST_FIXTURE(Test, testTdf148784StretchCommandQ)
628 // The document has a custom shapes of type "non-primitive" to trigger the custGeom export.
629 // They use formulas with 'right' and 'bottom'.
630 // When saving to PPTX the attributes stretchpoint-x and stretchpoint-y were not considered.
631 // That results in wrong arcs on the right or bottom side of the shape.
632 loadFromURL(u"tdf148784_StretchCommandQ.odp");
633 save("Impress Office Open XML");
635 // Verify the markup.
636 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
638 // x-position of second quadBezTo control should be same as path width. It was 21600 without fix.
639 sal_Int32 nWidth
640 = getXPathContent(pXmlDoc, "//p:spTree/p:sp[1]/p:spPr/a:custGeom/a:pathLst/a:path/@w")
641 .toInt32();
642 sal_Int32 nPosX
643 = getXPathContent(
644 pXmlDoc,
645 "//p:spTree/p:sp[1]/p:spPr/a:custGeom/a:pathLst/a:path/a:quadBezTo[2]/a:pt/@x")
646 .toInt32();
647 CPPUNIT_ASSERT_EQUAL_MESSAGE("StretchX", nWidth, nPosX);
649 // y-position of third quadBezTo control should be same as path height. It was 21600 without fix.
650 sal_Int32 nHeight
651 = getXPathContent(pXmlDoc, "//p:spTree/p:sp[2]/p:spPr/a:custGeom/a:pathLst/a:path/@h")
652 .toInt32();
653 sal_Int32 nPosY
654 = getXPathContent(
655 pXmlDoc,
656 "//p:spTree/p:sp[2]/p:spPr/a:custGeom/a:pathLst/a:path/a:quadBezTo[3]/a:pt/@y")
657 .toInt32();
658 CPPUNIT_ASSERT_EQUAL_MESSAGE("StretchY", nHeight, nPosY);
660 // The test reflects the state of Apr 2022. It needs to be adapted when export of handles and
661 // guides is implemented.
664 CPPUNIT_TEST_FIXTURE(Test, testTdf148784StretchCommandVW)
666 // The document has a custom shapes of type "non-primitive" to trigger the custGeom export.
667 // It should not need adaption when export of handles and guides is implemented because it
668 // has only fixed values in the path.
669 // When saving to PPTX the attributes stretchpoint-x and stretchpoint-y were not considered.
670 // That results in circles instead of ellipses.
671 loadFromURL(u"tdf148784_StretchCommandVW.odp");
672 save("Impress Office Open XML");
674 // Verify the markup.
675 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
677 // wR of first ArcTo in first shape should be same as path width/2. It was 10800 without fix.
678 sal_Int32 nHalfWidth
679 = getXPathContent(pXmlDoc, "//p:spTree/p:sp[1]/p:spPr/a:custGeom/a:pathLst/a:path/@w")
680 .toInt32()
681 / 2;
682 sal_Int32 nWR
683 = getXPathContent(pXmlDoc,
684 "//p:spTree/p:sp[1]/p:spPr/a:custGeom/a:pathLst/a:path/a:arcTo[1]/@wR")
685 .toInt32();
686 CPPUNIT_ASSERT_EQUAL_MESSAGE("StretchX", nHalfWidth, nWR);
688 // hR of first ArcTo in second shape should be same as path height /2. It was 10800 without fix.
689 sal_Int32 nHalfHeight
690 = getXPathContent(pXmlDoc, "//p:spTree/p:sp[2]/p:spPr/a:custGeom/a:pathLst/a:path/@h")
691 .toInt32()
692 / 2;
693 sal_Int32 nHR
694 = getXPathContent(pXmlDoc,
695 "//p:spTree/p:sp[2]/p:spPr/a:custGeom/a:pathLst/a:path/a:arcTo[1]/@hR")
696 .toInt32();
697 CPPUNIT_ASSERT_EQUAL_MESSAGE("StretchY", nHalfHeight, nHR);
700 CPPUNIT_TEST_FIXTURE(Test, testTdf149551VertPadding)
702 // The document has shape[1] with attribute vert="vert270" and shape[2] with vert="vert". The text
703 // has paddings lIns="720000"=2cm, tIns="360000"=1cm, rIns="0" and bIns="0".
704 // After load and save the paddings were rotated and a 90deg text rotation was added.
705 loadFromURL(u"tdf149551_vert_and_padding.pptx");
706 save("Impress Office Open XML");
708 // Verify the markup. The values must be the same as in the original file.
709 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
710 for (sal_Int32 i = 1; i <= 2; i++)
712 OString sElement = "//p:spTree/p:sp[" + OString::number(i) + "]/p:txBody/a:bodyPr";
713 assertXPath(pXmlDoc, sElement, "lIns", "720000");
714 assertXPath(pXmlDoc, sElement, "tIns", "360000");
715 assertXPath(pXmlDoc, sElement, "rIns", "0");
716 assertXPath(pXmlDoc, sElement, "bIns", "0");
717 assertXPathNoAttribute(pXmlDoc, sElement, "rot");
721 CPPUNIT_TEST_FIXTURE(Test, testTdf149538upright)
723 // The document has a shape with attribute upright="1" in the bodyPr element. On import it is
724 // emulated by rotating the text area rectangle. On export there should be an upright="1"
725 // attribute but no 'rot' attribute. Without the fix the 'rot' attribute with values from
726 // the emulation was written out.
727 loadFromURL(u"tdf149538_upright.pptx");
728 save("Impress Office Open XML");
730 // Verify the markup. The values must be the same as in the original file.
731 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
732 assertXPath(pXmlDoc, "//p:spTree/p:sp/p:txBody/a:bodyPr", "upright", "1");
733 assertXPathNoAttribute(pXmlDoc, "//p:spTree/p:sp/p:txBody/a:bodyPr", "rot");
736 CPPUNIT_TEST_FIXTURE(Test, testTdf151008VertAnchor)
738 loadFromURL(u"tdf151008_eaVertAnchor.pptx");
739 save("Impress Office Open XML");
740 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
741 // The order of the shapes in the file is by name "Right", "Center", "Left", "RightMiddle",
742 // "CenterMiddle" and "LeftMiddle". I access the shapes here by index, because the XPath is
743 // easier then.
744 // As of Sep 2022 LibreOffice does not write the default anchorCtr="0"
745 // Right
746 assertXPath(pXmlDoc, "//p:spTree/p:sp[1]/p:txBody/a:bodyPr", "anchor", "t");
747 assertXPathNoAttribute(pXmlDoc, "//p:spTree/p:sp[1]/p:txBody/a:bodyPr", "anchorCtr");
748 // Center
749 assertXPath(pXmlDoc, "//p:spTree/p:sp[2]/p:txBody/a:bodyPr", "anchor", "ctr");
750 assertXPathNoAttribute(pXmlDoc, "//p:spTree/p:sp[2]/p:txBody/a:bodyPr", "anchorCtr");
751 // Left
752 assertXPath(pXmlDoc, "//p:spTree/p:sp[3]/p:txBody/a:bodyPr", "anchor", "b");
753 assertXPathNoAttribute(pXmlDoc, "//p:spTree/p:sp[3]/p:txBody/a:bodyPr", "anchorCtr");
754 // RightMiddle
755 assertXPath(pXmlDoc, "//p:spTree/p:sp[4]/p:txBody/a:bodyPr", "anchor", "t");
756 assertXPath(pXmlDoc, "//p:spTree/p:sp[4]/p:txBody/a:bodyPr", "anchorCtr", "1");
757 // CenterMiddle
758 assertXPath(pXmlDoc, "//p:spTree/p:sp[5]/p:txBody/a:bodyPr", "anchor", "ctr");
759 assertXPath(pXmlDoc, "//p:spTree/p:sp[5]/p:txBody/a:bodyPr", "anchorCtr", "1");
760 // LeftMiddle
761 assertXPath(pXmlDoc, "//p:spTree/p:sp[6]/p:txBody/a:bodyPr", "anchor", "b");
762 assertXPath(pXmlDoc, "//p:spTree/p:sp[6]/p:txBody/a:bodyPr", "anchorCtr", "1");
765 CPPUNIT_TEST_FIXTURE(Test, testFontworkBitmapFill)
767 // The document has a Fontwork shape with bitmap fill.
768 loadFromURL(u"tdf128568_FontworkBitmapFill.odt");
770 // FIXME: validation error in OOXML export: Errors: 1
771 // Attribute ID is not allowed in element v:shape
772 skipValidation();
774 // Saving that to DOCX:
775 save("Office Open XML Text");
777 // Make sure it is exported to VML and has no txbxContent but a textpath element. Without fix it
778 // was exported as DML 'abc transform', but that is not able to use bitmap fill in Word.
779 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
780 assertXPath(pXmlDoc, "//mc:alternateContent", 0);
781 assertXPath(pXmlDoc, "//v:shape/v:textbox/v:txbxContent", 0);
782 assertXPath(pXmlDoc, "//v:shape/v:textpath", 1);
784 // Without fix the bitmap was referenced by v:imagedata element. But that produces a picture
785 // in Word not a WordArt shape. Instead a v:fill has to be used.
786 assertXPath(pXmlDoc, "//v:shape/v:imagedata", 0);
787 assertXPath(pXmlDoc, "//v:shape/v:fill", 1);
788 assertXPath(pXmlDoc, "//v:shape/v:fill[@r:id]", 1);
790 // The fill is set to 'stretched' in LO, that is type="frame" in VML. That was not implemented
791 // in VML export.
792 assertXPath(pXmlDoc, "//v:shape/v:fill", "type", "frame");
795 CPPUNIT_TEST_FIXTURE(Test, testFontworkFontProperties)
797 // The document has five Fontwork shapes. They have bitmap fill and thus are exported to VML.
798 // They differ in font properties e.g. font weight and character spacing.
799 loadFromURL(u"tdf128568_FontworkFontProperties.odt");
801 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
802 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
803 skipValidation();
805 // Save to DOCX:
806 save("Office Open XML Text");
808 // Make sure the style attribute of the textpath element has the needed items. Without fix only
809 // font-family and font-size were written.
810 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
811 OUString sStyle;
812 // bold
813 sStyle = getXPath(pXmlDoc, "(//v:shape)[1]/v:textpath", "style");
814 CPPUNIT_ASSERT(sStyle.indexOf("font-weight:bold") > -1);
815 // italic
816 sStyle = getXPath(pXmlDoc, "(//v:shape)[2]/v:textpath", "style");
817 CPPUNIT_ASSERT(sStyle.indexOf("font-style:italic") > -1);
818 // character spacing 'very loose', 150 * 655, see escherex.cxx
819 sStyle = getXPath(pXmlDoc, "(//v:shape)[3]/v:textpath", "style");
820 CPPUNIT_ASSERT(sStyle.indexOf("v-text-spacing:98250f") > -1);
821 // character spacing 'tight', 90 * 655, see escherex.cxx
822 sStyle = getXPath(pXmlDoc, "(//v:shape)[4]/v:textpath", "style");
823 CPPUNIT_ASSERT(sStyle.indexOf("v-text-spacing:58950f") > -1);
824 // same letter heights
825 sStyle = getXPath(pXmlDoc, "(//v:shape)[5]/v:textpath", "style");
826 CPPUNIT_ASSERT(sStyle.indexOf("v-same-letter-heights:t") > -1);
829 CPPUNIT_TEST_FIXTURE(Test, testVMLFontworkSlantUp)
831 // The document has a Fontwork shape type 'textSlantUp' (172). When exporting to docx, Word does
832 // not recognize its markup as preset WordArt, because the used markup differs from what Word
833 // expects for this type of shape. As a result Word saves the shape as having custom geometry
834 // and such is not understand by LibreOffice.
835 loadFromURL(u"tdf153296_VML_export_SlantUp.odt");
837 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
838 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
839 skipValidation();
841 // Save to DOCX:
842 save("Office Open XML Text");
844 // Examine the saved markup. I could identify the following two problems to hinder Word from
845 // accepting the markup. There might exist more problems.
846 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
848 // Make sure a <v:path> element exists and has an o:connecttype attribute
849 assertXPath(pXmlDoc, "//v:shapetype/v:path", 1);
850 assertXPath(pXmlDoc, "//v:shapetype/v:path[@o:connecttype]", 1);
852 // Make sure the handle position is written without reference to a formula
853 OUString sPosition = getXPath(pXmlDoc, "//v:h", "position");
854 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), sPosition.indexOf("@"));
855 CPPUNIT_ASSERT_EQUAL(OUString("topLeft,#0"), sPosition);
858 CPPUNIT_TEST_FIXTURE(Test, testVMLFontworkArchUp)
860 // The document has a Fontwork shape type 'textArchUp' (172). When exporting to docx, the shape
861 // was not exported as VML Fontwork but as a rectangle.
862 loadFromURL(u"tdf153296_VML_export_ArchUpCurve.odt");
864 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
865 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
866 skipValidation();
868 // Save to DOCX:
869 save("Office Open XML Text");
871 // Examine the saved markup.
872 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
874 // Make sure there is no <v:rect> element
875 assertXPath(pXmlDoc, "//v:rect", 0);
876 // ..., but a <v:shapetype> element with <v:textpath> subelement
877 assertXPath(pXmlDoc, "//v:shapetype/v:textpath", 1);
880 CPPUNIT_TEST_FIXTURE(Test, testVMLAdjustmentExport)
882 // The document has a Fontwork shape type 'textCirclePour' (150). When exporting to docx, the
883 // adjustment values were not exported at all.
884 loadFromURL(u"tdf153246_VML_export_Fontwork_Adjustment.odt");
886 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
887 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
888 skipValidation();
890 // Save to DOCX:
891 save("Office Open XML Text");
893 // Examine the saved markup.
894 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
896 // Make sure an "adj" attribute exists
897 assertXPath(pXmlDoc, "//v:shape[@adj]", 1);
898 // ... and has the correct values
899 OUString sAdjustments = getXPath(pXmlDoc, "//v:shape", "adj");
900 sal_Int32 nTokenStart = 0;
901 OUString sAngle = sAdjustments.getToken(0, ',', nTokenStart);
902 CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(-7341733), sAngle.toInt32(), 2);
903 OUString sRadius = sAdjustments.copy(nTokenStart);
904 CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(5296), sRadius.toInt32(), 2);
907 CPPUNIT_TEST_FIXTURE(Test, testFontworkDirectColor)
909 // The document has a Fontwork shape with fill #2e8b57 plus 60% transparency and line color
910 // #ff7f50 with 20% transparency. When exporting to docx, line color was not exported at all
911 // and fill color was replaced with character color.
912 loadFromURL(u"tdf51195_Fontwork_DirectColor.odt");
914 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
915 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
916 skipValidation();
918 // Save to DOCX:
919 save("Office Open XML Text");
921 // Examine the saved markup.
922 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
923 const OString sElement = "//w:txbxContent/w:p/w:r/w:rPr/";
925 // Make sure the fallback in <w:color> has correct value.
926 assertXPath(pXmlDoc, sElement + "w:color", "val", "2E8B57");
928 // ... and <w14:textOutline> exists and has correct values.
929 assertXPath(pXmlDoc, sElement + "w14:textOutline", 1);
930 assertXPath(pXmlDoc, sElement + "w14:textOutline/w14:solidFill/w14:srgbClr", "val", "ff7f50");
931 assertXPath(pXmlDoc, sElement + "w14:textOutline/w14:solidFill/w14:srgbClr/w14:alpha", "val",
932 "20000");
933 assertXPath(pXmlDoc, sElement + "w14:textOutline/w14:round", 1);
935 // ... and w14:textFill exists and has correct values.
936 assertXPath(pXmlDoc, sElement + "w14:textFill", 1);
937 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:solidFill/w14:srgbClr", "val", "2e8b57");
938 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:solidFill/w14:srgbClr/w14:alpha", "val",
939 "60000");
942 CPPUNIT_TEST_FIXTURE(Test, testFontworkThemeColor)
944 // The document has a Fontwork shape with fill theme color 'lt2' and 50% darker, and a Fontwork
945 // shape with theme color 'dk2' and 40% lighter. When exporting to docx, fill color was not
946 // exported as theme color at all, and it was replaced with character color.
947 loadFromURL(u"tdf51195_Fontwork_ThemeColor.fodt");
949 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
950 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
951 skipValidation();
953 // Save to DOCX:
954 save("Office Open XML Text");
956 // Examine the saved markup.
957 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
959 // shape with 'darker'
960 OString sElement = "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/"
961 "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent/w:p/w:r/"
962 "w:rPr/";
964 // Make sure the fallback in <w:color> has correct values
965 assertXPath(pXmlDoc, sElement + "w:color", "val", "948A54");
966 assertXPath(pXmlDoc, sElement + "w:color", "themeColor", "light2");
967 assertXPath(pXmlDoc, sElement + "w:color", "themeShade", "80");
969 // ... and w14:textFill exists and has correct values.
970 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:solidFill/w14:schemeClr", "val", "bg2");
971 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:solidFill/w14:schemeClr/w14:lumMod", "val",
972 "50000");
974 // shape with 'lighter'
975 sElement = "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/"
976 "a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/";
978 // Make sure the fallback in <w:color> has correct values
979 assertXPath(pXmlDoc, sElement + "w:color", "val", "558ED5");
980 assertXPath(pXmlDoc, sElement + "w:color", "themeColor", "dark2");
981 assertXPath(pXmlDoc, sElement + "w:color", "themeTint", "99");
983 // ... and w14:textFill exists and has correct values.
984 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:solidFill/w14:schemeClr", "val", "tx2");
985 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:solidFill/w14:schemeClr/w14:lumMod", "val",
986 "60000");
987 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:solidFill/w14:schemeClr/w14:lumOff", "val",
988 "40000");
991 CPPUNIT_TEST_FIXTURE(Test, testFontworkDistance)
993 // LO ignores 'Spacing to Borders' of the 'Text Attributes' for Fontwork shapes. Word interprets
994 // them. Make sure we force them to zero on export to docx, otherwise Word might wrap the text.
995 loadFromURL(u"tdf51195_Fontwork_Distance.odt");
997 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
998 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
999 skipValidation();
1001 // Save to DOCX:
1002 save("Office Open XML Text");
1004 // Examine the saved markup.
1005 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1006 assertXPathAttrs(pXmlDoc,
1007 "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
1008 "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:bodyPr",
1009 { { "lIns", "0" }, { "rIns", "0" }, { "tIns", "0" }, { "bIns", "0" } });
1012 CPPUNIT_TEST_FIXTURE(Test, testFontworkLinGradientRGBColor)
1014 // The document has a Fontwork shape with UI settings: linear gradient fill with angle 330deg,
1015 // start color #ffff00 (Yellow) with 'Intensity' 80%, end color #4682B4 (Steel Blue), Transition
1016 // Start 25% and solid transparency 30%.
1017 // Without fix the gradient was not exported at all.
1018 loadFromURL(u"tdf51195_Fontwork_linearGradient.fodt");
1020 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
1021 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
1022 skipValidation();
1024 // Save to DOCX:
1025 save("Office Open XML Text");
1027 // Examine the saved markup.
1028 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1030 // path to shape text run properties
1031 OString sElement = "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
1032 "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent/w:p/w:r/"
1033 "w:rPr/";
1035 // Make sure w14:textFill and w14:gradFill elements exist with child elements
1036 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst", 1);
1037 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst/w14:gs", 3);
1038 // 330deg gradient rotation = 120deg color transition direction
1039 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:lin", "ang", "7200000");
1040 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:lin", "scaled", "0");
1042 // Make sure the color stops have correct position and color
1043 // The 'intensity' property in the UI has a different algorithm than the 'lumMod' attribute in
1044 // OOXML. Therefore it cannot be exported as 'lumMod' but need to be incorporated into the color.
1045 sElement += "w14:textFill/w14:gradFill/w14:gsLst/";
1046 assertXPath(pXmlDoc, sElement + "w14:gs[1]", "pos", "0");
1047 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:srgbClr", "val", "cccc00");
1048 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:srgbClr/w14:alpha", "val", "30000");
1050 assertXPath(pXmlDoc, sElement + "w14:gs[2]", "pos", "25000");
1051 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:srgbClr", "val", "cccc00");
1052 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:srgbClr/w14:alpha", "val", "30000");
1054 assertXPath(pXmlDoc, sElement + "w14:gs[3]", "pos", "100000");
1055 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:srgbClr", "val", "4682b4");
1056 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:srgbClr/w14:alpha", "val", "30000");
1059 CPPUNIT_TEST_FIXTURE(Test, testFontworkAxialGradientTransparency)
1061 // The document has a Fontwork shape with UI settings: solid fill theme color Accent3 25% darker,
1062 // Transparency gradient Type Axial with Angle 160deg, Transition start 40%,
1063 // Start value 5%, End value 90%
1064 // Without fix the gradient was not exported at all.
1065 loadFromURL(u"tdf51195_Fontwork_axialGradient.fodt");
1067 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
1068 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
1069 skipValidation();
1071 // Save to DOCX:
1072 save("Office Open XML Text");
1074 // Examine the saved markup.
1075 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1077 // path to shape text run properties
1078 OString sElement = "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
1079 "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent/w:p/w:r/"
1080 "w:rPr/";
1082 // Make sure w14:textFill and w14:gradFill elements exist with child elements
1083 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst", 1);
1084 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst/w14:gs", 3);
1085 // 160deg gradient rotation = 290deg (360deg-160deg+90deg) color transition direction
1086 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:lin", "ang", "17400000");
1087 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:lin", "scaled", "0");
1089 // Make sure the color stops have correct position and color
1090 sElement += "w14:textFill/w14:gradFill/w14:gsLst/";
1091 // gradient is in transparency, color is always the same.
1092 for (char ch = '1'; ch <= '3'; ++ch)
1094 assertXPath(pXmlDoc, sElement + "w14:gs[" + OStringChar(ch) + "]/w14:schemeClr", "val",
1095 "accent3");
1096 assertXPath(pXmlDoc, sElement + "w14:gs[" + OStringChar(ch) + "]/w14:schemeClr/w14:lumMod",
1097 "val", "75000");
1099 // transparency values are not exactly like in UI because converting through rgb-color.
1100 // border 40% in UI means 20% on each side.
1101 assertXPath(pXmlDoc, sElement + "w14:gs[1]", "pos", "20000");
1102 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:schemeClr/w14:alpha", "val", "89800");
1103 assertXPath(pXmlDoc, sElement + "w14:gs[2]", "pos", "50000");
1104 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:schemeClr/w14:alpha", "val", "4710");
1105 assertXPath(pXmlDoc, sElement + "w14:gs[3]", "pos", "80000");
1106 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:schemeClr/w14:alpha", "val", "89800");
1109 CPPUNIT_TEST_FIXTURE(Test, testFontworkRadialGradient)
1111 // The document has a Fontwork shape with UI settings: gradient fill, Type radial,
1112 // From Color #40E0D0, To Color #FF0000, Center x|y 75%|20%, no transparency
1113 // Transition start 10%
1114 // Without fix the gradient was not exported at all.
1115 loadFromURL(u"tdf51195_Fontwork_radialGradient.fodt");
1117 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
1118 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
1119 skipValidation();
1121 // Save to DOCX:
1122 save("Office Open XML Text");
1124 // Examine the saved markup.
1125 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1127 // path to shape text run properties
1128 OString sElement = "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
1129 "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent/w:p/w:r/"
1130 "w:rPr/";
1132 // Make sure w14:textFill and w14:gradFill elements exist with child elements
1133 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst", 1);
1134 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst/w14:gs", 3);
1135 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:path", "path", "circle");
1136 assertXPathAttrs(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:path/w14:fillToRect",
1137 { { "l", "75000" }, { "t", "20000" }, { "r", "25000" }, { "b", "80000" } });
1139 // Make sure the color stops have correct position and color
1140 // The first stop is duplicated to force Word to render the gradient same as LO.
1141 sElement += "w14:textFill/w14:gradFill/w14:gsLst/";
1142 assertXPath(pXmlDoc, sElement + "w14:gs[1]", "pos", "0");
1143 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:srgbClr", "val", "ff0000");
1144 assertXPath(pXmlDoc, sElement + "w14:gs[2]", "pos", "0");
1145 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:srgbClr", "val", "ff0000");
1146 assertXPath(pXmlDoc, sElement + "w14:gs[3]", "pos", "90000");
1147 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:srgbClr", "val", "40e0d0");
1150 CPPUNIT_TEST_FIXTURE(Test, testFontworkEllipticalGradient)
1152 // The document has a Fontwork shape with UI settings: solid fill, Color #00008B (deep blue),
1153 // transparency gradient type Ellipsoid, Center x|y 50%|50%, Transition Start 50%,
1154 // Start 70%, End 0%.
1155 // Without fix the gradient was not exported at all.
1156 loadFromURL(u"tdf51195_Fontwork_ellipticalGradient.fodt");
1158 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
1159 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
1160 skipValidation();
1162 // Save to DOCX:
1163 save("Office Open XML Text");
1165 // Examine the saved markup.
1166 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1168 // path to shape text run properties
1169 OString sElement = "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
1170 "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent/w:p/w:r/"
1171 "w:rPr/";
1173 // Make sure w14:textFill and w14:gradFill elements exist with child elements
1174 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst", 1);
1175 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst/w14:gs", 3);
1176 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:path", "path", "circle");
1177 assertXPathAttrs(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:path/w14:fillToRect",
1178 { { "l", "50000" }, { "t", "50000" }, { "r", "50000" }, { "b", "50000" } });
1180 // Make sure the color stops have correct position and color
1181 // transparency values are not exactly like in UI because converting through rgb-color.
1182 sElement += "w14:textFill/w14:gradFill/w14:gsLst/";
1183 assertXPath(pXmlDoc, sElement + "w14:gs[1]", "pos", "0");
1184 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:srgbClr", "val", "00008b");
1185 // stop is duplicated to force Word to same rendering as LO does.
1186 assertXPath(pXmlDoc, sElement + "w14:gs[2]", "pos", "0");
1187 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:srgbClr", "val", "00008b");
1188 assertXPath(pXmlDoc, sElement + "w14:gs[3]", "pos", "50000");
1189 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:srgbClr", "val", "00008b");
1190 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:srgbClr/w14:alpha", "val", "69800");
1193 CPPUNIT_TEST_FIXTURE(Test, testFontworkSquareGradient)
1195 // The document has a Fontwork shape with UI settings: gradient fill Type "Square (Quadratic)",
1196 // From Color #4963ef 40%, To Color #ffff6e 90%, Center x|y 100%|50%,
1197 // no transparency
1198 // Without fix the gradient was not exported at all.
1199 loadFromURL(u"tdf51195_Fontwork_squareGradient.fodt");
1201 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
1202 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
1203 skipValidation();
1205 // Save to DOCX:
1206 save("Office Open XML Text");
1208 // Examine the saved markup.
1209 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1211 // path to shape text run properties
1212 OString sElement = "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
1213 "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent/w:p/w:r/"
1214 "w:rPr/";
1216 // Make sure w14:textFill and w14:gradFill elements exist with child elements
1217 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst", 1);
1218 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst/w14:gs", 3);
1219 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:path", "path", "rect");
1220 assertXPathAttrs(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:path/w14:fillToRect",
1221 { { "l", "100000" }, { "t", "50000" }, { "r", "0" }, { "b", "50000" } });
1223 // Make sure the color stops have correct position and color
1224 // The 'intensity' property in the UI has a different algorithm than the 'lumMod' attribute in
1225 // OOXML. Therefore it cannot be exported as 'lumMod' but need to be incorporated into the color.
1226 sElement += "w14:textFill/w14:gradFill/w14:gsLst/";
1227 assertXPath(pXmlDoc, sElement + "w14:gs[1]", "pos", "0");
1228 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:srgbClr", "val", "e6e663");
1229 assertXPath(pXmlDoc, sElement + "w14:gs[2]", "pos", "0");
1230 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:srgbClr", "val", "e6e663");
1231 assertXPath(pXmlDoc, sElement + "w14:gs[3]", "pos", "100000");
1232 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:srgbClr", "val", "1d4860");
1235 CPPUNIT_TEST_FIXTURE(Test, testFontworkRectGradient)
1237 // The document has a Fontwork shape with UI settings: solid color theme Accent 4 60% lighter,
1238 // transparency gradient Type "Rectangular", Center x|y 50%|50%, Transition start 10%,
1239 // Start value 70%, End value 5%.
1240 // Without fix the gradient was not exported at all.
1241 loadFromURL(u"tdf51195_Fontwork_rectGradient.fodt");
1243 // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
1244 // Attribute 'ID' is not allowed to appear in element 'v:shape'.
1245 skipValidation();
1247 // Save to DOCX:
1248 save("Office Open XML Text");
1250 // Examine the saved markup.
1251 xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1253 // path to shape text run properties
1254 OString sElement = "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
1255 "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent/w:p/w:r/"
1256 "w:rPr/";
1258 // Make sure w14:textFill and w14:gradFill elements exist with child elements
1259 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst", 1);
1260 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:gsLst/w14:gs", 3);
1261 assertXPath(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:path", "path", "rect");
1262 assertXPathAttrs(pXmlDoc, sElement + "w14:textFill/w14:gradFill/w14:path/w14:fillToRect",
1263 { { "l", "50000" }, { "t", "50000" }, { "r", "50000" }, { "b", "50000" } });
1265 // Make sure the color stops have correct position and color
1266 // transparency values are not exactly like in UI because converting through rgb-color.
1267 sElement += "w14:textFill/w14:gradFill/w14:gsLst/";
1268 assertXPath(pXmlDoc, sElement + "w14:gs[1]", "pos", "0");
1269 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:schemeClr", "val", "accent4");
1270 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:schemeClr/w14:lumMod", "val", "40000");
1271 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:schemeClr/w14:lumOff", "val", "60000");
1272 assertXPath(pXmlDoc, sElement + "w14:gs[1]/w14:schemeClr/w14:alpha", "val", "4710");
1273 // The first stop is duplicated to force Word to render the gradient same as LO.
1274 assertXPath(pXmlDoc, sElement + "w14:gs[2]", "pos", "0");
1275 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:schemeClr", "val", "accent4");
1276 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:schemeClr/w14:lumMod", "val", "40000");
1277 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:schemeClr/w14:lumOff", "val", "60000");
1278 assertXPath(pXmlDoc, sElement + "w14:gs[2]/w14:schemeClr/w14:alpha", "val", "4710");
1279 assertXPath(pXmlDoc, sElement + "w14:gs[3]", "pos", "90000");
1280 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:schemeClr", "val", "accent4");
1281 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:schemeClr/w14:lumMod", "val", "40000");
1282 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:schemeClr/w14:lumOff", "val", "60000");
1283 assertXPath(pXmlDoc, sElement + "w14:gs[3]/w14:schemeClr/w14:alpha", "val", "69800");
1286 CPPUNIT_TEST_FIXTURE(Test, testThemeColorTransparency)
1288 // The document has first a Fontwork shape with solid fill theme color with transparency and
1289 // outline transparency and second a textbox with character transparency.
1290 // Without fix the transparency was not written to file.
1291 loadFromURL(u"tdf139618_ThemeColorTransparency.pptx");
1293 save("Impress Office Open XML");
1294 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
1296 // Make sure a:alpha is written for line color and for fill color.
1297 // Make sure fill color is a schemeClr.
1298 OString sElement = "/p:sld/p:cSld/p:spTree/p:sp[1]/p:txBody/a:p/a:r/a:rPr/";
1299 assertXPath(pXmlDoc, sElement + "a:ln/a:solidFill/a:srgbClr/a:alpha", "val", "25000");
1300 assertXPath(pXmlDoc, sElement + "a:solidFill/a:schemeClr", "val", "accent1");
1301 assertXPath(pXmlDoc, sElement + "a:solidFill/a:schemeClr/a:lumMod", "val", "60000");
1302 assertXPath(pXmlDoc, sElement + "a:solidFill/a:schemeClr/a:lumOff", "val", "40000");
1303 assertXPath(pXmlDoc, sElement + "a:solidFill/a:schemeClr/a:alpha", "val", "35000");
1305 // Make sure a:alpha is written for characters and fill color is a schemeClr.
1306 sElement = "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p/a:r/a:rPr/";
1307 assertXPath(pXmlDoc, sElement + "a:solidFill/a:schemeClr", "val", "accent4");
1308 assertXPath(pXmlDoc, sElement + "a:solidFill/a:schemeClr/a:lumMod", "val", "75000");
1309 assertXPath(pXmlDoc, sElement + "a:solidFill/a:schemeClr/a:alpha", "val", "20000");
1312 CPPUNIT_TEST_FIXTURE(Test, testThemeFontTypeface)
1314 // Saving the document had produced a file which PowerPoint wants to repair. The mandatory
1315 // attribute 'typeface' was missing in the <a:ea> elements.
1317 loadFromURL(u"tdf155412_typeface.pptx");
1319 save("Impress Office Open XML");
1320 xmlDocUniquePtr pXmlDoc = parseExport("ppt/theme/theme1.xml");
1322 // Make sure typeface is written.
1323 OString sElement = "/a:theme/a:themeElements/a:fontScheme/";
1324 assertXPath(pXmlDoc, sElement + "a:majorFont/a:ea", "typeface", "");
1325 assertXPath(pXmlDoc, sElement + "a:minorFont/a:ea", "typeface", "");
1328 CPPUNIT_TEST_FIXTURE(Test, testTdf157289CircularArrowExport)
1330 // The document has a custom shape of type "circular-arrow". Such uses a B command where
1331 // the ellipse bounding box is defined by bottom-right vertex first and then top-left vertex.
1332 // When saving to PPTX this had resulted in negative radii for the ellipse.
1333 loadFromURL(u"tdf157289_circularArrow_export.fodp");
1334 save("Impress Office Open XML");
1336 // Verify the markup. Both wR and hR must be positive.
1337 xmlDocUniquePtr pXmlDoc = parseExport("ppt/slides/slide1.xml");
1338 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo[1]", "wR", "6750");
1339 assertXPath(pXmlDoc, "//a:pathLst/a:path/a:arcTo[1]", "hR", "6750");
1343 CPPUNIT_PLUGIN_IMPLEMENT();
1345 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */