Kaydet (Commit) 279c7f83 authored tarafından Miklos Vajna's avatar Miklos Vajna

oox smartart, picture strip: fix lack of margin in text shapes

Shape text has two kind of spacing inside the shape's bounding box: the
shape-level margin and the paragraph-level one. Only the second was
handled in the tx algorithm so far, add support for the first.

The margins taken from constraints were way large by default: the only
explanation I found for that is that SmartArt layout sometimes
calculates in MMs, sometimes in Points, and the ratio between the two is
exactly the Impress / PowerPoint margin. So assume that indeed that unit
difference is the reason for the smaller in-PowerPoint margin values and
do the same on our side.

Change-Id: I6f1e54301e2e9b33a7e721be34244d968cccf42d
Reviewed-on: https://gerrit.libreoffice.org/68453Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
üst b436b039
......@@ -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
{
......
......@@ -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 ||
......
......@@ -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();
}
......
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