summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-09-11 17:30:27 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-09-15 17:21:51 +0200
commit6a6a8f25f8c75f1220b66c4071d1739ced7c80b4 (patch)
tree70b76d0d42d0de7eac26c8180914f0c00ec5889c /oox
parent3e8cce134c92690da1955953da118d45f1c5ddde (diff)
oox smartart: add support for syncing font heights of multiple shapes
When 2 or more shapes have their text set to autofit and they have a constraint like: <dgm:constr type="primFontSz" for="des" forName="node" op="equ"/> Then make sure that the automatic font size is the same for all shapes and all content fits, by using the smallest scaling factor from all relevant shapes. Some rework is needed, because normally oox::drawingml::Shapes don't have access to their parents, at the same time there can be multiple SmartArts on a single slide, so storing the grouping info in the filter is problematic, too. Solve this by storing the grouping in the toplevel oox::drawingml::Shape and exposing them in XmlFilterBase just during the time the children of the toplevel shape of the SmartArt are added. This works, because we know SmartArts can't be nested. (cherry picked from commit 1bd3474c7c7945e1182dfbaca89be05ea98dd3e8) Conflicts: include/oox/core/xmlfilterbase.hxx oox/source/drawingml/diagram/diagram.cxx Change-Id: I6c591eadc7166c7c42752650afdb7ee1e416cff6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102726 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/core/xmlfilterbase.cxx8
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx9
-rw-r--r--oox/source/drawingml/diagram/diagram.hxx14
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.cxx26
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.hxx12
-rw-r--r--oox/source/drawingml/shape.cxx55
-rw-r--r--oox/source/ppt/pptshape.cxx13
7 files changed, 126 insertions, 11 deletions
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index 2cc1daa54b04..fe449dd70909 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -180,6 +180,7 @@ struct XmlFilterBaseImpl
RelationsMap maRelationsMap;
TextFieldStack maTextFieldStack;
const NamespaceMap& mrNamespaceMap;
+ NamedShapePairs* mpDiagramFontHeights = nullptr;
/// @throws RuntimeException
explicit XmlFilterBaseImpl();
@@ -957,6 +958,13 @@ void XmlFilterBase::setMissingExtDrawing()
mbMissingExtDrawing = true;
}
+void XmlFilterBase::setDiagramFontHeights(NamedShapePairs* pDiagramFontHeights)
+{
+ mxImpl->mpDiagramFontHeights = pDiagramFontHeights;
+}
+
+NamedShapePairs* XmlFilterBase::getDiagramFontHeights() { return mxImpl->mpDiagramFontHeights; }
+
OUString XmlFilterBase::getNamespaceURL(sal_Int32 nNSID) const
{
auto itr = mxImpl->mrNamespaceMap.maTransitionalNamespaceMap.find(nNSID);
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index 509a1f845e25..21dea33204bc 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -135,6 +135,11 @@ void Diagram::addTo( const ShapePtr & pParentShape )
aChildren.insert(aChildren.begin(), pBackground);
}
+Diagram::Diagram(const ShapePtr& pShape)
+ : mpShape(pShape)
+{
+}
+
uno::Sequence<beans::PropertyValue> Diagram::getDomsAsPropertyValues() const
{
sal_Int32 length = maMainDomMap.size();
@@ -245,7 +250,7 @@ void loadDiagram( ShapePtr const & pShape,
const OUString& rColorStylePath,
const oox::core::Relations& rRelations )
{
- DiagramPtr pDiagram( new Diagram );
+ DiagramPtr pDiagram( new Diagram(pShape) );
DiagramDataPtr pData( new DiagramData() );
pDiagram->setData( pData );
@@ -365,7 +370,7 @@ void loadDiagram(ShapePtr const& pShape,
const uno::Reference<xml::dom::XDocument>& colorDom,
core::XmlFilterBase& rFilter)
{
- DiagramPtr pDiagram(new Diagram);
+ DiagramPtr pDiagram(new Diagram(pShape));
pDiagram->setData(pDiagramData);
diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx
index a674e248961e..5cf562d075fd 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -49,7 +49,10 @@ typedef std::map<const dgm::Point*, ShapePtr> PresPointShapeMap;
class DiagramLayout
{
public:
- DiagramLayout(const Diagram& rDgm) : mrDgm(rDgm) {}
+ DiagramLayout(Diagram& rDgm)
+ : mrDgm(rDgm)
+ {
+ }
void setDefStyle( const OUString & sDefStyle )
{ msDefStyle = sDefStyle; }
void setMinVer( const OUString & sMinVer )
@@ -60,8 +63,7 @@ public:
{ msTitle = sTitle; }
void setDesc( const OUString & sDesc )
{ msDesc = sDesc; }
- const Diagram& getDiagram() const
- { return mrDgm; }
+ Diagram& getDiagram() { return mrDgm; }
LayoutNodePtr & getNode()
{ return mpNode; }
const LayoutNodePtr & getNode() const
@@ -80,7 +82,7 @@ public:
{ return maPresPointShapeMap; }
private:
- const Diagram& mrDgm;
+ Diagram& mrDgm;
OUString msDefStyle;
OUString msMinVer;
OUString msUniqueId;
@@ -128,6 +130,7 @@ typedef std::map<OUString,DiagramColor> DiagramColorMap;
class Diagram
{
public:
+ explicit Diagram(const ShapePtr& pShape);
void setData( const DiagramDataPtr & pData )
{ mpData = pData; }
const DiagramDataPtr& getData() const
@@ -146,7 +149,10 @@ public:
void addTo( const ShapePtr & pShape );
css::uno::Sequence<css::beans::PropertyValue> getDomsAsPropertyValues() const;
+ ShapePtr getShape() { return mpShape; }
+
private:
+ ShapePtr mpShape;
DiagramDataPtr mpData;
DiagramLayoutPtr mpLayout;
DiagramQStyleMap maStyles;
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 44a66f819e98..6823e45b3043 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -217,7 +217,7 @@ namespace
* Takes the connection list from rLayoutNode, navigates from rFrom on an edge
* of type nType, using a direction determined by bSourceToDestination.
*/
-OUString navigate(const LayoutNode& rLayoutNode, sal_Int32 nType, const OUString& rFrom,
+OUString navigate(LayoutNode& rLayoutNode, sal_Int32 nType, const OUString& rFrom,
bool bSourceToDestination)
{
for (const auto& rConnection : rLayoutNode.getDiagram().getData()->getConnections())
@@ -649,6 +649,16 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
nVertMin = std::min(aPos.Y, nVertMin);
nVertMax = std::max(aPos.Y + aSize.Height, nVertMax);
+
+ NamedShapePairs& rDiagramFontHeights
+ = getLayoutNode().getDiagram().getShape()->getDiagramFontHeights();
+ auto it = rDiagramFontHeights.find(aCurrShape->getInternalName());
+ if (it != rDiagramFontHeights.end())
+ {
+ // Internal name matches: put drawingml::Shape to the relevant group, for
+ // syncronized font height handling.
+ it->second.insert({ aCurrShape, {} });
+ }
}
// See if all vertical space is used or we have to center the content.
@@ -943,6 +953,20 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
}
}
+ if (rConstraint.mnType == XML_primFontSz && rConstraint.mnFor == XML_des
+ && rConstraint.mnOperator == XML_equ)
+ {
+ NamedShapePairs& rDiagramFontHeights
+ = getLayoutNode().getDiagram().getShape()->getDiagramFontHeights();
+ auto it = rDiagramFontHeights.find(rConstraint.msForName);
+ if (it == rDiagramFontHeights.end())
+ {
+ // Start tracking all shapes with this internal name: they'll have the same
+ // font height.
+ rDiagramFontHeights[rConstraint.msForName] = {};
+ }
+ }
+
// TODO: get values from differently named constraints as well
if (rConstraint.msForName == "sp" || rConstraint.msForName == "space" || rConstraint.msForName == "sibTrans")
{
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index ab152bed0b70..7789007622dc 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -260,9 +260,13 @@ class LayoutNode
public:
typedef std::map<sal_Int32, OUString> VarMap;
- LayoutNode(const Diagram& rDgm) : LayoutAtom(*this), mrDgm(rDgm), mnChildOrder(0) {}
- const Diagram& getDiagram() const
- { return mrDgm; }
+ LayoutNode(Diagram& rDgm)
+ : LayoutAtom(*this)
+ , mrDgm(rDgm)
+ , mnChildOrder(0)
+ {
+ }
+ Diagram& getDiagram() { return mrDgm; }
virtual void accept( LayoutAtomVisitor& ) override;
VarMap & variables()
{ return mVariables; }
@@ -289,7 +293,7 @@ public:
const LayoutNode* getParentLayoutNode() const;
private:
- const Diagram& mrDgm;
+ Diagram& mrDgm;
VarMap mVariables;
OUString msMoveWith;
OUString msStyleLabel;
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 2e100a41c309..84e59293b335 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -190,6 +190,7 @@ Shape::Shape( const ShapePtr& pSourceShape )
, mnDataNodeType(pSourceShape->mnDataNodeType)
, mfAspectRatio(pSourceShape->mfAspectRatio)
, mbUseBgFill(pSourceShape->mbUseBgFill)
+, maDiagramFontHeights(pSourceShape->maDiagramFontHeights)
{}
Shape::~Shape()
@@ -300,6 +301,22 @@ void Shape::addShape(
if( !SvtFilterOptions::Get().IsSmartArt2Shape() )
convertSmartArtToMetafile( rFilterBase );
}
+
+ NamedShapePairs* pNamedShapePairs = rFilterBase.getDiagramFontHeights();
+ if (xShape.is() && pNamedShapePairs)
+ {
+ auto itPairs = pNamedShapePairs->find(getInternalName());
+ if (itPairs != pNamedShapePairs->end())
+ {
+ auto it = itPairs->second.find(shared_from_this());
+ if (it != itPairs->second.end())
+ {
+ // Our drawingml::Shape is in the list of an internal name, remember the now
+ // inserted XShape.
+ it->second = xShape;
+ }
+ }
+ }
}
}
catch( const Exception& )
@@ -1528,6 +1545,44 @@ void Shape::keepDiagramCompatibilityInfo()
}
}
+void Shape::syncDiagramFontHeights()
+{
+ // Each name represents a group of shapes, for which the font height should have the same
+ // scaling.
+ for (const auto& rNameAndPairs : maDiagramFontHeights)
+ {
+ // Find out the minimum scale within this group.
+ const ShapePairs& rShapePairs = rNameAndPairs.second;
+ sal_Int16 nMinScale = 100;
+ for (const auto& rShapePair : rShapePairs)
+ {
+ uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ sal_Int16 nTextFitToSizeScale = 0;
+ xPropertySet->getPropertyValue("TextFitToSizeScale") >>= nTextFitToSizeScale;
+ if (nTextFitToSizeScale > 0 && nTextFitToSizeScale < nMinScale)
+ {
+ nMinScale = nTextFitToSizeScale;
+ }
+ }
+ }
+
+ // Set that minimum scale for all members of the group.
+ if (nMinScale < 100)
+ {
+ for (const auto& rShapePair : rShapePairs)
+ {
+ uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ xPropertySet->setPropertyValue("TextFitToSizeScale", uno::makeAny(nMinScale));
+ }
+ }
+ }
+ }
+}
+
void Shape::convertSmartArtToMetafile(XmlFilterBase const & rFilterBase)
{
try
diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx
index 88277219d0b0..71b94c727132 100644
--- a/oox/source/ppt/pptshape.cxx
+++ b/oox/source/ppt/pptshape.cxx
@@ -411,10 +411,23 @@ void PPTShape::addShape(
// if this is a group shape, we have to add also each child shape
Reference<XShapes> xShapes(xShape, UNO_QUERY);
if (xShapes.is())
+ {
+ if (meFrameType == FRAMETYPE_DIAGRAM)
+ {
+ rFilterBase.setDiagramFontHeights(&getDiagramFontHeights());
+ }
addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aTransformation );
+ if (meFrameType == FRAMETYPE_DIAGRAM)
+ {
+ rFilterBase.setDiagramFontHeights(nullptr);
+ }
+ }
if (meFrameType == FRAMETYPE_DIAGRAM)
+ {
keepDiagramCompatibilityInfo();
+ syncDiagramFontHeights();
+ }
}
}
catch (const Exception&)