oox/source/drawingml/diagram/diagramlayoutatoms.cxx | 78 ++++++++++++-------- sd/qa/unit/import-tests-smartart.cxx | 10 +- 2 files changed, 54 insertions(+), 34 deletions(-)
New commits: commit 1b9344b95a685743d7b0e9bd831fea06d12df201 Author: Grzegorz Araminowicz <grzegorz.araminow...@collabora.com> AuthorDate: Thu May 30 13:29:08 2019 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri May 31 11:59:57 2019 +0200 SmartArt: more constraints used in linear algorithm * both width and height of children and space is taken from constraints * better handling of space between children (not lost in some cases) * children centered in the other axis Change-Id: I25b8360790de0292b2b5c313dfa55e58dc042193 Reviewed-on: https://gerrit.libreoffice.org/73201 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx index 1b1aadf77db7..4d0c18c27561 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -797,7 +797,6 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, const sal_Int32 nIncY = nDir==XML_fromT ? 1 : (nDir==XML_fromB ? -1 : 0); sal_Int32 nCount = rShape->getChildren().size(); - double fSpace = 0.3; sal_Int32 nConnectorAngle = 0; switch (nDir) { @@ -807,6 +806,8 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, case XML_fromB: nConnectorAngle = 90; break; } + awt::Size aSpaceSize; + // Find out which constraint is relevant for which (internal) name. LayoutPropertyMap aProperties; for (const auto& rConstraint : rConstraints) @@ -817,17 +818,25 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, LayoutProperty& rProperty = aProperties[rConstraint.msForName]; if (rConstraint.mnType == XML_w) rProperty[XML_w] = rShape->getSize().Width * rConstraint.mfFactor; + if (rConstraint.mnType == XML_h) + rProperty[XML_h] = rShape->getSize().Height * rConstraint.mfFactor; // TODO: get values from differently named constraints as well - if (rConstraint.msForName == "sibTrans" && rConstraint.mnType == XML_w) - fSpace = rConstraint.mfFactor; + if (rConstraint.msForName == "sp" || rConstraint.msForName == "space" || rConstraint.msForName == "sibTrans") + { + if (rConstraint.mnType == XML_w) + aSpaceSize.Width = rShape->getSize().Width * rConstraint.mfFactor; + if (rConstraint.mnType == XML_h) + aSpaceSize.Height = rShape->getSize().Height * rConstraint.mfFactor; + } } + // first approximation of children size awt::Size aChildSize = rShape->getSize(); if (nDir == XML_fromL || nDir == XML_fromR) - aChildSize.Width /= (nCount + (nCount-1)*fSpace); + aChildSize.Width /= nCount; else if (nDir == XML_fromT || nDir == XML_fromB) - aChildSize.Height /= (nCount + (nCount-1)*fSpace); + aChildSize.Height /= nCount; awt::Point aCurrPos(0, 0); if (nIncX == -1) @@ -837,51 +846,58 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, // See if children requested more than 100% space in total: scale // down in that case. - sal_Int32 nTotalWidth = 0; - bool bSpaceFromConstraints = false; + awt::Size aTotalSize; for (auto & aCurrShape : rShape->getChildren()) { - oox::OptValue<sal_Int32> oWidth - = findProperty(aProperties, aCurrShape->getInternalName(), XML_w); - + oox::OptValue<sal_Int32> oWidth = findProperty(aProperties, aCurrShape->getInternalName(), XML_w); + oox::OptValue<sal_Int32> oHeight = findProperty(aProperties, aCurrShape->getInternalName(), XML_h); awt::Size aSize = aChildSize; if (oWidth.has()) - { aSize.Width = oWidth.get(); - bSpaceFromConstraints = true; - } - if (nDir == XML_fromL || nDir == XML_fromR) - nTotalWidth += aSize.Width; + if (oHeight.has()) + aSize.Height = oHeight.get(); + aTotalSize.Width += aSize.Width; + aTotalSize.Height += aSize.Height; } - double fWidthScale = 1.0; - if (nTotalWidth > rShape->getSize().Width && nTotalWidth) - { - fWidthScale = rShape->getSize().Width; - fWidthScale /= nTotalWidth; - } + aTotalSize.Width += (nCount-1) * aSpaceSize.Width; + aTotalSize.Height += (nCount-1) * aSpaceSize.Height; - // Don't add automatic space if we take space from constraints. - if (bSpaceFromConstraints) - fSpace = 0; + double fWidthScale = 1.0; + double fHeightScale = 1.0; + if (nIncX && aTotalSize.Width > rShape->getSize().Width) + fWidthScale = static_cast<double>(rShape->getSize().Width) / aTotalSize.Width; + if (nIncY && aTotalSize.Height > rShape->getSize().Height) + fHeightScale = static_cast<double>(rShape->getSize().Height) / aTotalSize.Height; + aSpaceSize.Width *= fWidthScale; + aSpaceSize.Height *= fHeightScale; for (auto& aCurrShape : rShape->getChildren()) { // Extract properties relevant for this shape from constraints. - oox::OptValue<sal_Int32> oWidth - = findProperty(aProperties, aCurrShape->getInternalName(), XML_w); - - aCurrShape->setPosition(aCurrPos); + oox::OptValue<sal_Int32> oWidth = findProperty(aProperties, aCurrShape->getInternalName(), XML_w); + oox::OptValue<sal_Int32> oHeight = findProperty(aProperties, aCurrShape->getInternalName(), XML_h); awt::Size aSize = aChildSize; if (oWidth.has()) aSize.Width = oWidth.get(); + if (oHeight.has()) + aSize.Height = oHeight.get(); aSize.Width *= fWidthScale; + aSize.Height *= fHeightScale; aCurrShape->setSize(aSize); - aCurrShape->setChildSize(aSize); - aCurrPos.X += nIncX * (aSize.Width + fSpace*aSize.Width); - aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height); + + // center in the other axis - probably some parameter controls it + if (nIncX) + aCurrPos.Y = (rShape->getSize().Height - aSize.Height) / 2; + if (nIncY) + aCurrPos.X = (rShape->getSize().Width - aSize.Width) / 2; + + aCurrShape->setPosition(aCurrPos); + + aCurrPos.X += nIncX * (aSize.Width + aSpaceSize.Width); + aCurrPos.Y += nIncY * (aSize.Height + aSpaceSize.Height); // connectors should be handled in conn, but we don't have // reference to previous and next child, so it's easier here diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx index 0267961f70cf..722cb142fbfc 100644 --- a/sd/qa/unit/import-tests-smartart.cxx +++ b/sd/qa/unit/import-tests-smartart.cxx @@ -1222,9 +1222,9 @@ void SdImportTestSmartArt::testVerticalBlockList() // 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_LESS(xShapeA->getSize().Height, xShapeBC->getSize().Width); CPPUNIT_ASSERT_GREATER(xShapeA->getPosition().X, xShapeBC->getPosition().X); - CPPUNIT_ASSERT_GREATEREQUAL(xShapeA->getPosition().Y, xShapeBC->getPosition().Y); + CPPUNIT_ASSERT_GREATER(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()); @@ -1235,7 +1235,11 @@ void SdImportTestSmartArt::testVerticalBlockList() 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); + CPPUNIT_ASSERT_GREATER(xShapeA->getPosition().Y + 2*xShapeA->getSize().Height, xShapeEmpty->getPosition().Y); + + uno::Reference<drawing::XShape> xGroupShape(xGroup, uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(xGroupShape->getPosition().Y + xGroupShape->getSize().Height, + xShapeEmpty->getPosition().Y + xShapeEmpty->getSize().Height); xDocShRef->DoClose(); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits