Kaydet (Commit) 2828e3c8 authored tarafından Grzegorz Araminowicz's avatar Grzegorz Araminowicz Kaydeden (comit) Miklos Vajna

SmartArt: sort shapes by Z order after layout algorithms

so that they are laid out in correct order

Change-Id: I82baa61311197880654d09f356decc666e6fa4c7
Reviewed-on: https://gerrit.libreoffice.org/73094
Tested-by: Jenkins
Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.com>
üst a65918c5
...@@ -138,6 +138,46 @@ static sal_Int32 calcDepth( const OUString& rNodeName, ...@@ -138,6 +138,46 @@ static sal_Int32 calcDepth( const OUString& rNodeName,
return 0; return 0;
} }
static void sortChildrenByZOrder(const ShapePtr& pShape)
{
std::vector<ShapePtr>& rChildren = pShape->getChildren();
// Offset the children from their default z-order stacking, if necessary.
for (size_t i = 0; i < rChildren.size(); ++i)
rChildren[i]->setZOrder(i);
for (size_t i = 0; i < rChildren.size(); ++i)
{
const ShapePtr& pChild = rChildren[i];
sal_Int32 nZOrderOff = pChild->getZOrderOff();
if (nZOrderOff <= 0)
continue;
// Increase my ZOrder by nZOrderOff.
pChild->setZOrder(pChild->getZOrder() + nZOrderOff);
pChild->setZOrderOff(0);
for (sal_Int32 j = 0; j < nZOrderOff; ++j)
{
size_t nIndex = i + j + 1;
if (nIndex >= rChildren.size())
break;
// Decrease the ZOrder of the next nZOrderOff elements by one.
const ShapePtr& pNext = rChildren[nIndex];
pNext->setZOrder(pNext->getZOrder() - 1);
}
}
// Now that the ZOrders are adjusted, sort the children.
std::sort(rChildren.begin(), rChildren.end(),
[](const ShapePtr& a, const ShapePtr& b) { return a->getZOrder() < b->getZOrder(); });
// Apply also for children.
for (auto& rChild : rChildren)
sortChildrenByZOrder(rChild);
}
void Diagram::build( ) void Diagram::build( )
{ {
// build name-object maps // build name-object maps
...@@ -318,6 +358,8 @@ void Diagram::addTo( const ShapePtr & pParentShape ) ...@@ -318,6 +358,8 @@ void Diagram::addTo( const ShapePtr & pParentShape )
// layout shapes - now all shapes are created // layout shapes - now all shapes are created
ShapeLayoutingVisitor aLayoutingVisitor; ShapeLayoutingVisitor aLayoutingVisitor;
mpLayout->getNode()->accept(aLayoutingVisitor); mpLayout->getNode()->accept(aLayoutingVisitor);
sortChildrenByZOrder(pParentShape);
} }
ShapePtr pBackground(new Shape("com.sun.star.drawing.CustomShape")); ShapePtr pBackground(new Shape("com.sun.star.drawing.CustomShape"));
......
...@@ -187,38 +187,6 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) ...@@ -187,38 +187,6 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
std::remove_if(pCurrParent->getChildren().begin(), pCurrParent->getChildren().end(), std::remove_if(pCurrParent->getChildren().begin(), pCurrParent->getChildren().end(),
[] (const ShapePtr & aChild) { return aChild->getServiceName() == "com.sun.star.drawing.GroupShape" && aChild->getChildren().empty(); }), [] (const ShapePtr & aChild) { return aChild->getServiceName() == "com.sun.star.drawing.GroupShape" && aChild->getChildren().empty(); }),
pCurrParent->getChildren().end()); pCurrParent->getChildren().end());
// Offset the children from their default z-order stacking, if necessary.
std::vector<ShapePtr>& rChildren = pCurrParent->getChildren();
for (size_t i = 0; i < rChildren.size(); ++i)
rChildren[i]->setZOrder(i);
for (size_t i = 0; i < rChildren.size(); ++i)
{
const ShapePtr& pChild = rChildren[i];
sal_Int32 nZOrderOff = pChild->getZOrderOff();
if (nZOrderOff <= 0)
continue;
// Increase my ZOrder by nZOrderOff.
pChild->setZOrder(pChild->getZOrder() + nZOrderOff);
pChild->setZOrderOff(0);
for (sal_Int32 j = 0; j < nZOrderOff; ++j)
{
size_t nIndex = i + j + 1;
if (nIndex >= rChildren.size())
break;
// Decrease the ZOrder of the next nZOrderOff elements by one.
const ShapePtr& pNext = rChildren[nIndex];
pNext->setZOrder(pNext->getZOrder() - 1);
}
}
// Now that the ZOrders are adjusted, sort the children.
std::sort(rChildren.begin(), rChildren.end(),
[](const ShapePtr& a, const ShapePtr& b) { return a->getZOrder() < b->getZOrder(); });
} }
void ShapeCreationVisitor::visit(ShapeAtom& /*rAtom*/) void ShapeCreationVisitor::visit(ShapeAtom& /*rAtom*/)
......
...@@ -77,6 +77,7 @@ public: ...@@ -77,6 +77,7 @@ public:
void testBackgroundDrawingmlFallback(); void testBackgroundDrawingmlFallback();
void testCenterCycle(); void testCenterCycle();
void testFontSize(); void testFontSize();
void testVerticalBlockList();
CPPUNIT_TEST_SUITE(SdImportTestSmartArt); CPPUNIT_TEST_SUITE(SdImportTestSmartArt);
...@@ -115,6 +116,7 @@ public: ...@@ -115,6 +116,7 @@ public:
CPPUNIT_TEST(testBackgroundDrawingmlFallback); CPPUNIT_TEST(testBackgroundDrawingmlFallback);
CPPUNIT_TEST(testCenterCycle); CPPUNIT_TEST(testCenterCycle);
CPPUNIT_TEST(testFontSize); CPPUNIT_TEST(testFontSize);
CPPUNIT_TEST(testVerticalBlockList);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
}; };
...@@ -1199,6 +1201,45 @@ void SdImportTestSmartArt::testFontSize() ...@@ -1199,6 +1201,45 @@ void SdImportTestSmartArt::testFontSize()
xDocShRef->DoClose(); xDocShRef->DoClose();
} }
void SdImportTestSmartArt::testVerticalBlockList()
{
sd::DrawDocShellRef xDocShRef = loadURL(
m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/smartart-vertical-block-list.pptx"), PPTX);
uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0, xDocShRef), 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(OUString("a"), xTextA->getString());
CPPUNIT_ASSERT_EQUAL(OUString("b\nc"), xTextBC->getString());
uno::Reference<beans::XPropertySet> xPropSetBC(xShapeBC, uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(27000), xPropSetBC->getPropertyValue("RotateAngle").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_LESSEQUAL(xShapeA->getSize().Height, xShapeBC->getSize().Width);
CPPUNIT_ASSERT_GREATER(xShapeA->getPosition().X, xShapeBC->getPosition().X);
CPPUNIT_ASSERT_GREATEREQUAL(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(OUString("empty"), 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_GREATEREQUAL(xShapeA->getPosition().Y + 2*xShapeA->getSize().Height, xShapeEmpty->getPosition().Y);
xDocShRef->DoClose();
}
CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTestSmartArt); CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTestSmartArt);
CPPUNIT_PLUGIN_IMPLEMENT(); CPPUNIT_PLUGIN_IMPLEMENT();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment