Kaydet (Commit) 55e531de authored tarafından Grzegorz Araminowicz's avatar Grzegorz Araminowicz Kaydeden (comit) Miklos Vajna

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: 's avatarMiklos Vajna <vmiklos@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/73259
üst 83d10115
...@@ -788,7 +788,8 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, ...@@ -788,7 +788,8 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
const sal_Int32 nIncY = nDir==XML_fromT ? 1 : (nDir==XML_fromB ? -1 : 0); const sal_Int32 nIncY = nDir==XML_fromT ? 1 : (nDir==XML_fromB ? -1 : 0);
sal_Int32 nCount = rShape->getChildren().size(); sal_Int32 nCount = rShape->getChildren().size();
double fSpace = 0.3;
awt::Size aSpaceSize;
// Find out which constraint is relevant for which (internal) name. // Find out which constraint is relevant for which (internal) name.
LayoutPropertyMap aProperties; LayoutPropertyMap aProperties;
...@@ -800,17 +801,25 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, ...@@ -800,17 +801,25 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
LayoutProperty& rProperty = aProperties[rConstraint.msForName]; LayoutProperty& rProperty = aProperties[rConstraint.msForName];
if (rConstraint.mnType == XML_w) if (rConstraint.mnType == XML_w)
rProperty[XML_w] = rShape->getSize().Width * rConstraint.mfFactor; 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 // TODO: get values from differently named constraints as well
if (rConstraint.msForName == "sibTrans" && rConstraint.mnType == XML_w) if (rConstraint.msForName == "sp" || rConstraint.msForName == "space" || rConstraint.msForName == "sibTrans")
fSpace = rConstraint.mfFactor; {
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(); awt::Size aChildSize = rShape->getSize();
if (nDir == XML_fromL || nDir == XML_fromR) if (nDir == XML_fromL || nDir == XML_fromR)
aChildSize.Width /= (nCount + (nCount-1)*fSpace); aChildSize.Width /= nCount;
else if (nDir == XML_fromT || nDir == XML_fromB) else if (nDir == XML_fromT || nDir == XML_fromB)
aChildSize.Height /= (nCount + (nCount-1)*fSpace); aChildSize.Height /= nCount;
awt::Point aCurrPos(0, 0); awt::Point aCurrPos(0, 0);
if (nIncX == -1) if (nIncX == -1)
...@@ -820,51 +829,58 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, ...@@ -820,51 +829,58 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
// See if children requested more than 100% space in total: scale // See if children requested more than 100% space in total: scale
// down in that case. // down in that case.
sal_Int32 nTotalWidth = 0; awt::Size aTotalSize;
bool bSpaceFromConstraints = false;
for (auto & aCurrShape : rShape->getChildren()) for (auto & aCurrShape : rShape->getChildren())
{ {
oox::OptValue<sal_Int32> oWidth oox::OptValue<sal_Int32> oWidth = findProperty(aProperties, aCurrShape->getInternalName(), XML_w);
= findProperty(aProperties, aCurrShape->getInternalName(), XML_w); oox::OptValue<sal_Int32> oHeight = findProperty(aProperties, aCurrShape->getInternalName(), XML_h);
awt::Size aSize = aChildSize; awt::Size aSize = aChildSize;
if (oWidth.has()) if (oWidth.has())
{
aSize.Width = oWidth.get(); aSize.Width = oWidth.get();
bSpaceFromConstraints = true; if (oHeight.has())
} aSize.Height = oHeight.get();
if (nDir == XML_fromL || nDir == XML_fromR) aTotalSize.Width += aSize.Width;
nTotalWidth += aSize.Width; aTotalSize.Height += aSize.Height;
} }
double fWidthScale = 1.0; aTotalSize.Width += (nCount-1) * aSpaceSize.Width;
if (nTotalWidth > rShape->getSize().Width && nTotalWidth) aTotalSize.Height += (nCount-1) * aSpaceSize.Height;
{
fWidthScale = rShape->getSize().Width;
fWidthScale /= nTotalWidth;
}
// Don't add automatic space if we take space from constraints. double fWidthScale = 1.0;
if (bSpaceFromConstraints) double fHeightScale = 1.0;
fSpace = 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()) for (auto& aCurrShape : rShape->getChildren())
{ {
// Extract properties relevant for this shape from constraints. // Extract properties relevant for this shape from constraints.
oox::OptValue<sal_Int32> oWidth oox::OptValue<sal_Int32> oWidth = findProperty(aProperties, aCurrShape->getInternalName(), XML_w);
= findProperty(aProperties, aCurrShape->getInternalName(), XML_w); oox::OptValue<sal_Int32> oHeight = findProperty(aProperties, aCurrShape->getInternalName(), XML_h);
aCurrShape->setPosition(aCurrPos);
awt::Size aSize = aChildSize; awt::Size aSize = aChildSize;
if (oWidth.has()) if (oWidth.has())
aSize.Width = oWidth.get(); aSize.Width = oWidth.get();
if (oHeight.has())
aSize.Height = oHeight.get();
aSize.Width *= fWidthScale; aSize.Width *= fWidthScale;
aSize.Height *= fHeightScale;
aCurrShape->setSize(aSize); aCurrShape->setSize(aSize);
aCurrShape->setChildSize(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);
} }
break; break;
} }
......
...@@ -1054,9 +1054,9 @@ void SdImportTestSmartArt::testVerticalBlockList() ...@@ -1054,9 +1054,9 @@ void SdImportTestSmartArt::testVerticalBlockList()
// BC shape is rotated 90*, so width and height is swapped // BC shape is rotated 90*, so width and height is swapped
CPPUNIT_ASSERT_GREATER(xShapeA->getSize().Width, xShapeBC->getSize().Height); 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_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); uno::Reference<drawing::XShapes> xGroup3(xGroup->getByIndex(3), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xGroup3->getCount()); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xGroup3->getCount());
...@@ -1067,7 +1067,11 @@ void SdImportTestSmartArt::testVerticalBlockList() ...@@ -1067,7 +1067,11 @@ void SdImportTestSmartArt::testVerticalBlockList()
CPPUNIT_ASSERT_EQUAL(xShapeA->getSize().Width, xShapeEmpty->getSize().Width); CPPUNIT_ASSERT_EQUAL(xShapeA->getSize().Width, xShapeEmpty->getSize().Width);
CPPUNIT_ASSERT_EQUAL(xShapeA->getSize().Height, xShapeEmpty->getSize().Height); CPPUNIT_ASSERT_EQUAL(xShapeA->getSize().Height, xShapeEmpty->getSize().Height);
CPPUNIT_ASSERT_EQUAL(xShapeA->getPosition().X, xShapeEmpty->getPosition().X); 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(); xDocShRef->DoClose();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment