summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/oox/core/xmlfilterbase.hxx8
-rw-r--r--include/oox/drawingml/shape.hxx8
-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
-rw-r--r--sd/qa/unit/data/pptx/smartart-autofit-sync.pptxbin0 -> 45546 bytes
-rw-r--r--sd/qa/unit/import-tests-smartart.cxx30
11 files changed, 172 insertions, 11 deletions
diff --git a/include/oox/core/xmlfilterbase.hxx b/include/oox/core/xmlfilterbase.hxx
index 68bd801eaefd..cb8be7117fdf 100644
--- a/include/oox/core/xmlfilterbase.hxx
+++ b/include/oox/core/xmlfilterbase.hxx
@@ -65,6 +65,7 @@ namespace sax_fastparser {
namespace utl { class MediaDescriptor; }
namespace oox {
+namespace drawingml { class Shape; }
namespace core {
class FragmentHandler;
@@ -79,6 +80,10 @@ typedef std::vector< TextField > TextFieldStack;
struct XmlFilterBaseImpl;
+using ShapePairs
+ = std::map<std::shared_ptr<drawingml::Shape>, css::uno::Reference<css::drawing::XShape>>;
+using NamedShapePairs = std::map<OUString, ShapePairs>;
+
class OOX_DLLPUBLIC XmlFilterBase : public FilterBase
{
public:
@@ -242,6 +247,9 @@ public:
/// user about it.
void setMissingExtDrawing();
+ void setDiagramFontHeights(NamedShapePairs* pDiagramFontHeights);
+ NamedShapePairs* getDiagramFontHeights();
+
void checkDocumentProperties(
const css::uno::Reference<css::document::XDocumentProperties>& xDocProps);
diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index 1895c2f2aad6..5b6fd21ce00d 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -29,6 +29,8 @@
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Sequence.hxx>
+
+#include <oox/core/xmlfilterbase.hxx>
#include <oox/dllapi.h>
#include <oox/drawingml/color.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
@@ -239,6 +241,8 @@ public:
void keepDiagramDrawing(::oox::core::XmlFilterBase& rFilterBase, const OUString& rFragmentPath);
+ oox::core::NamedShapePairs& getDiagramFontHeights() { return maDiagramFontHeights; }
+
protected:
enum FrameType
@@ -272,6 +276,7 @@ protected:
const basegfx::B2DHomMatrix& aTransformation );
void keepDiagramCompatibilityInfo();
+ void syncDiagramFontHeights();
void convertSmartArtToMetafile( ::oox::core::XmlFilterBase const& rFilterBase );
css::uno::Reference< css::drawing::XShape >
@@ -377,6 +382,9 @@ private:
/// The shape fill should be set to that of the slide background surface.
bool mbUseBgFill = false;
+
+ /// For SmartArt, this contains groups of shapes: automatic font size is the same in each group.
+ oox::core::NamedShapePairs maDiagramFontHeights;
};
} }
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&)
diff --git a/sd/qa/unit/data/pptx/smartart-autofit-sync.pptx b/sd/qa/unit/data/pptx/smartart-autofit-sync.pptx
new file mode 100644
index 000000000000..f682c143f584
--- /dev/null
+++ b/sd/qa/unit/data/pptx/smartart-autofit-sync.pptx
Binary files differ
diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx
index 110b7d2c81ea..0d41e3094052 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -107,6 +107,7 @@ public:
void testOrgChart2();
void testFillColorList();
void testLinearRule();
+ void testAutofitSync();
CPPUNIT_TEST_SUITE(SdImportTestSmartArt);
@@ -153,6 +154,7 @@ public:
CPPUNIT_TEST(testOrgChart2);
CPPUNIT_TEST(testFillColorList);
CPPUNIT_TEST(testLinearRule);
+ CPPUNIT_TEST(testAutofitSync);
CPPUNIT_TEST_SUITE_END();
};
@@ -1530,6 +1532,34 @@ void SdImportTestSmartArt::testLinearRule()
xDocShRef->DoClose();
}
+void SdImportTestSmartArt::testAutofitSync()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(
+ m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/smartart-autofit-sync.pptx"), PPTX);
+
+ uno::Reference<drawing::XShape> xDiagram(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xMiddle = getChildShape(xDiagram, 2);
+ uno::Reference<beans::XPropertySet> xFirstInner(getChildShape(getChildShape(xMiddle, 0), 0),
+ uno::UNO_QUERY);
+ sal_Int16 nFirstScale = 0;
+ CPPUNIT_ASSERT(xFirstInner->getPropertyValue("TextFitToSizeScale") >>= nFirstScale);
+ CPPUNIT_ASSERT_GREATER(static_cast<sal_Int16>(0), nFirstScale);
+ uno::Reference<beans::XPropertySet> xSecondInner(getChildShape(getChildShape(xMiddle, 2), 0),
+ uno::UNO_QUERY);
+ sal_Int16 nSecondScale = 0;
+ CPPUNIT_ASSERT(xSecondInner->getPropertyValue("TextFitToSizeScale") >>= nSecondScale);
+ CPPUNIT_ASSERT_GREATER(static_cast<sal_Int16>(0), nSecondScale);
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 56
+ // - Actual : 100
+ // i.e. the left shape had no scale-down and the right shape was scaled down, even if it was
+ // requested that their scaling matches.
+ CPPUNIT_ASSERT_EQUAL(nSecondScale, nFirstScale);
+
+ xDocShRef->DoClose();
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTestSmartArt);
CPPUNIT_PLUGIN_IMPLEMENT();