summaryrefslogtreecommitdiffstats
path: root/writerfilter/qa/cppunittests/dmapper
diff options
context:
space:
mode:
Diffstat (limited to 'writerfilter/qa/cppunittests/dmapper')
-rw-r--r--writerfilter/qa/cppunittests/dmapper/CellColorHandler.cxx70
-rw-r--r--writerfilter/qa/cppunittests/dmapper/DomainMapper.cxx134
-rw-r--r--writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx87
-rw-r--r--writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx323
-rw-r--r--writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx411
-rw-r--r--writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx173
-rw-r--r--writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx219
-rw-r--r--writerfilter/qa/cppunittests/dmapper/TextEffectsHandler.cxx74
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/1cell-insidev-rightborder.docxbin0 -> 13204 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/alt-chunk.docxbin0 -> 22007 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/chart-zorder.docxbin0 -> 21206 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/clearing-break.docxbin0 -> 15739 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/create-date-preserve.docxbin0 -> 13310 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/draw-shape-inline-effect.docxbin0 -> 16534 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docxbin0 -> 12874 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/floating-table-header.docxbin0 -> 15046 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/follow-page-top-margin.docxbin0 -> 23144 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/frame-direction.docxbin0 -> 28204 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/group-shape-rotation.docxbin0 -> 24177 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/inline-anchored-zorder.docxbin0 -> 16684 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/inline-inshape-anchored-zorder.docxbin0 -> 17243 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/large-para-top-margin.docxbin0 -> 23126 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/layout-in-cell-2.docxbin0 -> 66189 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/layout-in-cell-wrapnone-column.docxbin0 -> 12900 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/negative-page-border-no-margin.docxbin0 -> 12206 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/negative-page-border.docxbin0 -> 12124 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/nested-floating-table.docxbin0 -> 12915 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/num-restart-style-parent.docxbin0 -> 12336 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/page-break-footer-table.docxbin0 -> 15416 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/paste-ole.rtf30
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/ptab.docxbin0 -> 15861 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/relfromh-insidemargin.docxbin0 -> 16119 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/sdt-dropdown-no-display-text.docxbin0 -> 11858 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/sdt-run-checkbox.docxbin0 -> 4244 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/sdt-run-dropdown.docxbin0 -> 4323 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/sdt-run-in-para.docxbin0 -> 11987 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/sdt-run-picture.docxbin0 -> 13686 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/sdt-run-rich-text.docxbin0 -> 4356 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/semi-transparent-text.docxbin0 -> 12738 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/table-negative-vertical-pos.docxbin0 -> 12648 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/tdf129205.docxbin0 -> 13237 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/tdf141540ChildRotation.docxbin0 -> 15385 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docxbin0 -> 19457 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/tdf141540GroupRotation.docxbin0 -> 18803 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/tdf142304GroupPosition.docxbin0 -> 20932 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docxbin0 -> 23700 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docxbin0 -> 74805 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/tdf143208_wrapTight.docxbin0 -> 20136 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docxbin0 -> 24753 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/textbox-textline-top.docxbin0 -> 12637 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/textbox-textline.docxbin0 -> 12934 bytes
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/wrap-poly-crop.docxbin0 -> 15018 bytes
52 files changed, 1521 insertions, 0 deletions
diff --git a/writerfilter/qa/cppunittests/dmapper/CellColorHandler.cxx b/writerfilter/qa/cppunittests/dmapper/CellColorHandler.cxx
new file mode 100644
index 000000000..4449e9a20
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/CellColorHandler.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/dmapper/CellColorHandler.cxx.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/writerfilter/qa/cppunittests/dmapper/data/";
+
+CPPUNIT_TEST_FIXTURE(Test, test129205)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf129205.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ drawing::FillStyle eFillStyle = drawing::FillStyle::FillStyle_NONE;
+ xPara->getPropertyValue("FillStyle") >>= eFillStyle;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: drawing::FillStyle_NONE
+ // - Actual : FillStyle_SOLID
+ // i.e. the paragraph had a solid fill, making the header image invisible.
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, eFillStyle);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapper.cxx
new file mode 100644
index 000000000..639c8e9e0
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper.cxx
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+
+#include <tools/UnitConversion.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/dmapper/DomainMapper.cxx.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/writerfilter/qa/cppunittests/dmapper/data/";
+
+CPPUNIT_TEST_FIXTURE(Test, testLargeParaTopMargin)
+{
+ // Given a document with a paragraph with a large "before" spacing.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "large-para-top-margin.docx";
+ getComponent() = loadFromDesktop(aURL);
+
+ // When checking the first paragraph.
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+
+ // Then assert its top margin.
+ sal_Int32 nParaTopMargin{};
+ xPara->getPropertyValue("ParaTopMargin") >>= nParaTopMargin;
+ // <w:spacing w:before="37050"/> in the document.
+ sal_Int32 nExpected = convertTwipToMm100(37050);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 65352
+ // - Actual : 0
+ // i.e. the paragraph margin was lost, which shifted the paragraph to the right (no top margin
+ // -> wrap around a TextBox), which shifted the triangle shape out of the page frame.
+ CPPUNIT_ASSERT_EQUAL(nExpected, nParaTopMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunInPara)
+{
+ // Given a document with a block SDT, and inside that some content + a run SDT:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "sdt-run-in-para.docx";
+
+ // When loading that document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure the content inside the block SDT but outside the run SDT is not lost:
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: first-second
+ // - Actual : second
+ // i.e. the block-SDT-only string was lost.
+ CPPUNIT_ASSERT_EQUAL(OUString("first-second"), xPara->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtDropdownNoDisplayText)
+{
+ // Given a document with <w:listItem w:value="..."/> (no display text):
+ OUString aURL
+ = m_directories.getURLFromSrc(DATA_DIRECTORY) + "sdt-dropdown-no-display-text.docx";
+
+ // When loading that document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure we create a dropdown content control, not a rich text one:
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
+ OUString aPortionType;
+ xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValues> aListItems;
+ xContentControlProps->getPropertyValue("ListItems") >>= aListItems;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 0
+ // i.e. the list item was lost on import.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aListItems.getLength());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx
new file mode 100644
index 000000000..1accc77a1
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/table/BorderLine2.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/dmapper/DomainMapperTableHandler.cxx.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/writerfilter/qa/cppunittests/dmapper/data/";
+
+CPPUNIT_TEST_FIXTURE(Test, test1cellInsidevRightborder)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "1cell-insidev-rightborder.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<text::XTextTablesSupplier> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextDocument->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+ table::BorderLine2 aBorder;
+ xCell->getPropertyValue("RightBorder") >>= aBorder;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 0
+ // - Actual : 18
+ // i.e. the request to have no table-level right border was lost on import.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), aBorder.LineWidth);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testNestedFloatingTable)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "nested-floating-table.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xFrame(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ bool bIsFollowingTextFlow = false;
+ xFrame->getPropertyValue("IsFollowingTextFlow") >>= bIsFollowingTextFlow;
+ // Without the accompanying fix in place, this test would have failed, the nested floating table
+ // was partly positioned outside the table cell, leading to overlapping text.
+ CPPUNIT_ASSERT(bIsFollowingTextFlow);
+}
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
new file mode 100644
index 000000000..16039f983
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
@@ -0,0 +1,323 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/style/BreakType.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/document/XDocumentInsertable.hpp>
+
+#include <vcl/scheduler.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/dmapper/DomainMapper_Impl.cxx.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/writerfilter/qa/cppunittests/dmapper/data/";
+
+CPPUNIT_TEST_FIXTURE(Test, testPageBreakFooterTable)
+{
+ // Load a document which refers to a footer which ends with a table, and there is a page break
+ // in the body text right after the footer reference.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "page-break-footer-table.docx";
+ getComponent() = loadFromDesktop(aURL);
+
+ // Check the last paragraph.
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPara;
+ while (xParaEnum->hasMoreElements())
+ {
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ }
+ style::BreakType eType = style::BreakType_NONE;
+ xPara->getPropertyValue("BreakType") >>= eType;
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 4
+ // - Actual : 0
+ // i.e. there was no page break before the last paragraph.
+ CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, eType);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testNumberingRestartStyleParent)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "num-restart-style-parent.docx";
+ getComponent() = loadFromDesktop(aURL);
+
+ // The paragraphs are A 1 2 B 1 2.
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPara;
+ static OUStringLiteral aProp(u"ListLabelString");
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("A."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("1."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("B."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1.
+ // - Actual : 3.
+ // i.e. the numbering was not restarted after B.
+ CPPUNIT_ASSERT_EQUAL(OUString("1."), xPara->getPropertyValue(aProp).get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2."), xPara->getPropertyValue(aProp).get<OUString>());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFrameDirection)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "frame-direction.docx";
+ getComponent() = loadFromDesktop(aURL);
+
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xFrame0(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xFrame1(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xFrame2(xDrawPage->getByIndex(2), uno::UNO_QUERY);
+ // Without the accompanying fix in place, all of the following values would be text::WritingMode2::CONTEXT
+ CPPUNIT_ASSERT_EQUAL(text::WritingMode2::CONTEXT,
+ xFrame0->getPropertyValue("WritingMode").get<sal_Int16>());
+ CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR,
+ xFrame1->getPropertyValue("WritingMode").get<sal_Int16>());
+ CPPUNIT_ASSERT_EQUAL(text::WritingMode2::TB_RL,
+ xFrame2->getPropertyValue("WritingMode").get<sal_Int16>());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testAltChunk)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "alt-chunk.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xPara;
+ uno::Reference<beans::XPropertySet> xParaProps;
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ xParaProps.set(xPara, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("outer, before sect break"), xPara->getString());
+ CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
+ xParaProps->getPropertyValue("PageStyleName").get<OUString>());
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ xParaProps.set(xPara, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("outer, after sect break"), xPara->getString());
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Converted1
+ // - Actual : Standard
+ // i.e. the page break between the first and the second paragraph was missing.
+ CPPUNIT_ASSERT_EQUAL(OUString("Converted1"),
+ xParaProps->getPropertyValue("PageStyleName").get<OUString>());
+
+ // Without the accompanying fix in place, this test would have failed with a
+ // container.NoSuchElementException, as the document had only 2 paragraphs, all the "inner"
+ // content was lost.
+ xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("inner doc, first para"), xPara->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFieldIfInsideIf)
+{
+ // Load a document with a field in a table cell: it contains an IF field with various nested
+ // fields.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "field-if-inside-if.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<text::XTextTablesSupplier> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextDocument->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+
+ // Get the result of the topmost field.
+ uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 0** Expression is faulty **2
+ // i.e. some of the inner fields escaped outside the outer field.
+ CPPUNIT_ASSERT_EQUAL(OUString("2"), xCell->getString());
+
+ // Test the second cell: it contains "IF ", not the usual " IF ".
+ xCell.set(xTable->getCellByName("A2"), uno::UNO_QUERY);
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 25
+ // - Actual : 025
+ // i.e. some of the inner fields escaped outside the outer field.
+ CPPUNIT_ASSERT_EQUAL(OUString("25"), xCell->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testCreateDatePreserve)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "create-date-preserve.docx";
+ getComponent() = loadFromDesktop(aURL);
+ // Trigger idle layout.
+ Scheduler::ProcessEventsToIdle();
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPortionEnumAccess(xParaEnum->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPortionEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 7/7/2020 10:11:00 AM
+ // - Actual : 07/07/2020
+ // i.e. the formatting of the create date field was lost.
+ CPPUNIT_ASSERT_EQUAL(OUString("7/7/2020 10:11:00 AM"), xPortion->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testChartZOrder)
+{
+ // Given a document with a chart and a shape on it:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "chart-zorder.docx";
+
+ // When loading the document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure the shape is on top of the chart:
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<lang::XServiceInfo> xChart(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed, as the chart was on top
+ // of the shape.
+ CPPUNIT_ASSERT(xChart->supportsService("com.sun.star.text.TextEmbeddedObject"));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testPTab)
+{
+ // Given a document that has a <w:ptab> to render a linebreak:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "ptab.docx";
+
+ // When opening that file:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that the Writer doc model contains that linebreak:
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(getComponent(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ auto xFooter = xStyle->getPropertyValue("FooterText").get<uno::Reference<text::XTextRange>>();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: <space><newline>1\n
+ // - Actual: <space><tab>1\n
+ // i.e. the layout height of the footer text was incorrect, the page number field was not
+ // visually inside the background shape.
+ CPPUNIT_ASSERT_EQUAL(OUString(" \n1" SAL_NEWLINE_STRING), xFooter->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testPasteOle)
+{
+ // Given an empty document:
+ getComponent() = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
+
+ // When pasting RTF into that document:
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xTextDocument->getText();
+ uno::Reference<document::XDocumentInsertable> xCursor(
+ xText->createTextCursorByRange(xText->getStart()), uno::UNO_QUERY);
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "paste-ole.rtf";
+ xCursor->insertDocumentFromURL(aURL, {});
+
+ // Then make sure that all the 3 paragraphs of the paste data (empty para, OLE obj, text) are
+ // inserted to the document:
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ xParaEnum->nextElement();
+ // Without the accompanying fix in place, this test would have failed, as the paste result was a
+ // single paragraph, containing the OLE object, and the content after the OLE object was lost.
+ CPPUNIT_ASSERT(xParaEnum->hasMoreElements());
+ xParaEnum->nextElement();
+ CPPUNIT_ASSERT(xParaEnum->hasMoreElements());
+ uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("hello"), xPara->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreak)
+{
+ // Given a document with a clearing break:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "clearing-break.docx";
+
+ // When loading that file:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that the clear property of the break is not ignored:
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xTextDocument->getText();
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ xPortions->nextElement();
+ xPortions->nextElement();
+ // Without the accompanying fix in place, this test would have failed with:
+ // An uncaught exception of type com.sun.star.container.NoSuchElementException
+ // i.e. the first para was just a fly + text portion, the clearing break was lost.
+ uno::Reference<beans::XPropertySet> xPortion(xPortions->nextElement(), uno::UNO_QUERY);
+ OUString aPortionType;
+ xPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+ CPPUNIT_ASSERT_EQUAL(OUString("LineBreak"), aPortionType);
+ uno::Reference<text::XTextContent> xLineBreak;
+ xPortion->getPropertyValue("LineBreak") >>= xLineBreak;
+ sal_Int16 eClear{};
+ uno::Reference<beans::XPropertySet> xLineBreakProps(xLineBreak, uno::UNO_QUERY);
+ xLineBreakProps->getPropertyValue("Clear") >>= eClear;
+ // SwLineBreakClear::ALL
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(3), eClear);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx b/writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx
new file mode 100644
index 000000000..a20c84905
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx
@@ -0,0 +1,411 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/view/XViewCursor.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/dmapper/GraphicImport.cxx.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/writerfilter/qa/cppunittests/dmapper/data/";
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf143455SmartArtPosition)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf143455_SmartArtPosition.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ // Without fix in place the group, which represents the SmartArt, was placed at the initializing
+ // position 0|0.
+ sal_Int32 nHoriPosition = 0;
+ xShape->getPropertyValue("HoriOrientPosition") >>= nHoriPosition;
+ // The test would have failed with Expected: 2858, Actual: 0
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2858), nHoriPosition);
+ sal_Int32 nVertPosition = 0;
+ xShape->getPropertyValue("VertOrientPosition") >>= nVertPosition;
+ // The test would have failed with Expected: 1588, Actual: 0
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1588), nVertPosition);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf143208wrapTight)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf143208_wrapTight.docx";
+ // The document has a shape with indentation and contour wrap "wrapTight". Error was, that
+ // the corresponding shape property 'ContourOutside=true' was not set.
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ bool bContourOutside = false;
+ xShape->getPropertyValue("ContourOutside") >>= bContourOutside;
+ CPPUNIT_ASSERT(bContourOutside);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf142305StrokeGlowMargin)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf142305StrokeGlowMargin.docx";
+ // The document has an arc with fat stroke and glow. Its bounding rectangle differs much
+ // from the snap rectangle. Error was, that the margins were not set in a way, that the shape
+ // would render similar to Word.
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nTopMargin = 0;
+ xShape->getPropertyValue("TopMargin") >>= nTopMargin;
+ // Without fix in place top margin was 0, so that the text comes near to the shape.
+ // The test would have failed with Expected: 838, Actual: 0
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(838), nTopMargin);
+ sal_Int32 nBottomMargin = 0;
+ // Without fix in place bottom margin was >0, so that the text was far from to the shape.
+ // The test would have failed with Expected: 0, Actual: 637
+ xShape->getPropertyValue("BottomMargin") >>= nBottomMargin;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nBottomMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf142305SquareWrapMargin)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf142305SquareWrapMargin.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<frame::XModel> xModel(getComponent(), uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+ xModel->getCurrentController(), uno::UNO_QUERY_THROW);
+ uno::Reference<text::XTextViewCursor> xViewCursor(xTextViewCursorSupplier->getViewCursor());
+ xViewCursor->gotoStart(/*bExpand=*/false);
+ uno::Reference<view::XViewCursor> xCursor(xViewCursor, uno::UNO_QUERY);
+ xCursor->goDown(/*nCount=*/10, /*bExpand=*/false);
+ xViewCursor->goRight(/*nCount=*/1, /*bExpand=*/true);
+ OUString sText = xViewCursor->getString();
+ // Without fix in place, wrap was tight to the bounding box and not around the full shape as in
+ // Word. That results in different text at start of line, here "u" instead of expected "m".
+ CPPUNIT_ASSERT(sText.startsWith("m"));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf142304GroupPosition)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf142304GroupPosition.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nVertPosition = 0;
+ xShape->getPropertyValue("VertOrientPosition") >>= nVertPosition;
+ // Without fix in place the group was shifted left and down
+ // The test would have failed with Expected: 2178, Actual: 2521
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2178), nVertPosition);
+ sal_Int32 nHoriPosition = 0;
+ // The test would have failed with Expected: 4304, Actual: 3874
+ xShape->getPropertyValue("HoriOrientPosition") >>= nHoriPosition;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4304), nHoriPosition);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf141540ChildRotation)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf141540ChildRotation.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<container::XIndexAccess> xGroup(xDrawPage->getByIndex(0), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xRotatedShape(xGroup->getByIndex(1), uno::UNO_QUERY);
+ sal_Int32 nShearAngle = 9000; // initialize with invalid value
+ xRotatedShape->getPropertyValue("ShearAngle") >>= nShearAngle;
+ // Without fix in place, this test would have failed with:
+ // - Expected: 0
+ // - Actual : 2494
+ // i.e. the rotated rectangle in the group was sheared, although the group itself is not rotated
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nShearAngle);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf141540GroupRotation)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf141540GroupRotation.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nShearAngle = 9000; // init with invalid value
+ xShape->getPropertyValue("ShearAngle") >>= nShearAngle;
+ // Without fix in place, this test would have failed with:
+ // - Expected: 0
+ // - Actual : -3190
+ // i.e. the group has got a shearing although MSO does not know shearing at all.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nShearAngle);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf141540GroupLinePosSize)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf141540GroupLinePosSize.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+
+ // Test line
+ uno::Reference<drawing::XShape> xLineShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ awt::Point aPosition = xLineShape->getPosition();
+ awt::Size aSize = xLineShape->getSize();
+ // Without fix in place, you had got Position = (19|6498), Size = 5001 x 2
+ // i.e. the line was nearly horizontal instead of vertical
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5022), aPosition.X);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2963), aPosition.Y);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aSize.Width);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(7073), aSize.Height);
+
+ // Test group
+ uno::Reference<drawing::XShape> xGroupShape(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ aPosition = xGroupShape->getPosition();
+ aSize = xGroupShape->getSize();
+ // Without fix in place, you had got Position = (11511|3480), Size = 4022 x 4022
+ // i.e. the group was erroneously downscaled to unrotated size
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(10679), aPosition.X);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2648), aPosition.Y);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5687), aSize.Width);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5687), aSize.Height);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testGroupShapeRotation)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "group-shape-rotation.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nVertPosition = 0;
+ xShape->getPropertyValue("VertOrientPosition") >>= nVertPosition;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1221
+ // - Actual : -2048
+ // i.e. the group shape had a so low vertical position that the line shape did not point into
+ // it.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1221), nVertPosition);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testDrawShapeInlineEffect)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "draw-shape-inline-effect.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int32 nBottomMargin = 0;
+ xShape->getPropertyValue("BottomMargin") >>= nBottomMargin;
+ // 273 in mm100 is 98425 EMUs from the file.
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 273
+ // - Actual : 0
+ // i.e. the layout result had less pages than expected (compared to Word).
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(273), nBottomMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineAnchoredZOrder)
+{
+ // Load a document which has two shapes: an inline one and an anchored one. The inline has no
+ // explicit ZOrder, the anchored one has, and it's set to a value so it's visible.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "inline-anchored-zorder.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<container::XNamed> xOval(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Oval 2
+ // - Actual :
+ // i.e. the rectangle (with no name) was on top of the oval one, not the other way around.
+ CPPUNIT_ASSERT_EQUAL(OUString("Oval 2"), xOval->getName());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineInShapeAnchoredZOrder)
+{
+ // This document has a textbox shape and then an inline shape inside that.
+ // The ZOrder of the inline shape is larger than the hosting textbox, so the image is visible.
+ OUString aURL
+ = m_directories.getURLFromSrc(DATA_DIRECTORY) + "inline-inshape-anchored-zorder.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<container::XNamed> xOval(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Picture 1
+ // - Actual : Text Box 2
+ // i.e. the image was behind the textbox that was hosting it.
+ CPPUNIT_ASSERT_EQUAL(OUString("Picture 1"), xOval->getName());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testRelfromhInsidemargin)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "relfromh-insidemargin.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int16 nRelation = 0;
+ xShape->getPropertyValue("HoriOrientRelation") >>= nRelation;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 7 (PAGE_FRAME)
+ // - Actual : 0 (FRAME)
+ // i.e. the horizontal position was relative to the paragraph area, not to the entire page.
+ CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, nRelation);
+ bool bPageToggle = false;
+ xShape->getPropertyValue("PageToggle") >>= bPageToggle;
+ CPPUNIT_ASSERT(bPageToggle);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testWrapPolyCrop)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "wrap-poly-crop.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ drawing::PointSequenceSequence aContour;
+ xShape->getPropertyValue("ContourPolyPolygon") >>= aContour;
+ auto aPolyPolygon = basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(aContour);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aPolyPolygon.count());
+ auto aPolygon = aPolyPolygon.getB2DPolygon(0);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(4), aPolygon.count());
+
+ // Ideally this would be 2352, because the graphic size in mm100, using the graphic's DPI is
+ // 10582, the lower 33% of the graphic is cropped, and the wrap polygon covers the middle third
+ // of the area vertically. Which means 10582*2/3 = 7054.67 is the cropped height, and the top of
+ // the middle third is 2351.55.
+ // Then there is a 15 twips shift from the origo, so it's 2351.55 + 26.46 = 2378.01 in mm100.
+ //
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2368
+ // - Actual : 3542
+ // i.e. the wrap polygon covered a larger-than-correct area, which end the end means 3 lines
+ // were wrapping around the image, not only 2 as Word does it.
+ CPPUNIT_ASSERT_EQUAL(2368., aPolygon.getB2DPoint(0).getY());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTextboxTextline)
+{
+ // Load a document with a shape with a textbox.
+ // The shape's vertical relation is <wp:positionV relativeFrom="line">.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "textbox-textline.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int16 nActualRelation{};
+ CPPUNIT_ASSERT(xShape->getPropertyValue("VertOrientRelation") >>= nActualRelation);
+ sal_Int32 nActualPosition{};
+ CPPUNIT_ASSERT(xShape->getPropertyValue("VertOrientPosition") >>= nActualPosition);
+
+ sal_Int16 nExpectedRelation = text::RelOrientation::TEXT_LINE;
+ CPPUNIT_ASSERT_EQUAL(nExpectedRelation, nActualRelation);
+ sal_Int32 nExpectedPosition = -2;
+ CPPUNIT_ASSERT_EQUAL(nExpectedPosition, nActualPosition);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTextboxTextlineTop)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "textbox-textline-top.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ sal_Int16 nActualRelation{};
+ CPPUNIT_ASSERT(xShape->getPropertyValue("VertOrientRelation") >>= nActualRelation);
+ sal_Int16 nExpectedRelation = text::RelOrientation::TEXT_LINE;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 9 (TEXT_LINE)
+ // - Actual : 0 (FRAME)
+ // i.e. the anchor point for the positioning was wrong, resulting in overlapping textboxes.
+ CPPUNIT_ASSERT_EQUAL(nExpectedRelation, nActualRelation);
+
+ sal_Int16 nActualOrient{};
+ CPPUNIT_ASSERT(xShape->getPropertyValue("VertOrient") >>= nActualOrient);
+ sal_Int16 nExpectedOrient = text::VertOrientation::BOTTOM;
+ CPPUNIT_ASSERT_EQUAL(nExpectedOrient, nActualOrient);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testLayoutInCellWrapnoneColumn)
+{
+ // Given a file with a table, then a shape anchored inside the cell:
+ OUString aURL
+ = m_directories.getURLFromSrc(DATA_DIRECTORY) + "layout-in-cell-wrapnone-column.docx";
+
+ // When loading that document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure the shape can leave the cell:
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ uno::Reference<container::XNamed> xNamedShape(xShape, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Text Box 1"), xNamedShape->getName());
+ bool bFollowingTextFlow = true;
+ // Without the accompanying fix in place, this test would have failed, the shape was not allowed
+ // to leave the cell, leading to incorrect layout.
+ CPPUNIT_ASSERT(xShape->getPropertyValue("IsFollowingTextFlow") >>= bFollowingTextFlow);
+ CPPUNIT_ASSERT(!bFollowingTextFlow);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testLayoutInCellOfHraphics)
+{
+ // Given a file with a table, then a shape anchored inside the cell:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "layout-in-cell-2.docx";
+
+ // When loading that document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure the cell obeys the layoutInCell:
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+ uno::Reference<container::XNamed> xNamedShape(xShape, uno::UNO_QUERY);
+ bool bFollowingTextFlow = false;
+ CPPUNIT_ASSERT(xShape->getPropertyValue("IsFollowingTextFlow") >>= bFollowingTextFlow);
+ CPPUNIT_ASSERT(bFollowingTextFlow);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx b/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx
new file mode 100644
index 000000000..cc651d224
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/table/BorderLine2.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/dmapper/PropertyMap.cxx.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/writerfilter/qa/cppunittests/dmapper/data/";
+
+CPPUNIT_TEST_FIXTURE(Test, testFloatingTableHeader)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "floating-table-header.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<frame::XModel> xModel(getComponent(), uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+ xModel->getCurrentController(), uno::UNO_QUERY);
+ uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
+ uno::UNO_QUERY);
+ xCursor->jumpToLastPage();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 3
+ // i.e. a document which is 1 page in Word was imported as a 3 page one.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), xCursor->getPage());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testFollowPageTopMargin)
+{
+ // Load a document with 2 pages: first page has larger top margin, second page has smaller top
+ // margin.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "follow-page-top-margin.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(getComponent(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ auto nTopMargin = xStyle->getPropertyValue("TopMargin").get<sal_Int32>();
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 250
+ // - Actual : 1249
+ // i.e. the top margin on page 2 was too large.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(250), nTopMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTableNegativeVerticalPos)
+{
+ // Given a document with a table which has a negative vertical position (moves up to overlap
+ // with the header):
+ OUString aURL
+ = m_directories.getURLFromSrc(DATA_DIRECTORY) + "table-negative-vertical-pos.docx";
+
+ // When loading that document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure we don't import that as a plain table, which can't have a negative top margin:
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 0
+ // i.e. this was imported as a plain table, resulting in a 0 top margin (y pos too large).
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xDrawPage->getCount());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testNegativePageBorder)
+{
+ // Given a document with a top margin and a border which has more spacing than the margin:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "negative-page-border.docx";
+
+ // When loading that document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that the border distance is negative, so it can appear at the correct
+ // position:
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(getComponent(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ auto nTopMargin = xStyle->getPropertyValue("TopMargin").get<sal_Int32>();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(501), nTopMargin);
+ auto aTopBorder = xStyle->getPropertyValue("TopBorder").get<table::BorderLine2>();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(159), aTopBorder.LineWidth);
+ auto nTopBorderDistance = xStyle->getPropertyValue("TopBorderDistance").get<sal_Int32>();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: -646
+ // - Actual : 0
+ // i.e. the border negative distance was lost.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-646), nTopBorderDistance);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testNegativePageBorderNoMargin)
+{
+ // Given a document with no top margin and a border which has spacing:
+ OUString aURL
+ = m_directories.getURLFromSrc(DATA_DIRECTORY) + "negative-page-border-no-margin.docx";
+
+ // When loading that document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that the border distance is negative, so it can appear at the correct
+ // position:
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(getComponent(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ auto nTopMargin = xStyle->getPropertyValue("TopMargin").get<sal_Int32>();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nTopMargin);
+ auto aTopBorder = xStyle->getPropertyValue("TopBorder").get<table::BorderLine2>();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(159), aTopBorder.LineWidth);
+ auto nTopBorderDistance = xStyle->getPropertyValue("TopBorderDistance").get<sal_Int32>();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: -1147
+ // - Actual : 0
+ // i.e. the border negative distance was lost.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-1147), nTopBorderDistance);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx b/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
new file mode 100644
index 000000000..b2e7f1058
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+using namespace com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/dmapper/SdtHelper.cxx.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/writerfilter/qa/cppunittests/dmapper/data/";
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunRichText)
+{
+ // Given a document with a rich text inline/run SDT:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "sdt-run-rich-text.docx";
+
+ // When loading the document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that formatting of the text inside the SDT is not lost:
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ OUString aTextPortionType;
+ xPortion->getPropertyValue("TextPortionType") >>= aTextPortionType;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: ContentControl
+ // - Actual : TextField
+ // i.e. the SDT was imported as a text field, and the whole SDT had 12pt font size.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aTextPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<text::XTextRange> xContentControlRange(xContentControl, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xContentControlRange->getText();
+ uno::Reference<container::XEnumerationAccess> xContentEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xContentEnum = xContentEnumAccess->createEnumeration();
+ uno::Reference<beans::XPropertySet> xContent(xContentEnum->nextElement(), uno::UNO_QUERY);
+ float fCharheight{};
+ xContent->getPropertyValue("CharHeight") >>= fCharheight;
+ CPPUNIT_ASSERT_EQUAL(12.f, fCharheight);
+ xContent.set(xContentEnum->nextElement(), uno::UNO_QUERY);
+ xContent->getPropertyValue("CharHeight") >>= fCharheight;
+ CPPUNIT_ASSERT_EQUAL(24.f, fCharheight);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunCheckbox)
+{
+ // Given a document with a checkbox inline/run SDT:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "sdt-run-checkbox.docx";
+
+ // When loading the document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that the doc model has a clickable checkbox content control:
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ OUString aTextPortionType;
+ xPortion->getPropertyValue("TextPortionType") >>= aTextPortionType;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: ContentControl
+ // - Actual : Text
+ // i.e. the SDT was imported as plain text, making it hard to fill in checkboxes.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aTextPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ bool bCheckbox{};
+ xContentControlProps->getPropertyValue("Checkbox") >>= bCheckbox;
+ CPPUNIT_ASSERT(bCheckbox);
+ bool bChecked{};
+ xContentControlProps->getPropertyValue("Checked") >>= bChecked;
+ CPPUNIT_ASSERT(bChecked);
+ OUString aCheckedState;
+ xContentControlProps->getPropertyValue("CheckedState") >>= aCheckedState;
+ CPPUNIT_ASSERT_EQUAL(OUString(u"☒"), aCheckedState);
+ OUString aUncheckedState;
+ xContentControlProps->getPropertyValue("UncheckedState") >>= aUncheckedState;
+ CPPUNIT_ASSERT_EQUAL(OUString(u"☐"), aUncheckedState);
+ uno::Reference<text::XTextRange> xContentControlRange(xContentControl, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xContentControlRange->getText();
+ uno::Reference<container::XEnumerationAccess> xContentEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xContentEnum = xContentEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString(u"☒"), xContent->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunDropdown)
+{
+ // Given a document with a dropdown inline/run SDT:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "sdt-run-dropdown.docx";
+
+ // When loading the document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that the doc model has a clickable dropdown content control:
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
+ OUString aPortionType;
+ xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+ // Without the accompanying fix in place, this failed with:
+ // - Expected: ContentControl
+ // - Actual : TextField
+ // i.e. the SDT was imported as a dropdown field, which does not support display-text + value
+ // pairs.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValues> aListItems;
+ xContentControlProps->getPropertyValue("ListItems") >>= aListItems;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), aListItems.getLength());
+ comphelper::SequenceAsHashMap aMap0(aListItems[0]);
+ CPPUNIT_ASSERT_EQUAL(OUString("red"), aMap0["DisplayText"].get<OUString>());
+ CPPUNIT_ASSERT_EQUAL(OUString("R"), aMap0["Value"].get<OUString>());
+ comphelper::SequenceAsHashMap aMap1(aListItems[1]);
+ CPPUNIT_ASSERT_EQUAL(OUString("green"), aMap1["DisplayText"].get<OUString>());
+ CPPUNIT_ASSERT_EQUAL(OUString("G"), aMap1["Value"].get<OUString>());
+ comphelper::SequenceAsHashMap aMap2(aListItems[2]);
+ CPPUNIT_ASSERT_EQUAL(OUString("blue"), aMap2["DisplayText"].get<OUString>());
+ CPPUNIT_ASSERT_EQUAL(OUString("B"), aMap2["Value"].get<OUString>());
+ uno::Reference<text::XTextRange> xContentControlRange(xContentControl, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xContentControlRange->getText();
+ uno::Reference<container::XEnumerationAccess> xContentEnumAccess(xText, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xContentEnum = xContentEnumAccess->createEnumeration();
+ uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("choose a color"), xContent->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunPicture)
+{
+ // Given a document with a dropdown inline/run SDT:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "sdt-run-picture.docx";
+
+ // When loading the document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that the doc model has a clickable picture content control:
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
+ OUString aPortionType;
+ xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+ // Without the accompanying fix in place, this failed with:
+ // - Expected: ContentControl
+ // - Actual : Frame
+ // i.e. the SDT was imported as a plain image, not as a clickable placeholder in a content
+ // control.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+ uno::Reference<text::XTextContent> xContentControl;
+ xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY);
+ bool bPicture{};
+ xContentControlProps->getPropertyValue("Picture") >>= bPicture;
+ CPPUNIT_ASSERT(bPicture);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/TextEffectsHandler.cxx b/writerfilter/qa/cppunittests/dmapper/TextEffectsHandler.cxx
new file mode 100644
index 000000000..45a689b6b
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/TextEffectsHandler.cxx
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/dmapper/TextEffectsHandler.cxx.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/writerfilter/qa/cppunittests/dmapper/data/";
+
+CPPUNIT_TEST_FIXTURE(Test, testSemiTransparentText)
+{
+ // Load a document with a single paragraph: second text portion has semi-transparent text.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "semi-transparent-text.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ xPortionEnum->nextElement();
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ sal_Int16 nCharTransparence = 0;
+ xPortion->getPropertyValue("CharTransparence") >>= nCharTransparence;
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 74
+ // - Actual : 0
+ // i.e. text was imported as regular text with solid color only.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(74), nCharTransparence);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/data/1cell-insidev-rightborder.docx b/writerfilter/qa/cppunittests/dmapper/data/1cell-insidev-rightborder.docx
new file mode 100644
index 000000000..d0bc40e23
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/1cell-insidev-rightborder.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/alt-chunk.docx b/writerfilter/qa/cppunittests/dmapper/data/alt-chunk.docx
new file mode 100644
index 000000000..40d071ff4
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/alt-chunk.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/chart-zorder.docx b/writerfilter/qa/cppunittests/dmapper/data/chart-zorder.docx
new file mode 100644
index 000000000..e022a3bde
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/chart-zorder.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/clearing-break.docx b/writerfilter/qa/cppunittests/dmapper/data/clearing-break.docx
new file mode 100644
index 000000000..453a4c2b8
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/clearing-break.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/create-date-preserve.docx b/writerfilter/qa/cppunittests/dmapper/data/create-date-preserve.docx
new file mode 100644
index 000000000..4a587ce0d
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/create-date-preserve.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/draw-shape-inline-effect.docx b/writerfilter/qa/cppunittests/dmapper/data/draw-shape-inline-effect.docx
new file mode 100644
index 000000000..3eb5b0e2f
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/draw-shape-inline-effect.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx b/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx
new file mode 100644
index 000000000..65e238869
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/floating-table-header.docx b/writerfilter/qa/cppunittests/dmapper/data/floating-table-header.docx
new file mode 100644
index 000000000..3840b2550
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/floating-table-header.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/follow-page-top-margin.docx b/writerfilter/qa/cppunittests/dmapper/data/follow-page-top-margin.docx
new file mode 100644
index 000000000..ceae0b784
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/follow-page-top-margin.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/frame-direction.docx b/writerfilter/qa/cppunittests/dmapper/data/frame-direction.docx
new file mode 100644
index 000000000..33f191e80
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/frame-direction.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/group-shape-rotation.docx b/writerfilter/qa/cppunittests/dmapper/data/group-shape-rotation.docx
new file mode 100644
index 000000000..c9fee726b
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/group-shape-rotation.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/inline-anchored-zorder.docx b/writerfilter/qa/cppunittests/dmapper/data/inline-anchored-zorder.docx
new file mode 100644
index 000000000..93932c470
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/inline-anchored-zorder.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/inline-inshape-anchored-zorder.docx b/writerfilter/qa/cppunittests/dmapper/data/inline-inshape-anchored-zorder.docx
new file mode 100644
index 000000000..3792285f4
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/inline-inshape-anchored-zorder.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/large-para-top-margin.docx b/writerfilter/qa/cppunittests/dmapper/data/large-para-top-margin.docx
new file mode 100644
index 000000000..34f24a3e2
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/large-para-top-margin.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/layout-in-cell-2.docx b/writerfilter/qa/cppunittests/dmapper/data/layout-in-cell-2.docx
new file mode 100644
index 000000000..5b6926460
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/layout-in-cell-2.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/layout-in-cell-wrapnone-column.docx b/writerfilter/qa/cppunittests/dmapper/data/layout-in-cell-wrapnone-column.docx
new file mode 100644
index 000000000..d88761421
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/layout-in-cell-wrapnone-column.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/negative-page-border-no-margin.docx b/writerfilter/qa/cppunittests/dmapper/data/negative-page-border-no-margin.docx
new file mode 100644
index 000000000..8bd464a9e
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/negative-page-border-no-margin.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/negative-page-border.docx b/writerfilter/qa/cppunittests/dmapper/data/negative-page-border.docx
new file mode 100644
index 000000000..878ba1e78
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/negative-page-border.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/nested-floating-table.docx b/writerfilter/qa/cppunittests/dmapper/data/nested-floating-table.docx
new file mode 100644
index 000000000..73fd922fc
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/nested-floating-table.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/num-restart-style-parent.docx b/writerfilter/qa/cppunittests/dmapper/data/num-restart-style-parent.docx
new file mode 100644
index 000000000..f908d94b5
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/num-restart-style-parent.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/page-break-footer-table.docx b/writerfilter/qa/cppunittests/dmapper/data/page-break-footer-table.docx
new file mode 100644
index 000000000..376a1fb1e
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/page-break-footer-table.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/paste-ole.rtf b/writerfilter/qa/cppunittests/dmapper/data/paste-ole.rtf
new file mode 100644
index 000000000..27ce59baa
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/paste-ole.rtf
@@ -0,0 +1,30 @@
+{\rtf1
+\pard\plain\par
+\pard\plain
+{\object\objemb\objw1287\objh832\objscalex100\objscaley99
+{\*\objclass Package}
+{\*\objdata 0105000002000000080000005061636b616765000000000000000000eb010000
+020030322e73766700443a5c446e445c54657374646174656e5c416c6c654461746569547970656e5c30322e737667000000030036000000443a5c54454d505c7b42433241443335362d363732422d344345302d394136342d3033373544464134324334377d5c30322e73766700ab0000003c7376672076657273696f6e
+3d22312e31222076696577426f783d223020302034342032362220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667223e0a203c7265637420783d222e352220793d222e35222077696474683d22343322206865696768743d223235222072783d2232222072793d2232222066696c6c3d
+222366666622207374726f6b653d2223303037616666222f3e0a3c2f7376673e0a3500000044003a005c00540045004d0050005c007b00420043003200410044003300350036002d0036003700320042002d0034004300450030002d0039004100360034002d003000330037003500440046004100340032004300340037
+007d005c00300032002e0073007600670006000000300032002e007300760067002600000044003a005c0044006e0044005c00540065007300740064006100740065006e005c0041006c006c0065004400610074006500690054007900700065006e005c00300032002e007300760067000105000000000000}
+{\result
+{\*\shppict
+{\pict
+\picscalex100\picscaley99\picw2270\pich1468\picwgoal1287\pichgoal832\emfblip
+010000006c00000000000000000000009500000095000000000000000000
+0000670f0000630f000020454d4600000100280100000700000002000000
+00000000000000000000000038070000bd030000e9010000fd0000000000
+00000000000000000000f675070016dd0300210000000800000062000000
+0c0000000100000027000000180000000100000000000000ff0000000000
+000047000000700000000000000000000000950000009500000050000000
+010000002000000001000000030000003000000000000000000000009600
+000096000000320000000000000064000000320000000000000032000000
+960000006400000032000000640000006400000096000000220000000c00
+0000ffffffff0e00000014000000000000001000000014000000}
+}
+}
+}
+\pard\plain\par
+\pard\plain hello\par
+}
diff --git a/writerfilter/qa/cppunittests/dmapper/data/ptab.docx b/writerfilter/qa/cppunittests/dmapper/data/ptab.docx
new file mode 100644
index 000000000..d1ae18a27
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/ptab.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/relfromh-insidemargin.docx b/writerfilter/qa/cppunittests/dmapper/data/relfromh-insidemargin.docx
new file mode 100644
index 000000000..1f7a281e8
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/relfromh-insidemargin.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/sdt-dropdown-no-display-text.docx b/writerfilter/qa/cppunittests/dmapper/data/sdt-dropdown-no-display-text.docx
new file mode 100644
index 000000000..ed6d7ac54
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/sdt-dropdown-no-display-text.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/sdt-run-checkbox.docx b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-checkbox.docx
new file mode 100644
index 000000000..c6718b97c
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-checkbox.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/sdt-run-dropdown.docx b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-dropdown.docx
new file mode 100644
index 000000000..7718c0b04
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-dropdown.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/sdt-run-in-para.docx b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-in-para.docx
new file mode 100644
index 000000000..863bc9213
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-in-para.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/sdt-run-picture.docx b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-picture.docx
new file mode 100644
index 000000000..25fcc7f6f
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-picture.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/sdt-run-rich-text.docx b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-rich-text.docx
new file mode 100644
index 000000000..b945d0bb3
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-rich-text.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/semi-transparent-text.docx b/writerfilter/qa/cppunittests/dmapper/data/semi-transparent-text.docx
new file mode 100644
index 000000000..6c0f8a79c
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/semi-transparent-text.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/table-negative-vertical-pos.docx b/writerfilter/qa/cppunittests/dmapper/data/table-negative-vertical-pos.docx
new file mode 100644
index 000000000..2031f4769
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/table-negative-vertical-pos.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/tdf129205.docx b/writerfilter/qa/cppunittests/dmapper/data/tdf129205.docx
new file mode 100644
index 000000000..4289254d0
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/tdf129205.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/tdf141540ChildRotation.docx b/writerfilter/qa/cppunittests/dmapper/data/tdf141540ChildRotation.docx
new file mode 100644
index 000000000..902bb6192
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/tdf141540ChildRotation.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docx b/writerfilter/qa/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docx
new file mode 100644
index 000000000..d0ceff118
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/tdf141540GroupLinePosSize.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/tdf141540GroupRotation.docx b/writerfilter/qa/cppunittests/dmapper/data/tdf141540GroupRotation.docx
new file mode 100644
index 000000000..13e65c1d1
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/tdf141540GroupRotation.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/tdf142304GroupPosition.docx b/writerfilter/qa/cppunittests/dmapper/data/tdf142304GroupPosition.docx
new file mode 100644
index 000000000..681a6e3b7
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/tdf142304GroupPosition.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docx b/writerfilter/qa/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docx
new file mode 100644
index 000000000..9a0fc8a2b
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/tdf142305SquareWrapMargin.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docx b/writerfilter/qa/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docx
new file mode 100644
index 000000000..3adc2d91b
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/tdf142305StrokeGlowMargin.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/tdf143208_wrapTight.docx b/writerfilter/qa/cppunittests/dmapper/data/tdf143208_wrapTight.docx
new file mode 100644
index 000000000..fab911ad9
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/tdf143208_wrapTight.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docx b/writerfilter/qa/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docx
new file mode 100644
index 000000000..1b1881b1e
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/tdf143455_SmartArtPosition.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/textbox-textline-top.docx b/writerfilter/qa/cppunittests/dmapper/data/textbox-textline-top.docx
new file mode 100644
index 000000000..dbd750092
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/textbox-textline-top.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/textbox-textline.docx b/writerfilter/qa/cppunittests/dmapper/data/textbox-textline.docx
new file mode 100644
index 000000000..493604d77
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/textbox-textline.docx
Binary files differ
diff --git a/writerfilter/qa/cppunittests/dmapper/data/wrap-poly-crop.docx b/writerfilter/qa/cppunittests/dmapper/data/wrap-poly-crop.docx
new file mode 100644
index 000000000..1835a130d
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/wrap-poly-crop.docx
Binary files differ