[Libreoffice-commits] core.git: svgio/inc svgio/source

Armin Le Grand alg at apache.org
Wed Jul 16 04:01:25 PDT 2014


 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              |   48 +++++++++++-------
 svgio/source/svgreader/svggradientnode.cxx       |    1 
 svgio/source/svgreader/svgnode.cxx               |    6 ++
 svgio/source/svgreader/svgstyleattributes.cxx    |   22 +++++++-
 svgio/source/svgreader/svgstylenode.cxx          |   13 ++++
 svgio/source/svgreader/svgsvgnode.cxx            |   60 ++++++++++++++++++-----
 svgio/source/svgreader/svgtitledescnode.cxx      |    1 
 11 files changed, 133 insertions(+), 32 deletions(-)

New commits:
commit 0879a639bc7c734f0847f74b965809f9107b3195
Author: Armin Le Grand <alg at apache.org>
Date:   Wed Jul 16 09:42:11 2014 +0000

    Resolves: #i125258# reworked some of the style hierarchy stuff
    
    (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
    
    Change-Id: I5cfe6871ab235305f206d83d643884b493901dfe

diff --git a/svgio/inc/svgio/svgreader/svgnode.hxx b/svgio/inc/svgio/svgreader/svgnode.hxx
index 38ae243..cc88b26 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 1f16a3b..345eb65 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 23e0230..fc851df 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 27180bf..d4fb304 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 45fa6a3..c3957c7 100644
--- a/svgio/source/svgreader/svggnode.cxx
+++ b/svgio/source/svgreader/svggnode.cxx
@@ -43,13 +43,16 @@ namespace svgio
 
         const SvgStyleAttributes* SvgGNode::getSvgStyleAttributes() const
         {
-            const SvgStyleAttributes* aCheckCssStyle = checkForCssStyle(OUString("g"), maSvgStyleAttributes);
-            const SvgStyleAttributes* aGetCssStyleParent = maSvgStyleAttributes.getCssStyleParent();
-
-            if (aGetCssStyleParent == NULL)
-                return aCheckCssStyle;
-
-            return aGetCssStyleParent;
+            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)
@@ -87,22 +90,31 @@ namespace svgio
 
         void SvgGNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
         {
-            const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
-
-            if(pStyle)
+            if(SVGTokenDefs == getType())
+            {
+                // #i125258# no decompose needed for defs element, call parent for SVGTokenDefs
+                SvgNode::decomposeSvgNode(rTarget, bReferenced);
+            }
+            else
             {
-                const double fOpacity(pStyle->getOpacity().getNumber());
+                // #i125258# for SVGTokenG decompose childs
+                const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
 
-                if(fOpacity > 0.0 && Display_none != getDisplay())
+                if(pStyle)
                 {
-                    drawinglayer::primitive2d::Primitive2DSequence aContent;
+                    const double fOpacity(pStyle->getOpacity().getNumber());
 
-                    // decompose children
-                    SvgNode::decomposeSvgNode(aContent, bReferenced);
-
-                    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 e22ffba..893ff96 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 293834c..e37594d 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 1051e46..cc9d40c 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -205,9 +205,10 @@ namespace svgio
         {
             const SvgStyleAttributes* pParentStyle = 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;
@@ -1808,6 +1809,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 1ffbade..99f7ff5 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 73a5efb..6c39cc9 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 836d40f..d98cf2a 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()


More information about the Libreoffice-commits mailing list