summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/oox/drawingml/drawingmltypes.hxx7
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.cxx58
-rw-r--r--sd/qa/unit/import-tests-smartart.cxx15
3 files changed, 77 insertions, 3 deletions
diff --git a/include/oox/drawingml/drawingmltypes.hxx b/include/oox/drawingml/drawingmltypes.hxx
index c4f05fcdd84e..2abe05767d6a 100644
--- a/include/oox/drawingml/drawingmltypes.hxx
+++ b/include/oox/drawingml/drawingmltypes.hxx
@@ -190,6 +190,13 @@ inline float convertEmuToPoints( sal_Int64 nValue )
return static_cast<float>(nValue) / EMU_PER_PT;
}
+/** Converts the passed double value from points to mm. */
+inline double convertPointToMms(double fValue)
+{
+ constexpr double fFactor = static_cast<double>(EMU_PER_PT) / (EMU_PER_HMM * 100);
+ return fValue * fFactor;
+}
+
/** A structure for a point with 64-bit integer components. */
struct EmuPoint
{
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 6893f04d63f7..7dc6e7622cb0 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -66,6 +66,24 @@ bool isFontUnit(sal_Int32 nUnit)
return nUnit == oox::XML_primFontSz || nUnit == oox::XML_secFontSz;
}
+/// Determines which UNO property should be set for a given constraint type.
+sal_Int32 getPropertyFromConstraint(sal_Int32 nConstraint)
+{
+ switch (nConstraint)
+ {
+ case oox::XML_lMarg:
+ return oox::PROP_TextLeftDistance;
+ case oox::XML_rMarg:
+ return oox::PROP_TextRightDistance;
+ case oox::XML_tMarg:
+ return oox::PROP_TextUpperDistance;
+ case oox::XML_bMarg:
+ return oox::PROP_TextLowerDistance;
+ }
+
+ return 0;
+}
+
/// Determines the connector shape type from a linear alg.
sal_Int32 getConnectorType(const oox::drawingml::LayoutNode* pNode)
{
@@ -446,9 +464,20 @@ void ConstraintAtom::accept( LayoutAtomVisitor& rVisitor )
void ConstraintAtom::parseConstraint(std::vector<Constraint>& rConstraints,
bool bRequireForName) const
{
- // The snake algorithm do want a space constraint even without a name.
- if (bRequireForName && maConstraint.mnType == XML_sp)
- bRequireForName = false;
+ // Whitelist for cases where empty forName is handled.
+ if (bRequireForName)
+ {
+ switch (maConstraint.mnType)
+ {
+ case XML_sp:
+ case XML_lMarg:
+ case XML_rMarg:
+ case XML_tMarg:
+ case XML_bMarg:
+ bRequireForName = false;
+ break;
+ }
+ }
if (bRequireForName && maConstraint.msForName.isEmpty())
return;
@@ -1065,6 +1094,29 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
case XML_tx:
{
// adjust text alignment
+
+ // Parse constraints, only self margins as a start.
+ for (const auto& rConstr : rConstraints)
+ {
+ if (rConstr.mnRefType == XML_w)
+ {
+ if (!rConstr.msForName.isEmpty())
+ continue;
+
+ sal_Int32 nProperty = getPropertyFromConstraint(rConstr.mnType);
+ if (!nProperty)
+ continue;
+
+ // PowerPoint takes size as points, but gives margin as MMs.
+ double fFactor = convertPointToMms(rConstr.mfFactor);
+
+ // DrawingML works in EMUs, UNO API works in MM100s.
+ sal_Int32 nValue = rShape->getSize().Width * fFactor / EMU_PER_HMM;
+
+ rShape->getShapeProperties().setProperty(nProperty, nValue);
+ }
+ }
+
// TODO: adjust text size to fit shape
TextBodyPtr pTextBody = rShape->getTextBody();
if (!pTextBody ||
diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx
index 3d30f576cce0..3a98496735ef 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -15,6 +15,7 @@
#include <com/sun/star/text/XText.hpp>
#include <comphelper/sequenceashashmap.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
using namespace ::com::sun::star;
@@ -965,6 +966,20 @@ void SdImportTestSmartArt::testPictureStrip()
CPPUNIT_ASSERT_GREATER(xTitle->getPosition().Y + xTitle->getSize().Height,
xGroup->getPosition().Y);
+ // Make sure that left margin is 60% of width (if you count width in points and margin in mms).
+ uno::Reference<beans::XPropertySet> xFirstText(getChildShape(getChildShape(xGroup, 0), 0),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xFirstText.is());
+ sal_Int32 nTextLeftDistance = 0;
+ xFirstText->getPropertyValue("TextLeftDistance") >>= nTextLeftDistance;
+ uno::Reference<drawing::XShape> xFirstTextShape(xFirstText, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xFirstTextShape.is());
+ sal_Int32 nWidth = xFirstTextShape->getSize().Width;
+ double fFactor = oox::drawingml::convertPointToMms(0.6);
+ // Without the accompanying fix in place, this test would have failed with 'Expected: 3440,
+ // Actual : 263', i.e. the left margin was too small.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(nWidth * fFactor), nTextLeftDistance);
+
xDocShRef->DoClose();
}