diff --git a/bsc1112113.patch b/bsc1112113.patch new file mode 100644 index 0000000..d899c48 --- /dev/null +++ b/bsc1112113.patch @@ -0,0 +1,528 @@ +From 73cc724dc35551ea349b3da0c4ecd6cba2fdd0ae Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 13 Nov 2018 18:00:50 +0100 +Subject: [PATCH] Related: tdf#117761 oox smartart: backport fixes related to process types + +This is a combination of 9 commits. + +This is the 1st commit: + +oox smartart, accent process: add support for reading values from constraints + +(cherry picked from commit b389aafee9cfba9dc4dfa552347be39ff9fe41b2) + +This is the commit #2: + +oox smartart, accent process: add support for zorder offsets + +(cherry picked from commit cd348a6244a092c251a8e1362cd78de562d7bef6) + +This is the commit #3: + +oox smartart, accent process: fix overlapping shape pairs + +(cherry picked from commit 67e062aa5e5946d4985921fe2b6f87766f363ddc) + +This is the commit #4: + +oox smartart, accent process: handle multiple runs from a data point + +(cherry picked from commit cfa76f538a44d4396574ece59e8a3953c22c6eb7) + +This is the commit #5: + +oox smartart, accent process: handle followSib axis of forEach + +(cherry picked from commit aedc5427e4b6645ff3257e523c33190cf5e1934d) + +This is the commit #6: + +oox smartart, accent process: handle connector shape between pairs + +(cherry picked from commit 7f66a340933339974b5c6d70af4ae3c17e4f001a) + +This is the commit #7: + +oox smartart, accent process: adjust size of connector from constraints + +(cherry picked from commit ddc2786831367577967e806d603f337a2e42806a) + +This is the commit #8: + +oox smartart, continuous block process: read space width from constraint + +(cherry picked from commit ee6787fc5597b7f730c4ee3a1f2a1b261d0a5644) + +Conflicts: + oox/source/drawingml/diagram/diagramlayoutatoms.cxx + +This is the commit #9: + +oox smartart, accent process: fix missing bullets and large para indent + +(cherry picked from commit 6277a767f33bb5327408dafff2fed199087e938d) + +Change-Id: I60bbee75f3e834551ebb1963a2f42101f3bd91d4 +Reviewed-on: https://gerrit.libreoffice.org/65352 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +--- + +diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx +index 6028a11..e04a58beb 100644 +--- a/include/oox/drawingml/shape.hxx ++++ b/include/oox/drawingml/shape.hxx +@@ -214,6 +214,14 @@ + const LinkedTxbxAttr& getLinkedTxbxAttributes() { return maLinkedTxbxAttr; }; + bool isLinkedTxbx() { return mbHasLinkedTxbx; }; + ++ void setZOrder(sal_Int32 nZOrder) { mnZOrder = nZOrder; } ++ ++ sal_Int32 getZOrder() const { return mnZOrder; } ++ ++ void setZOrderOff(sal_Int32 nZOrderOff) { mnZOrderOff = nZOrderOff; } ++ ++ sal_Int32 getZOrderOff() const { return mnZOrderOff; } ++ + protected: + + css::uno::Reference< css::drawing::XShape > const & +@@ -327,6 +335,12 @@ + bool mbHasLinkedTxbx; // this text box has linked text box ? + + css::uno::Sequence maDiagramDoms; ++ ++ /// Z-Order. ++ sal_Int32 mnZOrder = 0; ++ ++ /// Z-Order offset. ++ sal_Int32 mnZOrderOff = 0; + }; + + } } +diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +index c1aaf6e..5024709 100644 +--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx ++++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +@@ -54,6 +54,50 @@ + + return oRet; + } ++ ++/** ++ * Determines if nUnit is a font unit (measured in points) or not (measured in ++ * millimeters). ++ */ ++bool isFontUnit(sal_Int32 nUnit) ++{ ++ return nUnit == oox::XML_primFontSz || nUnit == oox::XML_secFontSz; ++} ++ ++/// Determines the connector shape type from a linear alg. ++sal_Int32 getConnectorType(const oox::drawingml::LayoutNode* pNode) ++{ ++ sal_Int32 nType = oox::XML_rightArrow; ++ ++ if (!pNode) ++ return nType; ++ ++ for (const auto& pChild : pNode->getChildren()) ++ { ++ auto pAlgAtom = dynamic_cast(pChild.get()); ++ if (!pAlgAtom) ++ continue; ++ ++ if (pAlgAtom->getType() != oox::XML_lin) ++ continue; ++ ++ sal_Int32 nDir = oox::XML_fromL; ++ if (pAlgAtom->getMap().count(oox::XML_linDir)) ++ nDir = pAlgAtom->getMap().find(oox::XML_linDir)->second; ++ ++ switch (nDir) ++ { ++ case oox::XML_fromL: ++ nType = oox::XML_rightArrow; ++ break; ++ case oox::XML_fromR: ++ nType = oox::XML_leftArrow; ++ break; ++ } ++ } ++ ++ return nType; ++} + } + + namespace oox { namespace drawingml { +@@ -269,13 +313,15 @@ + rVisitor.visit(*this); + } + +-void ConstraintAtom::parseConstraint(std::vector& rConstraints) const ++void ConstraintAtom::parseConstraint(std::vector& rConstraints, ++ bool bRequireForName) const + { ++ if (bRequireForName && maConstraint.msForName.isEmpty()) ++ return; ++ + // accepting only basic equality constraints +- if (!maConstraint.msForName.isEmpty() && +- (maConstraint.mnOperator == XML_none || maConstraint.mnOperator == XML_equ) && +- maConstraint.mnType != XML_none && +- maConstraint.mfValue == 0) ++ if ((maConstraint.mnOperator == XML_none || maConstraint.mnOperator == XML_equ) ++ && maConstraint.mnType != XML_none) + { + rConstraints.push_back(maConstraint); + } +@@ -290,7 +336,7 @@ + const std::vector& rOwnConstraints ) const + { + // Algorithm result may depend on the parent constraints as well. +- std::vector aParentConstraints; ++ std::vector aMergedConstraints; + const LayoutNode* pParent = getLayoutNode().getParentLayoutNode(); + if (pParent) + { +@@ -298,10 +344,12 @@ + { + auto pConstraintAtom = dynamic_cast(pChild.get()); + if (pConstraintAtom) +- pConstraintAtom->parseConstraint(aParentConstraints); ++ pConstraintAtom->parseConstraint(aMergedConstraints, /*bRequireForName=*/true); + } + } +- const std::vector& rConstraints = rOwnConstraints.empty() ? aParentConstraints : rOwnConstraints; ++ aMergedConstraints.insert(aMergedConstraints.end(), rOwnConstraints.begin(), ++ rOwnConstraints.end()); ++ const std::vector& rConstraints = aMergedConstraints; + + switch(mnType) + { +@@ -327,7 +375,19 @@ + if (aRefType != aRef->second.end()) + aProperties[rConstr.msForName][rConstr.mnType] = aRefType->second * rConstr.mfFactor; + else +- aProperties[rConstr.msForName][rConstr.mnType] = 0; // TODO: val ++ { ++ // Values are never in EMU, while oox::drawingml::Shape ++ // position and size are always in EMU. ++ double fUnitFactor = 0; ++ if (isFontUnit(rConstr.mnRefType)) ++ // Points -> EMU. ++ fUnitFactor = EMU_PER_PT; ++ else ++ // Millimeters -> EMU. ++ fUnitFactor = EMU_PER_HMM * 100; ++ aProperties[rConstr.msForName][rConstr.mnType] ++ = rConstr.mfValue * fUnitFactor; ++ } + } + } + +@@ -376,7 +436,54 @@ + } + + case XML_conn: ++ { ++ if (rShape->getSubType() == XML_conn) ++ { ++ // There is no shape type "conn", replace it by an arrow based ++ // on the direction of the parent linear layout. ++ sal_Int32 nType = getConnectorType(pParent); ++ ++ rShape->setSubType(nType); ++ rShape->getCustomShapeProperties()->setShapePresetType(nType); ++ } ++ ++ // Parse constraints to adjust the size. ++ std::vector aDirectConstraints; ++ const LayoutNode& rLayoutNode = getLayoutNode(); ++ for (const auto& pChild : rLayoutNode.getChildren()) ++ { ++ auto pConstraintAtom = dynamic_cast(pChild.get()); ++ if (pConstraintAtom) ++ pConstraintAtom->parseConstraint(aDirectConstraints, /*bRequireForName=*/false); ++ } ++ ++ LayoutPropertyMap aProperties; ++ LayoutProperty& rParent = aProperties[""]; ++ rParent[XML_w] = rShape->getSize().Width; ++ rParent[XML_h] = rShape->getSize().Height; ++ rParent[XML_l] = 0; ++ rParent[XML_t] = 0; ++ rParent[XML_r] = rShape->getSize().Width; ++ rParent[XML_b] = rShape->getSize().Height; ++ for (const auto& rConstr : aDirectConstraints) ++ { ++ const LayoutPropertyMap::const_iterator aRef ++ = aProperties.find(rConstr.msRefForName); ++ if (aRef != aProperties.end()) ++ { ++ const LayoutProperty::const_iterator aRefType ++ = aRef->second.find(rConstr.mnRefType); ++ if (aRefType != aRef->second.end()) ++ aProperties[rConstr.msForName][rConstr.mnType] ++ = aRefType->second * rConstr.mfFactor; ++ } ++ } ++ awt::Size aSize; ++ aSize.Width = rParent[XML_w]; ++ aSize.Height = rParent[XML_h]; ++ rShape->setSize(aSize); + break; ++ } + + case XML_cycle: + { +@@ -428,9 +535,24 @@ + const sal_Int32 nIncX = nDir==XML_fromL ? 1 : (nDir==XML_fromR ? -1 : 0); + const sal_Int32 nIncY = nDir==XML_fromT ? 1 : (nDir==XML_fromB ? -1 : 0); + +- // TODO: get values from constraints + sal_Int32 nCount = rShape->getChildren().size(); + double fSpace = 0.3; ++ ++ // 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; ++ ++ // TODO: get values from differently named constraints as well ++ if (rConstraint.msForName == "sibTrans" && rConstraint.mnType == XML_w) ++ fSpace = rConstraint.mfFactor; ++ } + + awt::Size aChildSize = rShape->getSize(); + if (nDir == XML_fromL || nDir == XML_fromR) +@@ -443,18 +565,6 @@ + aCurrPos.X = rShape->getSize().Width - aChildSize.Width; + 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. +@@ -500,7 +610,7 @@ + aSize.Width *= fWidthScale; + aCurrShape->setSize(aSize); + +- aCurrShape->setChildSize(aChildSize); ++ aCurrShape->setChildSize(aSize); + aCurrPos.X += nIncX * (aSize.Width + fSpace*aSize.Width); + aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height); + } +@@ -711,13 +821,27 @@ + } + + ParamMap::const_iterator aBulletLvl = maMap.find(XML_stBulletLvl); ++ int nStartBulletsAtLevel = 0; + if (aBulletLvl != maMap.end()) ++ { + nBaseLevel -= aBulletLvl->second; ++ nStartBulletsAtLevel = aBulletLvl->second; ++ } + + for (auto & aParagraph : pTextBody->getParagraphs()) + { + sal_Int32 nLevel = aParagraph->getProperties().getLevel(); + aParagraph->getProperties().setLevel(nLevel - nBaseLevel); ++ if (nStartBulletsAtLevel > 0 && nLevel >= nStartBulletsAtLevel) ++ { ++ // It is not possible to change the bullet style for text. ++ sal_Int32 nLeftMargin = 285750 * (nLevel - nStartBulletsAtLevel) / EMU_PER_HMM; ++ aParagraph->getProperties().getParaLeftMargin() = nLeftMargin; ++ aParagraph->getProperties().getFirstLineIndentation() = -285750 / EMU_PER_HMM; ++ OUString aBulletChar = OUString::fromUtf8(u8"•"); ++ aParagraph->getProperties().getBulletList().setBulletChar(aBulletChar); ++ aParagraph->getProperties().getBulletList().setSuffixNone(); ++ } + } + + // explicit alignment +@@ -821,8 +945,10 @@ + if( aVecIter->second != -1 ) + rPara.getProperties().setLevel(aVecIter->second); + +- rPara.addRun( +- aDataNode2->second->mpShape->getTextBody()->getParagraphs().front()->getRuns().front()); ++ std::shared_ptr pSourceParagraph ++ = aDataNode2->second->mpShape->getTextBody()->getParagraphs().front(); ++ for (const auto& pRun : pSourceParagraph->getRuns()) ++ rPara.addRun(pRun); + rPara.getProperties().apply( + aDataNode2->second->mpShape->getTextBody()->getParagraphs().front()->getProperties()); + } +diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx +index 3d4d9c0..500495b 100644 +--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx ++++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx +@@ -141,7 +141,7 @@ + virtual void accept( LayoutAtomVisitor& ) override; + Constraint& getConstraint() + { return maConstraint; } +- void parseConstraint(std::vector& rConstraints) const; ++ void parseConstraint(std::vector& rConstraints, bool bRequireForName) const; + private: + Constraint maConstraint; + }; +@@ -162,6 +162,13 @@ + { maMap[nType]=nVal; } + void layoutShape( const ShapePtr& rShape, + const std::vector& rConstraints ) const; ++ ++ /// Gives access to . ++ sal_Int32 getType() const { return mnType; } ++ ++ /// Gives access to . ++ const ParamMap& getMap() const { return maMap; } ++ + private: + sal_Int32 mnType; + ParamMap maMap; +diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx +index ce8e6ab..49a664c 100644 +--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx ++++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx +@@ -46,6 +46,14 @@ + + void ShapeCreationVisitor::visit(ForEachAtom& rAtom) + { ++ if (rAtom.iterator().mnAxis == XML_followSib) ++ { ++ // If the axis is the follow sibling, then the last atom should not be ++ // visited. ++ if (mnCurrIdx + mnCurrStep >= mnCurrCnt) ++ return; ++ } ++ + const std::vector& rChildren=rAtom.getChildren(); + + sal_Int32 nChildren=1; +@@ -65,7 +73,11 @@ + rAtom.iterator().mnCnt==-1 ? nChildren : rAtom.iterator().mnCnt); + + const sal_Int32 nOldIdx=mnCurrIdx; ++ const sal_Int32 nOldStep = mnCurrStep; ++ const sal_Int32 nOldCnt = mnCurrCnt; + const sal_Int32 nStep=rAtom.iterator().mnStep; ++ mnCurrStep = nStep; ++ mnCurrCnt = nCnt; + for( mnCurrIdx=0; mnCurrIdx0; mnCurrIdx+=nStep ) + { + // TODO there is likely some conditions +@@ -75,6 +87,8 @@ + + // and restore idx + mnCurrIdx = nOldIdx; ++ mnCurrStep = nOldStep; ++ mnCurrCnt = nOldCnt; + } + + void ShapeCreationVisitor::visit(ConditionAtom& rAtom) +@@ -166,6 +180,38 @@ + std::remove_if(pCurrParent->getChildren().begin(), pCurrParent->getChildren().end(), + [] (const ShapePtr & aChild) { return aChild->getServiceName() == "com.sun.star.drawing.GroupShape" && aChild->getChildren().empty(); }), + pCurrParent->getChildren().end()); ++ ++ // Offset the children from their default z-order stacking, if necessary. ++ std::vector& rChildren = pCurrParent->getChildren(); ++ for (size_t i = 0; i < rChildren.size(); ++i) ++ rChildren[i]->setZOrder(i); ++ ++ for (size_t i = 0; i < rChildren.size(); ++i) ++ { ++ const ShapePtr& pChild = rChildren[i]; ++ sal_Int32 nZOrderOff = pChild->getZOrderOff(); ++ if (nZOrderOff <= 0) ++ continue; ++ ++ // Increase my ZOrder by nZOrderOff. ++ pChild->setZOrder(pChild->getZOrder() + nZOrderOff); ++ pChild->setZOrderOff(0); ++ ++ for (sal_Int32 j = 0; j < nZOrderOff; ++j) ++ { ++ size_t nIndex = i + j + 1; ++ if (nIndex >= rChildren.size()) ++ break; ++ ++ // Decrease the ZOrder of the next nZOrderOff elements by one. ++ const ShapePtr& pNext = rChildren[nIndex]; ++ pNext->setZOrder(pNext->getZOrder() - 1); ++ } ++ } ++ ++ // Now that the ZOrders are adjusted, sort the children. ++ std::sort(rChildren.begin(), rChildren.end(), ++ [](const ShapePtr& a, const ShapePtr& b) { return a->getZOrder() < b->getZOrder(); }); + } + + void ShapeCreationVisitor::visit(ShapeAtom& /*rAtom*/) +@@ -235,7 +281,7 @@ + void ShapeLayoutingVisitor::visit(ConstraintAtom& rAtom) + { + if (meLookFor == CONSTRAINT) +- rAtom.parseConstraint(maConstraints); ++ rAtom.parseConstraint(maConstraints, /*bRequireForName=*/true); + } + + void ShapeLayoutingVisitor::visit(AlgAtom& rAtom) +diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.hxx b/oox/source/drawingml/diagram/layoutatomvisitors.hxx +index 2997391..f395f6a 100644 +--- a/oox/source/drawingml/diagram/layoutatomvisitors.hxx ++++ b/oox/source/drawingml/diagram/layoutatomvisitors.hxx +@@ -33,6 +33,8 @@ + ShapePtr mpParentShape; + const Diagram& mrDgm; + sal_Int32 mnCurrIdx; ++ sal_Int32 mnCurrStep = 0; ++ sal_Int32 mnCurrCnt = 0; + const dgm::Point* mpCurrentNode; + + void defaultVisit(LayoutAtom const & rAtom); +diff --git a/oox/source/drawingml/diagram/layoutnodecontext.cxx b/oox/source/drawingml/diagram/layoutnodecontext.cxx +index 257f490..ad62ba5 100644 +--- a/oox/source/drawingml/diagram/layoutnodecontext.cxx ++++ b/oox/source/drawingml/diagram/layoutnodecontext.cxx +@@ -209,6 +209,8 @@ + + pShape->setDiagramRotation(rAttribs.getInteger(XML_rot, 0) * PER_DEGREE); + ++ pShape->setZOrderOff(rAttribs.getInteger(XML_zOrderOff, 0)); ++ + ShapeAtomPtr pAtom( new ShapeAtom(mpNode->getLayoutNode(), pShape) ); + LayoutAtom::connect(mpNode, pAtom); + return new ShapeContext( *this, ShapePtr(), pShape ); +diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx +index 2926614..16bc511 100644 +--- a/oox/source/drawingml/shape.cxx ++++ b/oox/source/drawingml/shape.cxx +@@ -175,6 +175,8 @@ + , maLinkedTxbxAttr() + , mbHasLinkedTxbx(false) + , maDiagramDoms( pSourceShape->maDiagramDoms ) ++, mnZOrder(pSourceShape->mnZOrder) ++, mnZOrderOff(pSourceShape->mnZOrderOff) + {} + + Shape::~Shape() diff --git a/libreoffice.changes b/libreoffice.changes index 663f272..f05eabb 100644 --- a/libreoffice.changes +++ b/libreoffice.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Dec 21 15:01:49 UTC 2018 - Andras Timar + +- [Bug 1112113] LO-L3: [PPTX] SmartArt: Basic rendering of Accent Process and Continuous Block Process + * bsc1112113.patch + ------------------------------------------------------------------- Thu Dec 13 11:23:56 UTC 2018 - Tomáš Chvátal diff --git a/libreoffice.spec b/libreoffice.spec index 17d0006..6c8aa06 100644 --- a/libreoffice.spec +++ b/libreoffice.spec @@ -12,7 +12,7 @@ # license that conforms to the Open Source Definition (Version 1.9) # 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/ # @@ -107,6 +107,8 @@ Patch6: 0001-call-System.runFinalizersOnExit-by-reflection-since-.patch Patch11: boost_1_69.patch # PATCH-FIX-UPSTREAM libreoffice-poppler-0.71.patch -- Fix build with poppler 0.71 Patch12: libreoffice-poppler-0.71.patch +# [Bug 1112113] LO-L3: [PPTX] SmartArt: Basic rendering of Accent Process and Continuous Block Process +Patch13: bsc1112113.patch # try to save space by using hardlinks Patch990: install-with-hardlinks.diff BuildRequires: %{name}-share-linker @@ -955,6 +957,7 @@ Provides %{langname} translations and additional resources (help files, etc.) fo %patch6 -p1 %patch11 -p1 %patch12 -p1 +%patch13 -p1 %patch990 -p1 # Disable some of the failing tests (some are random)