Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  import-tests-smartart.cxx

  Sprache: C
 

/* -*- 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 "sdmodeltestbase.hxx"

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/TextFitToSizeType.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/style/ParagraphAdjust.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>

#include <svx/svdoashp.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdogrp.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <oox/drawingml/drawingmltypes.hxx>

using namespace ::com::sun::star;

namespace
{
/// Gets one child of xShape, which one is specified by nIndex.
uno::Reference<drawing::XShape> getChildShape(const uno::Reference<drawing::XShape>&&nbsp;xShape,
                                              sal_Int32 nIndex)
{
    uno::Reference<container::XIndexAccess> xGroup(xShape, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    CPPUNIT_ASSERT(xGroup->getCount() > nIndex);

    uno::Reference<drawing::XShape> xRet(xGroup->getByIndex(nIndex), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xRet.is());

    return xRet;
}

uno::Reference<drawing::XShape> findChildShapeByText(const uno::Reference<drawing::XShape>& xShape,
                                                     const OUString& sText)
{
    uno::Reference<text::XText> xText(xShape, uno::UNO_QUERY);
    if (xText.is() && xText->getString() == sText)
        return xShape;

    uno::Reference<container::XIndexAccess> xGroup(xShape, uno::UNO_QUERY);
    if (!xGroup.is())
        return uno::Reference<drawing::XShape>();

    for (sal_Int32 i = 0; i < xGroup->getCount(); i++)
    {
        uno::Reference<drawing::XShape> xChildShape(xGroup->getByIndex(i), uno::UNO_QUERY);
        uno::Reference<drawing::XShape> xReturnShape = findChildShapeByText(xChildShape, sText);
        if (xReturnShape.is())
            return xReturnShape;
    }

    return uno::Reference<drawing::XShape>();
}
}

class SdImportTestSmartArt : public SdModelTestBase
{
public:
    SdImportTestSmartArt()
        : SdModelTestBase(u"/sd/qa/unit/data/"_ustr)
    {
    }
};

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testBase)
{
    createSdImpressDoc("pptx/smartart1.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xShapeGroup->getCount());

    uno::Reference<text::XText> xText0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xText0->getString());
    uno::Reference<text::XText> xText1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"b"_ustr, xText1->getString());
    uno::Reference<text::XText> xText2(xShapeGroup->getByIndex(3), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"c"_ustr, xText2->getString());
    uno::Reference<text::XText> xText3(xShapeGroup->getByIndex(4), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"d"_ustr, xText3->getString());
    uno::Reference<text::XText> xText4(xShapeGroup->getByIndex(5), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"e"_ustr, xText4->getString());

    uno::Reference<beans::XPropertySet> xShape(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);

    Color nFillColor;
    xShape->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
    CPPUNIT_ASSERT_EQUAL(Color(0x4F81BD), nFillColor);

    sal_Int16 nParaAdjust = 0;
    uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xShape));
    uno::Reference<beans::XPropertySet> xPropSet(xParagraph, uno::UNO_QUERY_THROW);
    xPropSet->getPropertyValue(u"ParaAdjust"_ustr) >>= nParaAdjust;
    CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER,
                         static_cast<style::ParagraphAdjust>(nParaAdjust));

    uno::Reference<drawing::XShape> xShape0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape2(xShapeGroup->getByIndex(3), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape3(xShapeGroup->getByIndex(4), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape4(xShapeGroup->getByIndex(5), uno::UNO_QUERY_THROW);

    /*
     *  Arrangement
     *     (LTR)
     *  ╭─────────╮
     *  │  0   1  │
     *  │  2   3  │
     *  │    4    │
     *  ╰─────────╯
     */

    CPPUNIT_ASSERT_EQUAL(xShape0->getPosition().Y, xShape1->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(xShape2->getPosition().Y, xShape3->getPosition().Y);

    CPPUNIT_ASSERT_EQUAL(xShape0->getPosition().X, xShape2->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(xShape1->getPosition().X, xShape3->getPosition().X);

    CPPUNIT_ASSERT_EQUAL(xShape2->getPosition().Y - xShape0->getPosition().Y,
                         xShape4->getPosition().Y - xShape2->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(xShape1->getPosition().X - xShape0->getPosition().X,
                         xShape3->getPosition().X - xShape2->getPosition().X);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(xShape2->getPosition().X + xShape3->getPosition().X,
                                 2 * xShape4->getPosition().X, 1);

    CPPUNIT_ASSERT(xShape2->getPosition().Y > xShape0->getPosition().Y);
    CPPUNIT_ASSERT(xShape4->getPosition().Y > xShape2->getPosition().Y);
    CPPUNIT_ASSERT(xShape0->getPosition().X < xShape1->getPosition().X);
    CPPUNIT_ASSERT(xShape2->getPosition().X < xShape3->getPosition().X);
    CPPUNIT_ASSERT((xShape2->getPosition().X < xShape4->getPosition().X));
    CPPUNIT_ASSERT((xShape3->getPosition().X > xShape4->getPosition().X));
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testChildren)
{
    createSdImpressDoc("pptx/smartart-children.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xShapeGroup->getCount());

    uno::Reference<drawing::XShapes> xShapeGroup0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xShapeGroup0->getCount());
    uno::Reference<text::XText> xTextA(xShapeGroup0->getByIndex(0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xTextA->getString());

    uno::Reference<drawing::XShapes> xChildren0(xShapeGroup0->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xChildren0->getCount());
    uno::Reference<drawing::XShapes> xChildB(xChildren0->getByIndex(0), uno::UNO_QUERY_THROW);
    uno::Reference<text::XText> xTextB(xChildB->getByIndex(0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"b"_ustr, xTextB->getString());
    uno::Reference<drawing::XShapes> xChildC(xChildren0->getByIndex(1), uno::UNO_QUERY_THROW);
    uno::Reference<text::XText> xTextC(xChildC->getByIndex(0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"c"_ustr, xTextC->getString());

    uno::Reference<drawing::XShapes> xShapeGroup1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xShapeGroup1->getCount());
    uno::Reference<text::XText> xTextX(xShapeGroup1->getByIndex(0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"x"_ustr, xTextX->getString());

    uno::Reference<drawing::XShapes> xChildren1(xShapeGroup1->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xChildren1->getCount());
    uno::Reference<drawing::XShapes> xChildY(xChildren1->getByIndex(0), uno::UNO_QUERY_THROW);
    uno::Reference<text::XText> xTextY(xChildY->getByIndex(0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"y"_ustr, xTextY->getString());
    uno::Reference<drawing::XShapes> xChildZ(xChildren1->getByIndex(1), uno::UNO_QUERY_THROW);
    uno::Reference<text::XText> xTextZ(xChildZ->getByIndex(0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"z"_ustr, xTextZ->getString());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testText)
{
    createSdImpressDoc("pptx/smartart-text.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShapes> xShapeGroup2(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);

    uno::Reference<text::XText> xText0(xShapeGroup2->getByIndex(0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xText0->getString().isEmpty());

    uno::Reference<text::XText> xText1(xShapeGroup2->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"test"_ustr, xText1->getString());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testCnt)
{
    createSdImpressDoc("pptx/smartart-cnt.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    sal_Int32 nCount = xShapeGroup->getCount();
    sal_Int32 nCorrect = 0;
    for (sal_Int32 i = 0; i < nCount; i++)
    {
        uno::Reference<text::XText> xText(xShapeGroup->getByIndex(i), uno::UNO_QUERY);
        if (xText.is() && !xText->getString().isEmpty())
            nCorrect++;
    }
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), nCorrect);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testDir)
{
    createSdImpressDoc("pptx/smartart-dir.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xShapeGroup->getCount());

    uno::Reference<drawing::XShape> xShape0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xShape0->getPosition().X > xShape1->getPosition().X);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf148665)
{
    // Without the fix in place, this test would have crashed at import time
    createSdImpressDoc("pptx/tdf148665.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xShapeGroup->getCount());

    uno::Reference<text::XText> xText0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"\nFufufu"_ustr, xText0->getString());
    uno::Reference<text::XText> xText1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"Susu"_ustr, xText1->getString());
    uno::Reference<text::XText> xText2(xShapeGroup->getByIndex(3), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"Sasa Haha"_ustr, xText2->getString());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf148921)
{
    createSdImpressDoc("pptx/tdf148921.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xShapeGroup->getCount());

    uno::Reference<drawing::XShapes> xShapeGroup2(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);

    // Without the fix in place, this test would have failed with
    // - Expected: 2
    // - Actual  : 4
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xShapeGroup2->getCount());

    uno::Reference<drawing::XShape> xShape0(xShapeGroup2->getByIndex(0), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape1(xShapeGroup2->getByIndex(1), uno::UNO_QUERY_THROW);

    CPPUNIT_ASSERT(xShape0->getPosition().X < xShape1->getPosition().X);
    CPPUNIT_ASSERT(xShape0->getPosition().Y < xShape1->getPosition().Y);
    CPPUNIT_ASSERT(xShape0->getSize().Height > xShape1->getSize().Height);
    CPPUNIT_ASSERT(xShape0->getSize().Width > xShape1->getSize().Width);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testMaxDepth)
{
    createSdImpressDoc("pptx/smartart-maxdepth.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xShapeGroup->getCount());

    uno::Reference<text::XText> xText0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"first"_ustr, xText0->getString());
    uno::Reference<text::XText> xText1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"second"_ustr, xText1->getString());

    uno::Reference<drawing::XShape> xShape0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(xShape0->getPosition().Y,
                         xShape1->getPosition().Y); // Confirms shapes are in same Y axis-level.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testRotation)
{
    createSdImpressDoc("pptx/smartart-rotation.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);

    uno::Reference<beans::XPropertySet> xShape0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
                         xShape0->getPropertyValue(u"RotateAngle"_ustr).get<sal_Int32>());

    uno::Reference<beans::XPropertySet> xShape1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(24000),
                         xShape1->getPropertyValue(u"RotateAngle"_ustr).get<sal_Int32>());

    uno::Reference<beans::XPropertySet> xShape2(xShapeGroup->getByIndex(3), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(12000),
                         xShape2->getPropertyValue(u"RotateAngle"_ustr).get<sal_Int32>());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTextAutoRotation)
{
    createSdImpressDoc("pptx/smartart-autoTxRot.pptx");

    auto testText = [&](int pageNo, sal_Int32 txtNo, const OUString& expTx, sal_Int32 expShRot,
                        sal_Int32 expTxRot) {
        OString msgText = "Page: " + OString::number(pageNo) + " text: " + OString::number(txtNo);
        uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, pageNo),
                                                     uno::UNO_QUERY_THROW);

        txtNo++; //skip background
        uno::Reference<text::XText> xTxt(xShapeGroup->getByIndex(txtNo), uno::UNO_QUERY_THROW);
        CPPUNIT_ASSERT_EQUAL_MESSAGE(msgText.getStr(), expTx, xTxt->getString());
        uno::Reference<beans::XPropertySet> xTxtProps(xTxt, uno::UNO_QUERY_THROW);
        CPPUNIT_ASSERT_EQUAL_MESSAGE(
            msgText.getStr(), expShRot,
            xTxtProps->getPropertyValue(u"RotateAngle"_ustr).get<sal_Int32>());

        auto aGeomPropSeq = xTxtProps->getPropertyValue(u"CustomShapeGeometry"_ustr)
                                .get<uno::Sequence<beans::PropertyValue>>();
        comphelper::SequenceAsHashMap aCustomShapeGeometry(aGeomPropSeq);

        auto it = aCustomShapeGeometry.find(u"TextPreRotateAngle"_ustr);
        if (it == aCustomShapeGeometry.end())
        {
            CPPUNIT_ASSERT_EQUAL_MESSAGE(msgText.getStr(), sal_Int32(0), expTxRot);
        }
        else
        {
            CPPUNIT_ASSERT_EQUAL_MESSAGE(msgText.getStr(), expTxRot, it->second.get<sal_Int32>());
        }
    };

    // Slide 1: absent autoTxRot => defaults to "upr"
    testText(0, 0, u"a"_ustr, 0, 0);
    testText(0, 1, u"b"_ustr, 33750, 0);
    testText(0, 2, u"c"_ustr, 31500, 0);
    testText(0, 3, u"d"_ustr, 29250, 90);
    testText(0, 4, u"e"_ustr, 27000, 90);
    testText(0, 5, u"f"_ustr, 24750, 90);
    testText(0, 6, u"g"_ustr, 22500, 180);
    testText(0, 7, u"h"_ustr, 20250, 180);
    testText(0, 8, u"i"_ustr, 18000, 180);
    testText(0, 9, u"j"_ustr, 15750, 180);
    testText(0, 10, u"k"_ustr, 13500, 180);
    testText(0, 11, u"l"_ustr, 11250, 270);
    testText(0, 12, u"m"_ustr, 9000, 270);
    testText(0, 13, u"n"_ustr, 6750, 270);
    testText(0, 14, u"o"_ustr, 4500, 0);
    testText(0, 15, u"p"_ustr, 2250, 0);

    // Slide 2: autoTxRot == "none"
    testText(1, 0, u"a"_ustr, 0, 0);
    testText(1, 1, u"b"_ustr, 33750, 0);
    testText(1, 2, u"c"_ustr, 31500, 0);
    testText(1, 3, u"d"_ustr, 29250, 0);
    testText(1, 4, u"e"_ustr, 27000, 0);
    testText(1, 5, u"f"_ustr, 24750, 0);
    testText(1, 6, u"g"_ustr, 22500, 0);
    testText(1, 7, u"h"_ustr, 20250, 0);
    testText(1, 8, u"i"_ustr, 18000, 0);
    testText(1, 9, u"j"_ustr, 15750, 0);
    testText(1, 10, u"k"_ustr, 13500, 0);
    testText(1, 11, u"l"_ustr, 11250, 0);
    testText(1, 12, u"m"_ustr, 9000, 0);
    testText(1, 13, u"n"_ustr, 6750, 0);
    testText(1, 14, u"o"_ustr, 4500, 0);
    testText(1, 15, u"p"_ustr, 2250, 0);

    // Slide 3: autoTxRot == "grav"
    testText(2, 0, u"a"_ustr, 0, 0);
    testText(2, 1, u"b"_ustr, 33750, 0);
    testText(2, 2, u"c"_ustr, 31500, 0);
    testText(2, 3, u"d"_ustr, 29250, 0);
    testText(2, 4, u"e"_ustr, 27000, 0);
    testText(2, 5, u"f"_ustr, 24750, 180);
    testText(2, 6, u"g"_ustr, 22500, 180);
    testText(2, 7, u"h"_ustr, 20250, 180);
    testText(2, 8, u"i"_ustr, 18000, 180);
    testText(2, 9, u"j"_ustr, 15750, 180);
    testText(2, 10, u"k"_ustr, 13500, 180);
    testText(2, 11, u"l"_ustr, 11250, 180);
    testText(2, 12, u"m"_ustr, 9000, 0);
    testText(2, 13, u"n"_ustr, 6750, 0);
    testText(2, 14, u"o"_ustr, 4500, 0);
    testText(2, 15, u"p"_ustr, 2250, 0);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testBasicProcess)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testPyramid)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testPyramidOneChild)
{
    // Load a document with a pyra algorithm in it.
    // Without the accompanying fix in place, this test would have crashed.
    createSdImpressDoc("pptx/smartart-pyramid-1child.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    uno::Reference<text::XTextRange> xText(getChildShape(getChildShape(xGroup, 1), 1),
                                           uno::UNO_QUERY);
    // Verify that the text of the only child is imported correctly.
    CPPUNIT_ASSERT_EQUAL(u"A"_ustr, xText->getString());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testChevron)
{
    createSdImpressDoc("pptx/smartart-chevron.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xShapeGroup->getCount());

    uno::Reference<text::XText> xText0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xText0->getString());
    uno::Reference<text::XText> xText1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"b"_ustr, xText1->getString());
    uno::Reference<text::XText> xText2(xShapeGroup->getByIndex(3), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"c"_ustr, xText2->getString());

    uno::Reference<drawing::XShape> xShape0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape2(xShapeGroup->getByIndex(3), uno::UNO_QUERY_THROW);

    CPPUNIT_ASSERT(xShape0->getPosition().X < xShape1->getPosition().X);
    CPPUNIT_ASSERT(xShape1->getPosition().X < xShape2->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(xShape0->getPosition().Y, xShape1->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(xShape1->getPosition().Y, xShape2->getPosition().Y);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testCycle)
{
    createSdImpressDoc("pptx/smartart-cycle.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    // 11 children: background, 5 shapes, 5 connectors
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(11), xGroup->getCount());

    uno::Reference<drawing::XShape> xShape0(xGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShapeConn(xGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape2(xGroup->getByIndex(3), uno::UNO_QUERY_THROW);

    uno::Reference<text::XText> xText0(xShape0, uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xText0->getString());
    uno::Reference<text::XText> xText2(xShape2, uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"b"_ustr, xText2->getString());

    // xShapeConn is connector between shapes 0 and 2
    // it should lay between them and be rotated 0 -> 2
    CPPUNIT_ASSERT(xShape0->getPosition().X < xShapeConn->getPosition().X);
    CPPUNIT_ASSERT(xShape0->getPosition().Y < xShapeConn->getPosition().Y);
    CPPUNIT_ASSERT(xShapeConn->getPosition().Y < xShape2->getPosition().Y);
    uno::Reference<beans::XPropertySet> xPropSetConn(xShapeConn, uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(32400),
                         xPropSetConn->getPropertyValue(u"RotateAngle"_ustr).get<sal_Int32>());

    // Make sure that we have an arrow shape between the two shapes
    comphelper::SequenceAsHashMap aCustomShapeGeometry(
        xPropSetConn->getPropertyValue(u"CustomShapeGeometry"_ustr));
    CPPUNIT_ASSERT(aCustomShapeGeometry[u"Type"_ustr].has<OUString>());
    OUString aType = aCustomShapeGeometry[u"Type"_ustr].get<OUString>();
    CPPUNIT_ASSERT_EQUAL(u"ooxml-rightArrow"_ustr, aType);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testHierarchy)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testmatrix)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testvenndiagram)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testInvertedPyramid)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testMultidirectional)
{
    // similar document as cycle, but arrows are pointing in both directions
    createSdImpressDoc("pptx/smartart-multidirectional.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    // 7 children: background, 3 shapes, 3 connectors
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(7), xGroup->getCount());

    uno::Reference<drawing::XShape> xShapeConn(xGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    uno::Reference<beans::XPropertySet> xPropSetConn(xShapeConn, uno::UNO_QUERY_THROW);
    comphelper::SequenceAsHashMap aCustomShapeGeometry(
        xPropSetConn->getPropertyValue(u"CustomShapeGeometry"_ustr));
    CPPUNIT_ASSERT(aCustomShapeGeometry[u"Type"_ustr].has<OUString>());
    OUString aType = aCustomShapeGeometry[u"Type"_ustr].get<OUString>();
    CPPUNIT_ASSERT_EQUAL(u"ooxml-leftRightArrow"_ustr, aType);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testHorizontalBulletList)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testEquation)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testBasicRadicals)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testSegmentedCycle)
{
    //FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testBaseRtoL)
{
    createSdImpressDoc("pptx/smartart-rightoleftblockdiagram.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xShapeGroup->getCount());

    uno::Reference<text::XText> xText0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xText0->getString());
    uno::Reference<text::XText> xText1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"b"_ustr, xText1->getString());
    uno::Reference<text::XText> xText2(xShapeGroup->getByIndex(3), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"c"_ustr, xText2->getString());
    uno::Reference<text::XText> xText3(xShapeGroup->getByIndex(4), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"d"_ustr, xText3->getString());
    uno::Reference<text::XText> xText4(xShapeGroup->getByIndex(5), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(u"e"_ustr, xText4->getString());

    uno::Reference<beans::XPropertySet> xShape(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);

    Color nFillColor;
    xShape->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
    CPPUNIT_ASSERT_EQUAL(Color(0x4F81BD), nFillColor);

    sal_Int16 nParaAdjust = 0;
    uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xShape));
    uno::Reference<beans::XPropertySet> xPropSet(xParagraph, uno::UNO_QUERY_THROW);
    xPropSet->getPropertyValue(u"ParaAdjust"_ustr) >>= nParaAdjust;
    CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER,
                         static_cast<style::ParagraphAdjust>(nParaAdjust));

    uno::Reference<drawing::XShape> xShape0(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape1(xShapeGroup->getByIndex(2), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape2(xShapeGroup->getByIndex(3), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape3(xShapeGroup->getByIndex(4), uno::UNO_QUERY_THROW);
    uno::Reference<drawing::XShape> xShape4(xShapeGroup->getByIndex(5), uno::UNO_QUERY_THROW);

    /*
     *  Arrangement
     *     (RTL)
     *  ╭─────────╮
     *  │  1   0  │
     *  │  3   2  │
     *  │    4    │
     *  ╰─────────╯
     */

    CPPUNIT_ASSERT_EQUAL(xShape0->getPosition().Y, xShape1->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(xShape2->getPosition().Y, xShape3->getPosition().Y);

    CPPUNIT_ASSERT_EQUAL(xShape0->getPosition().X, xShape2->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(xShape1->getPosition().X, xShape3->getPosition().X);

    CPPUNIT_ASSERT_EQUAL(xShape2->getPosition().Y - xShape0->getPosition().Y,
                         xShape4->getPosition().Y - xShape2->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(xShape1->getPosition().X - xShape0->getPosition().X,
                         xShape3->getPosition().X - xShape2->getPosition().X);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(xShape2->getPosition().X + xShape3->getPosition().X,
                                 2 * xShape4->getPosition().X, 1);

    CPPUNIT_ASSERT(xShape2->getPosition().Y > xShape0->getPosition().Y);
    CPPUNIT_ASSERT(xShape4->getPosition().Y > xShape2->getPosition().Y);
    CPPUNIT_ASSERT(xShape0->getPosition().X > xShape1->getPosition().X);
    CPPUNIT_ASSERT(xShape2->getPosition().X > xShape3->getPosition().X);
    CPPUNIT_ASSERT((xShape2->getPosition().X > xShape4->getPosition().X));
    CPPUNIT_ASSERT((xShape3->getPosition().X < xShape4->getPosition().X));
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testVerticalBoxList)
{
    createSdImpressDoc("pptx/smartart-vertical-box-list.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    // Without the accompanying fix in place, this test would have failed with
    // 'actual: 0'.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xShapeGroup->getCount());

    uno::Reference<drawing::XShapes> xFirstChild(xShapeGroup->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstChild.is());
    uno::Reference<drawing::XShape> xParentText(xFirstChild->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xParentText.is());
    // Without the accompanying fix in place, this test would have failed with
    // 'actual: 7361', i.e. the width was not the 70% of the parent as the
    // constraint wanted.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(11852), xParentText->getSize().Width);

    uno::Reference<drawing::XShape> xChildText(xShapeGroup->getByIndex(2), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xChildText.is());
    // Without the accompanying fix in place, this test would have failed with
    // 'actual: 7361' (and with the fix: 'actual: 16932', i.e. the width of the
    // parent).
    CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(10000), xChildText->getSize().Width);

    // Assert that the right edge of the parent text is closer to the slide
    // boundary than the right edge of the parent text.
    // Without the accompanying fix in place, this test would have failed with
    // 'Expected greater than: 25656, Actual  : 21165'.
    CPPUNIT_ASSERT_GREATER(xParentText->getPosition().X + xParentText->getSize().Width,
                           xChildText->getPosition().X + xChildText->getSize().Width);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testVerticalBracketList)
{
    createSdImpressDoc("pptx/vertical-bracket-list.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xShapeGroup->getCount());

    uno::Reference<drawing::XShapes> xFirstChild(xShapeGroup->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstChild.is());
    // Without the accompanying fix in place, this test would have failed with
    // 'actual: 2', i.e. one child shape (with its "A" text) was missing.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xFirstChild->getCount());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTableList)
{
    createSdImpressDoc("pptx/table-list.pptx");
    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xShapeGroup.is());
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xShapeGroup->getCount());

    uno::Reference<text::XText> xParentText(xShapeGroup->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xParentText.is());
    CPPUNIT_ASSERT_EQUAL(u"Parent"_ustr, xParentText->getString());
    uno::Reference<drawing::XShape> xParent(xParentText, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xParent.is());
    int nParentRight = xParent->getPosition().X + xParent->getSize().Width;

    uno::Reference<drawing::XShapes> xChildren(xShapeGroup->getByIndex(2), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xChildren.is());
    uno::Reference<text::XText> xChild2Text(xChildren->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xChild2Text.is());
    CPPUNIT_ASSERT_EQUAL(u"Child 2"_ustr, xChild2Text->getString());
    uno::Reference<drawing::XShape> xChild2(xChild2Text, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xChild2.is());
    int nChild2Right = xChild2->getPosition().X + xChild2->getSize().Width;

    // Without the accompanying fix in place, this test would have failed with
    // 'Expected less than: 100, Actual  : 22014', i.e. the second child was
    // shifted to the right too much.
    CPPUNIT_ASSERT_LESS(100, abs(nChild2Right - nParentRight));
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testAccentProcess)
{
    createSdImpressDoc("pptx/smartart-accent-process.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());
    // 3 children: first pair, connector, second pair.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xGroup->getCount());
    uno::Reference<drawing::XShape> xGroupShape(xGroup, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroupShape.is());

    // The pair is a parent (shape + text) and a child, so 3 shapes in total.
    // The order is important, first is at the back, last is at the front.
    uno::Reference<drawing::XShapes> xFirstPair(xGroup->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstPair.is());
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xFirstPair->getCount());

    uno::Reference<text::XText> xFirstParentText(xFirstPair->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstParentText.is());
    CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xFirstParentText->getString());
    uno::Reference<drawing::XShape> xFirstParent(xFirstParentText, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstParent.is());
    int nFirstParentTop = xFirstParent->getPosition().Y;

    uno::Reference<text::XText> xFirstChildText(xFirstPair->getByIndex(2), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstChildText.is());
    CPPUNIT_ASSERT_EQUAL(u"b"_ustr, xFirstChildText->getString());
    uno::Reference<drawing::XShape> xFirstChild(xFirstChildText, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstChildText.is());

    {
        uno::Reference<container::XEnumerationAccess> xParasAccess(xFirstChildText, uno::UNO_QUERY);
        uno::Reference<container::XEnumeration> xParas = xParasAccess->createEnumeration();
        uno::Reference<beans::XPropertySet> xPara(xParas->nextElement(), uno::UNO_QUERY);
        // Without the accompanying fix in place, this test would have failed
        // with 'Expected: 0; Actual  : 1270', i.e. there was a large
        // unexpected left margin.
        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0),
                             xPara->getPropertyValue(u"ParaLeftMargin"_ustr).get<sal_Int32>());

        uno::Reference<container::XIndexAccess> xRules(
            xPara->getPropertyValue(u"NumberingRules"_ustr), uno::UNO_QUERY);
        comphelper::SequenceAsHashMap aRule(xRules->getByIndex(0));
        CPPUNIT_ASSERT_EQUAL(u"•"_ustr, aRule[u"BulletChar"_ustr].get<OUString>());
    }

    int nFirstChildTop = xFirstChild->getPosition().Y;
    int nFirstChildRight = xFirstChild->getPosition().X + xFirstChild->getSize().Width;

    // First child is below the first parent.
    // Without the accompanying fix in place, this test would have failed with
    // 'Expected less than: 3881, Actual  : 3881', i.e. xFirstChild was not
    // below xFirstParent (a good position is 9081).
    CPPUNIT_ASSERT_LESS(nFirstChildTop, nFirstParentTop);

    // Make sure that we have an arrow shape between the two pairs.
    uno::Reference<beans::XPropertySet> xArrow(xGroup->getByIndex(2), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xArrow.is());
    comphelper::SequenceAsHashMap aCustomShapeGeometry(
        xArrow->getPropertyValue(u"CustomShapeGeometry"_ustr));
    // Without the accompanying fix in place, this test would have failed, i.e.
    // the custom shape lacked a type -> arrow was not visible.
    CPPUNIT_ASSERT(aCustomShapeGeometry[u"Type"_ustr].has<OUString>());
    OUString aType = aCustomShapeGeometry[u"Type"_ustr].get<OUString>();
    CPPUNIT_ASSERT_EQUAL(u"ooxml-rightArrow"_ustr, aType);

    // Make sure that height of the arrow is less than its width.
    uno::Reference<drawing::XShape> xArrowShape(xArrow, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xArrowShape.is());
    awt::Size aArrowSize = xArrowShape->getSize();
    CPPUNIT_ASSERT_LESS(aArrowSize.Width, aArrowSize.Height);

    uno::Reference<drawing::XShapes> xSecondPair(xGroup->getByIndex(3), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xSecondPair.is());
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xSecondPair->getCount());
    uno::Reference<text::XText> xSecondParentText(xSecondPair->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstParentText.is());
    // Without the accompanying fix in place, this test would have failed with
    // 'Expected: cc; Actual  : c', i.e. non-first runs on data points were ignored.
    CPPUNIT_ASSERT_EQUAL(u"cc"_ustr, xSecondParentText->getString());
    uno::Reference<drawing::XShape> xSecondParent(xSecondParentText, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xSecondParent.is());
    int nSecondParentLeft = xSecondParent->getPosition().X;
    // Without the accompanying fix in place, this test would have failed with
    // 'Expected less than: 12700; Actual  : 18540', i.e. the "b" and "c"
    // shapes overlapped.
    CPPUNIT_ASSERT_LESS(nSecondParentLeft, nFirstChildRight);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testContinuousBlockProcess)
{
    createSdImpressDoc("pptx/smartart-continuous-block-process.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());
    // 3 children: diagram background, background arrow, foreground.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xGroup->getCount());

    uno::Reference<drawing::XShapes> xLinear(xGroup->getByIndex(2), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xLinear.is());
    // 3 children: A, B and C.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xLinear->getCount());

    uno::Reference<text::XText> xA(xLinear->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xA.is());
    CPPUNIT_ASSERT_EQUAL(u"A"_ustr, xA->getString());
    uno::Reference<drawing::XShape> xAShape(xA, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xAShape.is());
    // Without the accompanying fix in place, this test would have failed: the
    // theoretically correct value is 5462 mm100 (16933 is the total width, and
    // need to divide that to 1, 0.5, 1, 0.5 and 1 units), while the old value
    // was 4703 and the new one is 5461.
    CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(5000), xAShape->getSize().Width);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testOrgChart)
{
    // Simple org chart with 1 manager and 1 employee only.
    createSdImpressDoc("pptx/smartart-org-chart.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    uno::Reference<text::XText> xManager(
        getChildShape(getChildShape(getChildShape(xGroup, 1), 0), 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xManager.is());
    // Without the accompanying fix in place, this test would have failed: this
    // was just "Manager", and the second paragraph was lost.
    CPPUNIT_ASSERT_EQUAL(u"Manager\nSecond para"_ustr, xManager->getString());

    uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xManager, uno::UNO_QUERY);
    uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
    uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
    uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xPara, uno::UNO_QUERY);
    uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
    uno::Reference<beans::XPropertySet> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
    Color nActualColor;
    xRun->getPropertyValue(u"CharColor"_ustr) >>= nActualColor;
    // Without the accompanying fix in place, this test would have failed: the
    // "Manager" font color was black, not white.
    CPPUNIT_ASSERT_EQUAL(COL_WHITE, nActualColor);

    uno::Reference<drawing::XShape> xManagerShape(xManager, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xManagerShape.is());

    awt::Point aManagerPos = xManagerShape->getPosition();
    awt::Size aManagerSize = xManagerShape->getSize();

    // Make sure that the manager has 2 employees.
    uno::Reference<drawing::XShapes> xEmployees(getChildShape(getChildShape(xGroup, 1), 2),
                                                uno::UNO_QUERY);
    CPPUNIT_ASSERT(xEmployees.is());
    // 4 children: connector, 1st employee, connector, 2nd employee.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xEmployees->getCount());

    uno::Reference<text::XText> xEmployee(
        getChildShape(
            getChildShape(getChildShape(getChildShape(getChildShape(xGroup, 1), 2), 1), 0), 0),
        uno::UNO_QUERY);
    CPPUNIT_ASSERT(xEmployee.is());
    CPPUNIT_ASSERT_EQUAL(u"Employee"_ustr, xEmployee->getString());

    uno::Reference<drawing::XShape> xEmployeeShape(xEmployee, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xEmployeeShape.is());

    awt::Point aEmployeePos = xEmployeeShape->getPosition();
    awt::Size aEmployeeSize = xEmployeeShape->getSize();

    CPPUNIT_ASSERT_EQUAL(aManagerPos.X, aEmployeePos.X);

    // Without the accompanying fix in place, this test would have failed: the
    // two shapes were overlapping, i.e. "manager" was not above "employee".
    CPPUNIT_ASSERT_GREATER(aManagerPos.Y, aEmployeePos.Y);

    // Make sure that the second employee is on the right of the first one.
    // Without the accompanying fix in place, this test would have failed, as
    // the second employee was below the first one.
    uno::Reference<text::XText> xEmployee2(
        getChildShape(
            getChildShape(getChildShape(getChildShape(getChildShape(xGroup, 1), 2), 3), 0), 0),
        uno::UNO_QUERY);
    CPPUNIT_ASSERT(xEmployee2.is());
    CPPUNIT_ASSERT_EQUAL(u"Employee2"_ustr, xEmployee2->getString());

    uno::Reference<drawing::XShape> xEmployee2Shape(xEmployee2, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xEmployee2Shape.is());

    awt::Point aEmployee2Pos = xEmployee2Shape->getPosition();
    //awt::Size aEmployee2Size = xEmployee2Shape->getSize();
    CPPUNIT_ASSERT_GREATER(aEmployeePos.X, aEmployee2Pos.X);

    // Make sure that assistant is above employees.
    uno::Reference<text::XText> xAssistant(
        getChildShape(
            getChildShape(getChildShape(getChildShape(getChildShape(xGroup, 1), 1), 1), 0), 0),
        uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"Assistant"_ustr, xAssistant->getString());

    uno::Reference<drawing::XShape> xAssistantShape(xAssistant, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xAssistantShape.is());

    awt::Point aAssistantPos = xAssistantShape->getPosition();
    // Without the accompanying fix in place, this test would have failed: the
    // assistant shape was below the employee shape.
    CPPUNIT_ASSERT_GREATER(aAssistantPos.Y, aEmployeePos.Y);

    // Make sure the connector of the assistant is above the shape.
    uno::Reference<drawing::XShape> xAssistantConnector
        = getChildShape(getChildShape(getChildShape(xGroup, 1), 1), 0);
    CPPUNIT_ASSERT(xAssistantConnector.is());
    //awt::Point aAssistantConnectorPos = xAssistantConnector->getPosition();
    // This failed, the vertical positions of the connector and the shape of
    // the assistant were the same.
    //CPPUNIT_ASSERT_LESS(aAssistantPos.Y, aAssistantConnectorPos.Y);
    // connectors are hidden as they don't work correctly

    // Make sure the height of xManager and xManager2 is the same.
    uno::Reference<text::XText> xManager2(
        getChildShape(getChildShape(getChildShape(xGroup, 2), 0), 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xManager2.is());
    CPPUNIT_ASSERT_EQUAL(u"Manager2"_ustr, xManager2->getString());

    uno::Reference<drawing::XShape> xManager2Shape(xManager2, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xManager2Shape.is());

    awt::Size aManager2Size = xManager2Shape->getSize();
    // Without the accompanying fix in place, this test would have failed:
    // xManager2's height was 3 times larger than xManager's height.
    CPPUNIT_ASSERT_EQUAL(aManagerSize.Height, aManager2Size.Height);

    // Make sure the employee nodes use the free space on the right, since
    // manager2 has no assistants / employees.
    //CPPUNIT_ASSERT_GREATER(aManagerSize.Width, aEmployeeSize.Width + aEmployee2Size.Width);
    // currently disabled as causes problems in complex charts

    // Without the accompanying fix in place, this test would have failed: an
    // employee was exactly the third of the total height, without any spacing.
    CPPUNIT_ASSERT_LESS(xGroup->getSize().Height / 3, aEmployeeSize.Height);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testCycleMatrix)
{
    createSdImpressDoc("pptx/smartart-cycle-matrix.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    // Without the accompanying fix in place, this test would have failed: the height was 12162,
    // which is not the mm100 equivalent of the 4064000 EMU in the input file.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(11288), xGroup->getSize().Height);

    uno::Reference<text::XText> xA1(getChildShape(getChildShape(xGroup, 2), 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xA1.is());
    CPPUNIT_ASSERT_EQUAL(u"A1"_ustr, xA1->getString());

    // Test fill color of B1, should be orange.
    uno::Reference<text::XText> xB1(getChildShape(getChildShape(xGroup, 2), 1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xB1.is());
    CPPUNIT_ASSERT_EQUAL(u"B1"_ustr, xB1->getString());

    uno::Reference<beans::XPropertySet> xB1Props(xB1, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xB1Props.is());
    Color nFillColor;
    xB1Props->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
    // Without the accompanying fix in place, this test would have failed: the background color was
    // 0x4f81bd, i.e. blue, not orange.
    CPPUNIT_ASSERT_EQUAL(Color(0xf79646), nFillColor);

    // Without the accompanying fix in place, this test would have failed: the
    // content of the "A2" shape was lost.
    uno::Reference<text::XText> xA2(getChildShape(getChildShape(getChildShape(xGroup, 1), 0), 1),
                                    uno::UNO_QUERY);
    CPPUNIT_ASSERT(xA2.is());
    CPPUNIT_ASSERT_EQUAL(u"A2"_ustr, xA2->getString());

    // Test that the layout of shapes is like this:
    // A2 B2
    // D2 C2

    uno::Reference<drawing::XShape> xA2Shape(xA2, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xA2Shape.is());

    uno::Reference<text::XText> xB2(getChildShape(getChildShape(getChildShape(xGroup, 1), 1), 1),
                                    uno::UNO_QUERY);
    CPPUNIT_ASSERT(xB2.is());
    CPPUNIT_ASSERT_EQUAL(u"B2"_ustr, xB2->getString());
    uno::Reference<drawing::XShape> xB2Shape(xB2, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xB2Shape.is());

    // Test line color of B2, should be orange.
    uno::Reference<beans::XPropertySet> xB2Props(xB2, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xB2Props.is());
    Color nLineColor = 0;
    xB2Props->getPropertyValue(u"LineColor"_ustr) >>= nLineColor;
    CPPUNIT_ASSERT_EQUAL(Color(0xf79646), nLineColor);

    uno::Reference<text::XText> xC2(getChildShape(getChildShape(getChildShape(xGroup, 1), 2), 1),
                                    uno::UNO_QUERY);
    CPPUNIT_ASSERT(xC2.is());
    // Without the accompanying fix in place, this test would have failed, i.e. the order of the
    // lines in the shape were wrong: C2-1\nC2-4\nC2-3\nC2-2.
    CPPUNIT_ASSERT_EQUAL(u"C2-1\nC2-2\nC2-3\nC2-4"_ustr, xC2->getString());
    uno::Reference<drawing::XShape> xC2Shape(xC2, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xC2Shape.is());

    uno::Reference<text::XText> xD2(getChildShape(getChildShape(getChildShape(xGroup, 1), 3), 1),
                                    uno::UNO_QUERY);
    CPPUNIT_ASSERT(xD2.is());
    CPPUNIT_ASSERT_EQUAL(u"D2"_ustr, xD2->getString());
    uno::Reference<drawing::XShape> xD2Shape(xD2, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xD2Shape.is());

    // Without the accompanying fix in place, this test would have failed, i.e.
    // the A2 and B2 shapes had the same horizontal position, while B2 should
    // be on the right of A2.
    CPPUNIT_ASSERT_GREATER(xA2Shape->getPosition().X, xB2Shape->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(xA2Shape->getPosition().Y, xB2Shape->getPosition().Y);
    CPPUNIT_ASSERT_GREATER(xA2Shape->getPosition().X, xC2Shape->getPosition().X);
    CPPUNIT_ASSERT_GREATER(xA2Shape->getPosition().Y, xC2Shape->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(xA2Shape->getPosition().X, xD2Shape->getPosition().X);
    CPPUNIT_ASSERT_GREATER(xA2Shape->getPosition().Y, xD2Shape->getPosition().Y);

    // Without the accompanying fix in place, this test would have failed: width was expected to be
    // 4887, was actually 7331.
    uno::Reference<drawing::XShape> xA1Shape(xA1, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xA1Shape.is());
    CPPUNIT_ASSERT_EQUAL(xA1Shape->getSize().Height, xA1Shape->getSize().Width);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testPictureStrip)
{
    createSdImpressDoc("pptx/smartart-picture-strip.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    uno::Reference<beans::XPropertySet> xFirstImage(getChildShape(getChildShape(xGroup, 1), 1),
                                                    uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstImage.is());
    drawing::FillStyle eFillStyle = drawing::FillStyle_NONE;
    xFirstImage->getPropertyValue(u"FillStyle"_ustr) >>= eFillStyle;
    // Without the accompanying fix in place, this test would have failed: fill style was solid, not
    // bitmap.
    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, eFillStyle);

    uno::Reference<graphic::XGraphic> xGraphic;
    xFirstImage->getPropertyValue(u"FillBitmap"_ustr) >>= xGraphic;
    Graphic aFirstGraphic(xGraphic);

    uno::Reference<beans::XPropertySet> xSecondImage(getChildShape(getChildShape(xGroup, 2), 1),
                                                     uno::UNO_QUERY);
    CPPUNIT_ASSERT(xSecondImage.is());
    eFillStyle = drawing::FillStyle_NONE;
    xSecondImage->getPropertyValue(u"FillStyle"_ustr) >>= eFillStyle;
    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, eFillStyle);

    xSecondImage->getPropertyValue(u"FillBitmap"_ustr) >>= xGraphic;
    Graphic aSecondGraphic(xGraphic);
    // Without the accompanying fix in place, this test would have failed: both xFirstImage and
    // xSecondImage had the bitmap fill from the second shape.
    CPPUNIT_ASSERT(aFirstGraphic.GetChecksum() != aSecondGraphic.GetChecksum());

    // Test that the 3 images are in a single column, in 3 rows.
    uno::Reference<drawing::XShape> xFirstImageShape(xFirstImage, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstImage.is());
    uno::Reference<drawing::XShape> xSecondImageShape(xSecondImage, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xSecondImage.is());
    uno::Reference<drawing::XShape> xThirdImageShape = getChildShape(getChildShape(xGroup, 3), 1);
    CPPUNIT_ASSERT(xThirdImageShape.is());
    // Without the accompanying fix in place, this test would have failed: the first and the second
    // image were in the same row.
    CPPUNIT_ASSERT_EQUAL(xFirstImageShape->getPosition().X, xSecondImageShape->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(xSecondImageShape->getPosition().X, xThirdImageShape->getPosition().X);
    CPPUNIT_ASSERT_GREATER(xFirstImageShape->getPosition().Y, xSecondImageShape->getPosition().Y);
    CPPUNIT_ASSERT_GREATER(xSecondImageShape->getPosition().Y, xThirdImageShape->getPosition().Y);

    // Make sure that the title shape doesn't overlap with the diagram.
    // Note that real "no overlap" is asserted here, though in fact what we want is a less strict
    // condition: that no text part of the title shape and the diagram overlaps.
    uno::Reference<drawing::XShape> xTitle(getShapeFromPage(1, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xTitle.is());
    // Without the accompanying fix in place, this test would have failed with 'Expected greater
    // than: 2873; Actual  : 2320', i.e. the title shape and the diagram overlapped.
    uno::Reference<drawing::XShape> xFirstPair = getChildShape(xGroup, 1);
    CPPUNIT_ASSERT_GREATER(xTitle->getPosition().Y + xTitle->getSize().Height - 1069,
                           xFirstPair->getPosition().Y);

    // Make sure that left margin is 60% of width (if you count width in points and margin in mms).
    uno::Reference<beans::XPropertySet> xFirstText(getChildShape(getChildShape(xGroup, 1), 0),
                                                   uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstText.is());
    sal_Int32 nTextLeftDistance = 0;
    xFirstText->getPropertyValue(u"TextLeftDistance"_ustr) >>= nTextLeftDistance;
    uno::Reference<drawing::XShape> xFirstTextShape(xFirstText, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xFirstTextShape.is());
    sal_Int32 nWidth = xFirstTextShape->getSize().Width;
    double fFactor = oox::drawingml::convertPointToMms(0.6);
    // Without the accompanying fix in place, this test would have failed with 'Expected: 3440,
    // Actual  : 263', i.e. the left margin was too small.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(nWidth * fFactor), nTextLeftDistance);

    // Make sure that aspect ratio is not ignored, i.e. width is not larger than height 3 times.
    awt::Size aFirstPairSize = xFirstPair->getSize();
    // Without the accompanying fix in place, this test would have failed: bad width was 16932, good
    // width is 12540, but let's accept 12541 as well.
    CPPUNIT_ASSERT_LESSEQUAL(aFirstPairSize.Height * 3 + 1, aFirstPairSize.Width);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testInteropGrabBag)
{
    createSdImpressDoc("pptx/smartart-interopgrabbag.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    uno::Reference<beans::XPropertySet> xPropertySet(xGroup, uno::UNO_QUERY_THROW);
    uno::Sequence<beans::PropertyValue> aGrabBagSeq;
    xPropertySet->getPropertyValue(u"InteropGrabBag"_ustr) >>= aGrabBagSeq;
    comphelper::SequenceAsHashMap aGrabBag(aGrabBagSeq);
    CPPUNIT_ASSERT(aGrabBag.find(u"OOXData"_ustr) != aGrabBag.end());
    CPPUNIT_ASSERT(aGrabBag.find(u"OOXLayout"_ustr) != aGrabBag.end());
    CPPUNIT_ASSERT(aGrabBag.find(u"OOXStyle"_ustr) != aGrabBag.end());
    CPPUNIT_ASSERT(aGrabBag.find(u"OOXColor"_ustr) != aGrabBag.end());
    CPPUNIT_ASSERT(aGrabBag.find(u"OOXDrawing"_ustr) != aGrabBag.end());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testBackground)
{
    createSdImpressDoc("pptx/smartart-background.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    // background should fill whole diagram
    uno::Reference<drawing::XShape> xShapeGroup(xGroup, uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShape(xGroup->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(xShape->getPosition().X, xShapeGroup->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(xShape->getPosition().Y, xShapeGroup->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(xShape->getSize().Width, xShapeGroup->getSize().Width);
    CPPUNIT_ASSERT_EQUAL(xShape->getSize().Height, xShapeGroup->getSize().Height);

    uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY_THROW);
    drawing::FillStyle eFillStyle = drawing::FillStyle_NONE;
    xPropertySet->getPropertyValue(u"FillStyle"_ustr) >>= eFillStyle;
    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, eFillStyle);

    Color nFillColor;
    xPropertySet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
    CPPUNIT_ASSERT_EQUAL(Color(0x339933), nFillColor);

    bool bMoveProtect = false;
    xPropertySet->getPropertyValue(u"MoveProtect"_ustr) >>= bMoveProtect;
    CPPUNIT_ASSERT_EQUAL(true, bMoveProtect);

    bool bSizeProtect = false;
    xPropertySet->getPropertyValue(u"SizeProtect"_ustr) >>= bSizeProtect;
    CPPUNIT_ASSERT_EQUAL(true, bSizeProtect);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testBackgroundDrawingmlFallback)
{
    // same as testBackground, but test file contains drawingML fallback

    createSdImpressDoc("pptx/smartart-background-drawingml-fallback.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    // background should fill whole diagram
    uno::Reference<drawing::XShape> xShapeGroup(xGroup, uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShape(xGroup->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(xShape->getPosition().X, xShapeGroup->getPosition().X);
    CPPUNIT_ASSERT_EQUAL(xShape->getPosition().Y, xShapeGroup->getPosition().Y);
    CPPUNIT_ASSERT_EQUAL(xShape->getSize().Width, xShapeGroup->getSize().Width);
    CPPUNIT_ASSERT_EQUAL(xShape->getSize().Height, xShapeGroup->getSize().Height);

    uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY_THROW);
    drawing::FillStyle eFillStyle = drawing::FillStyle_NONE;
    xPropertySet->getPropertyValue(u"FillStyle"_ustr) >>= eFillStyle;
    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, eFillStyle);

    Color nFillColor;
    xPropertySet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
    CPPUNIT_ASSERT_EQUAL(Color(0x339933), nFillColor);

    bool bMoveProtect = false;
    xPropertySet->getPropertyValue(u"MoveProtect"_ustr) >>= bMoveProtect;
    CPPUNIT_ASSERT_EQUAL(true, bMoveProtect);

    bool bSizeProtect = false;
    xPropertySet->getPropertyValue(u"SizeProtect"_ustr) >>= bSizeProtect;
    CPPUNIT_ASSERT_EQUAL(true, bSizeProtect);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testCenterCycle)
{
    createSdImpressDoc("pptx/smartart-center-cycle.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    uno::Reference<drawing::XShapes> xGroupNested(xGroup->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroupNested.is());

    uno::Reference<drawing::XShape> xShapeCenter(xGroupNested->getByIndex(0), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShapeA(xGroupNested->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShapeB(xGroupNested->getByIndex(2), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShapeC(xGroupNested->getByIndex(3), uno::UNO_QUERY);

    uno::Reference<text::XText> xTextCenter(xShapeCenter, uno::UNO_QUERY);
    CPPUNIT_ASSERT(xTextCenter.is());
    CPPUNIT_ASSERT_EQUAL(u"center"_ustr, xTextCenter->getString());

    CPPUNIT_ASSERT_LESS(xShapeCenter->getPosition().Y, xShapeA->getPosition().Y);
    CPPUNIT_ASSERT_GREATER(xShapeCenter->getPosition().X, xShapeB->getPosition().X);
    CPPUNIT_ASSERT_GREATER(xShapeCenter->getPosition().Y, xShapeB->getPosition().Y);
    CPPUNIT_ASSERT_LESS(xShapeCenter->getPosition().X, xShapeC->getPosition().X);
    CPPUNIT_ASSERT_GREATER(xShapeCenter->getPosition().Y, xShapeC->getPosition().Y);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testFontSize)
{
    createSdImpressDoc("pptx/smartart-font-size.pptx");

    uno::Reference<drawing::XShapes> xGroup1(getShapeFromPage(0, 0), uno::UNO_QUERY);
    uno::Reference<beans::XPropertySet> xShape1(xGroup1->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<text::XTextRange> xParagraph1(getParagraphFromShape(0, xShape1));
    uno::Reference<text::XTextRange> xRun1(getRunFromParagraph(0, xParagraph1));
    uno::Reference<beans::XPropertySet> xPropSet1(xRun1, uno::UNO_QUERY);
    double fFontSize1 = xPropSet1->getPropertyValue(u"CharHeight"_ustr).get<double>();
    CPPUNIT_ASSERT_DOUBLES_EQUAL(65.0, fFontSize1, 0.01);

    uno::Reference<drawing::XShapes> xGroup2(getShapeFromPage(1, 0), uno::UNO_QUERY);
    uno::Reference<beans::XPropertySet> xShape2(xGroup2->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<text::XTextRange> xParagraph2(getParagraphFromShape(0, xShape2));
    uno::Reference<text::XTextRange> xRun2(getRunFromParagraph(0, xParagraph2));
    uno::Reference<beans::XPropertySet> xPropSet2(xRun2, uno::UNO_QUERY);
    double fFontSize2 = xPropSet2->getPropertyValue(u"CharHeight"_ustr).get<double>();
    CPPUNIT_ASSERT_EQUAL(32.0, fFontSize2);

    uno::Reference<drawing::XShapes> xGroup3(getShapeFromPage(2, 0), uno::UNO_QUERY);
    uno::Reference<beans::XPropertySet> xShape3(xGroup3->getByIndex(1), uno::UNO_QUERY);
    drawing::TextFitToSizeType eTextFitToSize = drawing::TextFitToSizeType_NONE;
    xShape3->getPropertyValue(u"TextFitToSize"_ustr) >>= eTextFitToSize;
    CPPUNIT_ASSERT_EQUAL(drawing::TextFitToSizeType_AUTOFIT, eTextFitToSize);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testVerticalBlockList)
{
    createSdImpressDoc("pptx/smartart-vertical-block-list.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    uno::Reference<drawing::XShapes> xGroup1(xGroup->getByIndex(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xGroup1->getCount());
    uno::Reference<drawing::XShape> xShapeA(xGroup1->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShapeBC(xGroup1->getByIndex(0), uno::UNO_QUERY);
    uno::Reference<text::XText> xTextA(xShapeA, uno::UNO_QUERY);
    uno::Reference<text::XText> xTextBC(xShapeBC, uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xTextA->getString());
    CPPUNIT_ASSERT_EQUAL(u"b\nc"_ustr, xTextBC->getString());

    uno::Reference<beans::XPropertySet> xPropSetBC(xShapeBC, uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(27000),
                         xPropSetBC->getPropertyValue(u"RotateAngle"_ustr).get<sal_Int32>());

    // BC shape is rotated 90*, so width and height is swapped
    CPPUNIT_ASSERT_GREATER(xShapeA->getSize().Width, xShapeBC->getSize().Height);
    CPPUNIT_ASSERT_LESS(xShapeA->getSize().Height, xShapeBC->getSize().Width);
    CPPUNIT_ASSERT_GREATER(xShapeA->getPosition().X, xShapeBC->getPosition().X);
    CPPUNIT_ASSERT_GREATER(xShapeA->getPosition().Y, xShapeBC->getPosition().Y);

    uno::Reference<drawing::XShapes> xGroup3(xGroup->getByIndex(3), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xGroup3->getCount());
    uno::Reference<drawing::XShape> xShapeEmpty(xGroup3->getByIndex(0), uno::UNO_QUERY);
    uno::Reference<text::XText> xTextEmpty(xShapeEmpty, uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"empty"_ustr, xTextEmpty->getString());

    CPPUNIT_ASSERT_EQUAL(xShapeA->getSize().Width, xShapeEmpty->getSize().Width);
    CPPUNIT_ASSERT_EQUAL(xShapeA->getSize().Height, xShapeEmpty->getSize().Height);
    CPPUNIT_ASSERT_EQUAL(xShapeA->getPosition().X, xShapeEmpty->getPosition().X);
    CPPUNIT_ASSERT_GREATER(xShapeA->getPosition().Y + 2 * xShapeA->getSize().Height,
                           xShapeEmpty->getPosition().Y);

    uno::Reference<drawing::XShape> xGroupShape(xGroup, uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(xGroupShape->getPosition().Y + xGroupShape->getSize().Height,
                         xShapeEmpty->getPosition().Y + xShapeEmpty->getSize().Height);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testMissingBulletAndIndent)
{
    createSdImpressDoc("pptx/smartart-missing-bullet.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    uno::Reference<drawing::XShapes> xGroup1(xGroup->getByIndex(2), uno::UNO_QUERY);
    uno::Reference<drawing::XShapes> xGroup2(xGroup1->getByIndex(0), uno::UNO_QUERY);
    uno::Reference<text::XText> xText(xGroup2->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xText.is());

    uno::Reference<container::XEnumerationAccess> xParasAccess(xText, uno::UNO_QUERY);
    uno::Reference<container::XEnumeration> xParas = xParasAccess->createEnumeration();
    xParas->nextElement(); // skip parent

    uno::Reference<beans::XPropertySet> xPara1(xParas->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xPara1.is());

    sal_Int16 nNumberingLevel = -1;
    xPara1->getPropertyValue(u"NumberingLevel"_ustr) >>= nNumberingLevel;
    CPPUNIT_ASSERT_EQUAL(sal_Int16(1), nNumberingLevel);

    uno::Reference<container::XIndexAccess> xNumRule;
    xPara1->getPropertyValue(u"NumberingRules"_ustr) >>= xNumRule;
    uno::Sequence<beans::PropertyValue> aBulletProps;
    xNumRule->getByIndex(1) >>= aBulletProps;

    for (beans::PropertyValue const& rProp : aBulletProps)
    {
        if (rProp.Name == "LeftMargin")
            CPPUNIT_ASSERT_EQUAL(sal_Int32(309), rProp.Value.get<sal_Int32>());
    }
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testBulletList)
{
    createSdImpressDoc("pptx/smartart-bullet-list.pptx");
    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT(xGroup.is());

    uno::Reference<text::XText> xText(xGroup->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<container::XEnumerationAccess> xParasAccess(xText, uno::UNO_QUERY);
    uno::Reference<container::XEnumeration> xParas = xParasAccess->createEnumeration();
    xParas->nextElement(); // skip parent

    // child levels should have bullets
    uno::Reference<beans::XPropertySet> xPara1(xParas->nextElement(), uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xRules1(
        xPara1->getPropertyValue(u"NumberingRules"_ustr), uno::UNO_QUERY);
    comphelper::SequenceAsHashMap aRule1(xRules1->getByIndex(1));
    CPPUNIT_ASSERT_EQUAL(u"•"_ustr, aRule1[u"BulletChar"_ustr].get<OUString>());

    uno::Reference<beans::XPropertySet> xPara2(xParas->nextElement(), uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xRules2(
        xPara2->getPropertyValue(u"NumberingRules"_ustr), uno::UNO_QUERY);
    comphelper::SequenceAsHashMap aRule2(xRules2->getByIndex(2));
    CPPUNIT_ASSERT_EQUAL(u"•"_ustr, aRule2[u"BulletChar"_ustr].get<OUString>());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testRecursion)
{
    createSdImpressDoc("pptx/smartart-recursion.pptx");

    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    uno::Reference<drawing::XShapes> xGroup1(xGroup->getByIndex(1), uno::UNO_QUERY);

    uno::Reference<drawing::XShapes> xGroupA(xGroup1->getByIndex(0), uno::UNO_QUERY);
    uno::Reference<text::XText> xTextA(xGroupA->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"A"_ustr, xTextA->getString());

    uno::Reference<drawing::XShapes> xGroupB(xGroup1->getByIndex(1), uno::UNO_QUERY);
    // 5 connectors, B1 with children, B2 with children
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(7), xGroupB->getCount());

    uno::Reference<drawing::XShapes> xGroupB1(xGroupB->getByIndex(1), uno::UNO_QUERY);

    uno::Reference<drawing::XShapes> xGroupB1a(xGroupB1->getByIndex(0), uno::UNO_QUERY);
    uno::Reference<text::XText> xTextB1(xGroupB1a->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"B1"_ustr, xTextB1->getString());

    uno::Reference<drawing::XShape> xGroupC12(xGroupB1->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<text::XText> xTextC1(
        getChildShape(getChildShape(getChildShape(xGroupC12, 0), 0), 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"C1"_ustr, xTextC1->getString());
    uno::Reference<text::XText> xTextC2(
        getChildShape(getChildShape(getChildShape(xGroupC12, 1), 0), 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"C2"_ustr, xTextC2->getString());

    uno::Reference<drawing::XShapes> xGroupB2(xGroupB->getByIndex(5), uno::UNO_QUERY);

    uno::Reference<drawing::XShapes> xGroupB2a(xGroupB2->getByIndex(0), uno::UNO_QUERY);
    uno::Reference<text::XText> xTextB2(xGroupB2a->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"B2"_ustr, xTextB2->getString());

    uno::Reference<drawing::XShape> xGroupC3(xGroupB2->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<text::XText> xTextC3(
        getChildShape(getChildShape(getChildShape(xGroupC3, 0), 0), 0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"C3"_ustr, xTextC3->getString());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testDataFollow)
{
    // checks if data nodes are followed correctly
    // different variables are set for two presentation points with the same name
    // they should be layouted differently - one horizontally and one vertically

    createSdImpressDoc("pptx/smartart-data-follow.pptx");

    uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);

    uno::Reference<drawing::XShapes> xGroupLeft(xGroup->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xGroupB(xGroupLeft->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShapeB1
        = getChildShape(getChildShape(getChildShape(xGroupB, 1), 0), 0);
    uno::Reference<text::XText> xTextB1(xShapeB1, uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"B1"_ustr, xTextB1->getString());
    uno::Reference<drawing::XShape> xShapeB2
        = getChildShape(getChildShape(getChildShape(xGroupB, 3), 0), 0);
    uno::Reference<text::XText> xTextB2(xShapeB2, uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"B2"_ustr, xTextB2->getString());

    CPPUNIT_ASSERT_EQUAL(xShapeB1->getPosition().Y, xShapeB2->getPosition().Y);
    CPPUNIT_ASSERT_GREATEREQUAL(xShapeB1->getPosition().X + xShapeB1->getSize().Width,
                                xShapeB2->getPosition().X);

    uno::Reference<drawing::XShapes> xGroupRight(xGroup->getByIndex(2), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xGroupC(xGroupRight->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShapeC1
        = getChildShape(getChildShape(getChildShape(xGroupC, 3), 0), 0);
    uno::Reference<text::XText> xTextC1(xShapeC1, uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"C1"_ustr, xTextC1->getString());
    uno::Reference<drawing::XShape> xShapeC2
        = getChildShape(getChildShape(getChildShape(xGroupC, 5), 0), 0);
    uno::Reference<text::XText> xTextC2(xShapeC2, uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"C2"_ustr, xTextC2->getString());

    CPPUNIT_ASSERT_EQUAL(xShapeC1->getPosition().X, xShapeC2->getPosition().X);
    CPPUNIT_ASSERT_GREATEREQUAL(xShapeC1->getPosition().Y + xShapeC1->getSize().Height,
                                xShapeC2->getPosition().Y);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testOrgChart2)
{
    createSdImpressDoc("pptx/smartart-org-chart2.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);

    uno::Reference<drawing::XShape> xShapeC1 = findChildShapeByText(xGroup, u"C1"_ustr);
    uno::Reference<drawing::XShape> xShapeC2 = findChildShapeByText(xGroup, u"C2"_ustr);
    uno::Reference<drawing::XShape> xShapeC3 = findChildShapeByText(xGroup, u"C3"_ustr);
    uno::Reference<drawing::XShape> xShapeC4 = findChildShapeByText(xGroup, u"C4"_ustr);
    uno::Reference<drawing::XShape> xShapeD1 = findChildShapeByText(xGroup, u"D1"_ustr);
    uno::Reference<drawing::XShape> xShapeD2 = findChildShapeByText(xGroup, u"D2"_ustr);

    CPPUNIT_ASSERT(xShapeC1.is());
    CPPUNIT_ASSERT(xShapeC2.is());
    CPPUNIT_ASSERT(xShapeC3.is());
    CPPUNIT_ASSERT(xShapeC4.is());
    CPPUNIT_ASSERT(xShapeD1.is());
    CPPUNIT_ASSERT(xShapeD2.is());

    CPPUNIT_ASSERT_EQUAL(xShapeC1->getPosition().Y, xShapeC2->getPosition().Y);
    CPPUNIT_ASSERT_GREATEREQUAL(xShapeC1->getPosition().X + xShapeC1->getSize().Width,
                                xShapeC2->getPosition().X);

    CPPUNIT_ASSERT_EQUAL(xShapeC3->getPosition().X, xShapeC4->getPosition().X);
    CPPUNIT_ASSERT_GREATEREQUAL(xShapeC3->getPosition().Y + xShapeC3->getSize().Height,
                                xShapeC4->getPosition().Y);

    CPPUNIT_ASSERT_EQUAL(xShapeD1->getPosition().X, xShapeD2->getPosition().X);
    CPPUNIT_ASSERT_GREATEREQUAL(xShapeD1->getPosition().Y + xShapeD1->getSize().Height,
                                xShapeD2->getPosition().Y);

    CPPUNIT_ASSERT_GREATEREQUAL(xShapeC2->getPosition().X, xShapeD1->getPosition().X);
    CPPUNIT_ASSERT_GREATEREQUAL(xShapeC2->getPosition().Y + xShapeC2->getSize().Height,
                                xShapeD1->getPosition().Y);

    CPPUNIT_ASSERT_GREATEREQUAL(xShapeD1->getPosition().X + xShapeD1->getSize().Width,
                                xShapeC4->getPosition().X);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf131553)
{
    createSdImpressDoc("pptx/tdf131553.pptx");

    const SdrPage* pPage = GetPage(1);
    const SdrObjGroup* pObjGroup = dynamic_cast<SdrObjGroup*>(pPage->GetObj(0));
    CPPUNIT_ASSERT(pObjGroup);
    const SdrObject* pObj = pObjGroup->GetSubList()->GetObj(1);
    CPPUNIT_ASSERT_MESSAGE("no object", pObj != nullptr);
    CPPUNIT_ASSERT_EQUAL(SdrObjKind::OLE2, pObj->GetObjIdentifier());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testFillColorList)
{
    createSdImpressDoc("pptx/fill-color-list.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShape = getChildShape(getChildShape(xGroup, 1), 0);
    uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY_THROW);
    Color nFillColor;
    xPropertySet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 12603469 (0xc0504d)
    // - Actual  : 16225862 (0xf79646)
    // i.e. the background of the "A" shape was orange-ish, rather than red-ish.
    CPPUNIT_ASSERT_EQUAL(Color(0xC0504D), nFillColor);

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 2239
    // - Actual  : 5199
    // i.e. the "A" shape's height/width aspect ratio was not 0.4 but rather close to 1.0, even if
    // ppt/diagrams/layout1.xml's <dgm:constr type="h" refType="w" op="lte" fact="0.4"/> requested
    // 0.4.
    awt::Size aActualSize = xShape->getSize();
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2239), aActualSize.Height);

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected greater than: 1738 (2766)
    // - Actual  : 1738
    // i.e. the columns were not centered vertically.
    sal_Int32 nGroupTop = xGroup->getPosition().Y;
    sal_Int32 nShapeTop = xShape->getPosition().Y;
    CPPUNIT_ASSERT_GREATER(nGroupTop, nShapeTop);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf134221)
{
    createSdImpressDoc("pptx/smartart-tdf134221.pptx");
    saveAndReload(u"Impress Office Open XML"_ustr);
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShapeB = findChildShapeByText(xGroup, u"B"_ustr);
    CPPUNIT_ASSERT(xShapeB.is());
    uno::Reference<beans::XPropertySet> xTxtProps(xShapeB, uno::UNO_QUERY_THROW);

    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-248),
                         xTxtProps->getPropertyValue(u"TextUpperDistance"_ustr).get<sal_Int32>());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testLinearRule)
{
    createSdImpressDoc("pptx/smartart-linear-rule.pptx");

    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // Last child, then first child inside that.
    // It is first as backgroundArrow is last, but chOrder="t" is set to reverse the order.
    uno::Reference<drawing::XShape> xShape = getChildShape(getChildShape(xGroup, 1), 0);

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected greater than: 17500 (19867)
    // - Actual  : 4966
    // i.e. the width of the background arrow was too small.
    CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(17500), xShape->getSize().Width);

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 3160
    // - Actual  : 8770
    // i.e. there was unexpected spacing on the left of the arrow.
    // Then the imported version of the test document failed with:
    // - Expected: 3160
    // - Actual  : 19828
    // i.e. the spacing on the left of the arrow was so large that the shape was mostly outside the
    // slide.
    sal_Int32 nGroupLeft = xGroup->getPosition().X;
    sal_Int32 nArrowLeft = xShape->getPosition().X;
    CPPUNIT_ASSERT_EQUAL(nGroupLeft, nArrowLeft);

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected less or equal than: 10092
    // - Actual  : 20183
    // i.e. the arrow height was larger than the canvas given to the smartart on slide 1.
    CPPUNIT_ASSERT_LESSEQUAL(static_cast<sal_Int32>(10092), xShape->getSize().Height);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testLinearRuleVert)
{
    createSdImpressDoc("pptx/smartart-linear-rule-vert.pptx");

    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // Get the P1 shape.
    uno::Reference<drawing::XShape> xShape = getChildShape(getChildShape(xGroup, 1), 1);
    uno::Reference<text::XTextRange> xShapeText(xShape, uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(u"P1"_ustr, xShapeText->getString());

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 2020
    // - Actual  : 10308
    // i.e. the first item on the vertical linear layout used ~all space, the other items were not
    // visible.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2020), xShape->getSize().Height);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testAutofitSync)
{
    createSdImpressDoc("pptx/smartart-autofit-sync.pptx");

    uno::Reference<drawing::XShape> xDiagram(getShapeFromPage(0, 0), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xMiddle = getChildShape(xDiagram, 2);
    uno::Reference<beans::XPropertySet> xFirstInner(getChildShape(getChildShape(xMiddle, 0), 0),
                                                    uno::UNO_QUERY);
    double fFirstScale = 0;
    CPPUNIT_ASSERT(xFirstInner->getPropertyValue(u"TextFitToSizeFontScale"_ustr) >>= fFirstScale);
    CPPUNIT_ASSERT_GREATER(0.0, fFirstScale);
    CPPUNIT_ASSERT_LESS(100.0, fFirstScale);

    uno::Reference<beans::XPropertySet> xSecondInner(getChildShape(getChildShape(xMiddle, 2), 0),
                                                     uno::UNO_QUERY);
    double fSecondScale = 0;
    CPPUNIT_ASSERT(xSecondInner->getPropertyValue(u"TextFitToSizeFontScale"_ustr) >>= fSecondScale);

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 56
    // - Actual  : 100
    // i.e. the left shape had no scale-down and the right shape was scaled down, even if it was
    // requested that their scaling matches.
    CPPUNIT_ASSERT_EQUAL(fSecondScale, fFirstScale);

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 0 (drawing::TextFitToSizeType_NONE)
    // - Actual  : 3 (TextFitToSizeType_AUTOFIT)
    // i.e. the 3rd shape had font size as direct formatting, but its automatic text scale was not
    // disabled.
    uno::Reference<beans::XPropertySet> xThirdInner(getChildShape(getChildShape(xMiddle, 4), 0),
                                                    uno::UNO_QUERY);
    drawing::TextFitToSizeType eType{};
    CPPUNIT_ASSERT(xThirdInner->getPropertyValue(u"TextFitToSize"_ustr) >>= eType);
    CPPUNIT_ASSERT_EQUAL(drawing::TextFitToSizeType_NONE, eType);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testSnakeRows)
{
    // Load a smartart which contains a snake algorithm.
    // The expected layout of the 6 children is a 3x2 grid.
    createSdImpressDoc("pptx/smartart-snake-rows.pptx");

    uno::Reference<drawing::XShapes> xDiagram(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // Collect position of the background and the real child shapes. First row and background has
    // the same top position, unless some unexpected spacing happens, since this is a
    // "left-to-right, then top-to-bottom" snake direction.
    std::set<sal_Int32> aYPositions;
    for (sal_Int32 nChild = 0; nChild < xDiagram->getCount(); ++nChild)
    {
        uno::Reference<drawing::XShape> xChild(xDiagram->getByIndex(nChild), uno::UNO_QUERY);
        aYPositions.insert(xChild->getPosition().Y);
    }

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 2
    // - Actual  : 3
    // i.e. an unwanted row appeared.
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aYPositions.size());
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testCompositeInferRight)
{
    // Load a smartart which contains a composite algorithm.
    // One constraint says that the left of the text should be the right of the image.
    createSdImpressDoc("pptx/smartart-composite-infer-right.pptx");

    uno::Reference<drawing::XShape> xDiagram(getShapeFromPage(0, 0), uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xMiddle = getChildShape(xDiagram, 1);
    uno::Reference<drawing::XShape> xImage = getChildShape(xMiddle, 1);
    uno::Reference<drawing::XShape> xText = getChildShape(xMiddle, 2);
    sal_Int32 nRightOfImage = xImage->getPosition().X + xImage->getSize().Width;
    sal_Int32 nLeftOfText = xText->getPosition().X;

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected greater than: 7925
    // - Actual  : 2430
    // i.e. the text was overlapping with the image.
    CPPUNIT_ASSERT_GREATER(nRightOfImage, nLeftOfText);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf149551Pie)
{
    // The file contains a diagram of type "Basic Pie".
    createSdImpressDoc("pptx/tdf149551_SmartArt_Pie.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // shape at index 0 is the background shape
    uno::Reference<drawing::XShape> xShape = getChildShape(xGroup, 1);
    CPPUNIT_ASSERT(xShape.is());
    auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(SdrObject::getSdrObjectFromXShape(xShape));
    CPPUNIT_ASSERT(pCustomShape);
    tools::Rectangle aTextRect;
    pCustomShape->TakeTextAnchorRect(aTextRect);
    // without fix the text area rectangle had LT [7787,3420] and RB[16677,12312]. The values from
    // txXfrm were ignored.
    // The used tolerance is estimated.
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(12658), sal_Int32(aTextRect.Left()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(5073), sal_Int32(aTextRect.Top()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(15627), sal_Int32(aTextRect.Right()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(7990), sal_Int32(aTextRect.Bottom()), 4);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf149551Pyramid)
{
    // The file contains a diagram of type "Basic Pyramid".
    createSdImpressDoc("pptx/tdf149551_SmartArt_Pyramid.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // shape at index 0 is the background shape
    uno::Reference<drawing::XShape> xShape = getChildShape(xGroup, 1);
    CPPUNIT_ASSERT(xShape.is());
    auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(SdrObject::getSdrObjectFromXShape(xShape));
    CPPUNIT_ASSERT(pCustomShape);
    tools::Rectangle aTextRect;
    pCustomShape->TakeTextAnchorRect(aTextRect);
    // without fix the text area rectangle had LT [9369,2700] and RB[14632,6185]. The values from
    // txXfrm were ignored.
    // The used tolerance is estimated.
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(7591), sal_Int32(aTextRect.Left()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(1515), sal_Int32(aTextRect.Top()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(16410), sal_Int32(aTextRect.Right()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(7370), sal_Int32(aTextRect.Bottom()), 4);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf149551Venn)
{
    // The file contains a diagram of type "Stacked Venn".
    createSdImpressDoc("pptx/tdf149551_SmartArt_Venn.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // shape at index 0 is the background shape
    uno::Reference<drawing::XShape> xShape = getChildShape(xGroup, 1);
    CPPUNIT_ASSERT(xShape.is());
    auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(SdrObject::getSdrObjectFromXShape(xShape));
    CPPUNIT_ASSERT(pCustomShape);
    tools::Rectangle aTextRect;
    pCustomShape->TakeTextAnchorRect(aTextRect);
    // without fix the text area rectangle had LT [6865,3396] and RB[17136,4600]. The values from
    // txXfrm were ignored.
    // The used tolerance is estimated.
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(8772), sal_Int32(aTextRect.Left()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(1834), sal_Int32(aTextRect.Top()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(15229), sal_Int32(aTextRect.Right()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(6162), sal_Int32(aTextRect.Bottom()), 4);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf149551Gear)
{
    // The file contains a diagram of type "Gear".
    createSdImpressDoc("pptx/tdf149551_SmartArt_Gear.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // shape at index 0 is the background shape
    uno::Reference<drawing::XShape> xShape = getChildShape(xGroup, 1);
    CPPUNIT_ASSERT(xShape.is());
    auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(SdrObject::getSdrObjectFromXShape(xShape));
    CPPUNIT_ASSERT(pCustomShape);
    tools::Rectangle aTextRect;
    pCustomShape->TakeTextAnchorRect(aTextRect);
    // without fix the text area rectangle had LT [4101,1014] and RB[8019,4932]. The values from
    // txXfrm were ignored.
    // The used tolerance is estimated.
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(5501), sal_Int32(aTextRect.Left()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(4500), sal_Int32(aTextRect.Top()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(11000), sal_Int32(aTextRect.Right()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(9999), sal_Int32(aTextRect.Bottom()), 4);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf145528Matrix)
{
    // The file contains a diagram of type "Titled Matrix". Such is build from shapes of type
    // 'round1Rect'.
    createSdImpressDoc("pptx/tdf145528_SmartArt_Matrix.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // expected values
    sal_Int32 nLeft[]{ 4001, 12001, 12001, 18501 };
    sal_Int32 nTop[]{ 9999, 1999, 12499, 5999 };
    // nWidth = 10292, nHeight = 4499
    // Without the fix in place the values were
    // nLeft {2001, 12001, 12001, 22001}
    // nTop {7999. 1999, 13999, 7999}
    // nWidth {6000, 10000, 10000, 6000}
    // nHeight {10000, 6000, 6000, 10000}
    tools::Rectangle aTextRect;
    for (auto i : { 1, 2, 3, 4 }) // shape at index 0 is the background shape
    {
        uno::Reference<drawing::XShape> xShape = getChildShape(xGroup, i);
        CPPUNIT_ASSERT(xShape.is());
        auto pCustomShape
            = dynamic_cast<SdrObjCustomShape*>(SdrObject::getSdrObjectFromXShape(xShape));
        CPPUNIT_ASSERT(pCustomShape);
        pCustomShape->TakeTextAnchorRect(aTextRect);
        CPPUNIT_ASSERT_DOUBLES_EQUAL(nLeft[i - 1], sal_Int32(aTextRect.Left()), 4);
        CPPUNIT_ASSERT_DOUBLES_EQUAL(nTop[i - 1], sal_Int32(aTextRect.Top()), 4);
        CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(10293), sal_Int32(aTextRect.GetWidth()), 4);
        CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(4500), sal_Int32(aTextRect.GetHeight()), 4);
    }
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf135953TextPosition)
{
    // The file contains a diagram of type "Detailed Process". There the text area rectangle
    // is at the left edge of the shape and rotated there.
    createSdImpressDoc("pptx/tdf135953_SmartArt_textposition.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // shape at index 0 is the background shape
    uno::Reference<drawing::XShape> xShape = getChildShape(xGroup, 1);
    CPPUNIT_ASSERT(xShape.is());
    auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(SdrObject::getSdrObjectFromXShape(xShape));
    CPPUNIT_ASSERT(pCustomShape);
    tools::Rectangle aTextRect;
    pCustomShape->TakeTextAnchorRect(aTextRect);
    // without fix the text area rectangle had LT[-2213,2336] and RB[4123,4575]. It was not
    // considered that the txXfrm and the preset text area rectangle have different centers in this
    // case and thus the text was far off.
    // The used tolerance is estimated.
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(3223), sal_Int32(aTextRect.Left()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(-1661), sal_Int32(aTextRect.Top()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(9559), sal_Int32(aTextRect.Right()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(578), sal_Int32(aTextRect.Bottom()), 4);
}

CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testTdf132302RightArrow)
{
    // The file contains a diagram of type "Process Arrows". It uses shapes of type "rightArrow".
    // The text starts not at the left edge but in the middle to have space for a circle. Error was
    // that the text starts left and so was hidden by the circle.
    createSdImpressDoc("pptx/tdf132302_SmartArt_rightArrow.pptx");
    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
    // shape at index 0 is the background shape
    uno::Reference<drawing::XShape> xShape = getChildShape(xGroup, 1);
    CPPUNIT_ASSERT(xShape.is());
    auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(SdrObject::getSdrObjectFromXShape(xShape));
    CPPUNIT_ASSERT(pCustomShape);
    tools::Rectangle aTextRect;
    pCustomShape->TakeTextAnchorRect(aTextRect);
    // without fix the text area rectangle had LT[2790,59] and RB[11591,7940]. Position and size
    // given in txXfrm in drawing.xml were not considered.
    // The used tolerance is estimated.
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(5078), sal_Int32(aTextRect.Left()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(58), sal_Int32(aTextRect.Top()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(11989), sal_Int32(aTextRect.Right()), 4);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(7940), sal_Int32(aTextRect.Bottom()), 4);
}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5 in Prozent
C=86 H=91 G=88

¤ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet am  2026-05-07) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge