diff options
author | Armin Le Grand <alg@apache.org> | 2014-07-23 15:09:02 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2014-07-24 12:59:30 +0100 |
commit | ba4b92389bd7df92e1eddf025ad03ee6355cabfa (patch) | |
tree | a35abb7b949e03711511db946ff10d0b7a47b44c /svgio | |
parent | 81b594afa7162552fc2489ba0c7e1e8b5addb4f2 (diff) |
Related: #i125292#, #i125293# enhanced CssStyle handling in SVG import
(cherry picked from commit 7fc272837995079247594e173d977a2e541a7042)
Conflicts:
svgio/source/svgreader/svgnode.cxx
Change-Id: I1896d9859e07a8edfb46ede6a237efa3edce5ab1
Diffstat (limited to 'svgio')
-rw-r--r-- | svgio/source/svgreader/svgnode.cxx | 93 | ||||
-rw-r--r-- | svgio/source/svgreader/svgtspannode.cxx | 3 |
2 files changed, 67 insertions, 29 deletions
diff --git a/svgio/source/svgreader/svgnode.cxx b/svgio/source/svgreader/svgnode.cxx index e37594da76d1..431ba0c26a9f 100644 --- a/svgio/source/svgreader/svgnode.cxx +++ b/svgio/source/svgreader/svgnode.cxx @@ -48,6 +48,32 @@ namespace svgio if(rDocument.hasSvgStyleAttributesById()) { + // #i125293# If we have CssStyles we need to buuild a linked list of SvgStyleAttributes + // which represent this for the current object. There are various methods to + // specify CssStyles which need to be taken into account in a given order: + // - 'id' element + // - 'class' element(s) + // - type-dependent elements (e..g. 'rect' for all rect elements) + // - local firect attributes (rOriginal) + // - inherited attributes (up the hierarchy) + // The first three will be collected in maCssStyleVector for the current element + // (once, this will not change) and be linked in the needed order using the + // get/setCssStyleParent at the SvgStyleAttributes which will be used preferred in + // member evaluation over the existing parent hierarchy + + // check for 'id' references + if(getId()) + { + // search for CSS style equal to Id + const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(*getId()); + + if(pNew) + { + const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew); + } + } + + // check for 'class' references if(getClass()) { // find all referenced CSS styles, a list of entries is allowed @@ -87,20 +113,10 @@ namespace svgio } } - if(maCssStyleVector.empty() && getId()) - { - // if none found, search for CSS style equal to Id - const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(*getId()); - - if(pNew) - { - const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew); - } - } - - if(maCssStyleVector.empty() && !rClassStr.isEmpty()) + // check for class-dependent references to CssStyles + if(rClassStr.getLength()) { - // if none found, search for CSS style equal to class type + // search for CSS style equal to class type const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(rClassStr); if(pNew) @@ -111,29 +127,50 @@ namespace svgio } } - if(!maCssStyleVector.empty()) + if(maCssStyleVector.empty()) { - // #i123510# if CSS styles were found, create a linked list with rOriginal as parent - // and all CSS styles as linked children, so that the style attribute has - // priority over the CSS style. If there is no style attribute this means that - // no values are set at rOriginal, thus it is still correct to have that order. - // Repeated style requests should only be issued from sub-Text nodes and I'm not - // sure if in-between text nodes may build other chains (should not happen). But - // it's only a re-chaining with pointers (cheap), so allow to do it every time. - SvgStyleAttributes* pCurrent = const_cast< SvgStyleAttributes* >(&rOriginal); - pCurrent->setCssStyleParent(0); - - for(sal_uInt32 a(0); a < maCssStyleVector.size(); a++) + // return original if no CssStlyes found + return &rOriginal; + } + else + { + // #i125293# rOriginal will be the last element in the linked list; use no CssStyleParent + // there (reset it) to ensure that the parent hierarchy will be used when it's base + // is referenced. This new chaning inserts the CssStyles before the original style, + // this makes the whole process much safer since the original style when used will + // be not different to the situation without CssStyles; thus loops which may be caused + // by trying to use the parent hierarchy of the owner of the style will be avoided + // already in this mechanism. It's still good to keep the supportsParentStyle + // from #i125258# in place, though. + // This chain building using pointers will be done every time when checkForCssStyle + // is used (not the search, only the chaining). This is needed since the CssStyles + // themselves will be potentially used multiple times. It is not expensive since it's + // only changing some pointers. + // The alternative would be to create the style hierarchy for every element (or even + // for the element containing the hierarchy) in a vector of pointers and to use that. + // Resetting the CssStyleParent on rOriginal is probably not needeed + // but simply safer to do. + const_cast< SvgStyleAttributes& >(rOriginal).setCssStyleParent(0); + + // loop over the existing CssStyles and link them. There is a first one, take + // as current + SvgStyleAttributes* pCurrent = const_cast< SvgStyleAttributes* >(maCssStyleVector[0]); + + for(sal_uInt32 a(1); a < maCssStyleVector.size(); a++) { SvgStyleAttributes* pNext = const_cast< SvgStyleAttributes* >(maCssStyleVector[a]); pCurrent->setCssStyleParent(pNext); pCurrent = pNext; - pCurrent->setCssStyleParent(0); } - } - return &rOriginal; + // pCurrent is the last used CssStyle, let it point to the original style + pCurrent->setCssStyleParent(&rOriginal); + + // return 1st CssStyle as style chain start element (only for the + // local element, still no hierarchy used here) + return maCssStyleVector[0]; + } } SvgNode::SvgNode( diff --git a/svgio/source/svgreader/svgtspannode.cxx b/svgio/source/svgreader/svgtspannode.cxx index cc88e0cc0d3b..139724934303 100644 --- a/svgio/source/svgreader/svgtspannode.cxx +++ b/svgio/source/svgreader/svgtspannode.cxx @@ -38,7 +38,8 @@ namespace svgio const SvgStyleAttributes* SvgTspanNode::getSvgStyleAttributes() const { - return &maSvgStyleAttributes; + // #i125293# Need to support CssStyles in tspan text sections + return checkForCssStyle(OUString("tspan"), maSvgStyleAttributes); } void SvgTspanNode::parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent) |