[Libreoffice-commits] core.git: Branch 'libreoffice-7-0' - oox/source sd/qa

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Wed Aug 5 09:26:20 UTC 2020


 oox/source/drawingml/diagram/diagram.cxx            |   20 +++++
 oox/source/drawingml/diagram/diagramlayoutatoms.cxx |   72 ++++++++++++++++++--
 oox/source/drawingml/diagram/layoutatomvisitors.cxx |    6 -
 sd/qa/unit/data/pptx/smartart-linear-rule.pptx      |binary
 sd/qa/unit/import-tests-smartart.cxx                |   19 +++++
 5 files changed, 106 insertions(+), 11 deletions(-)

New commits:
commit 84a3c0a924dd074c2c3255739e037f475b7238a5
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jul 31 11:04:02 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Aug 5 11:25:42 2020 +0200

    oox smartart: consider rules when scaling in linear layout
    
    The bugdoc has an arrow shape which is 100% wide, and there are multiple
    shapes before it, which also have a 100% wide constraint. The reason
    PowerPoint scales down the shapes (but not the arrow) is because rules
    declare it should happen this way.
    
    So start taking rules into account in linear layouts.
    
    (cherry picked from commit 0024c48b4822062995effed7db4f1281196384bb)
    Change-Id: I352443277e88be0eb711659489587127727a258f
    
    Conflicts:
            sd/qa/unit/import-tests-smartart.cxx
    
    Change-Id: I352443277e88be0eb711659489587127727a258f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100102
    Tested-by: Jenkins
    Reviewed-by: Gülşah Köse <gulsah.kose at collabora.com>

diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index 5a4fef99cfcb..8265ae7b3a88 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -82,6 +82,25 @@ static void sortChildrenByZOrder(const ShapePtr& pShape)
         sortChildrenByZOrder(rChild);
 }
 
+/// Removes empty group shapes, now that their spacing influenced the layout.
+static void removeUnneededGroupShapes(const ShapePtr& pShape)
+{
+    std::vector<ShapePtr>& rChildren = pShape->getChildren();
+
+    rChildren.erase(std::remove_if(rChildren.begin(), rChildren.end(),
+                                   [](const ShapePtr& aChild) {
+                                       return aChild->getServiceName()
+                                                  == "com.sun.star.drawing.GroupShape"
+                                              && aChild->getChildren().empty();
+                                   }),
+                    rChildren.end());
+
+    for (const auto& pChild : rChildren)
+    {
+        removeUnneededGroupShapes(pChild);
+    }
+}
+
 void Diagram::addTo( const ShapePtr & pParentShape )
 {
     if (pParentShape->getSize().Width == 0 || pParentShape->getSize().Height == 0)
@@ -103,6 +122,7 @@ void Diagram::addTo( const ShapePtr & pParentShape )
         mpLayout->getNode()->accept(aLayoutingVisitor);
 
         sortChildrenByZOrder(pParentShape);
+        removeUnneededGroupShapes(pParentShape);
     }
 
     ShapePtr pBackground = std::make_shared<Shape>("com.sun.star.drawing.CustomShape");
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 73f97c0b21cf..42508f5984de 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -19,6 +19,8 @@
 
 #include "diagramlayoutatoms.hxx"
 
+#include <set>
+
 #include "layoutatomvisitorbase.hxx"
 
 #include <basegfx/numeric/ftools.hxx>
@@ -478,10 +480,21 @@ void ApplyConstraintToLayout(const Constraint& rConstraint, LayoutPropertyMap& r
 }
 }
 
-void AlgAtom::layoutShape( const ShapePtr& rShape,
-                           const std::vector<Constraint>& rConstraints,
-                           const std::vector<Rule>& /*rRules*/ )
+void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>& rConstraints,
+                          const std::vector<Rule>& rRules)
 {
+    if (mnType != XML_lin)
+    {
+        // TODO Handle spacing from constraints for non-lin algorithms as well.
+        rShape->getChildren().erase(
+            std::remove_if(rShape->getChildren().begin(), rShape->getChildren().end(),
+                           [](const ShapePtr& aChild) {
+                               return aChild->getServiceName() == "com.sun.star.drawing.GroupShape"
+                                      && aChild->getChildren().empty();
+                           }),
+            rShape->getChildren().end());
+    }
+
     switch(mnType)
     {
         case XML_composite:
@@ -928,6 +941,45 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
             }
 
             // first approximation of children size
+            std::set<OUString> aChildrenToShrink;
+            for (const auto& rRule : rRules)
+            {
+                // Consider rules: when scaling down, only change children where the rule allows
+                // doing so.
+                aChildrenToShrink.insert(rRule.msForName);
+            }
+
+            if (!aChildrenToShrink.empty())
+            {
+                // Have scaling info from rules: then only count scaled children.
+                for (auto& aCurrShape : rShape->getChildren())
+                {
+                    if (aChildrenToShrink.find(aCurrShape->getInternalName())
+                        == aChildrenToShrink.end())
+                    {
+                        if (nCount > 1)
+                        {
+                            --nCount;
+                        }
+                    }
+                }
+
+                // No manual spacing: spacings are children as well.
+                aSpaceSize = awt::Size();
+            }
+            else
+            {
+                // TODO Handle spacing from constraints without rules as well.
+                rShape->getChildren().erase(
+                    std::remove_if(rShape->getChildren().begin(), rShape->getChildren().end(),
+                                   [](const ShapePtr& aChild) {
+                                       return aChild->getServiceName()
+                                                  == "com.sun.star.drawing.GroupShape"
+                                              && aChild->getChildren().empty();
+                                   }),
+                    rShape->getChildren().end());
+                nCount = rShape->getChildren().size();
+            }
             awt::Size aChildSize = rShape->getSize();
             if (nDir == XML_fromL || nDir == XML_fromR)
                 aChildSize.Width /= nCount;
@@ -979,8 +1031,18 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
                     aSize.Width = oWidth.get();
                 if (oHeight.has())
                     aSize.Height = oHeight.get();
-                aSize.Width *= fWidthScale;
-                aSize.Height *= fHeightScale;
+                if (aChildrenToShrink.empty()
+                    || aChildrenToShrink.find(aCurrShape->getInternalName())
+                           != aChildrenToShrink.end())
+                {
+                    aSize.Width *= fWidthScale;
+                }
+                if (aChildrenToShrink.empty()
+                    || aChildrenToShrink.find(aCurrShape->getInternalName())
+                           != aChildrenToShrink.end())
+                {
+                    aSize.Height *= fHeightScale;
+                }
                 aCurrShape->setSize(aSize);
                 aCurrShape->setChildSize(aSize);
 
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index 6b064e28b39b..5d31fd21cc71 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -123,12 +123,6 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
     meLookFor = LAYOUT_NODE;
     defaultVisit(rAtom);
 
-    // remove unneeded empty group shapes
-    pCurrParent->getChildren().erase(
-        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());
-
     meLookFor = ALGORITHM;
     defaultVisit(rAtom);
     meLookFor = LAYOUT_NODE;
diff --git a/sd/qa/unit/data/pptx/smartart-linear-rule.pptx b/sd/qa/unit/data/pptx/smartart-linear-rule.pptx
new file mode 100644
index 000000000000..f5fbb5c87a54
Binary files /dev/null and b/sd/qa/unit/data/pptx/smartart-linear-rule.pptx differ
diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx
index f08b60c30193..84d6450b0df7 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -109,6 +109,7 @@ public:
     void testOrgChart2();
     void testTdf131553();
     void testFillColorList();
+    void testLinearRule();
 
     CPPUNIT_TEST_SUITE(SdImportTestSmartArt);
 
@@ -155,6 +156,7 @@ public:
     CPPUNIT_TEST(testOrgChart2);
     CPPUNIT_TEST(testTdf131553);
     CPPUNIT_TEST(testFillColorList);
+    CPPUNIT_TEST(testLinearRule);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -1509,6 +1511,23 @@ void SdImportTestSmartArt::testFillColorList()
     xDocShRef->DoClose();
 }
 
+void SdImportTestSmartArt::testLinearRule()
+{
+    sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/smartart-linear-rule.pptx"), PPTX);
+
+    uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY);
+    // Last child, then again last child.
+    uno::Reference<drawing::XShape> xShape = getChildShape(getChildShape(xGroup, 1), 3);
+
+    // 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);
+
+    xDocShRef->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTestSmartArt);
 
 CPPUNIT_PLUGIN_IMPLEMENT();


More information about the Libreoffice-commits mailing list