Accepting request 648618 from LibreOffice:Factory

OBS-URL: https://build.opensuse.org/request/show/648618
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libreoffice?expand=0&rev=167
This commit is contained in:
Dominique Leuenberger 2018-11-13 15:31:33 +00:00 committed by Git OBS Bridge
commit 2379c12e8e
4 changed files with 965 additions and 3 deletions

275
bsc1110348.patch Normal file
View File

@ -0,0 +1,275 @@
From b77f4f69bb2f1d3ab740446799da2fd3db9094da Mon Sep 17 00:00:00 2001
From: Balazs Varga <balazs.varga991@gmail.com>
Date: Wed, 31 Oct 2018 08:43:47 +0100
Subject: [PATCH] tdf#108104 OOXML Import: Fix Hatch fill in Charts
Sets an explicit fill hatch, or creates a named fill hatch
and stored in a global container. With this patch the
SUPPORTED MS Office hatch styles by LibreOffice, or the custom
LibreOffice hatches will be appeared correctly instead of the
previous display as horizontal lines in LibreOffice.
(The background color of the hatch styles are not imported correcty,
but that is another BUG.)
Change-Id: Ifda9dc805dd08f58db10b35f40d7f511a8614f77
Reviewed-on: https://gerrit.libreoffice.org/62681
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Reviewed-on: https://gerrit.libreoffice.org/62891
Reviewed-by: Andras Timar <andras.timar@collabora.com>
---
diff --git a/include/oox/drawingml/shapepropertymap.hxx b/include/oox/drawingml/shapepropertymap.hxx
index 2fb237c..dd2d0d4 100644
--- a/include/oox/drawingml/shapepropertymap.hxx
+++ b/include/oox/drawingml/shapepropertymap.hxx
@@ -71,7 +71,7 @@
FillBitmapOffsetX,
FillBitmapOffsetY,
FillBitmapRectanglePoint,
- FillHatch,
+ FillHatch, /// Explicit fill hatch or name of a fill hatch stored in a global container.
ShadowXDistance,
FillBitmapName,
FillBackground,
@@ -87,12 +87,13 @@
bool mbNamedLineDash; /// True = use named line dash instead of explicit line dash.
bool mbNamedFillGradient; /// True = use named fill gradient instead of explicit fill gradient.
bool mbNamedFillBitmap; /// True = use named fill bitmap instead of explicit fill bitmap.
+ bool mbNamedFillHatch; /// True = use named fill hatch instead of explicit fill hatch.
static ShapePropertyInfo DEFAULT; /// Default property info (used as default parameter of other methods).
explicit ShapePropertyInfo(const ShapePropertyIds& rnPropertyIds,
bool bNamedLineMarker, bool bNamedLineDash,
- bool bNamedFillGradient, bool bNamedFillBitmap);
+ bool bNamedFillGradient, bool bNamedFillBitmap, bool bNamedFillHatch);
bool has(ShapeProperty ePropId) const
{
@@ -147,6 +148,8 @@
bool setFillBitmap( sal_Int32 nPropId, const css::uno::Any& rValue );
/** Sets an explicit fill bitmap and pushes the name to FillBitmapName */
bool setFillBitmapName( const css::uno::Any& rValue );
+ /** Sets an explicit fill hatch, or creates a named fill hatch. */
+ bool setFillHatch( sal_Int32 nPropId, const css::uno::Any& rValue );
// not implemented, to prevent implicit conversion from enum to int
css::uno::Any& operator[]( ShapeProperty ePropId ) = delete;
diff --git a/include/oox/helper/modelobjecthelper.hxx b/include/oox/helper/modelobjecthelper.hxx
index eb9c7ba..016b963 100644
--- a/include/oox/helper/modelobjecthelper.hxx
+++ b/include/oox/helper/modelobjecthelper.hxx
@@ -32,6 +32,7 @@
namespace graphic { class XGraphic; }
namespace container { class XNameContainer; }
namespace drawing { struct LineDash; }
+ namespace drawing { struct Hatch; }
namespace drawing { struct PolyPolygonBezierCoords; }
namespace lang { class XMultiServiceFactory; }
} } }
@@ -105,6 +106,8 @@
OUString insertTransGrandient( const css::awt::Gradient& rGradient );
+ OUString insertFillHatch( const css::drawing::Hatch& rHatch );
+
/** Inserts a new named fill graphic, returns the bitmap name, based on
an internal constant name with a new unused index appended. */
OUString insertFillBitmapXGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic);
@@ -117,10 +120,12 @@
ObjectContainer maGradientContainer; ///< Contains all named fill gradients.
ObjectContainer maTransGradContainer; ///< Contains all named transparency Gradients.
ObjectContainer maBitmapUrlContainer; ///< Contains all named fill bitmap URLs.
+ ObjectContainer maHatchContainer; ///< Contains all named fill hatches.
const OUString maDashNameBase; ///< Base name for all named line dashes.
const OUString maGradientNameBase; ///< Base name for all named fill gradients.
const OUString maTransGradNameBase; ///< Base name for all named fill gradients.
const OUString maBitmapUrlNameBase; ///< Base name for all named fill bitmap URLs.
+ const OUString maHatchNameBase; ///< Base name for all named fill hatch URLs.
};
diff --git a/oox/source/drawingml/chart/objectformatter.cxx b/oox/source/drawingml/chart/objectformatter.cxx
index 5b5f67b..2eaad42 100644
--- a/oox/source/drawingml/chart/objectformatter.cxx
+++ b/oox/source/drawingml/chart/objectformatter.cxx
@@ -449,7 +449,8 @@
PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_INVALID, PROP_FillGradientName,
PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY,
- PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint
+ PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint,
+ PROP_FillHatchName
};
static const ShapePropertyIds spnLinearPropIds =
@@ -458,7 +459,8 @@
PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
- PROP_INVALID, PROP_INVALID, PROP_INVALID
+ PROP_INVALID, PROP_INVALID, PROP_INVALID,
+ PROP_INVALID
};
static const ShapePropertyIds spnFilledPropIds =
@@ -487,15 +489,15 @@
PROP_FillBitmapPositionOffsetX,
PROP_FillBitmapPositionOffsetY,
PROP_FillBitmapRectanglePoint,
- PROP_FillHatch
+ PROP_HatchName
};
/** Property info for common chart objects, to be used in ShapePropertyMap. */
-static const ShapePropertyInfo saCommonPropInfo( spnCommonPropIds, false, true, true, true );
+static const ShapePropertyInfo saCommonPropInfo( spnCommonPropIds, false, true, true, true, true );
/** Property info for linear data series, to be used in ShapePropertyMap. */
-static const ShapePropertyInfo saLinearPropInfo( spnLinearPropIds, false, true, true, true );
+static const ShapePropertyInfo saLinearPropInfo( spnLinearPropIds, false, true, true, true, true );
/** Property info for filled data series, to be used in ShapePropertyMap. */
-static const ShapePropertyInfo saFilledPropInfo( spnFilledPropIds, false, true, true, true );
+static const ShapePropertyInfo saFilledPropInfo( spnFilledPropIds, false, true, true, true, true );
/** Contains information about formatting of a specific chart object type. */
struct ObjectTypeFormatEntry
diff --git a/oox/source/drawingml/shapepropertymap.cxx b/oox/source/drawingml/shapepropertymap.cxx
index fcb1549..b072403 100644
--- a/oox/source/drawingml/shapepropertymap.cxx
+++ b/oox/source/drawingml/shapepropertymap.cxx
@@ -22,6 +22,7 @@
#include <com/sun/star/awt/Gradient.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/Hatch.hpp>
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
@@ -53,15 +54,16 @@
} // namespace
-ShapePropertyInfo ShapePropertyInfo::DEFAULT( spnDefaultShapeIds, true, false, false, false );
+ShapePropertyInfo ShapePropertyInfo::DEFAULT( spnDefaultShapeIds, true, false, false, false, false );
ShapePropertyInfo::ShapePropertyInfo( const ShapePropertyIds& rnPropertyIds,
- bool bNamedLineMarker, bool bNamedLineDash, bool bNamedFillGradient, bool bNamedFillBitmap ) :
+ bool bNamedLineMarker, bool bNamedLineDash, bool bNamedFillGradient, bool bNamedFillBitmap, bool bNamedFillHatch ) :
mrPropertyIds(rnPropertyIds),
mbNamedLineMarker( bNamedLineMarker ),
mbNamedLineDash( bNamedLineDash ),
mbNamedFillGradient( bNamedFillGradient ),
- mbNamedFillBitmap( bNamedFillBitmap )
+ mbNamedFillBitmap( bNamedFillBitmap ),
+ mbNamedFillHatch( bNamedFillHatch )
{
}
@@ -108,6 +110,9 @@
case ShapeProperty::FillBitmapName:
return setFillBitmapName(rValue);
+
+ case ShapeProperty::FillHatch:
+ return setFillHatch( nPropId, rValue );
default:; // suppress compiler warnings
}
@@ -168,6 +173,22 @@
return false;
}
+bool ShapePropertyMap::setFillHatch( sal_Int32 nPropId, const Any& rValue )
+{
+ // push hatch explicitly
+ if( !maShapePropInfo.mbNamedFillHatch )
+ return setAnyProperty( nPropId, rValue );
+
+ // create named hatch and push its name
+ if( rValue.has< Hatch >() )
+ {
+ OUString aHatchName = mrModelObjHelper.insertFillHatch( rValue.get< Hatch >() );
+ return !aHatchName.isEmpty() && setProperty( nPropId, aHatchName );
+ }
+
+ return false;
+}
+
bool ShapePropertyMap::setGradientTrans( sal_Int32 nPropId, const Any& rValue )
{
// create named gradient and push its name
diff --git a/oox/source/helper/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx
index 4929dc2..02481e2 100644
--- a/oox/source/helper/modelobjecthelper.cxx
+++ b/oox/source/helper/modelobjecthelper.cxx
@@ -22,6 +22,7 @@
#include <com/sun/star/awt/Gradient.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/Hatch.hpp>
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
@@ -92,12 +93,14 @@
maMarkerContainer( rxModelFactory, "com.sun.star.drawing.MarkerTable" ),
maDashContainer( rxModelFactory, "com.sun.star.drawing.DashTable" ),
maGradientContainer( rxModelFactory, "com.sun.star.drawing.GradientTable" ),
- maTransGradContainer( rxModelFactory, "com.sun.star.drawing.TransparencyGradientTable" ),
+ maTransGradContainer( rxModelFactory, "com.sun.star.drawing.TransparencyGradientTable" ),
maBitmapUrlContainer( rxModelFactory, "com.sun.star.drawing.BitmapTable" ),
+ maHatchContainer( rxModelFactory, "com.sun.star.drawing.HatchTable" ),
maDashNameBase( "msLineDash " ),
maGradientNameBase( "msFillGradient " ),
maTransGradNameBase( "msTransGradient " ),
- maBitmapUrlNameBase( "msFillBitmap " )
+ maBitmapUrlNameBase( "msFillBitmap " ),
+ maHatchNameBase( "msFillHatch " )
{
}
@@ -137,6 +140,11 @@
return OUString();
}
+OUString ModelObjectHelper::insertFillHatch( const Hatch& rHatch )
+{
+ return maHatchContainer.insertObject( maHatchNameBase, Any( rHatch ), true );
+}
+
uno::Reference<awt::XBitmap> ModelObjectHelper::getFillBitmap(OUString const & rGraphicName)
{
uno::Reference<awt::XBitmap> xBitmap;
diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx
index 8d6abaa..2704a24 100644
--- a/oox/source/ppt/slidepersist.cxx
+++ b/oox/source/ppt/slidepersist.cxx
@@ -171,7 +171,7 @@
oox::drawingml::ShapePropertyIds aPropertyIds = oox::drawingml::ShapePropertyInfo::DEFAULT.mrPropertyIds;
aPropertyIds[oox::drawingml::ShapeProperty::FillGradient] = PROP_FillGradientName;
- oox::drawingml::ShapePropertyInfo aPropInfo( aPropertyIds, true, false, true, false );
+ oox::drawingml::ShapePropertyInfo aPropInfo( aPropertyIds, true, false, true, false, false );
oox::drawingml::ShapePropertyMap aPropMap( rFilterBase.getModelObjectHelper(), aPropInfo );
mpBackgroundPropertiesPtr->pushToPropMap( aPropMap, rFilterBase.getGraphicHelper(), 0, nPhClr );
PropertySet( mxPage ).setProperty( PROP_Background, aPropMap.makePropertySet() );
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index 86dd843..1b06aa7 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -171,6 +171,7 @@
FillGradient
FillGradientName
FillHatch
+FillHatchName
FillStyle
FillTransparence
FillTransparenceGradient
@@ -202,6 +203,7 @@
GenerateVbaEvents
Geometry3D
GradientName
+HatchName
Graphic
GraphicBitmap
GraphicColorMode

669
bsc1112112.patch Normal file
View File

@ -0,0 +1,669 @@
diff --git a/oox/inc/drawingml/diagram/diagram.hxx b/oox/inc/drawingml/diagram/diagram.hxx
index 5277d98d2dee..a528668c08b4 100644
--- a/oox/inc/drawingml/diagram/diagram.hxx
+++ b/oox/inc/drawingml/diagram/diagram.hxx
@@ -39,7 +39,8 @@ void loadDiagram( ShapePtr const & pShape,
const OUString& rDataModelPath,
const OUString& rLayoutPath,
const OUString& rQStylePath,
- const OUString& rColorStylePath );
+ const OUString& rColorStylePath,
+ const oox::core::Relations& rRelations );
void loadDiagram( const ShapePtr& pShape,
core::XmlFilterBase& rFilter,
diff --git a/oox/source/drawingml/diagram/constraintlistcontext.cxx b/oox/source/drawingml/diagram/constraintlistcontext.cxx
index 99e3f3d10e72..cc71c89b226a 100644
--- a/oox/source/drawingml/diagram/constraintlistcontext.cxx
+++ b/oox/source/drawingml/diagram/constraintlistcontext.cxx
@@ -50,7 +50,7 @@ ConstraintListContext::onCreateContext( ::sal_Int32 aElement,
case DGM_TOKEN( constr ):
{
std::shared_ptr< ConstraintAtom > pNode( new ConstraintAtom(mpNode->getLayoutNode()) );
- mpNode->addChild( pNode );
+ LayoutAtom::connect(mpNode, pNode);
Constraint& rConstraint = pNode->getConstraint();
rConstraint.mnFor = rAttribs.getToken( XML_for, XML_none );
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index e7a2df78bd5e..4664a55e594c 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -30,6 +30,7 @@
#include <drawingml/fillproperties.hxx>
#include <oox/ppt/pptshapegroupcontext.hxx>
#include <oox/ppt/pptshape.hxx>
+#include <oox/token/namespaces.hxx>
#include "diagramlayoutatoms.hxx"
#include "layoutatomvisitors.hxx"
@@ -375,12 +376,57 @@ void importFragment( core::XmlFilterBase& rFilter,
rFilter.importFragment( rxHandler, xSerializer );
}
+namespace
+{
+/**
+ * A fragment handler that just counts the number of <dsp:sp> elements in a
+ * fragment.
+ */
+class DiagramShapeCounter : public oox::core::FragmentHandler2
+{
+public:
+ DiagramShapeCounter(oox::core::XmlFilterBase& rFilter, const OUString& rFragmentPath,
+ sal_Int32& nCounter);
+ oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement,
+ const AttributeList& rAttribs) override;
+
+private:
+ sal_Int32& m_nCounter;
+};
+
+DiagramShapeCounter::DiagramShapeCounter(oox::core::XmlFilterBase& rFilter,
+ const OUString& rFragmentPath, sal_Int32& nCounter)
+ : FragmentHandler2(rFilter, rFragmentPath)
+ , m_nCounter(nCounter)
+{
+}
+
+oox::core::ContextHandlerRef DiagramShapeCounter::onCreateContext(sal_Int32 nElement,
+ const AttributeList& /*rAttribs*/)
+{
+ switch (nElement)
+ {
+ case DSP_TOKEN(drawing):
+ case DSP_TOKEN(spTree):
+ return this;
+ case DSP_TOKEN(sp):
+ ++m_nCounter;
+ break;
+ default:
+ break;
+ }
+
+ return nullptr;
+}
+}
+
void loadDiagram( ShapePtr const & pShape,
core::XmlFilterBase& rFilter,
const OUString& rDataModelPath,
const OUString& rLayoutPath,
const OUString& rQStylePath,
- const OUString& rColorStylePath )
+ const OUString& rColorStylePath,
+ const oox::core::Relations& rRelations )
{
DiagramPtr pDiagram( new Diagram );
@@ -407,11 +453,26 @@ void loadDiagram( ShapePtr const & pShape,
// Pass the info to pShape
for (auto const& extDrawing : pData->getExtDrawings())
- pShape->addExtDrawingRelId(extDrawing);
+ {
+ OUString aFragmentPath = rRelations.getFragmentPathFromRelId(extDrawing);
+ // Ignore RelIds which don't resolve to a fragment path.
+ if (aFragmentPath.isEmpty())
+ continue;
+
+ sal_Int32 nCounter = 0;
+ rtl::Reference<core::FragmentHandler> xCounter(
+ new DiagramShapeCounter(rFilter, aFragmentPath, nCounter));
+ rFilter.importFragment(xCounter);
+ // Ignore ext drawings which don't actually have any shapes.
+ if (nCounter == 0)
+ continue;
+
+ pShape->addExtDrawingRelId(extDrawing);
+ }
}
// extLst is present, lets bet on that and ignore the rest of the data from here
- if( pData->getExtDrawings().empty() )
+ if( pShape->getExtDrawings().empty() )
{
// layout
if( !rLayoutPath.isEmpty() )
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 3c8993bd687d..c1aaf6e07025 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -35,6 +35,27 @@ using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::oox::core;
+namespace
+{
+/// Looks up the value of the rInternalName -> nProperty key in rProperties.
+oox::OptValue<sal_Int32> findProperty(const oox::drawingml::LayoutPropertyMap& rProperties,
+ const OUString& rInternalName, sal_Int32 nProperty)
+{
+ oox::OptValue<sal_Int32> oRet;
+
+ auto it = rProperties.find(rInternalName);
+ if (it != rProperties.end())
+ {
+ const oox::drawingml::LayoutProperty& rProperty = it->second;
+ auto itProperty = rProperty.find(nProperty);
+ if (itProperty != rProperty.end())
+ oRet = itProperty->second;
+ }
+
+ return oRet;
+}
+}
+
namespace oox { namespace drawingml {
IteratorAttr::IteratorAttr( )
@@ -145,6 +166,36 @@ const dgm::Point* ConditionAtom::getPresNode() const
return nullptr;
}
+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,
+ bool bSourceToDestination)
+{
+ for (const auto& rConnection : rLayoutNode.getDiagram().getData()->getConnections())
+ {
+ if (rConnection.mnType != nType)
+ continue;
+
+ if (bSourceToDestination)
+ {
+ if (rConnection.msSourceId == rFrom)
+ return rConnection.msDestId;
+ }
+ else
+ {
+ if (rConnection.msDestId == rFrom)
+ return rConnection.msSourceId;
+ }
+ }
+
+ return OUString();
+}
+}
+
sal_Int32 ConditionAtom::getNodeCount() const
{
sal_Int32 nCount = 0;
@@ -153,9 +204,21 @@ sal_Int32 ConditionAtom::getNodeCount() const
{
OUString sNodeId = "";
- for (const auto& aCxn : mrLayoutNode.getDiagram().getData()->getConnections())
- if (aCxn.mnType == XML_presOf && aCxn.msDestId == pPoint->msModelId)
- sNodeId = aCxn.msSourceId;
+ sNodeId
+ = navigate(mrLayoutNode, XML_presOf, pPoint->msModelId, /*bSourceToDestination*/ false);
+
+ if (sNodeId.isEmpty())
+ {
+ // The current layout node is not a presentation of anything. Look
+ // up the first presentation child of the layout node.
+ OUString sFirstPresChildId = navigate(mrLayoutNode, XML_presParOf, pPoint->msModelId,
+ /*bSourceToDestination*/ true);
+ if (!sFirstPresChildId.isEmpty())
+ // It has a presentation child: is that a presentation of a
+ // model node?
+ sNodeId = navigate(mrLayoutNode, XML_presOf, sFirstPresChildId,
+ /*bSourceToDestination*/ false);
+ }
if (!sNodeId.isEmpty())
{
@@ -224,8 +287,22 @@ void AlgAtom::accept( LayoutAtomVisitor& rVisitor )
}
void AlgAtom::layoutShape( const ShapePtr& rShape,
- const std::vector<Constraint>& rConstraints ) const
+ const std::vector<Constraint>& rOwnConstraints ) const
{
+ // Algorithm result may depend on the parent constraints as well.
+ std::vector<Constraint> aParentConstraints;
+ const LayoutNode* pParent = getLayoutNode().getParentLayoutNode();
+ if (pParent)
+ {
+ for (const auto& pChild : pParent->getChildren())
+ {
+ auto pConstraintAtom = dynamic_cast<ConstraintAtom*>(pChild.get());
+ if (pConstraintAtom)
+ pConstraintAtom->parseConstraint(aParentConstraints);
+ }
+ }
+ const std::vector<Constraint>& rConstraints = rOwnConstraints.empty() ? aParentConstraints : rOwnConstraints;
+
switch(mnType)
{
case XML_composite:
@@ -356,9 +433,9 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
double fSpace = 0.3;
awt::Size aChildSize = rShape->getSize();
- if (nIncX)
+ if (nDir == XML_fromL || nDir == XML_fromR)
aChildSize.Width /= (nCount + (nCount-1)*fSpace);
- if (nIncY)
+ else if (nDir == XML_fromT || nDir == XML_fromB)
aChildSize.Height /= (nCount + (nCount-1)*fSpace);
awt::Point aCurrPos(0, 0);
@@ -367,12 +444,64 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
if (nIncY == -1)
aCurrPos.Y = rShape->getSize().Height - aChildSize.Height;
+ // Find out which contraint is relevant for which (internal) name.
+ LayoutPropertyMap aProperties;
+ for (const auto& rConstraint : rConstraints)
+ {
+ if (rConstraint.msForName.isEmpty())
+ continue;
+
+ LayoutProperty& rProperty = aProperties[rConstraint.msForName];
+ if (rConstraint.mnType == XML_w)
+ rProperty[XML_w] = rShape->getSize().Width * rConstraint.mfFactor;
+ }
+
+ // See if children requested more than 100% space in total: scale
+ // down in that case.
+ sal_Int32 nTotalWidth = 0;
+ bool bSpaceFromConstraints = false;
for (auto & aCurrShape : rShape->getChildren())
{
+ oox::OptValue<sal_Int32> oWidth
+ = findProperty(aProperties, aCurrShape->getInternalName(), XML_w);
+
+ awt::Size aSize = aChildSize;
+ if (oWidth.has())
+ {
+ aSize.Width = oWidth.get();
+ bSpaceFromConstraints = true;
+ }
+ if (nDir == XML_fromL || nDir == XML_fromR)
+ nTotalWidth += aSize.Width;
+ }
+
+ double fWidthScale = 1.0;
+ if (nTotalWidth > rShape->getSize().Width && nTotalWidth)
+ {
+ fWidthScale = rShape->getSize().Width;
+ fWidthScale /= nTotalWidth;
+ }
+
+ // Don't add automatic space if we take space from constraints.
+ if (bSpaceFromConstraints)
+ fSpace = 0;
+
+ for (auto& aCurrShape : rShape->getChildren())
+ {
+ // Extract properties relevant for this shape from constraints.
+ oox::OptValue<sal_Int32> oWidth
+ = findProperty(aProperties, aCurrShape->getInternalName(), XML_w);
+
aCurrShape->setPosition(aCurrPos);
- aCurrShape->setSize(aChildSize);
+
+ awt::Size aSize = aChildSize;
+ if (oWidth.has())
+ aSize.Width = oWidth.get();
+ aSize.Width *= fWidthScale;
+ aCurrShape->setSize(aSize);
+
aCurrShape->setChildSize(aChildSize);
- aCurrPos.X += nIncX * (aChildSize.Width + fSpace*aChildSize.Width);
+ aCurrPos.X += nIncX * (aSize.Width + fSpace*aSize.Width);
aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height);
}
break;
@@ -402,18 +531,19 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
// TODO: get values from constraints
sal_Int32 nCount = rShape->getChildren().size();
double fSpace = 0.3;
- double fAspectRatio = 0.6;
+ double fAspectRatio = 0.54; // diagram should not spill outside, earlier it was 0.6
sal_Int32 nCol = 1;
sal_Int32 nRow = 1;
- for ( ; nCol<nCount; nCol++)
+ for ( ; nRow<nCount; nRow++)
{
- nRow = (nCount+nCol-1) / nCol;
+ nCol = (nCount+nRow-1) / nRow;
const double fShapeHeight = rShape->getSize().Height;
const double fShapeWidth = rShape->getSize().Width;
- if ((fShapeHeight / nRow) / (fShapeWidth / nCol) >= fAspectRatio)
+ if ((fShapeHeight / nCol) / (fShapeWidth / nRow) >= fAspectRatio)
break;
}
+
SAL_INFO("oox.drawingml", "Snake layout grid: " << nCol << "x" << nRow);
sal_Int32 nWidth = rShape->getSize().Width / (nCol + (nCol-1)*fSpace);
@@ -426,20 +556,89 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
aCurrPos.Y = rShape->getSize().Height - aChildSize.Height;
sal_Int32 nStartX = aCurrPos.X;
- sal_Int32 nColIdx = 0;
+ sal_Int32 nColIdx = 0,index = 0;
- for (auto & aCurrShape : rShape->getChildren())
+ sal_Int32 num = rShape->getChildren().size();
+
+ const sal_Int32 aContDir = maMap.count(XML_contDir) ? maMap.find(XML_contDir)->second : XML_sameDir;
+
+ switch(aContDir)
{
- aCurrShape->setPosition(aCurrPos);
- aCurrShape->setSize(aChildSize);
- aCurrShape->setChildSize(aChildSize);
- aCurrPos.X += nIncX * (aChildSize.Width + fSpace*aChildSize.Width);
- if (++nColIdx == nCol)
+ case XML_sameDir:
+ for (auto & aCurrShape : rShape->getChildren())
{
- aCurrPos.X = nStartX;
- aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height);
- nColIdx = 0;
+ aCurrShape->setPosition(aCurrPos);
+ aCurrShape->setSize(aChildSize);
+ aCurrShape->setChildSize(aChildSize);
+
+ index++; // counts index of child, helpful for positioning.
+
+ if(index%nCol==0 || ((index/nCol)+1)!=nRow)
+ aCurrPos.X += nIncX * (aChildSize.Width + fSpace*aChildSize.Width);
+
+ if(++nColIdx == nCol) // condition for next row
+ {
+ // if last row, then position children according to number of shapes.
+ if((index+1)%nCol!=0 && (index+1)>=3 && ((index+1)/nCol+1)==nRow && num!=nRow*nCol)
+ // position first child of last row
+ aCurrPos.X = nStartX + (nIncX * (aChildSize.Width + fSpace*aChildSize.Width))/2;
+ else
+ // if not last row, positions first child of that row
+ aCurrPos.X = nStartX;
+ aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height);
+ nColIdx = 0;
+ }
+
+ // positions children in the last row.
+ if(index%nCol!=0 && index>=3 && ((index/nCol)+1)==nRow)
+ aCurrPos.X += (nIncX * (aChildSize.Width + fSpace*aChildSize.Width));
}
+ break;
+ case XML_revDir:
+ for (auto & aCurrShape : rShape->getChildren())
+ {
+ aCurrShape->setPosition(aCurrPos);
+ aCurrShape->setSize(aChildSize);
+ aCurrShape->setChildSize(aChildSize);
+
+ index++; // counts index of child, helpful for positioning.
+
+ /*
+ index%col -> tests node is at last column
+ ((index/nCol)+1)!=nRow) -> tests node is at last row or not
+ ((index/nCol)+1)%2!=0 -> tests node is at row which is multiple of 2, important for revDir
+ num!=nRow*nCol -> tests how last row nodes should be spread.
+ */
+
+ if((index%nCol==0 || ((index/nCol)+1)!=nRow) && ((index/nCol)+1)%2!=0)
+ aCurrPos.X += (aChildSize.Width + fSpace*aChildSize.Width);
+ else if( index%nCol!=0 && ((index/nCol)+1)!=nRow) // child other than placed at last column
+ aCurrPos.X -= (aChildSize.Width + fSpace*aChildSize.Width);
+
+ if(++nColIdx == nCol) // condition for next row
+ {
+ // if last row, then position children according to number of shapes.
+ if((index+1)%nCol!=0 && (index+1)>=4 && ((index+1)/nCol+1)==nRow && num!=nRow*nCol && ((index/nCol)+1)%2==0)
+ // position first child of last row
+ aCurrPos.X -= aChildSize.Width*3/2;
+ else if((index+1)%nCol!=0 && (index+1)>=4 && ((index+1)/nCol+1)==nRow && num!=nRow*nCol && ((index/nCol)+1)%2!=0)
+ aCurrPos.X = nStartX + (nIncX * (aChildSize.Width + fSpace*aChildSize.Width))/2;
+ else if(((index/nCol)+1)%2!=0)
+ aCurrPos.X = nStartX;
+
+ aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height);
+ nColIdx = 0;
+ }
+
+ // positions children in the last row.
+ if(index%nCol!=0 && index>=3 && ((index/nCol)+1)==nRow && ((index/nCol)+1)%2==0)
+ //if row%2=0 then start from left else
+ aCurrPos.X -= (nIncX * (aChildSize.Width + fSpace*aChildSize.Width));
+ else if(index%nCol!=0 && index>=3 && ((index/nCol)+1)==nRow && ((index/nCol)+1)%2!=0)
+ // start from right
+ aCurrPos.X += (nIncX * (aChildSize.Width + fSpace*aChildSize.Width));
+ }
+ break;
}
break;
}
@@ -456,7 +655,6 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
{
// adjust text alignment
// TODO: adjust text size to fit shape
-
TextBodyPtr pTextBody = rShape->getTextBody();
if (!pTextBody ||
pTextBody->getParagraphs().empty() ||
@@ -465,12 +663,44 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
break;
}
- if (rShape->getRotation())
- pTextBody->getTextProperties().moRotation = -rShape->getRotation();
+ const sal_Int32 nautoTxRot = maMap.count(XML_autoTxRot) ? maMap.find(XML_autoTxRot)->second : XML_upr;
+
+ switch(nautoTxRot)
+ {
+ case XML_upr:
+ {
+ if (rShape->getRotation())
+ pTextBody->getTextProperties().moRotation = -F_PI180*90*rShape->getRotation();
+ }
+ break;
+ case XML_grav:
+ {
+ if (rShape->getRotation()==90*F_PI180 || rShape->getRotation()==180*F_PI180)
+ pTextBody->getTextProperties().moRotation = 180*F_PI180;
+ }
+ break;
+ case XML_none:
+ break;
+ }
+
+ const sal_Int32 atxAnchorVert = maMap.count(XML_txAnchorVert) ? maMap.find(XML_txAnchorVert)->second : XML_mid;
+
+ switch(atxAnchorVert)
+ {
+ case XML_t:
+ pTextBody->getTextProperties().meVA = css::drawing::TextVerticalAdjust_TOP;
+ break;
+ case XML_b:
+ pTextBody->getTextProperties().meVA = css::drawing::TextVerticalAdjust_BOTTOM;
+ break;
+ case XML_mid:
+ // text centered vertically by default
+ default:
+ pTextBody->getTextProperties().meVA = css::drawing::TextVerticalAdjust_CENTER;
+ break;
+ }
- // text centered vertically by default
- pTextBody->getTextProperties().meVA = css::drawing::TextVerticalAdjust_CENTER;
- pTextBody->getTextProperties().maPropertyMap.setProperty(PROP_TextVerticalAdjust, css::drawing::TextVerticalAdjust_CENTER);
+ pTextBody->getTextProperties().maPropertyMap.setProperty(PROP_TextVerticalAdjust, pTextBody->getTextProperties().meVA);
// normalize list level
sal_Int32 nBaseLevel = pTextBody->getParagraphs().front()->getProperties().getLevel();
@@ -653,6 +883,18 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const dgm::Point* pPresNode
return true;
}
+const LayoutNode* LayoutNode::getParentLayoutNode() const
+{
+ for (LayoutAtomPtr pAtom = getParent(); pAtom; pAtom = pAtom->getParent())
+ {
+ auto pLayoutNode = dynamic_cast<LayoutNode*>(pAtom.get());
+ if (pLayoutNode)
+ return pLayoutNode;
+ }
+
+ return nullptr;
+}
+
void ShapeAtom::accept( LayoutAtomVisitor& rVisitor )
{
rVisitor.visit(*this);
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index 5ab34b042c86..3d4d9c05aae2 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -106,17 +106,30 @@ public:
const OUString& getName() const
{ return msName; }
+private:
void addChild( const LayoutAtomPtr & pNode )
{ mpChildNodes.push_back( pNode ); }
+ void setParent(const LayoutAtomPtr& pParent) { mpParent = pParent; }
+
+public:
virtual const std::vector<LayoutAtomPtr>& getChildren() const
{ return mpChildNodes; }
+ LayoutAtomPtr getParent() const { return mpParent.lock(); }
+
+ static void connect(const LayoutAtomPtr& pParent, const LayoutAtomPtr& pChild)
+ {
+ pParent->addChild(pChild);
+ pChild->setParent(pParent);
+ }
+
// dump for debug
void dump(int level = 0);
protected:
const LayoutNode& mrLayoutNode;
std::vector< LayoutAtomPtr > mpChildNodes;
+ std::weak_ptr<LayoutAtom> mpParent;
OUString msName;
};
@@ -238,6 +251,8 @@ public:
bool setupShape( const ShapePtr& rShape,
const dgm::Point* pPresNode ) const;
+ const LayoutNode* getParentLayoutNode() const;
+
private:
const Diagram& mrDgm;
VarMap mVariables;
diff --git a/oox/source/drawingml/diagram/layoutnodecontext.cxx b/oox/source/drawingml/diagram/layoutnodecontext.cxx
index 9bbe8b31421c..257f490f7c7c 100644
--- a/oox/source/drawingml/diagram/layoutnodecontext.cxx
+++ b/oox/source/drawingml/diagram/layoutnodecontext.cxx
@@ -105,14 +105,14 @@ public:
{
// CT_When
ConditionAtomPtr pNode( new ConditionAtom(mpNode->getLayoutNode(), false, rAttribs.getFastAttributeList()) );
- mpNode->addChild( pNode );
+ LayoutAtom::connect(mpNode, pNode);
return new IfContext( *this, rAttribs, pNode );
}
case DGM_TOKEN( else ):
{
// CT_Otherwise
ConditionAtomPtr pNode( new ConditionAtom(mpNode->getLayoutNode(), true, rAttribs.getFastAttributeList()) );
- mpNode->addChild( pNode );
+ LayoutAtom::connect(mpNode, pNode);
return new IfContext( *this, rAttribs, pNode );
}
default:
@@ -182,7 +182,7 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
case DGM_TOKEN( layoutNode ):
{
LayoutNodePtr pNode( new LayoutNode(mpNode->getLayoutNode().getDiagram()) );
- mpNode->addChild( pNode );
+ LayoutAtom::connect(mpNode, pNode);
pNode->setChildOrder( rAttribs.getToken( XML_chOrder, XML_b ) );
pNode->setMoveWith( rAttribs.getString( XML_moveWith ).get() );
pNode->setStyleLabel( rAttribs.getString( XML_styleLbl ).get() );
@@ -210,7 +210,7 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
pShape->setDiagramRotation(rAttribs.getInteger(XML_rot, 0) * PER_DEGREE);
ShapeAtomPtr pAtom( new ShapeAtom(mpNode->getLayoutNode(), pShape) );
- mpNode->addChild( pAtom );
+ LayoutAtom::connect(mpNode, pAtom);
return new ShapeContext( *this, ShapePtr(), pShape );
}
case DGM_TOKEN( extLst ):
@@ -219,21 +219,21 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
{
// CT_Algorithm
AlgAtomPtr pAtom( new AlgAtom(mpNode->getLayoutNode()) );
- mpNode->addChild( pAtom );
+ LayoutAtom::connect(mpNode, pAtom);
return new AlgorithmContext( *this, rAttribs, pAtom );
}
case DGM_TOKEN( choose ):
{
// CT_Choose
LayoutAtomPtr pAtom( new ChooseAtom(mpNode->getLayoutNode()) );
- mpNode->addChild( pAtom );
+ LayoutAtom::connect(mpNode, pAtom);
return new ChooseContext( *this, rAttribs, pAtom );
}
case DGM_TOKEN( forEach ):
{
// CT_ForEach
ForEachAtomPtr pAtom( new ForEachAtom(mpNode->getLayoutNode(), rAttribs.getFastAttributeList()) );
- mpNode->addChild( pAtom );
+ LayoutAtom::connect(mpNode, pAtom);
return new ForEachContext( *this, rAttribs, pAtom );
}
case DGM_TOKEN( constrLst ):
diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx
index f8cfc0d40b0a..135966eee9b9 100644
--- a/oox/source/drawingml/graphicshapecontext.cxx
+++ b/oox/source/drawingml/graphicshapecontext.cxx
@@ -262,7 +262,8 @@ ContextHandlerRef DiagramGraphicDataContext::onCreateContext( ::sal_Int32 aEleme
getFragmentPathFromRelId( msDm ),
getFragmentPathFromRelId( msLo ),
getFragmentPathFromRelId( msQs ),
- getFragmentPathFromRelId( msCs ));
+ getFragmentPathFromRelId( msCs ),
+ getRelations());
SAL_INFO("oox.drawingml", "DiagramGraphicDataContext::onCreateContext: added shape " << mpShapePtr->getName()
<< " of type " << mpShapePtr->getServiceName()
<< ", position: " << mpShapePtr->getPosition().X
diff --git a/oox/source/ppt/dgmimport.cxx b/oox/source/ppt/dgmimport.cxx
index c10dc48a72ef..191ec1771028 100644
--- a/oox/source/ppt/dgmimport.cxx
+++ b/oox/source/ppt/dgmimport.cxx
@@ -68,6 +68,7 @@ bool QuickDiagrammingImport::importDocument()
Reference<drawing::XShapes> xParentShape(getParentShape(),
UNO_QUERY_THROW);
+ oox::core::Relations aRelations("");
oox::drawingml::ShapePtr pShape(
new oox::drawingml::Shape( "com.sun.star.drawing.DiagramShape" ) );
drawingml::loadDiagram(pShape,
@@ -75,7 +76,8 @@ bool QuickDiagrammingImport::importDocument()
"",
aFragmentPath,
"",
- "");
+ "",
+ aRelations);
oox::drawingml::ThemePtr pTheme(
new oox::drawingml::Theme());
basegfx::B2DHomMatrix aMatrix;

View File

@ -1,3 +1,15 @@
-------------------------------------------------------------------
Mon Nov 12 08:50:57 UTC 2018 - andras.timar@collabora.com
- bsc#1112112 - LO-L3: [PPTX] SmartArt: Basic rendering of several list types
* bsc1112112.patch
-------------------------------------------------------------------
Mon Nov 5 19:57:23 UTC 2018 - andras.timar@collabora.com
- bsc#1110348 LO-L3: [PPTX] Charts having weird/darker/ugly background versus Office 365 and strange artefacts where overlapping
* bsc1110348.patch
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Oct 31 11:08:05 UTC 2018 - Tomáš Chvátal <tchvatal@suse.com> Wed Oct 31 11:08:05 UTC 2018 - Tomáš Chvátal <tchvatal@suse.com>

View File

@ -12,7 +12,7 @@
# license that conforms to the Open Source Definition (Version 1.9) # license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative. # published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Please submit bugfixes or comments via http://bugs.opensuse.org/
# #
@ -104,6 +104,10 @@ Patch3: mediawiki-no-broken-help.diff
Patch4: libreoffice-java-sched.patch Patch4: libreoffice-java-sched.patch
Patch5: old-boost.patch Patch5: old-boost.patch
Patch6: 0001-call-System.runFinalizersOnExit-by-reflection-since-.patch Patch6: 0001-call-System.runFinalizersOnExit-by-reflection-since-.patch
# Bug 1110348 - LO-L3: [PPTX] Charts having weird/darker/ugly background versus Office 365 and strange artefacts where overlapping
Patch7: bsc1110348.patch
# Bug 1112112 - LO-L3: [PPTX] SmartArt: Basic rendering of several list types
Patch8: bsc1112112.patch
# try to save space by using hardlinks # try to save space by using hardlinks
Patch990: install-with-hardlinks.diff Patch990: install-with-hardlinks.diff
BuildRequires: %{name}-share-linker BuildRequires: %{name}-share-linker
@ -950,6 +954,8 @@ Provides %{langname} translations and additional resources (help files, etc.) fo
%patch3 %patch3
%patch4 -p1 %patch4 -p1
%patch6 -p1 %patch6 -p1
%patch7 -p1
%patch8 -p1
%patch990 -p1 %patch990 -p1
# Disable some of the failing tests (some are random) # Disable some of the failing tests (some are random)