Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 :
10 : #include <swmodeltestbase.hxx>
11 :
12 : #if !defined(WNT)
13 :
14 : #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
15 : #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
16 : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
17 : #include <com/sun/star/drawing/FillStyle.hpp>
18 : #include <com/sun/star/drawing/Hatch.hpp>
19 : #include <com/sun/star/drawing/LineJoint.hpp>
20 : #include <com/sun/star/drawing/LineStyle.hpp>
21 : #include <com/sun/star/drawing/PointSequenceSequence.hpp>
22 : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
23 : #include <com/sun/star/style/LineSpacing.hpp>
24 : #include <com/sun/star/style/LineSpacingMode.hpp>
25 : #include <com/sun/star/text/GraphicCrop.hpp>
26 :
27 : #include <comphelper/sequenceashashmap.hxx>
28 :
29 74 : class Test : public SwModelTestBase
30 : {
31 : public:
32 74 : Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
33 :
34 : protected:
35 : /**
36 : * Blacklist handling
37 : */
38 37 : bool mustTestImportOf(const char* filename) const SAL_OVERRIDE {
39 : // If the testcase is stored in some other format, it's pointless to test.
40 37 : return (OString(filename).endsWith(".docx"));
41 : }
42 : };
43 :
44 17 : DECLARE_OOXMLEXPORT_TEST(testDmlShapeTitle, "dml-shape-title.docx")
45 : {
46 2 : CPPUNIT_ASSERT_EQUAL(OUString("Title"), getProperty<OUString>(getShape(1), "Title"));
47 2 : CPPUNIT_ASSERT_EQUAL(OUString("Description"), getProperty<OUString>(getShape(1), "Description"));
48 2 : }
49 :
50 16 : DECLARE_OOXMLEXPORT_TEST(testDmlZorder, "dml-zorder.odt")
51 : {
52 1 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
53 1 : if (!pXmlDoc)
54 1 : return;
55 : // This was "0": causing that in Word, the second shape was on top, while in the original odt the first shape is on top.
56 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor", "relativeHeight", "2");
57 : }
58 :
59 17 : DECLARE_OOXMLEXPORT_TEST(testDmlShapeRelsize, "dml-shape-relsize.docx")
60 : {
61 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
62 2 : if (!pXmlDoc)
63 3 : return;
64 : // Relative size wasn't exported all, then relativeFrom was "page", not "margin".
65 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp14:sizeRelH", "relativeFrom", "margin");
66 : }
67 :
68 17 : DECLARE_OOXMLEXPORT_TEST(testDmlPictureInTextframe, "dml-picture-in-textframe.docx")
69 : {
70 2 : if (!mbExported)
71 3 : return;
72 :
73 1 : uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL());
74 1 : CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/media/image1.gif")));
75 : // This was also true, image was written twice.
76 1 : CPPUNIT_ASSERT_EQUAL(false, bool(xNameAccess->hasByName("word/media/image2.gif")));
77 : }
78 :
79 17 : DECLARE_OOXMLEXPORT_TEST(testDmlGroupshapeRelsize, "dml-groupshape-relsize.docx")
80 : {
81 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
82 2 : if (!pXmlDoc)
83 3 : return;
84 : // Relative size wasn't imported.
85 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp14:sizeRelH", "relativeFrom", "margin");
86 : }
87 :
88 17 : DECLARE_OOXMLEXPORT_TEST(testDmlTextshape, "dml-textshape.docx")
89 : {
90 2 : uno::Reference<container::XIndexAccess> xGroup(getShape(1), uno::UNO_QUERY);
91 3 : uno::Reference<drawing::XShape> xShape(xGroup->getByIndex(1), uno::UNO_QUERY);
92 : // This was drawing::FillStyle_NONE.
93 2 : CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xShape, "FillStyle"));
94 : // This was drawing::LineStyle_NONE.
95 2 : CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, getProperty<drawing::LineStyle>(xShape, "LineStyle"));
96 :
97 2 : xmlDocPtr pXmlDocument = parseExport("word/document.xml");
98 2 : if (!pXmlDocument)
99 3 : return;
100 : // This was wrap="none".
101 1 : assertXPath(pXmlDocument, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/a:graphicData/wpg:wgp/wps:wsp[2]/wps:bodyPr", "wrap", "square");
102 :
103 1 : xShape.set(xGroup->getByIndex(3), uno::UNO_QUERY);
104 2 : OUString aType = comphelper::SequenceAsHashMap(getProperty<beans::PropertyValues>(xShape, "CustomShapeGeometry"))["Type"].get<OUString>();
105 1 : CPPUNIT_ASSERT_EQUAL(OUString("ooxml-bentConnector3"), aType);
106 : // Connector was incorrectly shifted towards the top left corner, X was 552, Y was 0.
107 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(4018), xShape->getPosition().X);
108 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1256), xShape->getPosition().Y);
109 :
110 1 : xShape.set(xGroup->getByIndex(5), uno::UNO_QUERY);
111 : // This was incorrectly shifted towards the top of the page, Y was 106.
112 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1016), xShape->getPosition().Y);
113 : }
114 :
115 17 : DECLARE_OOXMLEXPORT_TEST(testDMLSolidfillAlpha, "dml-solidfill-alpha.docx")
116 : {
117 : // Problem was that the transparency was not exported (a:alpha).
118 : // RGB color (a:srgbClr)
119 2 : uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);;
120 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(70), getProperty<sal_Int16>(xShape, "FillTransparence"));
121 :
122 : // Theme color (a:schemeClr)
123 2 : xShape.set(getShape(2), uno::UNO_QUERY);
124 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(20), getProperty<sal_Int16>(xShape, "FillTransparence"));
125 2 : }
126 :
127 17 : DECLARE_OOXMLEXPORT_TEST(testDMLCustomGeometry, "dml-customgeometry-cubicbezier.docx")
128 : {
129 :
130 : // The problem was that a custom shape was not exported.
131 2 : uno::Sequence<beans::PropertyValue> aProps = getProperty< uno::Sequence<beans::PropertyValue> >(getShape(1), "CustomShapeGeometry");
132 4 : uno::Sequence<beans::PropertyValue> aPathProps;
133 18 : for (int i = 0; i < aProps.getLength(); ++i)
134 : {
135 16 : const beans::PropertyValue& rProp = aProps[i];
136 16 : if (rProp.Name == "Path")
137 2 : rProp.Value >>= aPathProps;
138 : }
139 4 : uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aPairs;
140 4 : uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
141 10 : for (int i = 0; i < aPathProps.getLength(); ++i)
142 : {
143 8 : const beans::PropertyValue& rProp = aPathProps[i];
144 8 : if (rProp.Name == "Coordinates")
145 2 : rProp.Value >>= aPairs;
146 6 : else if (rProp.Name == "Segments")
147 2 : rProp.Value >>= aSegments;
148 : }
149 :
150 : // (a:moveTo)
151 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(1), aSegments[0].Count);
152 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(drawing::EnhancedCustomShapeSegmentCommand::MOVETO), aSegments[0].Command );
153 :
154 : // (a:cubicBezTo)
155 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(5), aSegments[1].Count);
156 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(drawing::EnhancedCustomShapeSegmentCommand::CURVETO), aSegments[1].Command );
157 :
158 : // Coordinates
159 2 : sal_Int32 nLength = 16;
160 2 : CPPUNIT_ASSERT_EQUAL(nLength, aPairs.getLength());
161 : std::pair<sal_Int32,sal_Int32> aCoordinates[] =
162 : {
163 : std::pair<sal_Int32,sal_Int32>(9084, 0),
164 : std::pair<sal_Int32,sal_Int32>(6734, 689),
165 : std::pair<sal_Int32,sal_Int32>(4489, 893),
166 : std::pair<sal_Int32,sal_Int32>(2633, 893),
167 : std::pair<sal_Int32,sal_Int32>(1631, 893),
168 : std::pair<sal_Int32,sal_Int32>(733, 830),
169 : std::pair<sal_Int32,sal_Int32>(0, 752),
170 : std::pair<sal_Int32,sal_Int32>(987, 908),
171 : std::pair<sal_Int32,sal_Int32>(2274, 1034),
172 : std::pair<sal_Int32,sal_Int32>(3756, 1034),
173 : std::pair<sal_Int32,sal_Int32>(5357, 1034),
174 : std::pair<sal_Int32,sal_Int32>(7183, 877),
175 : std::pair<sal_Int32,sal_Int32>(9084, 423),
176 : std::pair<sal_Int32,sal_Int32>(9084, 0),
177 : std::pair<sal_Int32,sal_Int32>(9084, 0),
178 : std::pair<sal_Int32,sal_Int32>(9084, 0)
179 2 : };
180 :
181 34 : for( int i = 0; i < nLength; ++i )
182 : {
183 32 : CPPUNIT_ASSERT(abs(aCoordinates[i].first - aPairs[i].First.Value.get<sal_Int32>()) < 20);
184 32 : CPPUNIT_ASSERT(abs(aCoordinates[i].second - aPairs[i].Second.Value.get<sal_Int32>()) < 20);
185 2 : }
186 2 : }
187 :
188 17 : DECLARE_OOXMLEXPORT_TEST(testDmlRectangleRelsize, "dml-rectangle-relsize.docx")
189 : {
190 : // This was around 19560, as we did not read wp14:pctHeight for
191 : // drawinglayer shapes and the fallback data was invalid.
192 2 : OString aMessage("Height is only " + OString::number(getShape(1)->getSize().Height));
193 2 : CPPUNIT_ASSERT_MESSAGE(aMessage.getStr(), getShape(1)->getSize().Height >= 20967);
194 :
195 : // This was around 0: relative size of 0% was imported as 0, not "fall back to absolute size".
196 2 : CPPUNIT_ASSERT(getShape(2)->getSize().Height > 300);
197 2 : }
198 :
199 17 : DECLARE_OOXMLEXPORT_TEST(testDMLTextFrameVertAdjust, "dml-textframe-vertadjust.docx")
200 : {
201 : // DOCX textboxes with text are imported as text frames but in Writer text frames did not have
202 : // TextVerticalAdjust attribute so far.
203 :
204 : // 1st frame's context is adjusted to the top
205 2 : uno::Reference<beans::XPropertySet> xFrame(getShapeByName("Rectangle 1"), uno::UNO_QUERY);
206 2 : CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_TOP, getProperty<drawing::TextVerticalAdjust>(xFrame, "TextVerticalAdjust"));
207 : // 2nd frame's context is adjusted to the center
208 2 : xFrame.set(getShapeByName("Rectangle 2"), uno::UNO_QUERY);
209 2 : CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_CENTER, getProperty<drawing::TextVerticalAdjust>(xFrame, "TextVerticalAdjust"));
210 : // 3rd frame's context is adjusted to the bottom
211 2 : xFrame.set(getShapeByName("Rectangle 3"), uno::UNO_QUERY);
212 2 : CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_BOTTOM, getProperty<drawing::TextVerticalAdjust>(xFrame, "TextVerticalAdjust"));
213 2 : }
214 :
215 17 : DECLARE_OOXMLEXPORT_TEST(testDMLShapeFillBitmapCrop, "dml-shape-fillbitmapcrop.docx")
216 : {
217 : // Test the new GraphicCrop property which is introduced to define
218 : // cropping of shapes filled with a picture in stretch mode.
219 :
220 : // 1st shape has some cropping
221 2 : text::GraphicCrop aGraphicCropStruct = getProperty<text::GraphicCrop>(getShape(1), "GraphicCrop");
222 2 : CPPUNIT_ASSERT_EQUAL( sal_Int32(mbExported ? 454 : 455 ), aGraphicCropStruct.Left );
223 2 : CPPUNIT_ASSERT_EQUAL( sal_Int32(mbExported ? 367 : 368 ), aGraphicCropStruct.Right );
224 2 : CPPUNIT_ASSERT_EQUAL( sal_Int32(mbExported ? -454 : -455 ), aGraphicCropStruct.Top );
225 2 : CPPUNIT_ASSERT_EQUAL( sal_Int32(mbExported ? -367 : -368 ), aGraphicCropStruct.Bottom );
226 :
227 : // 2nd shape has no cropping
228 2 : aGraphicCropStruct = getProperty<text::GraphicCrop>(getShape(2), "GraphicCrop");
229 2 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), aGraphicCropStruct.Left );
230 2 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), aGraphicCropStruct.Right );
231 2 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), aGraphicCropStruct.Top );
232 2 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), aGraphicCropStruct.Bottom );
233 :
234 2 : }
235 :
236 17 : DECLARE_OOXMLEXPORT_TEST(testDMLShapeFillPattern, "dml-shape-fillpattern.docx")
237 : {
238 : // Hatching was ignored by the export.
239 :
240 : // 1st shape: light horizontal pattern (ltHorz)
241 2 : drawing::Hatch aHatch = getProperty<drawing::Hatch>(getShape(1), "FillHatch");
242 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aHatch.Angle);
243 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(50), aHatch.Distance);
244 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x99FF66), aHatch.Color);
245 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_SINGLE, aHatch.Style);
246 :
247 : // 2nd shape: horizontal pattern (horz)
248 2 : aHatch = getProperty<drawing::Hatch>(getShape(2), "FillHatch");
249 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aHatch.Angle);
250 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(100), aHatch.Distance);
251 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_SINGLE, aHatch.Style);
252 :
253 : // 3rd shape: light vertical pattern (ltVert)
254 2 : aHatch = getProperty<drawing::Hatch>(getShape(3), "FillHatch");
255 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(900), aHatch.Angle);
256 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(50), aHatch.Distance);
257 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_SINGLE, aHatch.Style);
258 :
259 : // 4th shape: vertical pattern (vert)
260 2 : aHatch = getProperty<drawing::Hatch>(getShape(4), "FillHatch");
261 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(900), aHatch.Angle);
262 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(100), aHatch.Distance);
263 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_SINGLE, aHatch.Style);
264 :
265 : // 5th shape: light upward diagonal pattern (ltUpDiag)
266 2 : aHatch = getProperty<drawing::Hatch>(getShape(5), "FillHatch");
267 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(450), aHatch.Angle);
268 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(50), aHatch.Distance);
269 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_SINGLE, aHatch.Style);
270 :
271 : // 6th shape: wide upward diagonal pattern (wdUpDiag)
272 2 : aHatch = getProperty<drawing::Hatch>(getShape(6), "FillHatch");
273 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(450), aHatch.Angle);
274 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(100), aHatch.Distance);
275 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_SINGLE, aHatch.Style);
276 :
277 : // 7th shape: light downward diagonal pattern (ltDnDiag)
278 2 : aHatch = getProperty<drawing::Hatch>(getShape(7), "FillHatch");
279 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1350), aHatch.Angle);
280 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(50), aHatch.Distance);
281 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_SINGLE, aHatch.Style);
282 :
283 : // 8th shape: wide downward diagonal pattern (wdDnDiag)
284 2 : aHatch = getProperty<drawing::Hatch>(getShape(8), "FillHatch");
285 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1350), aHatch.Angle);
286 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(100), aHatch.Distance);
287 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_SINGLE, aHatch.Style);
288 :
289 : // 9th shape: small grid pattern (smGrid)
290 2 : aHatch = getProperty<drawing::Hatch>(getShape(9), "FillHatch");
291 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aHatch.Angle);
292 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(50), aHatch.Distance);
293 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_DOUBLE, aHatch.Style);
294 :
295 : // 10th shape: large grid pattern (lgGrid)
296 2 : aHatch = getProperty<drawing::Hatch>(getShape(10), "FillHatch");
297 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aHatch.Angle);
298 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(100), aHatch.Distance);
299 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_DOUBLE, aHatch.Style);
300 :
301 : // 11th shape: small checker board pattern (smCheck)
302 2 : aHatch = getProperty<drawing::Hatch>(getShape(11), "FillHatch");
303 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(450), aHatch.Angle);
304 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(50), aHatch.Distance);
305 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_DOUBLE, aHatch.Style);
306 :
307 : // 12th shape: outlined diamond pattern (openDmnd)
308 2 : aHatch = getProperty<drawing::Hatch>(getShape(12), "FillHatch");
309 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(450), aHatch.Angle);
310 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(100), aHatch.Distance);
311 2 : CPPUNIT_ASSERT_EQUAL(drawing::HatchStyle_DOUBLE, aHatch.Style);
312 2 : }
313 :
314 17 : DECLARE_OOXMLEXPORT_TEST(testDMLGroupShapeChildPosition, "dml-groupshape-childposition.docx")
315 : {
316 : // Problem was parent transformation was ignored fully, but translate component
317 : // which specify the position must be also applied for children of the group.
318 :
319 2 : uno::Reference<drawing::XShapes> xGroup(getShape(1), uno::UNO_QUERY);
320 4 : uno::Reference<drawing::XShape> xChildGroup(xGroup->getByIndex(1), uno::UNO_QUERY);
321 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(mbExported ? -2120 : -2122), xChildGroup->getPosition().X);
322 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(mbExported ? 11336 : 11333), xChildGroup->getPosition().Y);
323 :
324 2 : xGroup.set(xChildGroup, uno::UNO_QUERY);
325 2 : xChildGroup.set(xGroup->getByIndex(0), uno::UNO_QUERY);
326 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(mbExported ? -1856 : -1858), xChildGroup->getPosition().X);
327 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(mbExported ? 11336 : 11333), xChildGroup->getPosition().Y);
328 :
329 2 : xChildGroup.set(xGroup->getByIndex(1), uno::UNO_QUERY);
330 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(mbExported ? -2120 : -2122), xChildGroup->getPosition().X);
331 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(mbExported ? 14026 : 14023), xChildGroup->getPosition().Y);
332 2 : }
333 :
334 17 : DECLARE_OOXMLEXPORT_TEST(testDMLGradientFillTheme, "dml-gradientfill-theme.docx")
335 : {
336 : // Problem was when a fill gradient was imported from a theme, (fillRef in ooxml)
337 : // not just the theme was written out but the explicit values too
338 : // Besides the duplication of values it causes problems with writing out
339 : // <a:schemeClr val="phClr"> into document.xml, while phClr can be used just for theme definitions.
340 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
341 2 : if (!pXmlDoc)
342 3 : return;
343 :
344 : // check no explicit gradFill has been exported
345 : assertXPath(pXmlDoc,
346 : "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill",
347 1 : 0);
348 :
349 : // check shape style has been exported
350 : assertXPath(pXmlDoc,
351 : "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:fillRef",
352 1 : "idx", "2");
353 : assertXPath(pXmlDoc,
354 : "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:fillRef/a:schemeClr",
355 1 : "val", "accent1");
356 : }
357 :
358 17 : DECLARE_OOXMLEXPORT_TEST(testDMLGroupShapeParaSpacing, "dml-groupshape-paraspacing.docx")
359 : {
360 : // Paragraph spacing (top/bottom margin and line spacing) inside a group shape was not imported
361 2 : uno::Reference<container::XIndexAccess> xGroup(getShape(1), uno::UNO_QUERY);
362 4 : uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xGroup->getByIndex(1), uno::UNO_QUERY)->getText();
363 :
364 : // 1st paragraph has 1.5x line spacing but it has no spacing before/after.
365 4 : uno::Reference<text::XTextRange> xRun = getRun(getParagraphOfText(1, xText),1);
366 2 : style::LineSpacing aLineSpacing = getProperty<style::LineSpacing>(xRun, "ParaLineSpacing");
367 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), aLineSpacing.Mode);
368 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(150), aLineSpacing.Height);
369 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaTopMargin"));
370 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaBottomMargin"));
371 :
372 : // 2nd paragraph has double line spacing but it has no spacing before/after.
373 2 : xRun.set(getRun(getParagraphOfText(2, xText),1));
374 2 : aLineSpacing = getProperty<style::LineSpacing>(xRun, "ParaLineSpacing");
375 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), aLineSpacing.Mode);
376 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(200), aLineSpacing.Height);
377 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaTopMargin"));
378 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaBottomMargin"));
379 :
380 : // 3rd paragraph has 24 pt line spacing but it has no spacing before/after.
381 2 : xRun.set(getRun(getParagraphOfText(3, xText),1));
382 2 : aLineSpacing = getProperty<style::LineSpacing>(xRun, "ParaLineSpacing");
383 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::MINIMUM), aLineSpacing.Mode);
384 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(847), aLineSpacing.Height);
385 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaTopMargin"));
386 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaBottomMargin"));
387 :
388 : // 4th paragraph has 1.75x line spacing but it has no spacing before/after.
389 2 : xRun.set(getRun(getParagraphOfText(4, xText),1));
390 2 : aLineSpacing = getProperty<style::LineSpacing>(xRun, "ParaLineSpacing");
391 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), aLineSpacing.Mode);
392 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(175), aLineSpacing.Height);
393 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaTopMargin"));
394 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaBottomMargin"));
395 :
396 : // 5th paragraph has margins which are defined by w:beforeLines and w:afterLines.
397 2 : xRun.set(getRun(getParagraphOfText(5, xText),1));
398 2 : aLineSpacing = getProperty<style::LineSpacing>(xRun, "ParaLineSpacing");
399 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), aLineSpacing.Mode);
400 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(100), aLineSpacing.Height);
401 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(635), getProperty<sal_Int32>(xRun, "ParaTopMargin"));
402 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(741), getProperty<sal_Int32>(xRun, "ParaBottomMargin"));
403 :
404 : // 6th paragraph has margins which are defined by w:before and w:after.
405 2 : xRun.set(getRun(getParagraphOfText(6, xText),1));
406 2 : aLineSpacing = getProperty<style::LineSpacing>(xRun, "ParaLineSpacing");
407 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), aLineSpacing.Mode);
408 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(100), aLineSpacing.Height);
409 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(423), getProperty<sal_Int32>(xRun, "ParaTopMargin"));
410 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(635), getProperty<sal_Int32>(xRun, "ParaBottomMargin"));
411 :
412 : // 7th paragraph has auto paragraph margins a:afterAutospacing and a:beforeAutospacing, which means margins must be ignored.
413 2 : xRun.set(getRun(getParagraphOfText(7, xText),1));
414 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaTopMargin"));
415 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun, "ParaBottomMargin"));
416 2 : }
417 :
418 17 : DECLARE_OOXMLEXPORT_TEST(testTableFloatingMargins, "table-floating-margins.docx")
419 : {
420 : // In case the table had custom left cell margin, the horizontal position was still incorrect (too small, -199).
421 2 : uno::Reference<beans::XPropertySet> xFrame(getShape(1), uno::UNO_QUERY);
422 2 : sal_Int32 nHoriOrientPosition = getProperty<sal_Int32>(xFrame, "HoriOrientPosition");
423 2 : CPPUNIT_ASSERT(nHoriOrientPosition < sal_Int32(-495));
424 : // These were 0 as well, due to lack of import.
425 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), getProperty<sal_Int32>(xFrame, "TopMargin"));
426 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(2000), getProperty<sal_Int32>(xFrame, "BottomMargin"));
427 :
428 : // Paragraph bottom margin wasn't 0 in the A1 cell of the floating table.
429 2 : xmlDocPtr pXmlDoc = parseExport();
430 2 : if (!pXmlDoc)
431 3 : return;
432 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:rect/v:textbox/w:txbxContent/w:tbl/w:tr[1]/w:tc[1]/w:p/w:pPr/w:spacing", "after", "0");
433 : }
434 :
435 17 : DECLARE_OOXMLEXPORT_TEST(testFdo69636, "fdo69636.docx")
436 : {
437 : /*
438 : * The problem was that the exporter didn't mirror the workaround of the
439 : * importer, regarding the btLr text frame direction: the
440 : * mso-layout-flow-alt property was completely missing in the output.
441 : */
442 2 : xmlDocPtr pXmlDoc = parseExport();
443 2 : if (!pXmlDoc)
444 3 : return;
445 : // VML
446 1 : CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:rect/v:textbox", "style").match("mso-layout-flow-alt:bottom-to-top"));
447 : // drawingML
448 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:bodyPr", "vert", "vert270");
449 : }
450 :
451 17 : DECLARE_OOXMLEXPORT_TEST(testVMLData, "TestVMLData.docx")
452 : {
453 : // The problem was exporter was exporting vml data for shape in w:rPr element.
454 : // vml data should not come under w:rPr element.
455 2 : xmlDocPtr pXmlDoc = parseExport("word/header2.xml");
456 2 : if (!pXmlDoc)
457 3 : return;
458 1 : CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:hdr/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "stroked").match("f"));
459 : }
460 :
461 17 : DECLARE_OOXMLEXPORT_TEST(testImageData, "image_data.docx")
462 : {
463 : // The problem was exporter was exporting v:imagedata data for shape in w:pict as v:fill w element.
464 :
465 2 : xmlDocPtr pXmlDoc = parseExport("word/header2.xml");
466 2 : if (!pXmlDoc)
467 3 : return;
468 1 : CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:hdr/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:rect/v:imagedata", "detectmouseclick").match("t"));
469 : }
470 :
471 17 : DECLARE_OOXMLEXPORT_TEST(testFdo70838, "fdo70838.docx")
472 : {
473 : // The problem was that VMLExport::Commit didn't save the correct width and height,
474 : // and ImplEESdrWriter::ImplFlipBoundingBox made a mistake calculating the position
475 :
476 2 : xmlDocPtr pXmlDocument = parseExport("word/document.xml");
477 2 : if (!pXmlDocument)
478 3 : return;
479 :
480 : // Check DML document
481 :
482 : sal_Int32 aXPos[4], aYPos[4];
483 1 : aXPos[0] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32();
484 1 : aXPos[1] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32();
485 1 : aXPos[2] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32();
486 1 : aXPos[3] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32();
487 :
488 1 : aYPos[0] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32();
489 1 : aYPos[1] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32();
490 1 : aYPos[2] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32();
491 1 : aYPos[3] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32();
492 :
493 : // certain degree of error is tolerated due to rounding in unit conversions
494 1 : CPPUNIT_ASSERT(abs(1239520 - aXPos[0]) < 1000);
495 1 : CPPUNIT_ASSERT(abs(1239520 - aXPos[1]) < 1000);
496 1 : CPPUNIT_ASSERT(abs(1238250 - aXPos[2]) < 1000);
497 1 : CPPUNIT_ASSERT(abs(1238885 - aXPos[3]) < 1000);
498 :
499 1 : CPPUNIT_ASSERT(abs(2095500 - aYPos[0]) < 1000);
500 1 : CPPUNIT_ASSERT(abs(2094865 - aYPos[1]) < 1000);
501 1 : CPPUNIT_ASSERT(abs(2094230 - aYPos[2]) < 1000);
502 1 : CPPUNIT_ASSERT(abs(2094865 - aYPos[3]) < 1000);
503 :
504 : sal_Int32 aHSize[4], aVSize[4];
505 1 : aHSize[0] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32();
506 1 : aHSize[1] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32();
507 1 : aHSize[2] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32();
508 1 : aHSize[3] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32();
509 :
510 1 : aVSize[0] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32();
511 1 : aVSize[1] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32();
512 1 : aVSize[2] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32();
513 1 : aVSize[3] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32();
514 :
515 : // certain degree of error is tolerated due to rounding in unit conversions
516 1 : CPPUNIT_ASSERT(abs(3599280 - aHSize[0]) < 1000);
517 1 : CPPUNIT_ASSERT(abs(3599280 - aHSize[1]) < 1000);
518 1 : CPPUNIT_ASSERT(abs(3599280 - aHSize[2]) < 1000);
519 1 : CPPUNIT_ASSERT(abs(3599280 - aHSize[3]) < 1000);
520 :
521 1 : CPPUNIT_ASSERT(abs(1799640 - aVSize[0]) < 1000);
522 1 : CPPUNIT_ASSERT(abs(1799640 - aVSize[1]) < 1000);
523 1 : CPPUNIT_ASSERT(abs(1799640 - aVSize[2]) < 1000);
524 1 : CPPUNIT_ASSERT(abs(1799640 - aVSize[3]) < 1000);
525 :
526 : // Check VML document
527 :
528 : // get styles of the four shapes
529 5 : OUString aStyles[4];
530 1 : aStyles[0] = getXPath( pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:rect", "style");
531 : // original is: "position:absolute;margin-left:97.6pt;margin-top:165pt;width:283.4pt;height:141.7pt;rotation:285"
532 1 : aStyles[1] = getXPath( pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Fallback/w:pict/v:rect", "style");
533 : // original is: "position:absolute;margin-left:97.6pt;margin-top:164.95pt;width:283.4pt;height:141.7pt;rotation:255"
534 1 : aStyles[2] = getXPath( pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Fallback/w:pict/v:rect", "style");
535 : // original is: "position:absolute;margin-left:97.5pt;margin-top:164.9pt;width:283.4pt;height:141.7pt;rotation:105"
536 1 : aStyles[3] = getXPath( pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Fallback/w:pict/v:rect", "style");
537 : // original is: "position:absolute;margin-left:97.55pt;margin-top:164.95pt;width:283.4pt;height:141.7pt;rotation:75"
538 :
539 : //check the size and position of each of the shapes
540 5 : for( int i = 0; i < 4; ++i )
541 : {
542 4 : CPPUNIT_ASSERT(!aStyles[i].isEmpty());
543 :
544 4 : sal_Int32 nextTokenPos = 0;
545 24 : do
546 : {
547 24 : OUString aStyleCommand = aStyles[i].getToken( 0, ';', nextTokenPos );
548 24 : CPPUNIT_ASSERT(!aStyleCommand.isEmpty());
549 :
550 48 : OUString aStyleCommandName = aStyleCommand.getToken( 0, ':' );
551 48 : OUString aStyleCommandValue = aStyleCommand.getToken( 1, ':' );
552 :
553 24 : if( aStyleCommandName == "margin-left" )
554 : {
555 4 : float fValue = aStyleCommandValue.getToken( 0, 'p' ).toFloat();
556 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(97.6, fValue, 0.1);
557 : }
558 20 : else if( aStyleCommandName == "margin-top" )
559 : {
560 4 : float fValue = aStyleCommandValue.getToken( 0, 'p' ).toFloat();
561 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(165.0, fValue, 0.2);
562 : }
563 16 : else if( aStyleCommandName == "width" )
564 : {
565 4 : float fValue = aStyleCommandValue.getToken( 0, 'p' ).toFloat();
566 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(283.4, fValue, 0.1);
567 : }
568 12 : else if( aStyleCommandName == "height" )
569 : {
570 4 : float fValue = aStyleCommandValue.getToken( 0, 'p' ).toFloat();
571 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(141.7, fValue, 0.1);
572 24 : }
573 :
574 24 : } while( nextTokenPos != -1 );
575 : }
576 :
577 : // Check shape objects
578 :
579 1 : awt::Point aPos[4];
580 1 : aPos[0] = getShape(1)->getPosition();
581 1 : aPos[1] = getShape(2)->getPosition();
582 1 : aPos[2] = getShape(3)->getPosition();
583 1 : aPos[3] = getShape(4)->getPosition();
584 :
585 : // certain degree of error is tolerated due to rounding in unit conversions
586 1 : CPPUNIT_ASSERT(abs(4734 - aPos[0].X) < 10);
587 1 : CPPUNIT_ASSERT(abs(4734 - aPos[1].X) < 10);
588 1 : CPPUNIT_ASSERT(abs(4731 - aPos[2].X) < 10);
589 1 : CPPUNIT_ASSERT(abs(4733 - aPos[3].X) < 10);
590 :
591 1 : CPPUNIT_ASSERT(abs(2845 - aPos[0].Y) < 10);
592 1 : CPPUNIT_ASSERT(abs(2843 - aPos[1].Y) < 10);
593 1 : CPPUNIT_ASSERT(abs(2842 - aPos[2].Y) < 10);
594 5 : CPPUNIT_ASSERT(abs(2843 - aPos[3].Y) < 10);
595 : }
596 :
597 17 : DECLARE_OOXMLEXPORT_TEST(testFdo73215, "fdo73215.docx")
598 : {
599 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
600 2 : if (!pXmlDoc)
601 3 : return;
602 : // 'rect' was 'pictureFrame', which isn't valid.
603 : assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/a:graphicData/wpg:wgp/wps:wsp[1]/wps:spPr/a:prstGeom",
604 1 : "prst", "rect");
605 : // 'adj1' was 'adj', which is not valid for bentConnector3.
606 : assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/a:graphicData/wpg:wgp/wps:wsp[9]/wps:spPr/a:prstGeom/a:avLst/a:gd",
607 1 : "name", "adj1");
608 : }
609 :
610 17 : DECLARE_OOXMLEXPORT_TEST(testBehinddoc, "behinddoc.docx")
611 : {
612 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
613 2 : if (!pXmlDoc)
614 3 : return;
615 : // This was "0", shape was in the foreground.
616 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor", "behindDoc", "1");
617 : }
618 :
619 17 : DECLARE_OOXMLEXPORT_TEST(testSmartArtAnchoredInline, "fdo73227.docx")
620 : {
621 : /* Given file conatins 3 DrawingML objects as 1Picture,1SmartArt and 1Shape.
622 : * Check for SmartArt.
623 : * SmartArt shoould get written as "Floating Object" i.e. inside <wp:anchor> tag.
624 : * Also check for value of attribute "id" of <wp:docPr> . It should be unique for
625 : * all 3 DrawingML objects in a document.
626 : */
627 :
628 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
629 2 : if (!pXmlDoc)
630 3 : return;
631 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:drawing[1]/wp:anchor/wp:docPr","id","1");
632 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:drawing[1]/wp:anchor/wp:docPr","name","Diagram1");
633 :
634 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr","id","2");
635 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr","name","10-Point Star 3");
636 :
637 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:drawing[2]/wp:anchor/wp:docPr","id","3");
638 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:drawing[2]/wp:anchor/wp:docPr","name","Picture 1");
639 : }
640 :
641 17 : DECLARE_OOXMLEXPORT_TEST(testFdo65833, "fdo65833.docx")
642 : {
643 : // The "editas" attribute for vml group shape was not preserved.
644 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
645 2 : if (!pXmlDoc)
646 3 : return;
647 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:group", "editas", "canvas");
648 : }
649 :
650 17 : DECLARE_OOXMLEXPORT_TEST(testFdo73247, "fdo73247.docx")
651 : {
652 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
653 2 : if (!pXmlDoc)
654 3 : return;
655 :
656 : assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:xfrm",
657 1 : "rot", "1969200");
658 : }
659 :
660 17 : DECLARE_OOXMLEXPORT_TEST(testFdo70942, "fdo70942.docx")
661 : {
662 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
663 2 : if (!pXmlDoc)
664 3 : return;
665 : assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
666 1 : "prst", "ellipse");
667 : }
668 :
669 17 : DECLARE_OOXMLEXPORT_TEST(testDrawinglayerPicPos, "drawinglayer-pic-pos.docx")
670 : {
671 : // The problem was that the position of the picture was incorrect, it was shifted towards the bottom right corner.
672 2 : xmlDocPtr pXmlDocument = parseExport("word/document.xml");
673 2 : if (!pXmlDocument)
674 3 : return;
675 :
676 1 : OString aXPath("/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/pic:pic/pic:spPr/a:xfrm/a:off");
677 : // This was 720.
678 1 : assertXPath(pXmlDocument, aXPath, "x", "0");
679 : // This was 1828800.
680 1 : assertXPath(pXmlDocument, aXPath, "y", "0");
681 : }
682 :
683 17 : DECLARE_OOXMLEXPORT_TEST(testShapeThemePreservation, "shape-theme-preservation.docx")
684 : {
685 2 : xmlDocPtr pXmlDocument = parseExport("word/document.xml");
686 2 : if (!pXmlDocument)
687 3 : return;
688 :
689 : // check shape style has been preserved
690 : assertXPath(pXmlDocument,
691 : "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:fillRef",
692 1 : "idx", "1");
693 : assertXPath(pXmlDocument,
694 : "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:fillRef/a:schemeClr",
695 1 : "val", "accent1");
696 : assertXPath(pXmlDocument,
697 : "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:fillRef",
698 1 : "idx", "1");
699 : assertXPath(pXmlDocument,
700 : "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:fillRef/a:schemeClr",
701 1 : "val", "accent1");
702 : assertXPath(pXmlDocument,
703 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:fillRef",
704 1 : "idx", "1");
705 : assertXPath(pXmlDocument,
706 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:fillRef/a:schemeClr",
707 1 : "val", "accent1");
708 : assertXPath(pXmlDocument,
709 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:lnRef",
710 1 : "idx", "2");
711 : assertXPath(pXmlDocument,
712 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:lnRef/a:schemeClr",
713 1 : "val", "accent1");
714 : assertXPath(pXmlDocument,
715 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:lnRef/a:schemeClr/a:shade",
716 1 : "val", "50000");
717 : assertXPath(pXmlDocument,
718 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:effectRef",
719 1 : "idx", "0");
720 : assertXPath(pXmlDocument,
721 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:style/a:effectRef/a:schemeClr",
722 1 : "val", "accent1");
723 :
724 : // check shape style hasn't been overwritten
725 : assertXPath(pXmlDocument,
726 : "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:solidFill",
727 1 : 0);
728 : assertXPath(pXmlDocument,
729 : "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:solidFill",
730 1 : 0);
731 :
732 : // check direct theme assignments have been preserved
733 : assertXPath(pXmlDocument,
734 : "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:solidFill/a:schemeClr",
735 1 : "val", "accent6");
736 : assertXPath(pXmlDocument,
737 : "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:solidFill/a:schemeClr",
738 1 : "val", "accent3");
739 :
740 : // check color transformations applied to theme colors have been preserved
741 : assertXPath(pXmlDocument,
742 : "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:solidFill/a:schemeClr/a:lumMod",
743 1 : "val", "40000");
744 : assertXPath(pXmlDocument,
745 : "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:solidFill/a:schemeClr/a:lumOff",
746 1 : "val", "60000");
747 : assertXPath(pXmlDocument,
748 : "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:solidFill/a:schemeClr/a:lumMod",
749 1 : "val", "50000");
750 :
751 : // check direct color assignments have been preserved
752 : OUString sFillColor = getXPath(pXmlDocument,
753 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:solidFill/a:srgbClr",
754 1 : "val");
755 1 : CPPUNIT_ASSERT_EQUAL(sFillColor.toInt32(16), sal_Int32(0x00b050));
756 : sal_Int32 nLineColor = getXPath(pXmlDocument,
757 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:solidFill/a:srgbClr",
758 1 : "val").toInt32(16);
759 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xff0000), nLineColor);
760 :
761 : // check direct line type assignments have been preserved
762 : sal_Int32 nLineWidth = getXPath(pXmlDocument,
763 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln",
764 1 : "w").toInt32();
765 1 : CPPUNIT_ASSERT(abs(63500 - nLineWidth) < 1000); //some rounding errors in the conversion ooxml -> libo -> ooxml are tolerated
766 : assertXPath(pXmlDocument,
767 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:miter",
768 1 : 1);
769 : assertXPath(pXmlDocument,
770 : "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:custDash",
771 1 : 1);
772 :
773 2 : uno::Reference<drawing::XShape> xShape1 = getShape(1);
774 2 : uno::Reference<drawing::XShape> xShape2 = getShape(2);
775 2 : uno::Reference<drawing::XShape> xShape3 = getShape(3);
776 :
777 : // check colors are properly applied to shapes on import
778 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x4f81bd), getProperty<sal_Int32>(xShape1, "FillColor"));
779 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xfcd5b5), getProperty<sal_Int32>(xShape2, "FillColor"));
780 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00b050), getProperty<sal_Int32>(xShape3, "FillColor"));
781 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x3a5f8b), getProperty<sal_Int32>(xShape1, "LineColor"));
782 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x4f6228), getProperty<sal_Int32>(xShape2, "LineColor"));
783 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xff0000), getProperty<sal_Int32>(xShape3, "LineColor"));
784 :
785 : // check line properties are properly applied to shapes on import
786 1 : CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, getProperty<drawing::LineStyle>(xShape1, "LineStyle"));
787 1 : CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, getProperty<drawing::LineStyle>(xShape2, "LineStyle"));
788 1 : CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_DASH, getProperty<drawing::LineStyle>(xShape3, "LineStyle"));
789 1 : CPPUNIT_ASSERT_EQUAL(drawing::LineJoint_ROUND, getProperty<drawing::LineJoint>(xShape1, "LineJoint"));
790 1 : CPPUNIT_ASSERT_EQUAL(drawing::LineJoint_ROUND, getProperty<drawing::LineJoint>(xShape2, "LineJoint"));
791 2 : CPPUNIT_ASSERT_EQUAL(drawing::LineJoint_MITER, getProperty<drawing::LineJoint>(xShape3, "LineJoint"));
792 : }
793 :
794 17 : DECLARE_OOXMLEXPORT_TEST(testFDO73546, "FDO73546.docx")
795 : {
796 2 : xmlDocPtr pXmlDoc = parseExport("word/header1.xml");
797 2 : if (!pXmlDoc)
798 3 : return;
799 1 : assertXPath(pXmlDoc, "/w:hdr/w:p[1]/w:r[3]/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor", "distL","0");
800 : }
801 :
802 17 : DECLARE_OOXMLEXPORT_TEST(testFdo69616, "fdo69616.docx")
803 : {
804 2 : xmlDocPtr pXmlDoc = parseExport();
805 2 : if (!pXmlDoc)
806 3 : return;
807 : // VML
808 1 : CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtContent/w:p[1]/w:r[1]/mc:AlternateContent/mc:Fallback/w:pict/v:group", "coordorigin").match("696,725"));
809 : }
810 :
811 17 : DECLARE_OOXMLEXPORT_TEST(testAlignForShape,"Shape.docx")
812 : {
813 : //fdo73545:Shape Horizontal and vertical orientation is wrong
814 : //The wp:align tag is missing after roundtrip
815 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
816 2 : if (!pXmlDoc)
817 3 : return;
818 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:align","1");
819 : }
820 :
821 17 : DECLARE_OOXMLEXPORT_TEST(testLineStyle_DashType, "LineStyle_DashType.docx")
822 : {
823 : /* DOCX contatining Shape with LineStyle as Dash Type should get preserved inside
824 : * an XMl tag <a:prstDash> with value "dash".
825 : */
826 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
827 2 : if (!pXmlDoc)
828 3 : return;
829 :
830 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r[1]/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:prstDash", "val", "dash");
831 : }
832 :
833 17 : DECLARE_OOXMLEXPORT_TEST(testGradientFillPreservation, "gradient-fill-preservation.docx")
834 : {
835 2 : xmlDocPtr pXmlDocument = parseExport("word/document.xml");
836 2 : if (!pXmlDocument)
837 3 : return;
838 :
839 : // check rgb colors for every step in the gradient of the first shape
840 : assertXPath(pXmlDocument,
841 : "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill/a:gsLst/a:gs[1]/a:srgbClr",
842 1 : "val", "ffff00");
843 : assertXPath(pXmlDocument,
844 : "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill/a:gsLst/a:gs[2]/a:srgbClr",
845 1 : "val", "ffff33");
846 : assertXPath(pXmlDocument,
847 : "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill/a:gsLst/a:gs[3]/a:srgbClr",
848 1 : "val", "ff0000");
849 :
850 : // check theme colors for every step in the gradient of the second shape
851 : assertXPath(pXmlDocument,
852 : "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill/a:gsLst/a:gs[@pos='0']/a:schemeClr",
853 1 : "val", "accent5");
854 : assertXPath(pXmlDocument,
855 : "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill/a:gsLst/a:gs[@pos='50000']/a:schemeClr",
856 1 : "val", "accent1");
857 : assertXPath(pXmlDocument,
858 : "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill/a:gsLst/a:gs[@pos='100000']/a:schemeClr",
859 1 : "val", "accent1");
860 :
861 : assertXPath(pXmlDocument,
862 : "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill/a:gsLst/a:gs[@pos='50000']/a:srgbClr/a:alpha",
863 1 : "val", "20000");
864 : assertXPath(pXmlDocument,
865 : "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill/a:gsLst/a:gs[@pos='50000']/a:schemeClr/a:tint",
866 1 : "val", "44500");
867 : assertXPath(pXmlDocument,
868 : "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:gradFill/a:gsLst/a:gs[@pos='50000']/a:schemeClr/a:satMod",
869 1 : "val", "160000");
870 : }
871 :
872 17 : DECLARE_OOXMLEXPORT_TEST(testLineStyle_DashType_VML, "LineStyle_DashType_VML.docx")
873 : {
874 : /* DOCX contatining "Shape with text inside" having Line Style as "Dash Type" should get
875 : * preserved inside an XML tag <v:stroke> with attribute dashstyle having value "dash".
876 : */
877 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
878 2 : if (!pXmlDoc)
879 3 : return;
880 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r[1]/mc:AlternateContent/mc:Fallback/w:pict/v:rect/v:stroke", "dashstyle", "dash");
881 : }
882 :
883 17 : DECLARE_OOXMLEXPORT_TEST(testFdo74110,"fdo74110.docx")
884 : {
885 : /*
886 : The File contains word art which is being exported as shape and the mapping is defaulted to
887 : shape type rect since the actual shape type(s) is/are commented out for some reason.
888 : The actual shape type(s) has/have adjustment value(s) where as rect does not have adjustment value.
889 : Hence the following test case.
890 : */
891 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
892 2 : if (!pXmlDoc)
893 3 : return;
894 : assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent/mc:Choice/w:drawing[1]/wp:inline[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:prstGeom[1]",
895 1 : "prst", "rect");
896 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent/mc:Choice/w:drawing[1]/wp:inline[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:prstGeom[1]/a:avLst[1]/a:gd[1]",0);
897 : }
898 :
899 17 : DECLARE_OOXMLEXPORT_TEST(testOuterShdw,"testOuterShdw.docx")
900 : {
901 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
902 2 : if (!pXmlDoc)
903 3 : return;
904 1 : assertXPath(pXmlDoc, "//mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:effectLst[1]/a:outerShdw[1]", "dist", "57811035");
905 : }
906 :
907 17 : DECLARE_OOXMLEXPORT_TEST(testExtentValue, "fdo74605.docx")
908 : {
909 2 : xmlDocPtr pXmlDoc = parseExport();
910 2 : if (!pXmlDoc)
911 3 : return;
912 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/wp:extent","cx","0");
913 : }
914 :
915 : #endif
916 :
917 4 : CPPUNIT_PLUGIN_IMPLEMENT();
918 :
919 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|