From 09127d6622f9d0f8b9e1a4c6470cef41a10a8355 Mon Sep 17 00:00:00 2001 From: Joren De Cuyper Date: Wed, 16 Jul 2014 09:42:11 +0000 Subject: Resolves: #i125258# reworked some of the style hierarchy stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 3b13e15a7174f5177700fdcd4864b64fbf0b3535) Conflicts: svgio/inc/svgio/svgreader/svgstylenode.hxx svgio/source/svgreader/svggnode.cxx svgio/source/svgreader/svgstyleattributes.cxx svgio/source/svgreader/svgstylenode.cxx svgio/source/svgreader/svgsvgnode.cxx (cherry picked from commit 0879a639bc7c734f0847f74b965809f9107b3195) Conflicts: svgio/source/svgreader/svggnode.cxx Revert "fdo#74743 avoid infinite loop when gathering "svg" element styles" This reverts commit 3b7472b284131c09d91b69f26d5d26d54648f939. Commit 0879a639bc7c734f0847f74b965809f9107b3195 didn't revert all changes, so we ran into problems getting the css style correctly. Conflicts: svgio/source/svgreader/svgstyleattributes.cxx svgio/source/svgreader/svgsvgnode.cxx Reviewed-on: https://gerrit.libreoffice.org/10455 Reviewed-by: Tomaž Vajngerl Tested-by: Tomaž Vajngerl (cherry picked from commit 3d3401a6397e893808309ec374f5d8f890144906) Fix build: incorrect revertion svgio Incorrect revertion in commit 3d3401a6397e893808309ec374f5d8f890144906 Reviewed-on: https://gerrit.libreoffice.org/10466 Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara (cherry picked from commit 2662df924f7d5e2d65ec727be99e39c18e1e3e7b) Change-Id: I5cfe6871ab235305f206d83d643884b493901dfe 4d17c6d599482de005c009638d03ca851491f700 f4abac2670b083ebbc75c2fe06ae9e100072ef00 Reviewed-on: https://gerrit.libreoffice.org/10485 Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- svgio/inc/svgio/svgreader/svgnode.hxx | 3 ++ svgio/inc/svgio/svgreader/svgstyleattributes.hxx | 1 + svgio/inc/svgio/svgreader/svgstylenode.hxx | 3 ++ svgio/inc/svgio/svgreader/svgsvgnode.hxx | 7 +++ svgio/source/svgreader/svggnode.cxx | 42 ++++++++++++----- svgio/source/svgreader/svggradientnode.cxx | 1 + svgio/source/svgreader/svgnode.cxx | 6 +++ svgio/source/svgreader/svgstyleattributes.cxx | 29 +++++++++--- svgio/source/svgreader/svgstylenode.cxx | 13 +++++ svgio/source/svgreader/svgsvgnode.cxx | 60 +++++++++++++++++++----- svgio/source/svgreader/svgtitledescnode.cxx | 1 + 11 files changed, 137 insertions(+), 29 deletions(-) (limited to 'svgio') diff --git a/svgio/inc/svgio/svgreader/svgnode.hxx b/svgio/inc/svgio/svgreader/svgnode.hxx index 38ae2438cc76..cc88b264370e 100644 --- a/svgio/inc/svgio/svgreader/svgnode.hxx +++ b/svgio/inc/svgio/svgreader/svgnode.hxx @@ -127,6 +127,9 @@ namespace svgio virtual void parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent); virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const; + /// #i125258# tell if this node is allowed to have a parent style (e.g. defs do not) + virtual bool supportsParentStyle() const; + /// basic data read access SVGToken getType() const { return maType; } const SvgDocument& getDocument() const { return mrDocument; } diff --git a/svgio/inc/svgio/svgreader/svgstyleattributes.hxx b/svgio/inc/svgio/svgreader/svgstyleattributes.hxx index 1f16a3bb4221..345eb651810a 100644 --- a/svgio/inc/svgio/svgreader/svgstyleattributes.hxx +++ b/svgio/inc/svgio/svgreader/svgstyleattributes.hxx @@ -283,6 +283,7 @@ namespace svgio ~SvgStyleAttributes(); /// fill content + bool isFillSet() const; // #i125258# ask if fill is a direct hard attribute (no hierarchy) const basegfx::BColor* getFill() const; void setFill(const SvgPaint& rFill) { maFill = rFill; } diff --git a/svgio/inc/svgio/svgreader/svgstylenode.hxx b/svgio/inc/svgio/svgreader/svgstylenode.hxx index 23e0230d644b..fc851dfe6940 100644 --- a/svgio/inc/svgio/svgreader/svgstylenode.hxx +++ b/svgio/inc/svgio/svgreader/svgstylenode.hxx @@ -42,6 +42,9 @@ namespace svgio SvgNode* pParent); virtual ~SvgStyleNode(); + /// #i125258# tell if this node is allowed to have a parent style (e.g. defs do not) + virtual bool supportsParentStyle() const SAL_OVERRIDE; + virtual void parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent) SAL_OVERRIDE; void addCssStyleSheet(const OUString& aContent); diff --git a/svgio/inc/svgio/svgreader/svgsvgnode.hxx b/svgio/inc/svgio/svgreader/svgsvgnode.hxx index 27180bf3544c..d4fb304f653d 100644 --- a/svgio/inc/svgio/svgreader/svgsvgnode.hxx +++ b/svgio/inc/svgio/svgreader/svgsvgnode.hxx @@ -41,6 +41,13 @@ namespace svgio SvgNumber maHeight; SvgNumber maVersion; + /// #i125258# bitfield + bool mbStyleAttributesInitialized : 1; + + // #i125258# on-demand init hard attributes when this is the outmost svg element + // and more (see implementation) + void initializeStyleAttributes(); + public: SvgSvgNode( SvgDocument& rDocument, diff --git a/svgio/source/svgreader/svggnode.cxx b/svgio/source/svgreader/svggnode.cxx index 82d3d5d124f2..c3957c729fa9 100644 --- a/svgio/source/svgreader/svggnode.cxx +++ b/svgio/source/svgreader/svggnode.cxx @@ -43,7 +43,16 @@ namespace svgio const SvgStyleAttributes* SvgGNode::getSvgStyleAttributes() const { - return checkForCssStyle(OUString("g"), maSvgStyleAttributes); + if (SVGTokenDefs == getType()) + { + // #i125258# call parent for SVGTokenDefs + return SvgNode::getSvgStyleAttributes(); + } + else + { + // #i125258# for SVGTokenG take CssStyles into account + return checkForCssStyle(OUString("g"), maSvgStyleAttributes); + } } void SvgGNode::parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent) @@ -81,22 +90,31 @@ namespace svgio void SvgGNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const { - const SvgStyleAttributes* pStyle = getSvgStyleAttributes(); - - if(pStyle) + if(SVGTokenDefs == getType()) { - const double fOpacity(pStyle->getOpacity().getNumber()); + // #i125258# no decompose needed for defs element, call parent for SVGTokenDefs + SvgNode::decomposeSvgNode(rTarget, bReferenced); + } + else + { + // #i125258# for SVGTokenG decompose childs + const SvgStyleAttributes* pStyle = getSvgStyleAttributes(); - if(fOpacity > 0.0 && Display_none != getDisplay()) + if(pStyle) { - drawinglayer::primitive2d::Primitive2DSequence aContent; - - // decompose children - SvgNode::decomposeSvgNode(aContent, bReferenced); + const double fOpacity(pStyle->getOpacity().getNumber()); - if(aContent.hasElements()) + if(fOpacity > 0.0 && Display_none != getDisplay()) { - pStyle->add_postProcess(rTarget, aContent, getTransform()); + drawinglayer::primitive2d::Primitive2DSequence aContent; + + // decompose children + SvgNode::decomposeSvgNode(aContent, bReferenced); + + if(aContent.hasElements()) + { + pStyle->add_postProcess(rTarget, aContent, getTransform()); + } } } } diff --git a/svgio/source/svgreader/svggradientnode.cxx b/svgio/source/svgreader/svggradientnode.cxx index e22ffba7f0cd..893ff9657b93 100644 --- a/svgio/source/svgreader/svggradientnode.cxx +++ b/svgio/source/svgreader/svggradientnode.cxx @@ -54,6 +54,7 @@ namespace svgio maXLink(), mpXLink(0) { + OSL_ENSURE(aType == SVGTokenLinearGradient || aType == SVGTokenRadialGradient, "SvgGradientNode should ony be used for Linear and Radial gradient (!)"); } SvgGradientNode::~SvgGradientNode() diff --git a/svgio/source/svgreader/svgnode.cxx b/svgio/source/svgreader/svgnode.cxx index 293834cdf5e9..e37594da76d1 100644 --- a/svgio/source/svgreader/svgnode.cxx +++ b/svgio/source/svgreader/svgnode.cxx @@ -29,6 +29,12 @@ namespace svgio { namespace svgreader { + /// #i125258# + bool SvgNode::supportsParentStyle() const + { + return true; + } + const SvgStyleAttributes* SvgNode::getSvgStyleAttributes() const { return 0; diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx index 3e14c0317715..985283386cb3 100644 --- a/svgio/source/svgreader/svgstyleattributes.cxx +++ b/svgio/source/svgreader/svgstyleattributes.cxx @@ -203,14 +203,16 @@ namespace svgio const SvgStyleAttributes* SvgStyleAttributes::getParentStyle() const { - const SvgStyleAttributes* pParentStyle = getCssStyleParent(); + if(getCssStyleParent()) + { + return getCssStyleParent(); + } - // no parent style set, check parent for its style attributes - if(pParentStyle == NULL && mrOwner.getParent() != NULL) - pParentStyle = mrOwner.getParent()->getSvgStyleAttributes(); + if(mrOwner.supportsParentStyle() && mrOwner.getParent()) + { + return mrOwner.getParent()->getSvgStyleAttributes(); + } - if (pParentStyle != this) // to prevent infinite loop - return pParentStyle; return NULL; } @@ -1806,6 +1808,21 @@ namespace svgio } } + // #i125258# ask if fill is a direct hard attribute (no hierarchy) + bool SvgStyleAttributes::isFillSet() const + { + if(mbIsClipPathContent) + { + return false; + } + else if(maFill.isSet()) + { + return true; + } + + return false; + } + const basegfx::BColor* SvgStyleAttributes::getFill() const { if(mbIsClipPathContent) diff --git a/svgio/source/svgreader/svgstylenode.cxx b/svgio/source/svgreader/svgstylenode.cxx index 1ffbade7f8db..99f7ff53e9ce 100644 --- a/svgio/source/svgreader/svgstylenode.cxx +++ b/svgio/source/svgreader/svgstylenode.cxx @@ -42,6 +42,19 @@ namespace svgio } } + // #i125258# no parent when we are a CssStyle holder to break potential loops because + // when using CssStyles we jump uncontrolled inside the node tree hierarchy + bool SvgStyleNode::supportsParentStyle() const + { + if(isTextCss()) + { + return false; + } + + // call parent + return SvgNode::supportsParentStyle(); + } + void SvgStyleNode::parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent) { // call parent diff --git a/svgio/source/svgreader/svgsvgnode.cxx b/svgio/source/svgreader/svgsvgnode.cxx index 73a5efbdda9e..6c39cc996c31 100644 --- a/svgio/source/svgreader/svgsvgnode.cxx +++ b/svgio/source/svgreader/svgsvgnode.cxx @@ -42,12 +42,50 @@ namespace svgio maY(), maWidth(), maHeight(), - maVersion() + maVersion(), + mbStyleAttributesInitialized(false) // #i125258# { - if(!getParent()) + } + + // #i125258# + void SvgSvgNode::initializeStyleAttributes() + { + if(!mbStyleAttributesInitialized) { - // initial fill is black - maSvgStyleAttributes.setFill(SvgPaint(basegfx::BColor(0.0, 0.0, 0.0), true, true)); + // #i125258# determine if initial values need to be initialized with hard values + // for the case that this is the outmost SVG statement and it has no parent + // stale (CssStyle for svg may be defined) + bool bSetInitialValues(true); + + if(getParent()) + { + // #i125258# no initial values when it's a SVG element embedded in SVG + bSetInitialValues = false; + } + + if(bSetInitialValues) + { + const SvgStyleAttributes* pStyles = getSvgStyleAttributes(); + + if(pStyles && pStyles->getParentStyle()) + { + // #i125258# no initial values when SVG has a parent style (probably CssStyle) + bSetInitialValues = false; + } + } + + if(bSetInitialValues) + { + // #i125258# only set if not yet initialized (SvgSvgNode::parseAttribute is already done, + // just setting may revert an already set valid value) + if(!maSvgStyleAttributes.isFillSet()) + { + // #i125258# initial fill is black (see SVG1.1 spec) + maSvgStyleAttributes.setFill(SvgPaint(basegfx::BColor(0.0, 0.0, 0.0), true, true)); + } + } + + mbStyleAttributesInitialized = true; } } @@ -58,13 +96,8 @@ namespace svgio const SvgStyleAttributes* SvgSvgNode::getSvgStyleAttributes() const { - const SvgStyleAttributes* aCheckCssStyle = checkForCssStyle(OUString("svg"), maSvgStyleAttributes); - const SvgStyleAttributes* aGetCssStyleParent = maSvgStyleAttributes.getCssStyleParent(); - - if (aGetCssStyleParent == NULL) - return aCheckCssStyle; - - return aGetCssStyleParent; + // #i125258# svg node can have CssStyles, too, so check for it here + return checkForCssStyle(OUString("svg"), maSvgStyleAttributes); } void SvgSvgNode::parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent) @@ -250,6 +283,11 @@ namespace svgio { drawinglayer::primitive2d::Primitive2DSequence aSequence; + // #i125258# check now if we need to init some style settings locally. Do not do this + // in the constructor, there is not yet informatikon e.g. about existing CssStyles. + // Here all nodes are read and interpreted + const_cast< SvgSvgNode* >(this)->initializeStyleAttributes(); + // decompose children SvgNode::decomposeSvgNode(aSequence, bReferenced); diff --git a/svgio/source/svgreader/svgtitledescnode.cxx b/svgio/source/svgreader/svgtitledescnode.cxx index 836d40f0bb63..d98cf2abba58 100644 --- a/svgio/source/svgreader/svgtitledescnode.cxx +++ b/svgio/source/svgreader/svgtitledescnode.cxx @@ -32,6 +32,7 @@ namespace svgio : SvgNode(aType, rDocument, pParent), maText() { + OSL_ENSURE(aType == SVGTokenTitle || aType == SVGTokenDesc, "SvgTitleDescNode should ony be used for Title and Desc (!)"); } SvgTitleDescNode::~SvgTitleDescNode() -- cgit v1.2.3