summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Araminowicz <grzegorz.araminowicz@collabora.com>2019-05-28 13:36:59 +0200
committerMiklos Vajna <vmiklos@collabora.com>2019-06-03 09:48:49 +0200
commit8fce4133bd427351ac269c50e02e305d9eb34321 (patch)
tree7a7684187592c16c561e1c6e84470c4b650203fb
parent9b4cb15e41618fb1943c6c2cb150582dccc5c96c (diff)
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: Miklos Vajna <vmiklos@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/73255
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx42
-rw-r--r--oox/source/drawingml/diagram/layoutatomvisitors.cxx32
-rw-r--r--sd/qa/unit/data/pptx/smartart-vertical-block-list.pptxbin0 -> 47533 bytes
-rw-r--r--sd/qa/unit/import-tests-smartart.cxx41
4 files changed, 83 insertions, 32 deletions
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index 8efefe139dbf..be49c85d40aa 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -134,6 +134,46 @@ static sal_Int32 calcDepth( const OUString& rNodeName,
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( )
{
// build name-object maps
@@ -317,6 +357,8 @@ void Diagram::addTo( const ShapePtr & pParentShape )
// layout shapes - now all shapes are created
ShapeLayoutingVisitor aLayoutingVisitor;
mpLayout->getNode()->accept(aLayoutingVisitor);
+
+ sortChildrenByZOrder(pParentShape);
}
ShapePtr pBackground(new Shape("com.sun.star.drawing.CustomShape"));
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index a45317f9ffe4..602130b6b3e3 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -187,38 +187,6 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
std::remove_if(pCurrParent->getChildren().begin(), pCurrParent->getChildren().end(),
[] (const ShapePtr & aChild) { return aChild->getServiceName() == "com.sun.star.drawing.GroupShape" && aChild->getChildren().empty(); }),
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*/)
diff --git a/sd/qa/unit/data/pptx/smartart-vertical-block-list.pptx b/sd/qa/unit/data/pptx/smartart-vertical-block-list.pptx
new file mode 100644
index 000000000000..923f03c0ee23
--- /dev/null
+++ b/sd/qa/unit/data/pptx/smartart-vertical-block-list.pptx
Binary files differ
diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx
index 624205c5380a..ea83eb74a782 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -74,6 +74,7 @@ public:
void testBackground();
void testBackgroundDrawingmlFallback();
void testFontSize();
+ void testVerticalBlockList();
CPPUNIT_TEST_SUITE(SdImportTestSmartArt);
@@ -110,6 +111,7 @@ public:
CPPUNIT_TEST(testBackground);
CPPUNIT_TEST(testBackgroundDrawingmlFallback);
CPPUNIT_TEST(testFontSize);
+ CPPUNIT_TEST(testVerticalBlockList);
CPPUNIT_TEST_SUITE_END();
};
@@ -1031,6 +1033,45 @@ void SdImportTestSmartArt::testFontSize()
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_PLUGIN_IMPLEMENT();