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 <memory>
11 #include <string_view>
12 #include <config_features.h>
13 
14 #ifdef MACOSX
15 #define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
16 #include <premac.h>
17 #include <AppKit/AppKit.h>
18 #include <postmac.h>
19 #endif
20 
21 #include <swmodeltestbase.hxx>
22 
23 #include <com/sun/star/beans/XPropertySet.hpp>
24 #include <com/sun/star/document/XEmbeddedObjectSupplier2.hpp>
25 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
26 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
27 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
28 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/style/BreakType.hpp>
31 #include <com/sun/star/style/DropCapFormat.hpp>
32 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
33 #include <com/sun/star/text/HoriOrientation.hpp>
34 #include <com/sun/star/text/RelOrientation.hpp>
35 #include <com/sun/star/text/SetVariableType.hpp>
36 #include <com/sun/star/text/TableColumnSeparator.hpp>
37 #include <com/sun/star/text/TextContentAnchorType.hpp>
38 #include <com/sun/star/text/VertOrientation.hpp>
39 #include <com/sun/star/text/WrapTextMode.hpp>
40 #include <com/sun/star/text/XDependentTextField.hpp>
41 #include <com/sun/star/text/XFormField.hpp>
42 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
43 #include <com/sun/star/text/XTextFrame.hpp>
44 #include <com/sun/star/text/XTextFramesSupplier.hpp>
45 #include <com/sun/star/style/ParagraphAdjust.hpp>
46 #include <com/sun/star/text/SizeType.hpp>
47 #include <com/sun/star/util/DateTime.hpp>
48 #include <com/sun/star/text/GraphicCrop.hpp>
49 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
50 #include <com/sun/star/awt/CharSet.hpp>
51 #include <com/sun/star/text/WritingMode2.hpp>
52 #include <com/sun/star/text/XTextSectionsSupplier.hpp>
53 #include <com/sun/star/text/XTextDocument.hpp>
54 #include <com/sun/star/drawing/XShapes.hpp>
55 #include <com/sun/star/table/XTableRows.hpp>
56 #include <com/sun/star/text/XTextTablesSupplier.hpp>
57 #include <com/sun/star/text/XTextTable.hpp>
58 
59 #include <o3tl/cppunittraitshelper.hxx>
60 #include <unotools/fltrcfg.hxx>
61 #include <comphelper/sequenceashashmap.hxx>
62 #include <tools/datetimeutils.hxx>
63 #include <oox/drawingml/drawingmltypes.hxx>
64 #include <unotools/streamwrap.hxx>
65 #include <comphelper/propertysequence.hxx>
66 #include <osl/time.h>
67 #include <comphelper/processfactory.hxx>
68 #include <vcl/TypeSerializer.hxx>
69 #include <comphelper/scopeguard.hxx>
70 
71 constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/extras/ooxmlimport/data/";
72 
73 class Test : public SwModelTestBase
74 {
75 public:
Test()76     Test() : SwModelTestBase(DATA_DIRECTORY, "Office Open XML Text")
77     {
78     }
79 };
80 
CPPUNIT_TEST_FIXTURE(Test,testImageHyperlink)81 CPPUNIT_TEST_FIXTURE(Test, testImageHyperlink)
82 {
83     load(mpTestDocumentPath, "image-hyperlink.docx");
84     OUString URL = getProperty<OUString>(getShape(1), "HyperLinkURL");
85     CPPUNIT_ASSERT_EQUAL(OUString("http://www.libreoffice.org/"), URL);
86 }
87 
CPPUNIT_TEST_FIXTURE(Test,testMathMalformedXml)88 CPPUNIT_TEST_FIXTURE(Test, testMathMalformedXml)
89 {
90     OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "math-malformed_xml.docx";
91     mxComponent = mxDesktop->loadComponentFromURL(aURL, "_default", 0, {});
92     CPPUNIT_ASSERT(!mxComponent.is());
93 }
94 
CPPUNIT_TEST_FIXTURE(Test,testTdf103931)95 CPPUNIT_TEST_FIXTURE(Test, testTdf103931)
96 {
97     load(mpTestDocumentPath, "tdf103931.docx");
98     uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
99     uno::Reference<container::XIndexAccess> xTextSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
100     // This was 2, the last (empty) section of the document was lost on import.
101     // (import test only: Columns/Sections do not round-trip well)
102     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xTextSections->getCount());
103 }
104 
CPPUNIT_TEST_FIXTURE(Test,testN751017)105 CPPUNIT_TEST_FIXTURE(Test, testN751017)
106 {
107     load(mpTestDocumentPath, "n751017.docx");
108     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
109     uno::Reference<container::XNameAccess> xMasters(xTextFieldsSupplier->getTextFieldMasters());
110     // Make sure we have a variable named foo.
111     CPPUNIT_ASSERT(xMasters->hasByName("com.sun.star.text.FieldMaster.SetExpression.foo"));
112 
113     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
114     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
115     bool bFoundSet(false), bFoundGet(false);
116     while (xFields->hasMoreElements())
117     {
118         uno::Reference<lang::XServiceInfo> xServiceInfo(xFields->nextElement(), uno::UNO_QUERY);
119         uno::Reference<beans::XPropertySet> xPropertySet(xServiceInfo, uno::UNO_QUERY);
120         sal_Int16 nValue = 0;
121         OUString aValue;
122         if (xServiceInfo->supportsService("com.sun.star.text.TextField.SetExpression"))
123         {
124             bFoundSet = true;
125             uno::Reference<text::XDependentTextField> xDependentTextField(xServiceInfo, uno::UNO_QUERY);
126             uno::Reference<beans::XPropertySet> xMasterProps(xDependentTextField->getTextFieldMaster());
127 
128             // First step: did we set foo to "bar"?
129             xMasterProps->getPropertyValue("Name") >>= aValue;
130             CPPUNIT_ASSERT_EQUAL(OUString("foo"), aValue);
131             xPropertySet->getPropertyValue("SubType") >>= nValue;
132             CPPUNIT_ASSERT_EQUAL(text::SetVariableType::STRING, nValue);
133             xPropertySet->getPropertyValue("Content") >>= aValue;
134             CPPUNIT_ASSERT_EQUAL(OUString("bar"), aValue);
135         }
136         else if (xServiceInfo->supportsService("com.sun.star.text.TextField.GetExpression"))
137         {
138             // Second step: check the value of foo.
139             bFoundGet = true;
140             xPropertySet->getPropertyValue("Content") >>= aValue;
141             CPPUNIT_ASSERT_EQUAL(OUString("foo"), aValue);
142             xPropertySet->getPropertyValue("SubType") >>= nValue;
143             CPPUNIT_ASSERT_EQUAL(text::SetVariableType::STRING, nValue);
144             xPropertySet->getPropertyValue("CurrentPresentation") >>= aValue;
145             CPPUNIT_ASSERT_EQUAL(OUString("bar"), aValue);
146         }
147     }
148     CPPUNIT_ASSERT(bFoundSet);
149     CPPUNIT_ASSERT(bFoundGet);
150 }
151 
CPPUNIT_TEST_FIXTURE(Test,testN757890)152 CPPUNIT_TEST_FIXTURE(Test, testN757890)
153 {
154     load(mpTestDocumentPath, "n757890.docx");
155     // The w:pStyle token affected the text outside the textbox.
156     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
157     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
158     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
159     uno::Reference<beans::XPropertySet> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
160     OUString aValue;
161     xPara->getPropertyValue("ParaStyleName") >>= aValue;
162     CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"), aValue);
163 
164     // This wasn't centered
165     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
166     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
167     uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
168     sal_Int16 nValue;
169     xFrame->getPropertyValue("HoriOrient") >>= nValue;
170     CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, nValue);
171 }
172 
CPPUNIT_TEST_FIXTURE(Test,testN751077)173 CPPUNIT_TEST_FIXTURE(Test, testN751077)
174 {
175     load(mpTestDocumentPath, "n751077.docx");
176 /*
177 xray ThisComponent.DrawPage(1).getByIndex(0).String
178 xray ThisComponent.DrawPage(1).getByIndex(0).Anchor.PageStyleName
179 */
180     uno::Reference<drawing::XShapes> xShapes(getShape(2), uno::UNO_QUERY);
181     uno::Reference<text::XTextRange> xShape(xShapes->getByIndex(0), uno::UNO_QUERY);
182     CPPUNIT_ASSERT_EQUAL(OUString("TEXT1\n"), xShape->getString());
183     // we want to test the textbox is on the first page (it was put onto another page without the fix),
184     // use a small trick and instead of checking the page layout, check the page style
185     uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY);
186     CPPUNIT_ASSERT_EQUAL(OUString("First Page"), getProperty<OUString>(xTextContent->getAnchor(), "PageStyleName"));
187 }
188 
CPPUNIT_TEST_FIXTURE(Test,testTdf129237)189 CPPUNIT_TEST_FIXTURE(Test, testTdf129237)
190 {
191     load(mpTestDocumentPath, "tdf129237.docx");
192     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
193     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
194     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
195 
196     if( !xFields->hasMoreElements() ) {
197         CPPUNIT_ASSERT(false);
198         return;
199     }
200 
201     uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
202     CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Title (fixed)"), xEnumerationAccess1->getPresentation(true).trim());
203     CPPUNIT_ASSERT_EQUAL(OUString("title new"), xEnumerationAccess1->getPresentation(false).trim());
204 
205     if( !xFields->hasMoreElements() ) {
206         CPPUNIT_ASSERT(false);
207         return;
208     }
209 
210     uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
211     CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Title (fixed)"), xEnumerationAccess2->getPresentation(true).trim());
212     CPPUNIT_ASSERT_EQUAL(OUString("MoM is supreme"), xEnumerationAccess2->getPresentation(false).trim());
213 
214     if( !xFields->hasMoreElements() ) {
215         CPPUNIT_ASSERT(false);
216         return;
217     }
218 
219     uno::Reference<text::XTextField> xEnumerationAccess3(xFields->nextElement(), uno::UNO_QUERY);
220     CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Title (fixed)"), xEnumerationAccess3->getPresentation(true).trim());
221     CPPUNIT_ASSERT_EQUAL(OUString("MY PATNA IS BEST IN THE WORLD"), xEnumerationAccess3->getPresentation(false).trim());
222 
223     if( !xFields->hasMoreElements() ) {
224         CPPUNIT_ASSERT(false);
225         return;
226     }
227 
228     uno::Reference<text::XTextField> xEnumerationAccess4(xFields->nextElement(), uno::UNO_QUERY);
229     CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Title (fixed)"), xEnumerationAccess4->getPresentation(true).trim());
230     CPPUNIT_ASSERT_EQUAL(OUString("Title New"), xEnumerationAccess4->getPresentation(false).trim());
231 }
232 
CPPUNIT_TEST_FIXTURE(Test,testTdf134572)233 CPPUNIT_TEST_FIXTURE(Test, testTdf134572)
234 {
235     load(mpTestDocumentPath, "tdf134572.docx");
236     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
237     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
238     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
239 
240     if( !xFields->hasMoreElements() ) {
241         CPPUNIT_ASSERT(false);
242         return;
243     }
244 
245     // Without the fix in place, this test would have failed with
246     // - Expected: RK - Risk / EH&S
247     // - Actual  : [Responsible Office]
248     uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
249     CPPUNIT_ASSERT_EQUAL(OUString("RK - Risk / EH&S"), xEnumerationAccess1->getPresentation(false).trim());
250 
251     if( !xFields->hasMoreElements() ) {
252         CPPUNIT_ASSERT(false);
253         return;
254     }
255 
256     // - Expected: Choose an item.
257     // - Actual  : A.M.
258     uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
259     CPPUNIT_ASSERT_EQUAL(OUString("Choose an item."), xEnumerationAccess2->getPresentation(false).trim());
260 }
261 
CPPUNIT_TEST_FIXTURE(Test,testTdf128076)262 CPPUNIT_TEST_FIXTURE(Test, testTdf128076)
263 {
264     load(mpTestDocumentPath, "tdf128076.docx");
265     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
266     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
267     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
268 
269     if( !xFields->hasMoreElements() ) {
270         CPPUNIT_ASSERT(false);
271         return;
272     }
273 
274     uno::Reference<text::XTextField> xEnumerationAccess(xFields->nextElement(), uno::UNO_QUERY);
275     CPPUNIT_ASSERT_EQUAL(OUString("User Field adres = Test"), xEnumerationAccess->getPresentation(true).trim());
276     CPPUNIT_ASSERT_EQUAL(OUString("Test"), xEnumerationAccess->getPresentation(false).trim());
277 }
278 
CPPUNIT_TEST_FIXTURE(Test,testfdo90720)279 CPPUNIT_TEST_FIXTURE(Test, testfdo90720)
280 {
281     load(mpTestDocumentPath, "testfdo90720.docx");
282     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
283     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
284     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());
285     uno::Reference<text::XTextFrame> textbox(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
286     uno::Reference<beans::XPropertySet> properties(textbox, uno::UNO_QUERY);
287     sal_Int32 fill_transperence;
288     properties->getPropertyValue( "FillTransparence" ) >>= fill_transperence;
289     CPPUNIT_ASSERT_EQUAL( sal_Int32(100), fill_transperence );
290 }
291 
CPPUNIT_TEST_FIXTURE(Test,testN760764)292 CPPUNIT_TEST_FIXTURE(Test, testN760764)
293 {
294     load(mpTestDocumentPath, "n760764.docx");
295     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
296     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
297     uno::Reference<container::XEnumeration> xParaEnum(xParaEnumAccess->createEnumeration());
298     uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
299     uno::Reference<container::XEnumeration> xRunEnum(xRunEnumAccess->createEnumeration());
300 
301     // Access the second run, which is a textfield
302     xRunEnum->nextElement();
303     uno::Reference<beans::XPropertySet> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
304     float fValue;
305     xRun->getPropertyValue("CharHeight") >>= fValue;
306     // This used to be 11, as character properties were ignored.
307     CPPUNIT_ASSERT_EQUAL(8.f, fValue);
308 }
309 
CPPUNIT_TEST_FIXTURE(Test,testN764745)310 CPPUNIT_TEST_FIXTURE(Test, testN764745)
311 {
312     load(mpTestDocumentPath, "n764745-alignment.docx");
313 /*
314 shape = ThisComponent.DrawPage.getByIndex(0)
315 xray shape.AnchorType
316 xray shape.AnchorPosition.X
317 xray ThisComponent.StyleFamilies.PageStyles.Default.Width
318 */
319     uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY);
320     // The paragraph is right-aligned and the picture does not explicitly specify position,
321     // so check it's anchored as character and in the right side of the document.
322     text::TextContentAnchorType anchorType;
323     xPropertySet->getPropertyValue("AnchorType") >>= anchorType;
324     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER, anchorType);
325     awt::Point pos;
326     xPropertySet->getPropertyValue("AnchorPosition") >>= pos;
327     uno::Reference<style::XStyleFamiliesSupplier> styleFamiliesSupplier(mxComponent, uno::UNO_QUERY);
328     uno::Reference<container::XNameAccess> styleFamilies = styleFamiliesSupplier->getStyleFamilies();
329     uno::Reference<container::XNameAccess> pageStyles;
330     styleFamilies->getByName("PageStyles") >>= pageStyles;
331     uno::Reference<uno::XInterface> defaultStyle;
332     pageStyles->getByName("Standard") >>= defaultStyle;
333     uno::Reference<beans::XPropertySet> styleProperties( defaultStyle, uno::UNO_QUERY );
334     sal_Int32 width = 0;
335     styleProperties->getPropertyValue( "Width" ) >>= width;
336     CPPUNIT_ASSERT( pos.X > width / 2 );
337 }
338 
CPPUNIT_TEST_FIXTURE(Test,testTdf115719b)339 CPPUNIT_TEST_FIXTURE(Test, testTdf115719b)
340 {
341     load(mpTestDocumentPath, "tdf115719b.docx");
342     // This was 0, 4th (last) paragraph had no increased spacing.
343     CPPUNIT_ASSERT(getProperty<sal_Int32>(getParagraph(4), "ParaTopMargin") > 0);
344 }
345 
CPPUNIT_TEST_FIXTURE(Test,testN766477)346 CPPUNIT_TEST_FIXTURE(Test, testN766477)
347 {
348     load(mpTestDocumentPath, "n766477.docx");
349     /*
350      * The problem was that the checkbox was not checked.
351      *
352      * oParas = ThisComponent.Text.createEnumeration
353      * oPara = oParas.nextElement
354      * oRuns = oPara.createEnumeration
355      * oRun = oRuns.nextElement
356      * xray oRun.Bookmark.Parameters.ElementNames(0) 'Checkbox_Checked
357      */
358     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
359     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
360     uno::Reference<container::XEnumeration> xParaEnum(xParaEnumAccess->createEnumeration());
361     uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
362     uno::Reference<container::XEnumeration> xRunEnum(xRunEnumAccess->createEnumeration());
363     uno::Reference<beans::XPropertySet> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
364     uno::Reference<text::XFormField> xFormField(xRun->getPropertyValue("Bookmark"), uno::UNO_QUERY);
365     uno::Reference<container::XNameContainer> xParameters(xFormField->getParameters());
366     uno::Sequence<OUString> aElementNames(xParameters->getElementNames());
367     CPPUNIT_ASSERT_EQUAL(OUString("Checkbox_Checked"), aElementNames[0]);
368 }
369 
CPPUNIT_TEST_FIXTURE(Test,testTdf130804)370 CPPUNIT_TEST_FIXTURE(Test, testTdf130804)
371 {
372     load(mpTestDocumentPath, "tdf130804.docx");
373     OUString flyHeight = parseDump("/root/page/body/txt[1]/infos/bounds", "height");
374     OUString txtHeight = parseDump("/root/page/body/txt[1]/anchored/fly/infos/bounds", "height");
375 
376     //Without the fix in place, txtHeight would have been flyHeight + 55
377     CPPUNIT_ASSERT_EQUAL(flyHeight, txtHeight);
378 
379     // Also check the bookmark portion is ignored in the next paragraph
380     OUString aTop = parseDump("/root/page/body/txt[2]/infos/prtBounds", "top");
381     CPPUNIT_ASSERT_EQUAL(OUString("240"), aTop);
382 }
383 
CPPUNIT_TEST_FIXTURE(Test,testN758883)384 CPPUNIT_TEST_FIXTURE(Test, testN758883)
385 {
386     load(mpTestDocumentPath, "n758883.docx");
387     /*
388      * The problem was that direct formatting of the paragraph was not applied
389      * to the numbering. This is easier to test using a layout dump.
390      */
391     xmlDocUniquePtr pXmlDoc = parseLayoutDump();
392     assertXPath(pXmlDoc, "/root/page/body/txt/Special[1]", "nHeight", "220");
393 
394     // check the bookmark portions are of the expected height
395     assertXPath(pXmlDoc, "/root/page/body/txt/Special[2]", "nType", "PortionType::Bookmark");
396     assertXPath(pXmlDoc, "/root/page/body/txt/Special[2]", "nHeight", "253");
397     assertXPath(pXmlDoc, "/root/page/body/txt/Special[3]", "nType", "PortionType::Bookmark");
398     assertXPath(pXmlDoc, "/root/page/body/txt/Special[3]", "nHeight", "253");
399 
400     /*
401      * Next problem was that the page margin contained the width of the page border as well.
402      *
403      * xray ThisComponent.StyleFamilies.PageStyles.Default.LeftMargin
404      */
405     uno::Reference<beans::XPropertySet> xPropertySet(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
406     sal_Int32 nValue = 0;
407     xPropertySet->getPropertyValue("LeftMargin") >>= nValue;
408     CPPUNIT_ASSERT_EQUAL(sal_Int32(847), nValue);
409 
410     // No assert for the 3rd problem: see the comment in the test doc.
411 
412     /*
413      * 4th problem: Wrap type of the textwrape was not 'through'.
414      *
415      * xray ThisComponent.DrawPage(0).Surround ' was 2, should be 1
416      */
417     xPropertySet.set(getShape(1), uno::UNO_QUERY);
418     text::WrapTextMode eValue;
419     xPropertySet->getPropertyValue("Surround") >>= eValue;
420     CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_THROUGH, eValue);
421 
422     /*
423      * 5th problem: anchor type of the second textbox was wrong.
424      *
425      * xray ThisComponent.DrawPage(1).AnchorType ' was 1, should be 4
426      */
427     xPropertySet.set(getShape(2), uno::UNO_QUERY);
428     text::TextContentAnchorType eAnchorType;
429     xPropertySet->getPropertyValue("AnchorType") >>= eAnchorType;
430     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, eAnchorType);
431 
432     // 6th problem: xray ThisComponent.DrawPage(2).AnchorType ' was 2, should be 4
433     xPropertySet.set(getShape(3), uno::UNO_QUERY);
434     xPropertySet->getPropertyValue("AnchorType") >>= eAnchorType;
435     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, eAnchorType);
436 }
437 
CPPUNIT_TEST_FIXTURE(Test,testTdf74367_MarginsZeroed)438 CPPUNIT_TEST_FIXTURE(Test, testTdf74367_MarginsZeroed)
439 {
440     load(mpTestDocumentPath, "tdf74367_MarginsZeroed.docx");
441     // Do not import page borders with 'None' style, or else it will change the page margins.
442     uno::Reference<beans::XPropertySet> xPropertySet(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
443     sal_Int32 nValue = 0;
444     xPropertySet->getPropertyValue("TopMargin") >>= nValue;
445     CPPUNIT_ASSERT_EQUAL(sal_Int32(2501), nValue);
446     xPropertySet->getPropertyValue("RightMargin") >>= nValue;
447     CPPUNIT_ASSERT_EQUAL(sal_Int32(2501), nValue);
448     xPropertySet->getPropertyValue("BottomMargin") >>= nValue;
449     CPPUNIT_ASSERT_EQUAL(sal_Int32(2501), nValue);
450     xPropertySet->getPropertyValue("LeftMargin") >>= nValue;
451     CPPUNIT_ASSERT_EQUAL(sal_Int32(2501), nValue);
452 }
453 
CPPUNIT_TEST_FIXTURE(Test,testBnc773061)454 CPPUNIT_TEST_FIXTURE(Test, testBnc773061)
455 {
456     load(mpTestDocumentPath, "bnc773061.docx");
457     uno::Reference< text::XTextRange > paragraph = getParagraph( 1 );
458     uno::Reference< text::XTextRange > normal = getRun( paragraph, 1, "Normal " );
459     uno::Reference< text::XTextRange > raised = getRun( paragraph, 2, "Raised" );
460     uno::Reference< text::XTextRange > lowered = getRun( paragraph, 4, "Lowered" );
461     CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), getProperty< sal_Int32 >( normal, "CharEscapement" ));
462     CPPUNIT_ASSERT_EQUAL( sal_Int32( 50 ), getProperty< sal_Int32 >( raised, "CharEscapement" ));
463     CPPUNIT_ASSERT_EQUAL( sal_Int32( -25 ), getProperty< sal_Int32 >( lowered, "CharEscapement" ));
464     CPPUNIT_ASSERT_EQUAL( sal_Int32( 100 ), getProperty< sal_Int32 >( normal, "CharEscapementHeight" ));
465     CPPUNIT_ASSERT_EQUAL( sal_Int32( 100 ), getProperty< sal_Int32 >( raised, "CharEscapementHeight" ));
466     CPPUNIT_ASSERT_EQUAL( sal_Int32( 100 ), getProperty< sal_Int32 >( lowered, "CharEscapementHeight" ));
467 }
468 
CPPUNIT_TEST_FIXTURE(Test,testN775899)469 CPPUNIT_TEST_FIXTURE(Test, testN775899)
470 {
471     load(mpTestDocumentPath, "n775899.docx");
472     /*
473      * The problem was that a floating table wasn't imported as a frame, then it contained fake paragraphs.
474      *
475      * ThisComponent.TextFrames.Count ' was 0
476      * oParas = ThisComponent.TextFrames(0).Text.createEnumeration
477      * oPara = oParas.nextElement
478      * oPara.supportsService("com.sun.star.text.TextTable") 'was a fake paragraph
479      * oParas.hasMoreElements 'was true
480      */
481     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
482     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
483     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
484 
485     uno::Reference<text::XTextFrame> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
486     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xFrame->getText(), uno::UNO_QUERY);
487     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
488     uno::Reference<lang::XServiceInfo> xServiceInfo(xParaEnum->nextElement(), uno::UNO_QUERY);
489     CPPUNIT_ASSERT_EQUAL(sal_True, xServiceInfo->supportsService("com.sun.star.text.TextTable"));
490 
491     CPPUNIT_ASSERT_EQUAL(sal_False, xParaEnum->hasMoreElements());
492 }
493 
CPPUNIT_TEST_FIXTURE(Test,testN777345)494 CPPUNIT_TEST_FIXTURE(Test, testN777345)
495 {
496     load(mpTestDocumentPath, "n777345.docx");
497     // The problem was that v:imagedata inside v:rect was ignored.
498     uno::Reference<document::XEmbeddedObjectSupplier2> xSupplier(getShape(1), uno::UNO_QUERY);
499     uno::Reference<graphic::XGraphic> xGraphic = xSupplier->getReplacementGraphic();
500     Graphic aGraphic(xGraphic);
501     BitmapEx aBitmap = aGraphic.GetBitmapEx();
502     CPPUNIT_ASSERT_EQUAL( Size( 17, 16 ), aBitmap.GetSizePixel());
503     CPPUNIT_ASSERT_EQUAL( COL_BLACK, aBitmap.GetPixelColor( 0, 0 ));
504     CPPUNIT_ASSERT_EQUAL( COL_BLACK, aBitmap.GetPixelColor( 16, 15 ));
505     CPPUNIT_ASSERT_EQUAL( Color( 153, 0, 0 ), aBitmap.GetPixelColor( 16, 0 ));
506     CPPUNIT_ASSERT_EQUAL( Color( 153, 0, 0 ), aBitmap.GetPixelColor( 0, 15 ));
507 }
508 
CPPUNIT_TEST_FIXTURE(Test,testN778140)509 CPPUNIT_TEST_FIXTURE(Test, testN778140)
510 {
511     load(mpTestDocumentPath, "n778140.docx");
512     /*
513      * The problem was that the paragraph top/bottom margins were incorrect due
514      * to unhandled w:doNotUseHTMLParagraphAutoSpacing.
515      */
516     CPPUNIT_ASSERT_EQUAL(sal_Int32(176), getProperty<sal_Int32>(getParagraph(1), "ParaTopMargin"));
517     CPPUNIT_ASSERT_EQUAL(sal_Int32(176), getProperty<sal_Int32>(getParagraph(1), "ParaBottomMargin"));
518 }
519 
CPPUNIT_TEST_FIXTURE(Test,testInk)520 CPPUNIT_TEST_FIXTURE(Test, testInk)
521 {
522     load(mpTestDocumentPath, "ink.docx");
523     /*
524      * The problem was that ~nothing was imported, except an empty CustomShape.
525      *
526      * xray ThisComponent.DrawPage(0).supportsService("com.sun.star.drawing.OpenBezierShape")
527      */
528     uno::Reference<lang::XServiceInfo> xServiceInfo(getShape(1), uno::UNO_QUERY);
529     CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.drawing.OpenBezierShape"));
530 }
531 
CPPUNIT_TEST_FIXTURE(Test,testN779627)532 CPPUNIT_TEST_FIXTURE(Test, testN779627)
533 {
534     load(mpTestDocumentPath, "n779627.docx");
535     /*
536      * The problem was that the table left position was based on the tableCellMar left value
537      * even for nested tables, while it shouldn't.
538      */
539     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
540     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY);
541     uno::Reference<beans::XPropertySet> xTableProperties(xTables->getByIndex(0), uno::UNO_QUERY);
542     uno::Any aValue = xTableProperties->getPropertyValue("LeftMargin");
543     sal_Int32 nLeftMargin;
544     aValue >>= nLeftMargin;
545     // only border width considered.
546     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Left margin shouldn't take tableCellMar into account in nested tables",
547             sal_Int32(9), nLeftMargin);
548 
549     /*
550      * Another problem tested with this document is the loading of the shapes
551      * anchored to a hidden header or footer
552      */
553     CPPUNIT_ASSERT_EQUAL(2, getShapes());
554 }
555 
CPPUNIT_TEST_FIXTURE(Test,testN779627b)556 CPPUNIT_TEST_FIXTURE(Test, testN779627b)
557 {
558     load(mpTestDocumentPath, "n779627b.docx");
559     /*
560      * Another problem tested with the original n779627.docx document (before removing its unnecessary
561      * shape loading) is that the roundrect is centered vertically and horizontally.
562      */
563     uno::Reference<beans::XPropertySet> xShapeProperties( getShape(1), uno::UNO_QUERY );
564     uno::Reference<drawing::XShapeDescriptor> xShapeDescriptor(xShapeProperties, uno::UNO_QUERY);
565     // If this goes wrong, probably the index of the shape is changed and the test should be adjusted.
566     CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.RectangleShape"), xShapeDescriptor->getShapeType());
567     sal_Int16 nValue;
568     xShapeProperties->getPropertyValue("HoriOrient") >>= nValue;
569     CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered horizontally", text::HoriOrientation::CENTER, nValue);
570     xShapeProperties->getPropertyValue("HoriOrientRelation") >>= nValue;
571     CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered horizontally relatively to page", text::RelOrientation::PAGE_FRAME, nValue);
572     xShapeProperties->getPropertyValue("VertOrient") >>= nValue;
573     CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered vertically", text::VertOrientation::CENTER, nValue);
574     xShapeProperties->getPropertyValue("VertOrientRelation") >>= nValue;
575     CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered vertically relatively to page", text::RelOrientation::PAGE_FRAME, nValue);
576 }
577 
CPPUNIT_TEST_FIXTURE(Test,testN782061)578 CPPUNIT_TEST_FIXTURE(Test, testN782061)
579 {
580     load(mpTestDocumentPath, "n782061.docx");
581     /*
582      * The problem was that the character escapement in the second run was -58.
583      */
584     CPPUNIT_ASSERT_EQUAL(sal_Int32(-9), getProperty<sal_Int32>(getRun(getParagraph(1), 2), "CharEscapement"));
585 }
586 
CPPUNIT_TEST_FIXTURE(Test,testN773061)587 CPPUNIT_TEST_FIXTURE(Test, testN773061)
588 {
589     load(mpTestDocumentPath, "n773061.docx");
590 // xray ThisComponent.TextFrames(0).LeftBorderDistance
591     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
592     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
593     uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
594     CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), getProperty< sal_Int32 >( xFrame, "LeftBorderDistance" ) );
595     CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), getProperty< sal_Int32 >( xFrame, "TopBorderDistance" ) );
596     CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), getProperty< sal_Int32 >( xFrame, "RightBorderDistance" ) );
597     CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), getProperty< sal_Int32 >( xFrame, "BottomBorderDistance" ) );
598 }
599 
CPPUNIT_TEST_FIXTURE(Test,testN780645)600 CPPUNIT_TEST_FIXTURE(Test, testN780645)
601 {
602     load(mpTestDocumentPath, "n780645.docx");
603     // The problem was that when the number of cells didn't match the grid, we
604     // didn't take care of direct cell widths.
605     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
606     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY);
607     uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
608     uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
609     CPPUNIT_ASSERT_EQUAL(sal_Int16(2135), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(1), "TableColumnSeparators")[0].Position); // was 1999
610 }
611 
CPPUNIT_TEST_FIXTURE(Test,testWordArtResizing)612 CPPUNIT_TEST_FIXTURE(Test, testWordArtResizing)
613 {
614     load(mpTestDocumentPath, "WordArt.docx");
615     /* The Word-Arts and watermarks were getting resized automatically, It was as if they were
616        getting glued to the fallback geometry(the sdrObj) and were getting bound to the font size.
617        The test-case ensures the original height and width of the word-art is not changed while importing*/
618     CPPUNIT_ASSERT_EQUAL(1, getShapes());
619 
620     uno::Reference<drawing::XShape> xShape(getShape(1), uno::UNO_QUERY);
621     CPPUNIT_ASSERT_EQUAL(sal_Int32(10105), xShape->getSize().Width);
622     CPPUNIT_ASSERT_EQUAL(sal_Int32(4755), xShape->getSize().Height);
623 }
624 
CPPUNIT_TEST_FIXTURE(Test,testGroupshapeLine)625 CPPUNIT_TEST_FIXTURE(Test, testGroupshapeLine)
626 {
627     load(mpTestDocumentPath, "groupshape-line.docx");
628     /*
629      * Another fallout from n#792778, this time first the lines inside a
630      * groupshape wasn't imported, then the fix broke the size/position of
631      * non-groupshape lines. Test both here.
632      *
633      * xray ThisComponent.DrawPage.Count ' 2 shapes
634      * xray ThisComponent.DrawPage(0).Position 'x: 2656, y: 339
635      * xray ThisComponent.DrawPage(0).Size ' width: 3270, height: 1392
636      * xray ThisComponent.DrawPage(1).getByIndex(0).Position 'x: 1272, y: 2286
637      * xray ThisComponent.DrawPage(1).getByIndex(0).Size 'width: 10160, height: 0
638      */
639     CPPUNIT_ASSERT_EQUAL(2, getShapes());
640 
641     uno::Reference<drawing::XShape> xShape(getShape(1), uno::UNO_QUERY);
642     CPPUNIT_ASSERT_EQUAL(sal_Int32(2656), xShape->getPosition().X);
643     CPPUNIT_ASSERT_EQUAL(sal_Int32(339), xShape->getPosition().Y);
644     CPPUNIT_ASSERT_EQUAL(sal_Int32(3270), xShape->getSize().Width);
645     CPPUNIT_ASSERT_EQUAL(sal_Int32(1392), xShape->getSize().Height);
646 
647     uno::Reference<drawing::XShapes> xGroupShape(getShape(2), uno::UNO_QUERY);
648     xShape.set(xGroupShape->getByIndex(0), uno::UNO_QUERY);
649     CPPUNIT_ASSERT_EQUAL(sal_Int32(1272), xShape->getPosition().X);
650     CPPUNIT_ASSERT_EQUAL(sal_Int32(2286), xShape->getPosition().Y);
651     CPPUNIT_ASSERT_EQUAL(sal_Int32(10160), xShape->getSize().Width);
652     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xShape->getSize().Height);
653 }
654 
CPPUNIT_TEST_FIXTURE(Test,testGroupshapeChildRotation)655 CPPUNIT_TEST_FIXTURE(Test, testGroupshapeChildRotation)
656 {
657     load(mpTestDocumentPath, "groupshape-child-rotation.docx");
658     // The problem was that (due to incorrect handling of rotation inside
659     // groupshapes), the first child wasn't in the top left corner of an inline
660     // groupshape.
661     uno::Reference<drawing::XShapes> xGroupShape(getShape(1), uno::UNO_QUERY);
662     uno::Reference<drawing::XShape> xShape(xGroupShape->getByIndex(0), uno::UNO_QUERY);
663     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xShape->getPosition().X);
664     CPPUNIT_ASSERT_EQUAL(sal_Int32(-5741), xShape->getPosition().Y);
665 
666 #if HAVE_MORE_FONTS
667     xShape.set(xGroupShape->getByIndex(4), uno::UNO_QUERY);
668     // This was true, a VML textbox without <v:textbox style="mso-fit-shape-to-text:t"> had
669     // auto-grow on.
670     CPPUNIT_ASSERT(!getProperty<bool>(xShape, "TextAutoGrowHeight"));
671     // Paragraph Style Normal should provide the font name - which slightly affects the shape's height (was 686)
672     uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
673     CPPUNIT_ASSERT_EQUAL_MESSAGE("Font", OUString("Times New Roman"), getProperty<OUString>(getRun(xText, 1), "CharFontName"));
674 #endif
675 
676     uno::Reference<drawing::XShapeDescriptor> xShapeDescriptor(xGroupShape->getByIndex(5), uno::UNO_QUERY);
677     // This was com.sun.star.drawing.RectangleShape, all shape text in a single line.
678     CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.TextShape"), xShapeDescriptor->getShapeType());
679 }
680 
CPPUNIT_TEST_FIXTURE(Test,testTableWidth)681 CPPUNIT_TEST_FIXTURE(Test, testTableWidth)
682 {
683     load(mpTestDocumentPath, "table_width.docx");
684     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
685     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
686     // Relative width wasn't recognized during import.
687     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTables->getByIndex(0), "IsWidthRelative"));
688 
689     uno::Reference<text::XTextFramesSupplier> xFramesSupplier(mxComponent, uno::UNO_QUERY);
690     uno::Reference<container::XIndexAccess> xFrames(xFramesSupplier->getTextFrames(), uno::UNO_QUERY);
691     CPPUNIT_ASSERT_EQUAL(sal_Int32(100), getProperty<sal_Int32>(xFrames->getByIndex(0), "FrameWidthPercent"));
692 }
693 
CPPUNIT_TEST_FIXTURE(Test,testN820788)694 CPPUNIT_TEST_FIXTURE(Test, testN820788)
695 {
696     load(mpTestDocumentPath, "n820788.docx");
697     // The problem was that AutoSize was not enabled for the text frame.
698     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
699     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
700     uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
701     // This was text::SizeType::FIX.
702     CPPUNIT_ASSERT_EQUAL(text::SizeType::MIN, getProperty<sal_Int16>(xFrame, "SizeType"));
703 }
704 
CPPUNIT_TEST_FIXTURE(Test,testN820504)705 CPPUNIT_TEST_FIXTURE(Test, testN820504)
706 {
707     load(mpTestDocumentPath, "n820504.docx");
708     uno::Reference<style::XStyleFamiliesSupplier> xFamiliesSupplier(mxComponent, uno::UNO_QUERY);
709     uno::Reference<container::XNameAccess> xFamiliesAccess = xFamiliesSupplier->getStyleFamilies();
710     uno::Reference<container::XNameAccess> xStylesAccess(xFamiliesAccess->getByName("ParagraphStyles"), uno::UNO_QUERY);
711     uno::Reference<beans::XPropertySet> xStyle(xStylesAccess->getByName("Default Paragraph Style"), uno::UNO_QUERY);
712     // The problem was that the CharColor was set to AUTO (-1) even if we have some default char color set
713     CPPUNIT_ASSERT_EQUAL(sal_Int32(4040635), getProperty<sal_Int32>(xStyle, "CharColor"));
714 
715     // Also, the groupshape was anchored at-page instead of at-character
716     // (that's incorrect as Word only supports at-character and as-character).
717     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, getProperty<text::TextContentAnchorType>(getShape(1), "AnchorType"));
718 }
719 
CPPUNIT_TEST_FIXTURE(Test,testFdo43641)720 CPPUNIT_TEST_FIXTURE(Test, testFdo43641)
721 {
722     load(mpTestDocumentPath, "fdo43641.docx");
723     uno::Reference<container::XIndexAccess> xGroupShape(getShape(1), uno::UNO_QUERY);
724     uno::Reference<drawing::XShape> xLine(xGroupShape->getByIndex(1), uno::UNO_QUERY);
725     // This was 2200, not 2579 in mm100, i.e. the size of the line shape was incorrect.
726     // File cx=928694EMU = 2579.7Hmm, round up 2580Hmm. Currently off by 1.
727     CPPUNIT_ASSERT_EQUAL(sal_Int32(2581), xLine->getSize().Width);
728 }
729 
CPPUNIT_TEST_FIXTURE(Test,testGroupshapeSdt)730 CPPUNIT_TEST_FIXTURE(Test, testGroupshapeSdt)
731 {
732     load(mpTestDocumentPath, "groupshape-sdt.docx");
733     // All problems here are due to the groupshape: we have a drawinglayer rectangle, not a writer textframe.
734     uno::Reference<drawing::XShapes> xOuterGroupShape(getShape(1), uno::UNO_QUERY);
735     uno::Reference<drawing::XShapes> xInnerGroupShape(xOuterGroupShape->getByIndex(0), uno::UNO_QUERY);
736     uno::Reference<text::XTextRange> xShape(xInnerGroupShape->getByIndex(0), uno::UNO_QUERY);
737     // Border distances were not implemented, this was 0.
738     CPPUNIT_ASSERT_EQUAL(sal_Int32(1905), getProperty<sal_Int32>(xShape, "TextUpperDistance"));
739     // Sdt field result wasn't imported, this was "".
740     CPPUNIT_ASSERT_EQUAL(OUString("placeholder text"), xShape->getString());
741     // w:spacing was ignored in oox, this was 0.
742     CPPUNIT_ASSERT_EQUAL(sal_Int32(20), getProperty<sal_Int32>(getRun(getParagraphOfText(1, xShape->getText()), 1), "CharKerning"));
743 }
744 
lcl_countTextFrames(const css::uno::Reference<lang::XComponent> & xComponent,sal_Int32 nExpected)745 static void lcl_countTextFrames(const css::uno::Reference< lang::XComponent >& xComponent,
746    sal_Int32 nExpected )
747 {
748     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(xComponent, uno::UNO_QUERY);
749     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
750     CPPUNIT_ASSERT_EQUAL( nExpected, xIndexAccess->getCount());
751 }
752 
CPPUNIT_TEST_FIXTURE(Test,testBnc779620)753 CPPUNIT_TEST_FIXTURE(Test, testBnc779620)
754 {
755     load(mpTestDocumentPath, "bnc779620.docx");
756     // The problem was that the floating table was imported as a non-floating one.
757     lcl_countTextFrames( mxComponent, 1 );
758 }
759 
CPPUNIT_TEST_FIXTURE(Test,testTdf105127)760 CPPUNIT_TEST_FIXTURE(Test, testTdf105127)
761 {
762     load(mpTestDocumentPath, "tdf105127.docx");
763     auto aPolyPolygon = getProperty<drawing::PolyPolygonBezierCoords>(getShape(1), "PolyPolygonBezier");
764     // tdf#106792 These values were wrong all the time due to a missing
765     // conversion in SvxShapePolyPolygon::getPropertyValueImpl. There was no
766     // ForceMetricTo100th_mm -> the old results were in twips due to the
767     // object residing in Writer. The UNO API by definition is in 100thmm,
768     // thus I will correct the value here.
769     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5719), aPolyPolygon.Coordinates[0][0].Y); // was: 3257
770 }
771 
CPPUNIT_TEST_FIXTURE(Test,testTdf105143)772 CPPUNIT_TEST_FIXTURE(Test, testTdf105143)
773 {
774     load(mpTestDocumentPath, "tdf105143.docx");
775     OUString aTop = parseDump("/root/page/body/txt/anchored/SwAnchoredDrawObject/bounds", "top");
776     // This was 6272, i.e. the shape was moved up (incorrect position) to be
777     // inside the page rectangle.
778     CPPUNIT_ASSERT_EQUAL(OUString("6731"), aTop);
779 }
780 
CPPUNIT_TEST_FIXTURE(Test,testTdf105975)781 CPPUNIT_TEST_FIXTURE(Test, testTdf105975)
782 {
783     load(mpTestDocumentPath, "105975.docx");
784     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
785     uno::Reference<container::XNameAccess> xMasters(xTextFieldsSupplier->getTextFieldMasters());
786     // Make sure we have a variable named TEST_VAR.
787     CPPUNIT_ASSERT(xMasters->hasByName("com.sun.star.text.FieldMaster.SetExpression.TEST_VAR"));
788 }
789 
CPPUNIT_TEST_FIXTURE(Test,testfdo76583)790 CPPUNIT_TEST_FIXTURE(Test, testfdo76583)
791 {
792     load(mpTestDocumentPath, "fdo76583.docx");
793     // The problem was that the floating table was imported as a non-floating one.
794     // floating tables are imported as text frames, therefore the document should
795     // exactly 1 text frame.
796     lcl_countTextFrames( mxComponent, 1 );
797 }
798 
CPPUNIT_TEST_FIXTURE(Test,testTdf105975formula)799 CPPUNIT_TEST_FIXTURE(Test, testTdf105975formula)
800 {
801     load(mpTestDocumentPath, "tdf105975.docx");
802     // Make sure the field contains a formula with 10 + 15
803     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
804     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
805     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
806 
807     if( !xFields->hasMoreElements() ) {
808         CPPUNIT_ASSERT(false);
809         return;
810     }
811 
812     uno::Reference<text::XTextField> xEnumerationAccess(xFields->nextElement(), uno::UNO_QUERY);
813     CPPUNIT_ASSERT_EQUAL(OUString("10+15"), xEnumerationAccess->getPresentation(true).trim());
814     CPPUNIT_ASSERT_EQUAL(OUString("25"), xEnumerationAccess->getPresentation(false).trim());
815 }
816 
CPPUNIT_TEST_FIXTURE(Test,testTdf133647)817 CPPUNIT_TEST_FIXTURE(Test, testTdf133647)
818 {
819     load(mpTestDocumentPath, "tdf133647.docx");
820     /* Tests that argument lists, cell references, and cell ranges are translated correctly
821      * when importing table formulae from MS Word */
822     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
823     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
824     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
825 
826     if( !xFields->hasMoreElements() ) {
827         CPPUNIT_ASSERT(false);
828         return;
829     }
830 
831     uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
832     CPPUNIT_ASSERT_EQUAL(OUString("SUM(1|2|3)"), xEnumerationAccess1->getPresentation(true).trim());
833     CPPUNIT_ASSERT_EQUAL(OUString("6"), xEnumerationAccess1->getPresentation(false).trim());
834 
835     uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
836     CPPUNIT_ASSERT_EQUAL(OUString("sum(<A1>|<B1>)"), xEnumerationAccess2->getPresentation(true).trim());
837     CPPUNIT_ASSERT_EQUAL(OUString("3"), xEnumerationAccess2->getPresentation(false).trim());
838 
839     uno::Reference<text::XTextField> xEnumerationAccess3(xFields->nextElement(), uno::UNO_QUERY);
840     CPPUNIT_ASSERT_EQUAL(OUString("(SUM(<C1>|5)*(2+7))*(3+SUM(1|<B1>))"), xEnumerationAccess3->getPresentation(true).trim());
841     CPPUNIT_ASSERT_EQUAL(OUString("432"), xEnumerationAccess3->getPresentation(false).trim());
842 
843     uno::Reference<text::XTextField> xEnumerationAccess4(xFields->nextElement(), uno::UNO_QUERY);
844     CPPUNIT_ASSERT_EQUAL(OUString("1+(SUM(1|2))"), xEnumerationAccess4->getPresentation(true).trim());
845     CPPUNIT_ASSERT_EQUAL(OUString("4"), xEnumerationAccess4->getPresentation(false).trim());
846 
847     uno::Reference<text::XTextField> xEnumerationAccess5(xFields->nextElement(), uno::UNO_QUERY);
848     CPPUNIT_ASSERT_EQUAL(OUString("3*(2+SUM(<A1:C1>)+7)"), xEnumerationAccess5->getPresentation(true).trim());
849     CPPUNIT_ASSERT_EQUAL(OUString("45"), xEnumerationAccess5->getPresentation(false).trim());
850 
851     uno::Reference<text::XTextField> xEnumerationAccess6(xFields->nextElement(), uno::UNO_QUERY);
852     CPPUNIT_ASSERT_EQUAL(OUString("(1+2)*SUM(<C1>|<D1>)"), xEnumerationAccess6->getPresentation(true).trim());
853     CPPUNIT_ASSERT_EQUAL(OUString("21"), xEnumerationAccess6->getPresentation(false).trim());
854 
855     uno::Reference<text::XTextField> xEnumerationAccess7(xFields->nextElement(), uno::UNO_QUERY);
856     CPPUNIT_ASSERT_EQUAL(OUString("SUM(<A1>|5|<B1:C1>|6)"), xEnumerationAccess7->getPresentation(true).trim());
857     CPPUNIT_ASSERT_EQUAL(OUString("17"), xEnumerationAccess7->getPresentation(false).trim());
858 
859     uno::Reference<text::XTextField> xEnumerationAccess8(xFields->nextElement(), uno::UNO_QUERY);
860     CPPUNIT_ASSERT_EQUAL(OUString("SUM(<C1:D1>)"), xEnumerationAccess8->getPresentation(true).trim());
861     CPPUNIT_ASSERT_EQUAL(OUString("7"), xEnumerationAccess8->getPresentation(false).trim());
862 
863     uno::Reference<text::XTextField> xEnumerationAccess9(xFields->nextElement(), uno::UNO_QUERY);
864     CPPUNIT_ASSERT_EQUAL(OUString("SUM(<A1>|<B1>)"), xEnumerationAccess9->getPresentation(true).trim());
865     CPPUNIT_ASSERT_EQUAL(OUString("3"), xEnumerationAccess9->getPresentation(false).trim());
866 }
867 
CPPUNIT_TEST_FIXTURE(Test,testTdf123386)868 CPPUNIT_TEST_FIXTURE(Test, testTdf123386)
869 {
870     load(mpTestDocumentPath, "tdf123386.docx");
871     /* Tests that argument lists, cell references, and cell ranges are translated correctly
872      * when importing table formulae from MS Word */
873     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
874     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
875     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
876 
877     if( !xFields->hasMoreElements() ) {
878         CPPUNIT_ASSERT(false);
879         return;
880     }
881 
882     uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
883     CPPUNIT_ASSERT_EQUAL(OUString("<A1> L 2"), xEnumerationAccess1->getPresentation(true).trim());
884     CPPUNIT_ASSERT_EQUAL(OUString("1"), xEnumerationAccess1->getPresentation(false).trim());
885 
886     /* Ensures non-cell references passed to DEFINED() are preserved.
887      * Doesn't test the display string because LO doesn't support DEFINED(). */
888     uno::Reference<text::XTextField> xEnumerationAccess10(xFields->nextElement(), uno::UNO_QUERY);
889     CPPUNIT_ASSERT_EQUAL(OUString("((1) AND (DEFINED(ABC1)))"), xEnumerationAccess10->getPresentation(true).trim());
890 
891     uno::Reference<text::XTextField> xEnumerationAccess9(xFields->nextElement(), uno::UNO_QUERY);
892     CPPUNIT_ASSERT_EQUAL(OUString("NOT(TRUE)"), xEnumerationAccess9->getPresentation(true).trim());
893     CPPUNIT_ASSERT_EQUAL(OUString("0"), xEnumerationAccess9->getPresentation(false).trim());
894 
895     uno::Reference<text::XTextField> xEnumerationAccess8(xFields->nextElement(), uno::UNO_QUERY);
896     CPPUNIT_ASSERT_EQUAL(OUString("((TRUE) OR (FALSE))"), xEnumerationAccess8->getPresentation(true).trim());
897     CPPUNIT_ASSERT_EQUAL(OUString("1"), xEnumerationAccess8->getPresentation(false).trim());
898 
899     uno::Reference<text::XTextField> xEnumerationAccess7(xFields->nextElement(), uno::UNO_QUERY);
900     CPPUNIT_ASSERT_EQUAL(OUString("((<A1> EQ 1) OR (<B1> EQ 2))"), xEnumerationAccess7->getPresentation(true).trim());
901     CPPUNIT_ASSERT_EQUAL(OUString("1"), xEnumerationAccess7->getPresentation(false).trim());
902 
903     uno::Reference<text::XTextField> xEnumerationAccess6(xFields->nextElement(), uno::UNO_QUERY);
904     CPPUNIT_ASSERT_EQUAL(OUString("(((<A1> L 1)) AND ((<B1> NEQ 2)))"), xEnumerationAccess6->getPresentation(true).trim());
905     CPPUNIT_ASSERT_EQUAL(OUString("0"), xEnumerationAccess6->getPresentation(false).trim());
906 
907     uno::Reference<text::XTextField> xEnumerationAccess5(xFields->nextElement(), uno::UNO_QUERY);
908     CPPUNIT_ASSERT_EQUAL(OUString("((<A1> EQ 1) AND (<B1> EQ 2))"), xEnumerationAccess5->getPresentation(true).trim());
909     CPPUNIT_ASSERT_EQUAL(OUString("1"), xEnumerationAccess5->getPresentation(false).trim());
910 
911     uno::Reference<text::XTextField> xEnumerationAccess4(xFields->nextElement(), uno::UNO_QUERY);
912     CPPUNIT_ASSERT_EQUAL(OUString("<D1> NEQ 3"), xEnumerationAccess4->getPresentation(true).trim());
913     CPPUNIT_ASSERT_EQUAL(OUString("1"), xEnumerationAccess4->getPresentation(false).trim());
914 
915     uno::Reference<text::XTextField> xEnumerationAccess3(xFields->nextElement(), uno::UNO_QUERY);
916     CPPUNIT_ASSERT_EQUAL(OUString("<C1> EQ 3"), xEnumerationAccess3->getPresentation(true).trim());
917     CPPUNIT_ASSERT_EQUAL(OUString("1"), xEnumerationAccess3->getPresentation(false).trim());
918 
919     uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
920     CPPUNIT_ASSERT_EQUAL(OUString("<B1> G 1"), xEnumerationAccess2->getPresentation(true).trim());
921     CPPUNIT_ASSERT_EQUAL(OUString("1"), xEnumerationAccess2->getPresentation(false).trim());
922 
923 }
924 
CPPUNIT_TEST_FIXTURE(Test,testTdf133647_unicode)925 CPPUNIT_TEST_FIXTURE(Test, testTdf133647_unicode)
926 {
927     load(mpTestDocumentPath, "tdf133647_unicode.docx");
928     /* Tests that non-ASCII characters in formulas are preserved when importing from MS Word */
929     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
930     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
931     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
932 
933     if( !xFields->hasMoreElements() ) {
934         CPPUNIT_ASSERT(false);
935         return;
936     }
937 
938     xFields->nextElement();
939     xFields->nextElement();
940     xFields->nextElement();
941 
942     uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
943     CPPUNIT_ASSERT_EQUAL(OUString(u"defined(預期結果)"), xEnumerationAccess1->getPresentation(true).trim());
944 
945     uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
946     CPPUNIT_ASSERT_EQUAL(OUString(u"defined(نتيجةمتوقعة)"), xEnumerationAccess2->getPresentation(true).trim());
947 
948     uno::Reference<text::XTextField> xEnumerationAccess3(xFields->nextElement(), uno::UNO_QUERY);
949     CPPUNIT_ASSERT_EQUAL(OUString(u"defined(ExpectedResult)"), xEnumerationAccess3->getPresentation(true).trim());
950 }
951 
CPPUNIT_TEST_FIXTURE(Test,testTdf123389)952 CPPUNIT_TEST_FIXTURE(Test, testTdf123389)
953 {
954     load(mpTestDocumentPath, "tdf123389.docx");
955     /* Tests that argument lists, cell references, and cell ranges are translated correctly
956      * when importing table formulae from MS Word */
957     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
958     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
959     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
960 
961     if( !xFields->hasMoreElements() ) {
962         CPPUNIT_ASSERT(false);
963         return;
964     }
965 
966     uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
967     CPPUNIT_ASSERT_EQUAL(OUString("((2.345) ROUND (1))"), xEnumerationAccess1->getPresentation(true).trim());
968     CPPUNIT_ASSERT_EQUAL(OUString("2.3"), xEnumerationAccess1->getPresentation(false).trim());
969 
970     uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
971     CPPUNIT_ASSERT_EQUAL(OUString("((<A1>) ROUND (2))"), xEnumerationAccess2->getPresentation(true).trim());
972     CPPUNIT_ASSERT_EQUAL(OUString("2.35"), xEnumerationAccess2->getPresentation(false).trim());
973 }
974 
975 
CPPUNIT_TEST_FIXTURE(Test,testTdf107784)976 CPPUNIT_TEST_FIXTURE(Test, testTdf107784)
977 {
978     load(mpTestDocumentPath, "tdf107784.docx");
979     // Make sure the field displays the citation's title and not the identifier
980     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
981     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
982     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
983 
984     if( !xFields->hasMoreElements() ) {
985         CPPUNIT_ASSERT(false);
986         return;
987     }
988 
989     uno::Reference<text::XTextField> xEnumerationAccess(xFields->nextElement(), uno::UNO_QUERY);
990     CPPUNIT_ASSERT_EQUAL(OUString("Bibliography entry"), xEnumerationAccess->getPresentation(true).trim());
991     CPPUNIT_ASSERT_EQUAL(OUString("(Smith, 1950)"), xEnumerationAccess->getPresentation(false).trim());
992 }
993 
CPPUNIT_TEST_FIXTURE(Test,testTdf115883)994 CPPUNIT_TEST_FIXTURE(Test, testTdf115883)
995 {
996     load(mpTestDocumentPath, "tdf115883.docx");
997     // Import failed due to an unhandled exception when getting the Surround
998     // property of a not yet inserted frame.
999 }
1000 
CPPUNIT_TEST_FIXTURE(Test,testTdf75573)1001 CPPUNIT_TEST_FIXTURE(Test, testTdf75573)
1002 {
1003     load(mpTestDocumentPath, "tdf75573_page1frame.docx");
1004     // the problem was that the frame was discarded
1005     // when an unrelated, unused, odd-header was flagged as discardable
1006     lcl_countTextFrames( mxComponent, 1 );
1007 
1008     // the frame should be on page 1
1009     CPPUNIT_ASSERT_EQUAL( OUString("lorem ipsum"), parseDump("/root/page[1]/body/section/txt/anchored/fly/txt[1]/text()") );
1010 
1011     // the "Proprietary" style should set the vertical and horizontal anchors to the page
1012     uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY);
1013     CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xPropertySet, "VertOrientRelation"));
1014     CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xPropertySet, "HoriOrientRelation"));
1015 
1016     // the frame should be located near the bottom[23186]/center[2955] of the page
1017     CPPUNIT_ASSERT(sal_Int32(20000) < getProperty<sal_Int32>(xPropertySet, "VertOrientPosition"));
1018     CPPUNIT_ASSERT(sal_Int32(2500) < getProperty<sal_Int32>(xPropertySet, "HoriOrientPosition"));
1019 
1020     css::uno::Reference<css::lang::XMultiServiceFactory> m_xTextFactory(mxComponent, uno::UNO_QUERY);
1021     uno::Reference< beans::XPropertySet > xSettings(m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
1022     uno::Any aProtect = xSettings->getPropertyValue("ProtectForm");
1023     bool bProt = true;
1024     aProtect >>= bProt;
1025     CPPUNIT_ASSERT(!bProt);
1026 }
1027 
CPPUNIT_TEST_FIXTURE(Test,testTdf75573_lostTable)1028 CPPUNIT_TEST_FIXTURE(Test, testTdf75573_lostTable)
1029 {
1030     load(mpTestDocumentPath, "tdf75573_lostTable.docx");
1031     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1032     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
1033     CPPUNIT_ASSERT_EQUAL_MESSAGE("# of tables", sal_Int32(1), xTables->getCount() );
1034 
1035     CPPUNIT_ASSERT_EQUAL_MESSAGE("# of frames/shapes", 0, getShapes() );
1036 
1037     CPPUNIT_ASSERT_EQUAL_MESSAGE("# of pages", 3, getPages() );
1038 }
1039 
CPPUNIT_TEST_FIXTURE(Test,testTdf109316_dropCaps)1040 CPPUNIT_TEST_FIXTURE(Test, testTdf109316_dropCaps)
1041 {
1042     load(mpTestDocumentPath, "tdf109316_dropCaps.docx");
1043     uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
1044     css::style::DropCapFormat aDropCap = getProperty<css::style::DropCapFormat>(xSet,"DropCapFormat");
1045     CPPUNIT_ASSERT_EQUAL( sal_Int8(2), aDropCap.Lines );
1046     CPPUNIT_ASSERT_EQUAL( sal_Int8(1), aDropCap.Count );
1047     CPPUNIT_ASSERT_EQUAL( sal_Int16(1270), aDropCap.Distance );
1048 
1049     xSet.set(getParagraph(2), uno::UNO_QUERY);
1050     aDropCap = getProperty<css::style::DropCapFormat>(xSet,"DropCapFormat");
1051     CPPUNIT_ASSERT_EQUAL( sal_Int8(3), aDropCap.Lines );
1052     CPPUNIT_ASSERT_EQUAL( sal_Int8(1), aDropCap.Count );
1053     CPPUNIT_ASSERT_EQUAL( sal_Int16(508), aDropCap.Distance );
1054 
1055     xSet.set(getParagraph(3), uno::UNO_QUERY);
1056     aDropCap = getProperty<css::style::DropCapFormat>(xSet,"DropCapFormat");
1057     CPPUNIT_ASSERT_EQUAL( sal_Int8(4), aDropCap.Lines );
1058     CPPUNIT_ASSERT_EQUAL( sal_Int8(7), aDropCap.Count );
1059     CPPUNIT_ASSERT_EQUAL( sal_Int16(0), aDropCap.Distance );
1060 }
1061 
CPPUNIT_TEST_FIXTURE(Test,lineWpsOnly)1062 CPPUNIT_TEST_FIXTURE(Test, lineWpsOnly)
1063 {
1064     load(mpTestDocumentPath, "line-wps-only.docx");
1065     uno::Reference<drawing::XShape> xShape = getShape(1);
1066     // Check position, it was -7223 as it was set after the CustomShapeGeometry property.
1067     CPPUNIT_ASSERT_EQUAL(sal_Int32(210), xShape->getPosition().X);
1068 }
1069 
CPPUNIT_TEST_FIXTURE(Test,lineRotation)1070 CPPUNIT_TEST_FIXTURE(Test, lineRotation)
1071 {
1072     load(mpTestDocumentPath, "line-rotation.docx");
1073     uno::Reference<drawing::XShape> xShape = getShape(3);
1074     // This was 5096: the line was shifted towards the bottom, so the end of
1075     // the 3 different lines wasn't at the same point.
1076     CPPUNIT_ASSERT_EQUAL(sal_Int32(4808), xShape->getPosition().Y);
1077 }
1078 
CPPUNIT_TEST_FIXTURE(Test,textboxWpsOnly)1079 CPPUNIT_TEST_FIXTURE(Test, textboxWpsOnly)
1080 {
1081     load(mpTestDocumentPath, "textbox-wps-only.docx");
1082     uno::Reference<text::XTextRange> xFrame(getShape(1), uno::UNO_QUERY);
1083     CPPUNIT_ASSERT_EQUAL(OUString("Hello world!"), xFrame->getString());
1084     // Position wasn't horizontally centered.
1085     CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, getProperty<sal_Int16>(xFrame, "HoriOrient"));
1086 
1087     // Position was the default (hori center, vert top) for the textbox.
1088     xFrame.set(getShape(2), uno::UNO_QUERY);
1089     CPPUNIT_ASSERT_EQUAL(sal_Int32(2173), getProperty<sal_Int32>(xFrame, "HoriOrientPosition"));
1090 #ifdef MACOSX
1091     // FIXME: The assert below fails wildly on a Retina display
1092     NSScreen* nsScreen = [ NSScreen mainScreen ];
1093     CGFloat scaleFactor = [ nsScreen backingScaleFactor ];   // for instance on the 5K Retina iMac,
1094                                                              // [NSScreen mainScreen].frame.size is 2560x1440,
1095                                                              // while real display size is 5120x2880
1096     if ( nsScreen.frame.size.width * scaleFactor > 4000 )
1097         return;
1098 #endif
1099     CPPUNIT_ASSERT_EQUAL(sal_Int32(2805), getProperty<sal_Int32>(xFrame, "VertOrientPosition"));
1100 }
1101 
CPPUNIT_TEST_FIXTURE(Test,testGroupshapeRelsize)1102 CPPUNIT_TEST_FIXTURE(Test, testGroupshapeRelsize)
1103 {
1104     load(mpTestDocumentPath, "groupshape-relsize.docx");
1105     // This was 43760, i.e. the height of the groupshape was larger than the page height, which is obviously incorrect.
1106     CPPUNIT_ASSERT_EQUAL(oox::drawingml::convertEmuToHmm(9142730), getShape(1)->getSize().Height);
1107 }
1108 
CPPUNIT_TEST_FIXTURE(Test,testOleAnchor)1109 CPPUNIT_TEST_FIXTURE(Test, testOleAnchor)
1110 {
1111     load(mpTestDocumentPath, "ole-anchor.docx");
1112     // This was AS_CHARACTER, even if the VML style explicitly contains "position:absolute".
1113     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, getProperty<text::TextContentAnchorType>(getShape(1), "AnchorType"));
1114     // This was DYNAMIC, even if the default is THROUGH and there is no w10:wrap element in the bugdoc.
1115     CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_THROUGH, getProperty<text::WrapTextMode>(getShape(1), "Surround"));
1116 }
1117 
CPPUNIT_TEST_FIXTURE(Test,testTdf48658_transparentOLEheader)1118 CPPUNIT_TEST_FIXTURE(Test, testTdf48658_transparentOLEheader)
1119 {
1120     load(mpTestDocumentPath, "tdf48658_transparentOLEheader.docx");
1121     // The problem was that the shape in the header was hidden in the background.
1122     // The round-tripped document was always fine (even before the fix) but the shape numbers change, so import-only test.
1123     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getShape(1), "Opaque"));
1124 }
1125 
CPPUNIT_TEST_FIXTURE(Test,testDMLGroupShapeParaAdjust)1126 CPPUNIT_TEST_FIXTURE(Test, testDMLGroupShapeParaAdjust)
1127 {
1128     load(mpTestDocumentPath, "dml-groupshape-paraadjust.docx");
1129     // Paragraph adjustment inside a group shape was not imported
1130     uno::Reference<container::XIndexAccess> xGroup(getShape(1), uno::UNO_QUERY);
1131     uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xGroup->getByIndex(1), uno::UNO_QUERY_THROW)->getText();
1132     // 2nd line is adjusted to the right
1133     CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_RIGHT), getProperty<sal_Int16>(getRun(getParagraphOfText(2, xText), 1), "ParaAdjust"));
1134     // 3rd line has no adjustment
1135     CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getRun(getParagraphOfText(3, xText), 1), "ParaAdjust"));
1136     // 4th line is adjusted to center
1137     CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), getProperty<sal_Int16>(getRun(getParagraphOfText(4, xText), 1), "ParaAdjust"));
1138     // 5th line has no adjustment
1139     CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getRun(getParagraphOfText(5, xText), 1), "ParaAdjust"));
1140     // 6th line is justified
1141     CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_BLOCK), getProperty<sal_Int16>(getRun(getParagraphOfText(6, xText), 1), "ParaAdjust"));
1142     // 7th line has no adjustment
1143     CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_LEFT), getProperty<sal_Int16>(getRun(getParagraphOfText(7, xText), 1), "ParaAdjust"));
1144 }
1145 
CPPUNIT_TEST_FIXTURE(Test,testTdf99135)1146 CPPUNIT_TEST_FIXTURE(Test, testTdf99135)
1147 {
1148     load(mpTestDocumentPath, "tdf99135.docx");
1149     // This was 0, crop was ignored on VML import.
1150     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1825), getProperty<text::GraphicCrop>(getShape(1), "GraphicCrop").Bottom);
1151 }
1152 
CPPUNIT_TEST_FIXTURE(Test,testTdf85523)1153 CPPUNIT_TEST_FIXTURE(Test, testTdf85523)
1154 {
1155     load(mpTestDocumentPath, "tdf85523.docx");
1156     auto xTextField = getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 7), "TextField");
1157     auto xText = getProperty< uno::Reference<text::XText> >(xTextField, "TextRange");
1158     // This was "commentX": an unexpected extra char was added at the comment end.
1159     getParagraphOfText(1, xText, "comment");
1160 }
1161 
CPPUNIT_TEST_FIXTURE(Test,testStrictLockedcanvas)1162 CPPUNIT_TEST_FIXTURE(Test, testStrictLockedcanvas)
1163 {
1164     load(mpTestDocumentPath, "strict-lockedcanvas.docx");
1165     // locked canvas shape was missing.
1166     getShape(1);
1167 }
1168 
CPPUNIT_TEST_FIXTURE(Test,testFdo75722vml)1169 CPPUNIT_TEST_FIXTURE(Test, testFdo75722vml)
1170 {
1171     load(mpTestDocumentPath, "fdo75722-vml.docx");
1172     uno::Reference<drawing::XShape> xShape = getShape(1);
1173     awt::Point aPos = xShape->getPosition();
1174     awt::Size aSize = xShape->getSize();
1175     sal_Int64 nRot = getProperty<sal_Int64>(xShape, "RotateAngle");
1176 
1177     CPPUNIT_ASSERT_EQUAL(sal_Int32(3720), aPos.X);
1178     CPPUNIT_ASSERT_EQUAL(sal_Int32(-392), aPos.Y);
1179     CPPUNIT_ASSERT_EQUAL(sal_Int32(5457), aSize.Width);
1180     CPPUNIT_ASSERT_EQUAL(sal_Int32(3447), aSize.Height);
1181     CPPUNIT_ASSERT_EQUAL(sal_Int64(3100), nRot);
1182 }
1183 
CPPUNIT_TEST_FIXTURE(Test,testFdo75722dml)1184 CPPUNIT_TEST_FIXTURE(Test, testFdo75722dml)
1185 {
1186     load(mpTestDocumentPath, "fdo75722-dml.docx");
1187     uno::Reference<drawing::XShape> xShape = getShape(1);
1188     awt::Point aPos = xShape->getPosition();
1189     awt::Size aSize = xShape->getSize();
1190     sal_Int64 nRot = getProperty<sal_Int64>(xShape, "RotateAngle");
1191 
1192     // a slight difference regarding vml file is tolerated due to rounding errors
1193     CPPUNIT_ASSERT_EQUAL(sal_Int32(3720), aPos.X);
1194     CPPUNIT_ASSERT_EQUAL(sal_Int32(-397), aPos.Y);
1195     CPPUNIT_ASSERT_EQUAL(sal_Int32(5457), aSize.Width);
1196     CPPUNIT_ASSERT_EQUAL(sal_Int32(3447), aSize.Height);
1197     CPPUNIT_ASSERT_EQUAL(sal_Int64(3128), nRot);
1198 }
1199 
CPPUNIT_TEST_FIXTURE(Test,testUnbalancedColumnsCompat)1200 CPPUNIT_TEST_FIXTURE(Test, testUnbalancedColumnsCompat)
1201 {
1202     load(mpTestDocumentPath, "unbalanced-columns-compat.docx");
1203     uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
1204     uno::Reference<container::XIndexAccess> xTextSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
1205     // This was false, we ignored the relevant compat setting to make this non-last section unbalanced.
1206     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextSections->getByIndex(0), "DontBalanceTextColumns"));
1207 }
1208 
CPPUNIT_TEST_FIXTURE(Test,testFloatingTableSectionColumns)1209 CPPUNIT_TEST_FIXTURE(Test, testFloatingTableSectionColumns)
1210 {
1211     load(mpTestDocumentPath, "floating-table-section-columns.docx");
1212     OUString tableWidth = parseDump("/root/page[1]/body/section/column[2]/body/txt/anchored/fly/tab/infos/bounds", "width");
1213     // table width was restricted by a column
1214     CPPUNIT_ASSERT( tableWidth.toInt32() > 10000 );
1215 }
1216 
dateTimeToString(const util::DateTime & dt)1217 static OString dateTimeToString( const util::DateTime& dt )
1218 {
1219     return DateTimeToOString( DateTime( Date( dt.Day, dt.Month, dt.Year ), tools::Time( dt.Hours, dt.Minutes, dt.Seconds )));
1220 }
1221 
CPPUNIT_TEST_FIXTURE(Test,testBnc821804)1222 CPPUNIT_TEST_FIXTURE(Test, testBnc821804)
1223 {
1224     load(mpTestDocumentPath, "bnc821804.docx");
1225     CPPUNIT_ASSERT_EQUAL( OUString( "TITLE" ), getRun( getParagraph( 1 ), 1 )->getString());
1226     CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(1), 1), "RedlineType"));
1227     // Redline information (SwXRedlinePortion) are separate "runs" apparently.
1228     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 2), "RedlineType"));
1229     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(1), 2), "RedlineType"));
1230     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(1), 2), "IsStart"));
1231     CPPUNIT_ASSERT_EQUAL(OUString("unknown1"),getProperty<OUString>(getRun(getParagraph(1), 2), "RedlineAuthor"));
1232     CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T09:46:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(1), 2), "RedlineDateTime")));
1233     // So only the 3rd run is actual text (and the two runs have been merged into one, not sure why, but that shouldn't be a problem).
1234     CPPUNIT_ASSERT_EQUAL(OUString(" (1st run of an insert) (2nd run of an insert)"), getRun(getParagraph(1),3)->getString());
1235     CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(1), 3), "RedlineType"));
1236     // And the end SwXRedlinePortion of the redline.
1237     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 4), "RedlineType"));
1238     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(1), 4), "RedlineType"));
1239     CPPUNIT_ASSERT_EQUAL(OUString("unknown1"),getProperty<OUString>(getRun(getParagraph(1), 4), "RedlineAuthor"));
1240     CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T09:46:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(1), 4), "RedlineDateTime")));
1241     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(1), 4), "IsStart"));
1242 
1243     CPPUNIT_ASSERT_EQUAL(OUString("Normal text"), getRun(getParagraph(2),1)->getString());
1244     CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(2), 1), "RedlineType"));
1245 
1246     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(3), 1), "RedlineType"));
1247     CPPUNIT_ASSERT_EQUAL(OUString("Delete"),getProperty<OUString>(getRun(getParagraph(3), 1), "RedlineType"));
1248     CPPUNIT_ASSERT_EQUAL(OUString("unknown2"),getProperty<OUString>(getRun(getParagraph(3), 1), "RedlineAuthor"));
1249     CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T09:47:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(3), 1), "RedlineDateTime")));
1250     CPPUNIT_ASSERT_EQUAL(OUString("Deleted"), getRun(getParagraph(3),2)->getString());
1251 
1252     // This is both inserted and formatted, so there are two SwXRedlinePortion "runs". Given that the redlines overlap and Writer core
1253     // doesn't officially expect that (even though it copes, the redline info will be split depending on how Writer deal with it).
1254     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(4), 1), "RedlineType"));
1255     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(4), 1), "RedlineType"));
1256     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(4), 1), "IsStart"));
1257     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(4), 2), "RedlineType"));
1258     CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(4), 2), "RedlineType"));
1259     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(4), 2), "IsStart"));
1260     CPPUNIT_ASSERT_EQUAL(OUString("Inserted and formatted"), getRun(getParagraph(4),3)->getString());
1261     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(4), 4), "RedlineType"));
1262     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(4), 4), "RedlineType"));
1263     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(4), 4), "IsStart"));
1264     CPPUNIT_ASSERT_EQUAL(OUString(" and this is only formatted"), getRun(getParagraph(4),5)->getString());
1265     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(4), 6), "RedlineType"));
1266     CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(4), 6), "RedlineType"));
1267     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(4), 6), "IsStart"));
1268 
1269     CPPUNIT_ASSERT_EQUAL(OUString("Normal text"), getRun(getParagraph(5),1)->getString());
1270     CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(5), 1), "RedlineType"));
1271 
1272     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(6), 1), "RedlineType"));
1273     CPPUNIT_ASSERT_EQUAL(OUString("Format"),getProperty<OUString>(getRun(getParagraph(6), 1), "RedlineType"));
1274     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(6), 1), "IsStart"));
1275     CPPUNIT_ASSERT_EQUAL(OUString("unknown5"),getProperty<OUString>(getRun(getParagraph(6), 1), "RedlineAuthor"));
1276     CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T10:02:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(6), 1), "RedlineDateTime")));
1277     CPPUNIT_ASSERT_EQUAL(OUString("Formatted run"), getRun(getParagraph(6),2)->getString());
1278     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(6), 3), "RedlineType"));
1279     CPPUNIT_ASSERT_EQUAL(OUString("Format"),getProperty<OUString>(getRun(getParagraph(6), 3), "RedlineType"));
1280     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(6), 3), "IsStart"));
1281     CPPUNIT_ASSERT_EQUAL(OUString(" and normal text here "), getRun(getParagraph(6),4)->getString());
1282     CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(6), 4), "RedlineType"));
1283     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(6), 5), "RedlineType"));
1284     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(6), 5), "RedlineType"));
1285     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(6), 5), "IsStart"));
1286     CPPUNIT_ASSERT_EQUAL(OUString("unknown6"),getProperty<OUString>(getRun(getParagraph(6), 5), "RedlineAuthor"));
1287     CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T09:48:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(6), 5), "RedlineDateTime")));
1288     CPPUNIT_ASSERT_EQUAL(OUString("and inserted again"), getRun(getParagraph(6),6)->getString());
1289     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(6), 7), "RedlineType"));
1290     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(6), 7), "RedlineType"));
1291     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(6), 7), "IsStart"));
1292     CPPUNIT_ASSERT_EQUAL(OUString(" and normal text again "), getRun(getParagraph(6),8)->getString());
1293     CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(6), 8), "RedlineType"));
1294     CPPUNIT_ASSERT_EQUAL(OUString("Format"),getProperty<OUString>(getRun(getParagraph(6), 9), "RedlineType"));
1295     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(6), 9), "IsStart"));
1296     CPPUNIT_ASSERT_EQUAL(OUString("unknown7"),getProperty<OUString>(getRun(getParagraph(6), 9), "RedlineAuthor"));
1297     CPPUNIT_ASSERT_EQUAL(OUString("and formatted"), getRun(getParagraph(6),10)->getString());
1298     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(6), 11), "IsStart"));
1299     CPPUNIT_ASSERT_EQUAL(OUString(" and normal."), getRun(getParagraph(6),12)->getString());
1300     CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(6), 12), "RedlineType"));
1301 
1302     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(7), 1), "RedlineType"));
1303     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(7), 1), "RedlineType"));
1304     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(7), 1), "IsStart"));
1305     CPPUNIT_ASSERT_EQUAL(OUString("unknown8"),getProperty<OUString>(getRun(getParagraph(7), 1), "RedlineAuthor"));
1306     CPPUNIT_ASSERT_EQUAL(OUString("One insert."), getRun(getParagraph(7),2)->getString());
1307     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(7), 3), "RedlineType"));
1308     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(7), 3), "RedlineType"));
1309     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(7), 3), "IsStart"));
1310     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(7), 4), "RedlineType"));
1311     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(7), 4), "RedlineType"));
1312     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(7), 4), "IsStart"));
1313     CPPUNIT_ASSERT_EQUAL(OUString("unknown9"),getProperty<OUString>(getRun(getParagraph(7), 4), "RedlineAuthor"));
1314     CPPUNIT_ASSERT_EQUAL(OUString("Second insert."), getRun(getParagraph(7),5)->getString());
1315     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(7), 6), "RedlineType"));
1316     CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(7), 6), "RedlineType"));
1317     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(7), 6), "IsStart"));
1318 
1319     // Overlapping again.
1320     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(8), 1), "RedlineType"));
1321     CPPUNIT_ASSERT_EQUAL(OUString("Delete"),getProperty<OUString>(getRun(getParagraph(8), 1), "RedlineType"));
1322     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(8), 1), "IsStart"));
1323     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(8), 2), "RedlineType"));
1324     CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(8), 2), "RedlineType"));
1325     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(8), 1), "IsStart"));
1326     CPPUNIT_ASSERT_EQUAL(OUString("Deleted and formatted"), getRun(getParagraph(8),3)->getString());
1327     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(8), 4), "RedlineType"));
1328     CPPUNIT_ASSERT_EQUAL(OUString("Delete"),getProperty<OUString>(getRun(getParagraph(8), 4), "RedlineType"));
1329     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(8), 4), "IsStart"));
1330     CPPUNIT_ASSERT_EQUAL(OUString(" and this is only formatted"), getRun(getParagraph(8),5)->getString());
1331     CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(8), 6), "RedlineType"));
1332     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(8), 6), "IsStart"));
1333 
1334     CPPUNIT_ASSERT_EQUAL(OUString("Normal text"), getRun(getParagraph(9),1)->getString());
1335     CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(9), 1), "RedlineType"));
1336 
1337     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(10), 1), "RedlineType"));
1338     CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(10), 1), "RedlineType"));
1339     CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(10), 1), "IsStart"));
1340     CPPUNIT_ASSERT_EQUAL(OUString("This is only formatted."), getRun(getParagraph(10),2)->getString());
1341     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(10), 3), "RedlineType"));
1342     CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(10), 3), "RedlineType"));
1343     CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(10), 3), "IsStart"));
1344 }
1345 
CPPUNIT_TEST_FIXTURE(Test,testFdo87488)1346 CPPUNIT_TEST_FIXTURE(Test, testFdo87488)
1347 {
1348     // The shape on the right (index 0, CustomShape within a
1349     // GroupShape) is rotated 90 degrees clockwise and contains text
1350     // rotated 90 degrees anticlockwise.  Must be read with SmartArt
1351     // enabled in preTest above, otherwise it gets converted to a
1352     // StarView MetaFile.
1353     SvtFilterOptions::Get().SetSmartArt2Shape(true);
1354     comphelper::ScopeGuard g([] { SvtFilterOptions::Get().SetSmartArt2Shape(false); });
1355     load(mpTestDocumentPath, "fdo87488.docx");
1356     uno::Reference<container::XIndexAccess> group(getShape(1), uno::UNO_QUERY);
1357     {
1358         uno::Reference<text::XTextRange> text(group->getByIndex(1), uno::UNO_QUERY);
1359         CPPUNIT_ASSERT_EQUAL(OUString("text2"), text->getString());
1360     }
1361     {
1362         uno::Reference<beans::XPropertySet> props(group->getByIndex(1), uno::UNO_QUERY);
1363         CPPUNIT_ASSERT_EQUAL(props->getPropertyValue("RotateAngle"),
1364                              uno::makeAny<sal_Int32>(270 * 100));
1365         comphelper::SequenceAsHashMap geom(props->getPropertyValue("CustomShapeGeometry"));
1366         CPPUNIT_ASSERT_EQUAL(sal_Int32(90), geom["TextPreRotateAngle"].get<sal_Int32>());
1367     }
1368 }
1369 
CPPUNIT_TEST_FIXTURE(Test,testTdf85232)1370 CPPUNIT_TEST_FIXTURE(Test, testTdf85232)
1371 {
1372     load(mpTestDocumentPath, "tdf85232.docx");
1373     uno::Reference<drawing::XShapes> xShapes(getShapeByName(u"Group 219"), uno::UNO_QUERY);
1374     uno::Reference<drawing::XShape> xShape(xShapes->getByIndex(1), uno::UNO_QUERY);
1375     uno::Reference<drawing::XShapeDescriptor> xShapeDescriptor = xShape;
1376     // Make sure we're not testing the ellipse child.
1377     CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.LineShape"), xShapeDescriptor->getShapeType());
1378 
1379     // This was 2900: horizontal position of the line was incorrect, the 3 children were not connected visually.
1380     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2267), xShape->getPosition().X);
1381 }
1382 
CPPUNIT_TEST_FIXTURE(Test,testTdf95755)1383 CPPUNIT_TEST_FIXTURE(Test, testTdf95755)
1384 {
1385     load(mpTestDocumentPath, "tdf95755.docx");
1386     /*
1387     * The problem was that the width of a second table with single cell was discarded
1388     * and resulted in too wide table
1389     */
1390     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1391     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
1392     uno::Reference<beans::XPropertySet> xTableProperties(xTables->getByIndex(0), uno::UNO_QUERY);
1393     uno::Any aValue = xTableProperties->getPropertyValue("Width");
1394     sal_Int32 nWidth;
1395     aValue >>= nWidth;
1396     CPPUNIT_ASSERT_EQUAL(sal_Int32(10659), nWidth);
1397 }
1398 
CPPUNIT_TEST_FIXTURE(Test,testTdf60351)1399 CPPUNIT_TEST_FIXTURE(Test, testTdf60351)
1400 {
1401     load(mpTestDocumentPath, "tdf60351.docx");
1402     // Get the first image in the document and check its contour polygon.
1403     // It should contain 6 points. Check their coordinates.
1404     uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY);
1405     // test for TODO: if paragraph's background becomes bottommost [better yet: wraps around shape], then remove this hack
1406     CPPUNIT_ASSERT_EQUAL_MESSAGE("HACK ALERT: Shape is in foreground", true, getProperty<bool>(xPropertySet, "Opaque"));
1407 
1408     css::drawing::PointSequenceSequence aPolyPolygon;
1409     xPropertySet->getPropertyValue("ContourPolyPolygon") >>= aPolyPolygon;
1410     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aPolyPolygon.getLength());
1411     const css::drawing::PointSequence& aPolygon = aPolyPolygon[0];
1412     CPPUNIT_ASSERT_EQUAL(sal_Int32(6),   aPolygon.getLength());
1413     CPPUNIT_ASSERT_EQUAL(sal_Int32(0),   aPolygon[0].X);
1414     CPPUNIT_ASSERT_EQUAL(sal_Int32(0),   aPolygon[0].Y);
1415     CPPUNIT_ASSERT_EQUAL(sal_Int32(316), aPolygon[1].X);
1416     CPPUNIT_ASSERT_EQUAL(sal_Int32(0),   aPolygon[1].Y);
1417     CPPUNIT_ASSERT_EQUAL(sal_Int32(316), aPolygon[2].X);
1418     CPPUNIT_ASSERT_EQUAL(sal_Int32(316), aPolygon[2].Y);
1419     CPPUNIT_ASSERT_EQUAL(sal_Int32(158), aPolygon[3].X);
1420     CPPUNIT_ASSERT_EQUAL(sal_Int32(298), aPolygon[3].Y);
1421     CPPUNIT_ASSERT_EQUAL(sal_Int32(0),   aPolygon[4].X);
1422     CPPUNIT_ASSERT_EQUAL(sal_Int32(316), aPolygon[4].Y);
1423     CPPUNIT_ASSERT_EQUAL(sal_Int32(0),   aPolygon[5].X);
1424     CPPUNIT_ASSERT_EQUAL(sal_Int32(0),   aPolygon[5].Y);
1425 }
1426 
CPPUNIT_TEST_FIXTURE(Test,testTdf95970)1427 CPPUNIT_TEST_FIXTURE(Test, testTdf95970)
1428 {
1429     load(mpTestDocumentPath, "tdf95970.docx");
1430     // First shape: the rotation should be -12.94 deg, it should be mirrored.
1431     // Proper color order of image on test doc (left->right):
1432     // top row: green->red
1433     // bottom row: yellow->blue
1434     uno::Reference<drawing::XShape> xShape(getShape(1), uno::UNO_SET_THROW);
1435     uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY_THROW);
1436     sal_Int32 aRotate = 0;
1437     xPropertySet->getPropertyValue("RotateAngle") >>= aRotate;
1438     CPPUNIT_ASSERT_EQUAL(sal_Int32(34706), aRotate);
1439     bool bIsMirrored = false;
1440     xPropertySet->getPropertyValue("IsMirrored") >>= bIsMirrored;
1441     CPPUNIT_ASSERT(bIsMirrored);
1442     drawing::HomogenMatrix3 aTransform;
1443     xPropertySet->getPropertyValue("Transformation") >>= aTransform;
1444     CPPUNIT_ASSERT(basegfx::fTools::equal(aTransform.Line1.Column1,  4767.0507250872988));
1445     CPPUNIT_ASSERT(basegfx::fTools::equal(aTransform.Line1.Column2, -1269.0985325236848));
1446     CPPUNIT_ASSERT(basegfx::fTools::equal(aTransform.Line1.Column3,  696.73611111111109));
1447     CPPUNIT_ASSERT(basegfx::fTools::equal(aTransform.Line2.Column1,  1095.3035265135941));
1448     CPPUNIT_ASSERT(basegfx::fTools::equal(aTransform.Line2.Column2,  5523.4525711162969));
1449     CPPUNIT_ASSERT(basegfx::fTools::equal(aTransform.Line2.Column3,  672.04166666666663));
1450     CPPUNIT_ASSERT(basegfx::fTools::equal(aTransform.Line3.Column1,  0.0));
1451     CPPUNIT_ASSERT(basegfx::fTools::equal(aTransform.Line3.Column2,  0.0));
1452     CPPUNIT_ASSERT(basegfx::fTools::equal(aTransform.Line3.Column3,  1.0));
1453 }
1454 
CPPUNIT_TEST_FIXTURE(Test,testTdf96674)1455 CPPUNIT_TEST_FIXTURE(Test, testTdf96674)
1456 {
1457     load(mpTestDocumentPath, "tdf96674.docx");
1458     uno::Reference<drawing::XShape> xShape = getShape(1);
1459     CPPUNIT_ASSERT(xShape.is());
1460     awt::Size aActualSize(xShape->getSize());
1461     // Width was 3493: the vertical line was horizontal.
1462     CPPUNIT_ASSERT(aActualSize.Width < aActualSize.Height);
1463     CPPUNIT_ASSERT(aActualSize.Height > 0);
1464 }
1465 
CPPUNIT_TEST_FIXTURE(Test,testTdf122717)1466 CPPUNIT_TEST_FIXTURE(Test, testTdf122717)
1467 {
1468     load(mpTestDocumentPath, "tdf122717.docx");
1469     uno::Reference<drawing::XShape> xShape = getShape(1);
1470     CPPUNIT_ASSERT(xShape.is());
1471     awt::Size aActualSize(xShape->getSize());
1472     // Without the fix in place, this test would have failed with
1473     // - Expected: 2
1474     // - Actual  : 8160
1475     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aActualSize.Width);
1476     CPPUNIT_ASSERT_EQUAL(sal_Int32(8160), aActualSize.Height);
1477 
1478 }
1479 
CPPUNIT_TEST_FIXTURE(Test,testTdf98882)1480 CPPUNIT_TEST_FIXTURE(Test, testTdf98882)
1481 {
1482     load(mpTestDocumentPath, "tdf98882.docx");
1483     sal_Int32 nFlyHeight = parseDump("//anchored/fly/infos/bounds", "height").toInt32();
1484     sal_Int32 nContentHeight = parseDump("//notxt/infos/bounds", "height").toInt32();
1485     // The content height was 600, not 360, so the frame and the content height did not match.
1486     CPPUNIT_ASSERT_EQUAL(nFlyHeight, nContentHeight);
1487 }
1488 
CPPUNIT_TEST_FIXTURE(Test,testTdf100830)1489 CPPUNIT_TEST_FIXTURE(Test, testTdf100830)
1490 {
1491     load(mpTestDocumentPath, "tdf100830.docx");
1492     // FillTransparence wasn't imported, this was 0.
1493     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(30), getProperty<sal_Int16>(getShape(1), "FillTransparence"));
1494 }
1495 
CPPUNIT_TEST_FIXTURE(Test,testTdf103664)1496 CPPUNIT_TEST_FIXTURE(Test, testTdf103664)
1497 {
1498     load(mpTestDocumentPath, "tdf103664.docx");
1499     // Wingdings symbols were displayed as rectangles
1500     uno::Reference<text::XTextRange> xPara(getParagraph(1));
1501     CPPUNIT_ASSERT_EQUAL(u'\xf020', xPara->getString()[0] );
1502     CPPUNIT_ASSERT_EQUAL(u'\xf0fc', xPara->getString()[1] );
1503     CPPUNIT_ASSERT_EQUAL(u'\xf0dc', xPara->getString()[2] );
1504     CPPUNIT_ASSERT_EQUAL(u'\xf081', xPara->getString()[3] );
1505 
1506     uno::Reference<beans::XPropertySet> xRun(getRun(xPara,1), uno::UNO_QUERY);
1507     CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty<OUString>(xRun, "CharFontName"));
1508     CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty<OUString>(xRun, "CharFontNameAsian"));
1509     CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty<OUString>(xRun, "CharFontNameComplex"));
1510 
1511     // Make sure these special characters are imported as symbols
1512     CPPUNIT_ASSERT_EQUAL(awt::CharSet::SYMBOL, getProperty<sal_Int16>(xRun, "CharFontCharSet"));
1513 }
1514 
CPPUNIT_TEST_FIXTURE(Test,testTdf82824)1515 CPPUNIT_TEST_FIXTURE(Test, testTdf82824)
1516 {
1517     load(mpTestDocumentPath, "tdf82824.docx");
1518     // This was text::TextContentAnchorType_AS_CHARACTER, <wp:anchor> wasn't handled on import for the chart.
1519     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, getProperty<text::TextContentAnchorType>(getShape(1), "AnchorType"));
1520 }
1521 
CPPUNIT_TEST_FIXTURE(Test,testTdf96218)1522 CPPUNIT_TEST_FIXTURE(Test, testTdf96218)
1523 {
1524     load(mpTestDocumentPath, "tdf96218.docx");
1525     // Image had a bad position because layoutInCell attribute was not ignored
1526     CPPUNIT_ASSERT(!getProperty<bool>(getShape(1), "IsFollowingTextFlow"));
1527 }
1528 
CPPUNIT_TEST_FIXTURE(Test,testTdf101626)1529 CPPUNIT_TEST_FIXTURE(Test, testTdf101626)
1530 {
1531     load(mpTestDocumentPath, "tdf101626.docx");
1532     // Transform soft-hyphen to hard-hyphen as list bulletChar to avoid missing symbols in export
1533     uno::Reference<beans::XPropertySet> xPropertySet(getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY);
1534     uno::Reference<container::XIndexAccess> xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
1535     uno::Sequence<beans::PropertyValue> aProps;
1536     xLevels->getByIndex(0) >>= aProps; // 1st level
1537 
1538     for (beans::PropertyValue const & rProp : std::as_const(aProps))
1539     {
1540         if (rProp.Name == "BulletChar")
1541         {
1542             // the bulletChar has to be 0x2d!
1543             CPPUNIT_ASSERT_EQUAL(OUString("\x2d"), rProp.Value.get<OUString>());
1544             return;
1545         }
1546     }
1547 }
1548 
CPPUNIT_TEST_FIXTURE(Test,testTdf106606)1549 CPPUNIT_TEST_FIXTURE(Test,  testTdf106606)
1550 {
1551     load(mpTestDocumentPath, "tdf106606.docx" );
1552     auto FindGraphicBitmapPropertyInNumStyle = [&]( OUString rStyleName )
1553     {
1554         uno::Reference<beans::XPropertySet>     xPropertySet( getStyles( "NumberingStyles" )->getByName( rStyleName ), uno::UNO_QUERY );
1555         uno::Reference<container::XIndexAccess> xLevels( xPropertySet->getPropertyValue( "NumberingRules" ), uno::UNO_QUERY );
1556         uno::Sequence<beans::PropertyValue>     aProps;
1557         xLevels->getByIndex( 0 ) >>= aProps; // 1st level
1558 
1559         for ( beans::PropertyValue const & rProp : std::as_const(aProps))
1560         {
1561             // If the image was prematurely removed from cache when processed for previous numbering list, then the sequence hasn't the property.
1562             if ( rProp.Name == "GraphicBitmap" )
1563                 return true;
1564         }
1565         return false;
1566     };
1567 
1568     // The document has two numbering lists with a picture
1569     CPPUNIT_ASSERT( FindGraphicBitmapPropertyInNumStyle("WWNum1") );
1570     CPPUNIT_ASSERT( FindGraphicBitmapPropertyInNumStyle("WWNum2") );
1571 }
1572 
CPPUNIT_TEST_FIXTURE(Test,testTdf101627)1573 CPPUNIT_TEST_FIXTURE(Test, testTdf101627)
1574 {
1575     load(mpTestDocumentPath, "tdf101627.docx");
1576     // Do not shrink the textbox in the footer
1577     uno::Reference<text::XTextRange> xFrame(getShape(1), uno::UNO_QUERY);
1578     CPPUNIT_ASSERT(xFrame->getString().startsWith( "1" ) );
1579     CPPUNIT_ASSERT_EQUAL(sal_Int32(466), getProperty<sal_Int32>(xFrame, "Height"));
1580 }
1581 
CPPUNIT_TEST_FIXTURE(Test,testTdf133448)1582 CPPUNIT_TEST_FIXTURE(Test, testTdf133448)
1583 {
1584     load(mpTestDocumentPath, "tdf133448.docx");
1585     auto xGraphic = getProperty<uno::Reference<graphic::XGraphic>>(getShape(1), "Graphic");
1586     Graphic aGraphic(xGraphic);
1587     uno::Reference<beans::XPropertySet> xGraphicDescriptor(xGraphic, uno::UNO_QUERY_THROW);
1588     awt::Size aSizePixel;
1589     CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("SizePixel") >>= aSizePixel);
1590 
1591     //Without the fix in place, the graphic's size is 0x0
1592     CPPUNIT_ASSERT_GREATER(sal_Int32(0), aSizePixel.Width);
1593     CPPUNIT_ASSERT_GREATER(sal_Int32(0), aSizePixel.Height);
1594 }
1595 
CPPUNIT_TEST_FIXTURE(Test,testTdf100072)1596 CPPUNIT_TEST_FIXTURE(Test, testTdf100072)
1597 {
1598     load(mpTestDocumentPath, "tdf100072.docx");
1599     uno::Reference<drawing::XShape> xShape = getShape(1);
1600 
1601     // Ensure that shape has non-zero height
1602     CPPUNIT_ASSERT(xShape->getSize().Height > 0);
1603 
1604     // Ensure that shape left corner is within page (positive)
1605     CPPUNIT_ASSERT(xShape->getPosition().X > 0);
1606 
1607     // Save the first shape to a metafile.
1608     uno::Reference<drawing::XGraphicExportFilter> xGraphicExporter = drawing::GraphicExportFilter::create(comphelper::getProcessComponentContext());
1609     uno::Reference<lang::XComponent> xSourceDoc(xShape, uno::UNO_QUERY);
1610     xGraphicExporter->setSourceDocument(xSourceDoc);
1611 
1612     SvMemoryStream aStream;
1613     uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream));
1614     uno::Sequence<beans::PropertyValue> aDescriptor( comphelper::InitPropertySequence({
1615             { "OutputStream", uno::Any(xOutputStream) },
1616             { "FilterName", uno::Any(OUString("SVM")) }
1617         }));
1618     xGraphicExporter->filter(aDescriptor);
1619     aStream.Seek(STREAM_SEEK_TO_BEGIN);
1620 
1621     // Read it back and dump it as an XML file.
1622     Graphic aGraphic;
1623     TypeSerializer aSerializer(aStream);
1624     aSerializer.readGraphic(aGraphic);
1625     const GDIMetaFile& rMetaFile = aGraphic.GetGDIMetaFile();
1626     MetafileXmlDump dumper;
1627     xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, rMetaFile);
1628 
1629     // Get first polyline rightside x coordinate
1630     sal_Int32 nFirstEnd = getXPath(pXmlDoc, "(//polyline)[1]/point[2]", "x").toInt32();
1631 
1632     // Get last stroke x coordinate
1633     sal_Int32 nSecondEnd = getXPath(pXmlDoc, "(//polyline)[last()]/point[2]", "x").toInt32();
1634 
1635     // Assert that the difference is less than half point.
1636     CPPUNIT_ASSERT_MESSAGE("Shape line width does not match", abs(nFirstEnd - nSecondEnd) < 10);
1637 }
1638 
CPPUNIT_TEST_FIXTURE(Test,testTdf76446)1639 CPPUNIT_TEST_FIXTURE(Test, testTdf76446)
1640 {
1641     load(mpTestDocumentPath, "tdf76446.docx");
1642     uno::Reference<drawing::XShape> xShape = getShape(1);
1643     sal_Int64 nRot = getProperty<sal_Int64>(xShape, "RotateAngle");
1644     CPPUNIT_ASSERT_EQUAL(sal_Int64(3128), nRot);
1645 }
1646 
CPPUNIT_TEST_FIXTURE(Test,testTdf108350)1647 CPPUNIT_TEST_FIXTURE(Test, testTdf108350)
1648 {
1649     load(mpTestDocumentPath, "tdf108350.docx");
1650     // For OOXML without explicit font information, font needs to be Calibri 11 pt
1651     uno::Reference<text::XTextRange> xPara(getParagraph(1));
1652     uno::Reference<beans::XPropertySet> xRun(getRun(xPara, 1), uno::UNO_QUERY);
1653     CPPUNIT_ASSERT_EQUAL(OUString("Calibri"), getProperty<OUString>(xRun, "CharFontName"));
1654     CPPUNIT_ASSERT_EQUAL(double(11), getProperty<double>(xRun, "CharHeight"));
1655 }
1656 
CPPUNIT_TEST_FIXTURE(Test,testTdf108408)1657 CPPUNIT_TEST_FIXTURE(Test, testTdf108408)
1658 {
1659     load(mpTestDocumentPath, "tdf108408.docx");
1660     // Font size must consider units specifications; previously ignored and only used
1661     // integer part as half-pt size, i.e. 10 pt (20 half-pt) instead of 20 pt
1662     uno::Reference<text::XTextRange> xPara(getParagraph(1));
1663     uno::Reference<beans::XPropertySet> xRun(getRun(xPara, 1), uno::UNO_QUERY);
1664     CPPUNIT_ASSERT_EQUAL(double(20), getProperty<double>(xRun, "CharHeight"));
1665 }
1666 
CPPUNIT_TEST_FIXTURE(Test,testTdf108806)1667 CPPUNIT_TEST_FIXTURE(Test, testTdf108806)
1668 {
1669     load(mpTestDocumentPath, "tdf108806.docx");
1670     // tdf#108806:The CRLF in the text contents of XML must be converted to single spaces.
1671     CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
1672     uno::Reference< text::XTextRange > paragraph = getParagraph(1);
1673     CPPUNIT_ASSERT_EQUAL(
1674         OUString("First part of a line (before CRLF). Second part of the same line (after CRLF)."),
1675         paragraph->getString());
1676 }
1677 
CPPUNIT_TEST_FIXTURE(Test,testTdf87533_bidi)1678 CPPUNIT_TEST_FIXTURE(Test, testTdf87533_bidi)
1679 {
1680     load(mpTestDocumentPath, "tdf87533_bidi.docx");
1681     // "w:bidi" (specified inside Default paragraph properties) should not be ignored
1682     static const OUStringLiteral writingMode = u"WritingMode"; //getPropertyName(PROP_WRITING_MODE);
1683 
1684     // check: "Default Style" master-style has RTL
1685     {
1686         const uno::Reference<beans::XPropertySet> xPropertySet(getStyles("PageStyles")->getByName("Default Page Style"), uno::UNO_QUERY);
1687         CPPUNIT_ASSERT_EQUAL(sal_Int32(text::WritingMode2::RL_TB), getProperty<sal_Int32>(xPropertySet, writingMode));
1688     }
1689 
1690     // check: "Standard" master-style has RTL
1691     {
1692         const uno::Reference<beans::XPropertySet> xPropertySet(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
1693         CPPUNIT_ASSERT_EQUAL(sal_Int32(text::WritingMode2::RL_TB), getProperty<sal_Int32>(xPropertySet, writingMode));
1694     }
1695 
1696     // check: style of the first paragraph has RTL
1697     // it has missing usage of the <w:bidi> => this property should be taken from style
1698     {
1699         const uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY);
1700         CPPUNIT_ASSERT_EQUAL(sal_Int32(text::WritingMode2::RL_TB), getProperty<sal_Int32>(xPara, writingMode));
1701     }
1702 
1703     // check: style of the first paragraph has LTR
1704     // it has <w:bidi w:val="false"/>
1705     {
1706         const uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
1707         CPPUNIT_ASSERT_EQUAL(sal_Int32(text::WritingMode2::LR_TB), getProperty<sal_Int32>(xPara, writingMode));
1708     }
1709 }
1710 
CPPUNIT_TEST_FIXTURE(Test,testVmlAdjustments)1711 CPPUNIT_TEST_FIXTURE(Test, testVmlAdjustments)
1712 {
1713     load(mpTestDocumentPath, "vml-adjustments.docx");
1714     uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY);
1715     comphelper::SequenceAsHashMap aGeometry(xPropertySet->getPropertyValue("CustomShapeGeometry"));
1716     uno::Sequence<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustmentValues =
1717         aGeometry["AdjustmentValues"].get<uno::Sequence<drawing::EnhancedCustomShapeAdjustmentValue>>();
1718     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aAdjustmentValues.getLength());
1719     drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue = *aAdjustmentValues.begin();
1720     CPPUNIT_ASSERT_EQUAL(sal_Int32(17639), aAdjustmentValue.Value.get<sal_Int32>());
1721 }
1722 
CPPUNIT_TEST_FIXTURE(Test,testTdf108714)1723 CPPUNIT_TEST_FIXTURE(Test, testTdf108714)
1724 {
1725     load(mpTestDocumentPath, "tdf108714.docx");
1726     CPPUNIT_ASSERT_EQUAL(6, getParagraphs());
1727     CPPUNIT_ASSERT_EQUAL_MESSAGE("Page break is absent - we lost bug-to-bug compatibility with Word", 4, getPages());
1728 
1729     // The second (empty) paragraph must be at first page, despite the <w:br> element was before it.
1730     // That's because Word treats such break as first element in first run of following paragraph:
1731     //
1732     //    <w:br w:type="page"/>
1733     //    <w:p>
1734     //        <w:r>
1735     //            <w:t/>
1736     //        </w:r>
1737     //    </w:p>
1738     //
1739     // is equal to
1740     //
1741     //    <w:p>
1742     //        <w:r>
1743     //            <w:br w:type="page"/>
1744     //        </w:r>
1745     //    </w:p>
1746     //
1747     // which emits page break after that empty paragraph.
1748 
1749     uno::Reference< text::XTextRange > paragraph = getParagraph(1);
1750     CPPUNIT_ASSERT_EQUAL(OUString("Paragraph 1"), paragraph->getString());
1751     style::BreakType breakType = getProperty<style::BreakType>(paragraph, "BreakType");
1752     CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, breakType);
1753 
1754     paragraph = getParagraph(2);
1755     CPPUNIT_ASSERT_EQUAL(OUString(), paragraph->getString());
1756     breakType = getProperty<style::BreakType>(paragraph, "BreakType");
1757     CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, breakType);
1758 
1759     paragraph = getParagraph(3);
1760     CPPUNIT_ASSERT_EQUAL(OUString("Paragraph 3"), paragraph->getString());
1761     breakType = getProperty<style::BreakType>(paragraph, "BreakType");
1762     CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, breakType);
1763 
1764     paragraph = getParagraph(4);
1765     CPPUNIT_ASSERT_EQUAL(OUString("Paragraph 4"), paragraph->getString());
1766     breakType = getProperty<style::BreakType>(paragraph, "BreakType");
1767     CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, breakType);
1768 
1769     // A table with immediately following break
1770     // Line breaks in block and paragraph levels must be taken into account
1771     // Several successive out-of-place w:br's must produce required amount of breaks
1772     uno::Reference<text::XTextContent> table = getParagraphOrTable(5);
1773     getCell(table, "A1", "\n\n\n\nParagraph 5 in table");
1774     breakType = getProperty<style::BreakType>(table, "BreakType");
1775     CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, breakType);
1776 
1777     paragraph = getParagraph(6);
1778     CPPUNIT_ASSERT_EQUAL(OUString("Paragraph 6"), paragraph->getString());
1779     breakType = getProperty<style::BreakType>(paragraph, "BreakType");
1780     CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, breakType);
1781 }
1782 
CPPUNIT_TEST_FIXTURE(Test,testTdf136952_pgBreak3)1783 CPPUNIT_TEST_FIXTURE(Test, testTdf136952_pgBreak3)
1784 {
1785     load(mpTestDocumentPath, "tdf136952_pgBreak3.docx");
1786     // The original 6 page ODT was designed to visually exaggerate the problems
1787     // of emulating LO's followed-by-page-style into MSWord's sections.
1788     // While much has been improved, there are extra pages present, which still need fixing.
1789     xmlDocUniquePtr pDump = parseLayoutDump();
1790 
1791     //Do not lose the page::breakAfter. This SHOULD be on page 4, but sadly it is not.
1792     //The key part of this test is that the page starts with "Lorem ipsum"
1793     //Prior to this, there was no page break, and so it was in the middle of a page.
1794     CPPUNIT_ASSERT(getXPath(pDump, "//page[6]/body/txt[1]/Text[1]", "Portion").startsWith("Lorem ipsum"));
1795 }
1796 
1797 
CPPUNIT_TEST_FIXTURE(Test,testImageLazyRead)1798 CPPUNIT_TEST_FIXTURE(Test, testImageLazyRead)
1799 {
1800     load(mpTestDocumentPath, "image-lazy-read.docx");
1801     auto xGraphic = getProperty<uno::Reference<graphic::XGraphic>>(getShape(1), "Graphic");
1802     Graphic aGraphic(xGraphic);
1803     // This failed, import loaded the graphic, it wasn't lazy-read.
1804     CPPUNIT_ASSERT(!aGraphic.isAvailable());
1805 }
1806 
CPPUNIT_TEST_FIXTURE(Test,testTdf108995)1807 CPPUNIT_TEST_FIXTURE(Test, testTdf108995)
1808 {
1809     load(mpTestDocumentPath, "xml_space.docx");
1810     CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
1811     // We need to take xml:space attribute into account
1812     uno::Reference< text::XTextRange > paragraph = getParagraph(1);
1813     CPPUNIT_ASSERT_EQUAL(OUString("\tA\t\tline  with\txml:space=\"preserve\" \n"
1814                                   "A  line  without xml:space"),
1815                          paragraph->getString());
1816 }
1817 
CPPUNIT_TEST_FIXTURE(Test,testGroupShapeTextHighlight)1818 CPPUNIT_TEST_FIXTURE(Test, testGroupShapeTextHighlight)
1819 {
1820     load(mpTestDocumentPath, "tdf131841_HighlightColorGroupedShape.docx");
1821     // tdf#131841 Highlight color of text in grouped shapes was not imported.
1822 
1823     // These are the possible highlight colors in MSO Word. Check that we import them properly.
1824     const std::vector<sal_uInt32> xColors {
1825         0xFFFF00UL, // yellow
1826         0x00FF00UL, // green
1827         0x00FFFFUL, // cyan
1828         0xFF00FFUL, // magenta
1829         0x0000FFUL, // blue
1830         0xFF0000UL, // red
1831         0x00008BUL, // dark blue
1832         0x008B8BUL, // dark cyan
1833         0x006400UL, // dark green
1834         0x800080UL, // dark magenta
1835         0x8B0000UL, // dark red
1836         0x808000UL, // dark yellow
1837         0xA9A9A9UL, // dark grey
1838         0xD3D3D3UL, // light grey
1839         0x000000UL  // black
1840     };
1841 
1842     // The grouped shape, consists of 15 rectangles.
1843     uno::Reference<drawing::XShapes> xGroupShape(getShape(1), uno::UNO_QUERY);
1844 
1845     // Iterate through all of the rectangles and check the colors of the texts.
1846     // They should correspond to the list above.
1847     for (size_t idx = 0; idx < xColors.size(); ++idx)
1848     {
1849         uno::Reference<text::XTextRange> xTextRange(xGroupShape->getByIndex(idx), uno::UNO_QUERY);
1850         uno::Reference<text::XTextRange> firstParagraph = getParagraphOfText(1, xTextRange->getText());
1851         uno::Reference<text::XTextRange> firstRun = getRun(firstParagraph, 1);
1852         uno::Reference<beans::XPropertySet> props(firstRun, uno::UNO_QUERY_THROW);
1853 
1854         CPPUNIT_ASSERT_EQUAL(xColors[idx], props->getPropertyValue("CharBackColor").get<sal_uInt32>());
1855     }
1856 }
1857 
1858 // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
1859 
1860 CPPUNIT_PLUGIN_IMPLEMENT();
1861 
1862 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1863