File bsc1177955.diff of Package libreoffice

From 87386841d3d334656bf602d83cd7def37aaf7ba4 Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.com>
Date: Wed, 13 Jan 2021 15:10:48 +0100
Subject: [PATCH] bsc1177955.diff

This is a combination of 3 commits.
This is the 1st commit message:

oox smartart: extract pyra algo from AlgAtom::layoutShape()

AlgAtom::layoutShape() is more or less the single function where all
layouting happens for all algoritms. Extract the pyra algorithm part
from it to a separate PyraAlg::layoutShapeChildren() before that
function grows too large.

(cherry picked from commit 318438a680e6bf5c2c592d5e997f6f45a4ae8e5f)

This is the commit message #2:

loplugin:flatten

(cherry picked from commit 2d582244680e7f6dec6e4a466e276f93ccb01dc9)

This is the commit message #3:

oox smartart: composite algo: handle right constraint when left+width is given

The bugdoc had this constraint:

<dgm:constr type="l" for="ch" forName="text" refType="r" refFor="ch" refForName="img"/>

While img has no "r", it has:

<dgm:constr type="w" for="ch" forName="img" refType="w" refFor="ch" refForName="box" fact="0.2"/>
<dgm:constr type="l" for="ch" forName="img" refType="h" refFor="ch" refForName="box" fact="0.1"/>

Which is enough to fix the x position of the text to not overlap with
img.

(cherry picked from commit 1359e8c566970fcef860f7ba7f54a07d8e6e0513)

Change-Id: I80db290bd1695884ffb7b1eabaffa09462e8883d
---
 .../drawingml/diagram/diagramlayoutatoms.cxx  | 148 ++++++++++++------
 .../drawingml/diagram/diagramlayoutatoms.hxx  |  10 ++
 2 files changed, 108 insertions(+), 50 deletions(-)

diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 6a33148a7993..410b2c9e677e 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -440,6 +440,43 @@ void SnakeAlg::layoutShapeChildren(const AlgAtom::ParamMap& rMap, const ShapePtr
     }
 }
 
+void PyraAlg::layoutShapeChildren(const ShapePtr& rShape)
+{
+    if (rShape->getChildren().empty() || rShape->getSize().Width == 0
+        || rShape->getSize().Height == 0)
+        return;
+
+    // const sal_Int32 nDir = maMap.count(XML_linDir) ? maMap.find(XML_linDir)->second : XML_fromT;
+    // const sal_Int32 npyraAcctPos = maMap.count(XML_pyraAcctPos) ? maMap.find(XML_pyraAcctPos)->second : XML_bef;
+    // const sal_Int32 ntxDir = maMap.count(XML_txDir) ? maMap.find(XML_txDir)->second : XML_fromT;
+    // const sal_Int32 npyraLvlNode = maMap.count(XML_pyraLvlNode) ? maMap.find(XML_pyraLvlNode)->second : XML_level;
+    // uncomment when use in code.
+
+    sal_Int32 nCount = rShape->getChildren().size();
+    double fAspectRatio = 0.32;
+
+    awt::Size aChildSize = rShape->getSize();
+    aChildSize.Width /= nCount;
+    aChildSize.Height /= nCount;
+
+    awt::Point aCurrPos(0, 0);
+    aCurrPos.X = fAspectRatio * aChildSize.Width * (nCount - 1);
+    aCurrPos.Y = fAspectRatio * aChildSize.Height;
+
+    for (auto& aCurrShape : rShape->getChildren())
+    {
+        aCurrShape->setPosition(aCurrPos);
+        if (nCount > 1)
+        {
+            aCurrPos.X -= aChildSize.Height / (nCount - 1);
+        }
+        aChildSize.Width += aChildSize.Height;
+        aCurrShape->setSize(aChildSize);
+        aCurrShape->setChildSize(aChildSize);
+        aCurrPos.Y += (aChildSize.Height);
+    }
+}
+
 IteratorAttr::IteratorAttr( )
     : mnCnt( -1 )
     , mbHideLastTrans( true )
@@ -783,6 +820,37 @@ sal_Int32 AlgAtom::getVerticalShapesCount(const ShapePtr& rShape)
 
 namespace
 {
+/**
+ * Decides if a certain reference type (e.g. "right") can be inferred from the available properties
+ * in rMap (e.g. left and width). Returns true if rValue is written to.
+ */
+bool InferFromLayoutProperty(const LayoutProperty& rMap, sal_Int32 nRefType, sal_Int32& rValue)
+{
+    switch (nRefType)
+    {
+        case XML_r:
+        {
+            auto it = rMap.find(XML_l);
+            if (it == rMap.end())
+            {
+                return false;
+            }
+            sal_Int32 nLeft = it->second;
+            it = rMap.find(XML_w);
+            if (it == rMap.end())
+            {
+                return false;
+            }
+            rValue = nLeft + it->second;
+            return true;
+        }
+        default:
+            break;
+    }
+
+    return false;
+}
+
 /**
  * Apply rConstraint to the rProperties shared layout state.
  *
@@ -799,26 +867,37 @@ void ApplyConstraintToLayout(const Constraint& rConstraint, LayoutPropertyMap& r
     }
 
     const LayoutPropertyMap::const_iterator aRef = rProperties.find(rConstraint.msRefForName);
-    if (aRef != rProperties.end())
+    if (aRef == rProperties.end())
+        return;
+
+    const LayoutProperty::const_iterator aRefType = aRef->second.find(rConstraint.mnRefType);
+    sal_Int32 nInferredValue = 0;
+    if (aRefType != aRef->second.end())
+    {
+        // Reference is found directly.
+        rProperties[rConstraint.msForName][rConstraint.mnType]
+            = aRefType->second * rConstraint.mfFactor;
+    }
+    else if (InferFromLayoutProperty(aRef->second, rConstraint.mnRefType, nInferredValue))
     {
-        const LayoutProperty::const_iterator aRefType = aRef->second.find(rConstraint.mnRefType);
-        if (aRefType != aRef->second.end())
-            rProperties[rConstraint.msForName][rConstraint.mnType]
-                = aRefType->second * rConstraint.mfFactor;
+        // Reference can be inferred.
+        rProperties[rConstraint.msForName][rConstraint.mnType]
+            = nInferredValue * rConstraint.mfFactor;
+    }
+    else
+    {
+        // Reference not found, assume a fixed value.
+        // Values are never in EMU, while oox::drawingml::Shape position and size are always in
+        // EMU.
+        double fUnitFactor = 0;
+        if (isFontUnit(rConstraint.mnRefType))
+            // Points -> EMU.
+            fUnitFactor = EMU_PER_PT;
         else
-        {
-            // Values are never in EMU, while oox::drawingml::Shape position and size are always in
-            // EMU.
-            double fUnitFactor = 0;
-            if (isFontUnit(rConstraint.mnRefType))
-                // Points -> EMU.
-                fUnitFactor = EMU_PER_PT;
-            else
-                // Millimeters -> EMU.
-                fUnitFactor = EMU_PER_HMM * 100;
-            rProperties[rConstraint.msForName][rConstraint.mnType]
-                = rConstraint.mfValue * fUnitFactor;
-        }
+            // Millimeters -> EMU.
+            fUnitFactor = EMU_PER_HMM * 100;
+        rProperties[rConstraint.msForName][rConstraint.mnType]
+            = rConstraint.mfValue * fUnitFactor;
     }
 }
 
@@ -1594,38 +1673,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
 
         case XML_pyra:
         {
-            if (rShape->getChildren().empty() || rShape->getSize().Width == 0 || rShape->getSize().Height == 0)
-                break;
-
-            // const sal_Int32 nDir = maMap.count(XML_linDir) ? maMap.find(XML_linDir)->second : XML_fromT;
-            // const sal_Int32 npyraAcctPos = maMap.count(XML_pyraAcctPos) ? maMap.find(XML_pyraAcctPos)->second : XML_bef;
-            // const sal_Int32 ntxDir = maMap.count(XML_txDir) ? maMap.find(XML_txDir)->second : XML_fromT;
-            // const sal_Int32 npyraLvlNode = maMap.count(XML_pyraLvlNode) ? maMap.find(XML_pyraLvlNode)->second : XML_level;
-            // uncomment when use in code.
-
-            sal_Int32 nCount = rShape->getChildren().size();
-            double fAspectRatio = 0.32;
-
-            awt::Size aChildSize = rShape->getSize();
-            aChildSize.Width /= nCount;
-            aChildSize.Height /= nCount;
-
-            awt::Point aCurrPos(0, 0);
-            aCurrPos.X = fAspectRatio*aChildSize.Width*(nCount-1);
-            aCurrPos.Y = fAspectRatio*aChildSize.Height;
-
-            for (auto & aCurrShape : rShape->getChildren())
-            {
-                aCurrShape->setPosition(aCurrPos);
-                if (nCount > 1)
-                {
-                    aCurrPos.X -= aChildSize.Height / (nCount - 1);
-                }
-                aChildSize.Width += aChildSize.Height;
-                aCurrShape->setSize(aChildSize);
-                aCurrShape->setChildSize(aChildSize);
-                aCurrPos.Y += (aChildSize.Height);
-            }
+            PyraAlg::layoutShapeChildren(rShape);
             break;
         }
 
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index 571cca641d78..80f6b2d9bb0d 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -210,6 +210,16 @@ public:
                                     const std::vector<Constraint>& rConstraints);
 };
 
+/**
+ * Lays out child layout nodes along a vertical path and works with the trapezoid shape to create a
+ * pyramid.
+ */
+class PyraAlg
+{
+public:
+    static void layoutShapeChildren(const ShapePtr& rShape);
+};
+
 class ForEachAtom
     : public LayoutAtom
 {
-- 
2.26.2

openSUSE Build Service is sponsored by