[Libreoffice-commits] core.git: oox/source sd/qa

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Wed Sep 30 12:51:07 UTC 2020


 oox/source/drawingml/diagram/diagramlayoutatoms.cxx |   34 ++++++++++++++++----
 sd/qa/unit/import-tests-smartart.cxx                |    8 +---
 2 files changed, 31 insertions(+), 11 deletions(-)

New commits:
commit 71303c5c23bdb385e9f12c0dbe5d2a0818b836ec
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Sep 30 12:41:15 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Sep 30 14:50:23 2020 +0200

    oox smartart: snake algo: make sure child shape height stays within parent
    
    1) When applying double outside spacing, introduced with commit
    0a29c928afa74123bca05dc089c751603d368467 (oox smartart, picture strip:
    fix lack of spacing around the picture list, 2019-02-26), make sure that
    is only applied in the direction of a signle row: i.e. the bugdoc case
    is left/right outer spacing, but no top/bottom spacing.
    
    2) If a child shape has an aspect ratio request, make sure that it only
    decreases what would be allocated by default, so the children never
    leave the parent's rectangle.
    
    3) Fix a mis-match between the first and second row, the unexpected
    small left padding in the second row was because code assumed that all
    child shapes have the same width; which is not true, when widths come
    from constraints.
    
    With this in place, we finally do a good rendering of the bugdoc, and
    child shapes are always within the bounds of the background.
    
    Change-Id: Ia2606dcd945402f7dfe17c6e2f261bfd98667022
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103680
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index f4ca071976fa..d9d905066733 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -1384,12 +1384,13 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
             const sal_Int32 nDir = maMap.count(XML_grDir) ? maMap.find(XML_grDir)->second : XML_tL;
             sal_Int32 nIncX = 1;
             sal_Int32 nIncY = 1;
+            bool bHorizontal = true;
             switch (nDir)
             {
                 case XML_tL: nIncX =  1; nIncY =  1; break;
                 case XML_tR: nIncX = -1; nIncY =  1; break;
-                case XML_bL: nIncX =  1; nIncY = -1; break;
-                case XML_bR: nIncX = -1; nIncY = -1; break;
+                case XML_bL: nIncX =  1; nIncY = -1; bHorizontal = false; break;
+                case XML_bR: nIncX = -1; nIncY = -1; bHorizontal = false; break;
             }
 
             sal_Int32 nCount = rShape->getChildren().size();
@@ -1453,6 +1454,8 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
                                       static_cast<sal_Int32>(nHeight * fChildAspectRatio));
                     aChildSize = awt::Size(nWidth, nHeight);
                 }
+
+                bHorizontal = false;
             }
 
             awt::Point aCurrPos(0, 0);
@@ -1461,8 +1464,13 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
             if (nIncY == -1)
                 aCurrPos.Y = rShape->getSize().Height - aChildSize.Height;
             else if (bSpaceFromConstraints)
-                // Initial vertical offset to have upper spacing (outside, so double amount).
-                aCurrPos.Y = aChildSize.Height * fSpace * 2;
+            {
+                if (!bHorizontal)
+                {
+                    // Initial vertical offset to have upper spacing (outside, so double amount).
+                    aCurrPos.Y = aChildSize.Height * fSpace * 2;
+                }
+            }
 
             sal_Int32 nStartX = aCurrPos.X;
             sal_Int32 nColIdx = 0,index = 0;
@@ -1481,7 +1489,8 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
                     // aShapeWidths items are a portion of nMaxRowWidth. We want the same ratio,
                     // based on the original parent width, ignoring the aspect ratio request.
                     double fWidthFactor = static_cast<double>(aShapeWidths[index]) / nMaxRowWidth;
-                    if (nCount >= 2 && rShape->getChildren()[1]->getDataNodeType() == XML_sibTrans)
+                    bool bWidthsFromConstraints = nCount >= 2 && rShape->getChildren()[1]->getDataNodeType() == XML_sibTrans;
+                    if (bWidthsFromConstraints)
                     {
                         // We can only work from constraints if spacing is represented by a real
                         // child shape.
@@ -1490,6 +1499,9 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
                     if (fChildAspectRatio)
                     {
                         aCurrSize.Height = aCurrSize.Width / fChildAspectRatio;
+
+                        // Child shapes are not allowed to leave their parent.
+                        aCurrSize.Height = std::min<sal_Int32>(aCurrSize.Height, rShape->getSize().Height / (nRow + (nRow-1)*fSpace));
                     }
                     if (aCurrSize.Height > nRowHeight)
                     {
@@ -1507,8 +1519,18 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
                     {
                         // if last row, then position children according to number of shapes.
                         if((index+1)%nCol!=0 && (index+1)>=3 && ((index+1)/nCol+1)==nRow && nCount!=nRow*nCol)
+                        {
                             // position first child of last row
-                            aCurrPos.X = nStartX + (nIncX * (aCurrSize.Width + fSpace*aCurrSize.Width))/2;
+                            if (bWidthsFromConstraints)
+                            {
+                                aCurrPos.X = nStartX;
+                            }
+                            else
+                            {
+                                // Can assume that all child shape has the same width.
+                                aCurrPos.X = nStartX + (nIncX * (aCurrSize.Width + fSpace*aCurrSize.Width))/2;
+                            }
+                        }
                         else
                             // if not last row, positions first child of that row
                             aCurrPos.X = nStartX;
diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx
index 55cc20343e8e..f9ec7c430fb0 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -1615,14 +1615,12 @@ void SdImportTestSmartArt::testSnakeRows()
         m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/smartart-snake-rows.pptx"), PPTX);
 
     uno::Reference<drawing::XShapes> xDiagram(getShapeFromPage(0, 0, xDocShRef), 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)
     {
-        if (nChild == 0)
-        {
-            // Ignore background shape, we check how many rows actual children use.
-            continue;
-        }
         uno::Reference<drawing::XShape> xChild(xDiagram->getByIndex(nChild), uno::UNO_QUERY);
         aYPositions.insert(xChild->getPosition().Y);
     }


More information about the Libreoffice-commits mailing list