svgio/inc/svgio/svgreader/svgnode.hxx | 18 + svgio/source/svgreader/svgcirclenode.cxx | 2 svgio/source/svgreader/svgclippathnode.cxx | 2 svgio/source/svgreader/svgellipsenode.cxx | 2 svgio/source/svgreader/svggnode.cxx | 2 svgio/source/svgreader/svggradientnode.cxx | 9 svgio/source/svgreader/svggradientstopnode.cxx | 6 svgio/source/svgreader/svgimagenode.cxx | 2 svgio/source/svgreader/svglinenode.cxx | 2 svgio/source/svgreader/svgmarkernode.cxx | 2 svgio/source/svgreader/svgmasknode.cxx | 2 svgio/source/svgreader/svgnode.cxx | 234 ++++++++++++++----------- svgio/source/svgreader/svgpathnode.cxx | 2 svgio/source/svgreader/svgpatternnode.cxx | 2 svgio/source/svgreader/svgpolynode.cxx | 2 svgio/source/svgreader/svgrectnode.cxx | 2 svgio/source/svgreader/svgstyleattributes.cxx | 28 ++ svgio/source/svgreader/svgstylenode.cxx | 47 ++++- svgio/source/svgreader/svgsvgnode.cxx | 21 +- svgio/source/svgreader/svgsymbolnode.cxx | 2 svgio/source/svgreader/svgtextnode.cxx | 2 svgio/source/svgreader/svgtextpathnode.cxx | 2 svgio/source/svgreader/svgtrefnode.cxx | 2 svgio/source/svgreader/svgtspannode.cxx | 2 svgio/source/svgreader/svgusenode.cxx | 2 25 files changed, 271 insertions(+), 128 deletions(-)
New commits: commit f00d6d2ea3e73e687edb1da4c32c0960eaf5010b Author: Armin Le Grand <a...@apache.org> Date: Fri Jul 25 15:38:47 2014 +0000 i125293 Further corrections for CssStyle handling in SVG importer diff --git a/svgio/inc/svgio/svgreader/svgnode.hxx b/svgio/inc/svgio/svgreader/svgnode.hxx index 149344f..b3aaf4e 100644 --- a/svgio/inc/svgio/svgreader/svgnode.hxx +++ b/svgio/inc/svgio/svgreader/svgnode.hxx @@ -111,13 +111,25 @@ namespace svgio /// Display value #121656# Display maDisplay; - /// CSS styles + // CSS style vector chain, used in decompose phase and built up once per node. + // It contains the StyleHierarchy for the local node. INdependent from the + // node hierarchy itself which also needs to be used in style entry solving SvgStyleAttributeVector maCssStyleVector; + /// possibbe local CssStyle, e.g. style="fill:red; stroke:red;" + SvgStyleAttributes* mpLocalCssStyle; + + /// bitfield + // flag if maCssStyleVector is already computed (done only once) + bool mbCssStyleVectorBuilt : 1; + protected: /// helper to evtl. link to css style const SvgStyleAttributes* checkForCssStyle(const rtl::OUString& rClassStr, const SvgStyleAttributes& rOriginal) const; + /// helper for filling the CssStyle vector once dependent on mbCssStyleVectorBuilt + void fillCssStyleVector(const rtl::OUString& rClassStr); + public: SvgNode( SVGToken aType, @@ -125,6 +137,10 @@ namespace svgio SvgNode* pParent); virtual ~SvgNode(); + /// scan helper to read and interpret a local CssStyle to mpLocalCssStyle + void readLocalCssStyle(const rtl::OUString& aContent); + + /// style helpers void parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs); virtual const SvgStyleAttributes* getSvgStyleAttributes() const; virtual void parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent); diff --git a/svgio/source/svgreader/svgcirclenode.cxx b/svgio/source/svgreader/svgcirclenode.cxx index 77d13eb..714d10b 100644 --- a/svgio/source/svgreader/svgcirclenode.cxx +++ b/svgio/source/svgreader/svgcirclenode.cxx @@ -69,7 +69,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenCx: diff --git a/svgio/source/svgreader/svgclippathnode.cxx b/svgio/source/svgreader/svgclippathnode.cxx index 3e4ecd80..82003ed 100644 --- a/svgio/source/svgreader/svgclippathnode.cxx +++ b/svgio/source/svgreader/svgclippathnode.cxx @@ -70,7 +70,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenTransform: diff --git a/svgio/source/svgreader/svgellipsenode.cxx b/svgio/source/svgreader/svgellipsenode.cxx index 187045a..afe650c 100644 --- a/svgio/source/svgreader/svgellipsenode.cxx +++ b/svgio/source/svgreader/svgellipsenode.cxx @@ -70,7 +70,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenCx: diff --git a/svgio/source/svgreader/svggnode.cxx b/svgio/source/svgreader/svggnode.cxx index a86f82f..97ace93 100644 --- a/svgio/source/svgreader/svggnode.cxx +++ b/svgio/source/svgreader/svggnode.cxx @@ -77,7 +77,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenTransform: diff --git a/svgio/source/svgreader/svggradientnode.cxx b/svgio/source/svgreader/svggradientnode.cxx index a270c24..48c5ea2 100644 --- a/svgio/source/svgreader/svggradientnode.cxx +++ b/svgio/source/svgreader/svggradientnode.cxx @@ -72,7 +72,12 @@ namespace svgio const SvgStyleAttributes* SvgGradientNode::getSvgStyleAttributes() const { - return &maSvgStyleAttributes; + static rtl::OUString aClassStrA(rtl::OUString::createFromAscii("linearGradient")); + static rtl::OUString aClassStrB(rtl::OUString::createFromAscii("radialGradient")); + + return checkForCssStyle( + SVGTokenLinearGradient == getType() ? aClassStrA : aClassStrB, + maSvgStyleAttributes); } void SvgGradientNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent) @@ -88,7 +93,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenX1: diff --git a/svgio/source/svgreader/svggradientstopnode.cxx b/svgio/source/svgreader/svggradientstopnode.cxx index dd7f396..51cc5cf 100644 --- a/svgio/source/svgreader/svggradientstopnode.cxx +++ b/svgio/source/svgreader/svggradientstopnode.cxx @@ -45,7 +45,9 @@ namespace svgio const SvgStyleAttributes* SvgGradientStopNode::getSvgStyleAttributes() const { - return &maSvgStyleAttributes; + static rtl::OUString aClassStr(rtl::OUString::createFromAscii("stop")); + + return checkForCssStyle(aClassStr, maSvgStyleAttributes); } void SvgGradientStopNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent) @@ -61,7 +63,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenOffset: diff --git a/svgio/source/svgreader/svgimagenode.cxx b/svgio/source/svgreader/svgimagenode.cxx index a4646e7..a96e60b 100644 --- a/svgio/source/svgreader/svgimagenode.cxx +++ b/svgio/source/svgreader/svgimagenode.cxx @@ -87,7 +87,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenPreserveAspectRatio: diff --git a/svgio/source/svgreader/svglinenode.cxx b/svgio/source/svgreader/svglinenode.cxx index 77f2eb8..ac6577c 100644 --- a/svgio/source/svgreader/svglinenode.cxx +++ b/svgio/source/svgreader/svglinenode.cxx @@ -70,7 +70,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenX1: diff --git a/svgio/source/svgreader/svgmarkernode.cxx b/svgio/source/svgreader/svgmarkernode.cxx index 8cc7e6c..134898e 100644 --- a/svgio/source/svgreader/svgmarkernode.cxx +++ b/svgio/source/svgreader/svgmarkernode.cxx @@ -73,7 +73,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenViewBox: diff --git a/svgio/source/svgreader/svgmasknode.cxx b/svgio/source/svgreader/svgmasknode.cxx index 37459af..231e4ed 100644 --- a/svgio/source/svgreader/svgmasknode.cxx +++ b/svgio/source/svgreader/svgmasknode.cxx @@ -76,7 +76,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenX: diff --git a/svgio/source/svgreader/svgnode.cxx b/svgio/source/svgreader/svgnode.cxx index 78cb1e1..cf3f8e0 100644 --- a/svgio/source/svgreader/svgnode.cxx +++ b/svgio/source/svgreader/svgnode.cxx @@ -47,96 +47,131 @@ namespace svgio return 0; } - const SvgStyleAttributes* SvgNode::checkForCssStyle(const rtl::OUString& rClassStr, const SvgStyleAttributes& rOriginal) const + void SvgNode::fillCssStyleVector(const rtl::OUString& rClassStr) { - if(maCssStyleVector.empty()) // #120435# Evaluate for CSS styles only once, this cannot change + OSL_ENSURE(!mbCssStyleVectorBuilt, "OOps, fillCssStyleVector called double ?!?"); + mbCssStyleVectorBuilt = true; + + // #125293# 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: + // - local CssStyle (independent from global CssStyles at SvgDocument) + // - 'id' CssStyle + // - 'class' CssStyle(s) + // - type-dependent elements (e..g. 'rect' for all rect elements) + // - local attributes (rOriginal) + // - inherited attributes (up the hierarchy) + // The first four 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 local CssStyle with highest priority + if(mpLocalCssStyle) { - const SvgDocument& rDocument = getDocument(); + // if we have one, use as first entry + maCssStyleVector.push_back(mpLocalCssStyle); + } + + const SvgDocument& rDocument = getDocument(); - if(rDocument.hasSvgStyleAttributesById()) + if(rDocument.hasSvgStyleAttributesById()) + { + // check for 'id' references + if(getId()) { - // #125293# 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()) + // concatenate combined style name during search for CSS style equal to Id + // when travelling over node parents + rtl::OUString aConcatenatedStyleName; + const SvgNode* pCurrent = this; + const SvgStyleAttributes* pNew = 0; + + while(!pNew && pCurrent) { - // search for CSS style equal to Id - const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(*getId()); + if(pCurrent->getId()) + { + aConcatenatedStyleName = *pCurrent->getId() + aConcatenatedStyleName; + } - if(pNew) + if(aConcatenatedStyleName.getLength()) { - const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew); + pNew = rDocument.findSvgStyleAttributesById(aConcatenatedStyleName); } + + pCurrent = pCurrent->getParent(); } - // check for 'class' references - if(getClass()) + if(pNew) { - // find all referenced CSS styles, a list of entries is allowed - const rtl::OUString* pClassList = getClass(); - const sal_Int32 nLen(pClassList->getLength()); - sal_Int32 nPos(0); - const SvgStyleAttributes* pNew = 0; + maCssStyleVector.push_back(pNew); + } + } - skip_char(*pClassList, sal_Unicode(' '), nPos, nLen); + // check for 'class' references + if(getClass()) + { + // find all referenced CSS styles (a list of entries is allowed) + const rtl::OUString* pClassList = getClass(); + const sal_Int32 nLen(pClassList->getLength()); + sal_Int32 nPos(0); + const SvgStyleAttributes* pNew = 0; - while(nPos < nLen) - { - rtl::OUStringBuffer aTokenValue; + skip_char(*pClassList, sal_Unicode(' '), nPos, nLen); - copyToLimiter(*pClassList, sal_Unicode(' '), nPos, aTokenValue, nLen); - skip_char(*pClassList, sal_Unicode(' '), nPos, nLen); + while(nPos < nLen) + { + rtl::OUStringBuffer aTokenValue; - rtl::OUString aId(rtl::OUString::createFromAscii(".")); - const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear()); + copyToLimiter(*pClassList, sal_Unicode(' '), nPos, aTokenValue, nLen); + skip_char(*pClassList, sal_Unicode(' '), nPos, nLen); - // look for CSS style common to token - aId = aId + aOUTokenValue; - pNew = rDocument.findSvgStyleAttributesById(aId); + rtl::OUString aId(rtl::OUString::createFromAscii(".")); + const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear()); - if(!pNew && rClassStr.getLength()) - { - // look for CSS style common to class.token - aId = rClassStr + aId; + // look for CSS style common to token + aId = aId + aOUTokenValue; + pNew = rDocument.findSvgStyleAttributesById(aId); - pNew = rDocument.findSvgStyleAttributesById(aId); - } + if(!pNew && rClassStr.getLength()) + { + // look for CSS style common to class.token + aId = rClassStr + aId; - if(pNew) - { - const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew); - } + pNew = rDocument.findSvgStyleAttributesById(aId); } - } - - // check for class-dependent references to CssStyles - if(rClassStr.getLength()) - { - // search for CSS style equal to class type - const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(rClassStr); if(pNew) { - const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew); + maCssStyleVector.push_back(pNew); } } } + + // check for class-dependent references to CssStyles + if(rClassStr.getLength()) + { + // search for CSS style equal to class type + const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(rClassStr); + + if(pNew) + { + maCssStyleVector.push_back(pNew); + } + } + } + } + + const SvgStyleAttributes* SvgNode::checkForCssStyle(const rtl::OUString& rClassStr, const SvgStyleAttributes& rOriginal) const + { + if(!mbCssStyleVectorBuilt) + { + // build needed CssStyleVector for local node + const_cast< SvgNode* >(this)->fillCssStyleVector(rClassStr); } if(maCssStyleVector.empty()) { - // return original if no CssStlyes found + // return given original if no CssStlyes found return &rOriginal; } else @@ -193,7 +228,9 @@ namespace svgio mpClass(0), maXmlSpace(XmlSpace_notset), maDisplay(Display_inline), - maCssStyleVector() + maCssStyleVector(), + mpLocalCssStyle(0), + mbCssStyleVectorBuilt(false) { OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)"); @@ -220,50 +257,59 @@ namespace svgio maChildren.pop_back(); } - if(mpId) delete mpId; - if(mpClass) delete mpClass; + if(mpId) + { + delete mpId; + } + + if(mpClass) + { + delete mpClass; + } + + if(mpLocalCssStyle) + { + delete mpLocalCssStyle; + } + } + + void SvgNode::readLocalCssStyle(const rtl::OUString& aContent) + { + if(!mpLocalCssStyle) + { + // create LocalCssStyle if needed but not yet added + mpLocalCssStyle = new SvgStyleAttributes(*this); + } + else + { + // 2nd fill would be an error + OSL_ENSURE(false, "Svg node has two local CssStyles, this may lead to problems (!)"); + } + + if(mpLocalCssStyle) + { + // parse and set values to it + mpLocalCssStyle->readStyle(aContent); + } + else + { + OSL_ENSURE(false, "Could not get/create a local CssStyle for a node (!)"); + } } void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs) { + // no longer need to pre-sort moving 'style' entries to the back so that + // values get overwritten - that was the previous, not complete solution for + // handling the priorities between svg and Css properties const sal_uInt32 nAttributes(xAttribs->getLength()); - // #122522# SVG defines that 'In general, this means that the presentation attributes have - // lower priority than other CSS style rules specified in author style sheets or style - // attributes.' in http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes - // (6.4 Specifying properties using the presentation attributes SVG 1.1). That means that - // e.g. font-size will appear as presentation attribute and CSS style attribute. In these - // cases, CSS style attributes need to have precedence. To do so it is possible to create - // a proirity system for all properties of a shape, but it will also work to parse the - // presentation attributes of type 'style' last, so they will overwrite the less-prioritized - // already interpreted ones. Thus, remember SVGTokenStyle entries and parse them last. - // To make this work it is required that parseAttribute is only called by parseAttributes - // which is the case. - std::vector< sal_uInt32 > aSVGTokenStyleIndexes; for(sal_uInt32 a(0); a < nAttributes; a++) { const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a)); const SVGToken aSVGToken(StrToSVGToken(aTokenName)); - if(SVGTokenStyle == aSVGToken) - { - // #122522# remember SVGTokenStyle entry - aSVGTokenStyleIndexes.push_back(a); - } - else - { - parseAttribute(aTokenName, aSVGToken, xAttribs->getValueByIndex(a)); - } - } - - // #122522# parse SVGTokenStyle entries last to override already interpreted - // 'presentation attributes' of potenially the same type - for(sal_uInt32 b(0); b < aSVGTokenStyleIndexes.size(); b++) - { - const sal_uInt32 nSVGTokenStyleIndex(aSVGTokenStyleIndexes[b]); - const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(nSVGTokenStyleIndex)); - - parseAttribute(aTokenName, SVGTokenStyle, xAttribs->getValueByIndex(nSVGTokenStyleIndex)); + parseAttribute(aTokenName, aSVGToken, xAttribs->getValueByIndex(a)); } } diff --git a/svgio/source/svgreader/svgpathnode.cxx b/svgio/source/svgreader/svgpathnode.cxx index 08b10d7..2dd5088 100644 --- a/svgio/source/svgreader/svgpathnode.cxx +++ b/svgio/source/svgreader/svgpathnode.cxx @@ -68,7 +68,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenD: diff --git a/svgio/source/svgreader/svgpatternnode.cxx b/svgio/source/svgreader/svgpatternnode.cxx index c3db761..4610649 100644 --- a/svgio/source/svgreader/svgpatternnode.cxx +++ b/svgio/source/svgreader/svgpatternnode.cxx @@ -87,7 +87,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenViewBox: diff --git a/svgio/source/svgreader/svgpolynode.cxx b/svgio/source/svgreader/svgpolynode.cxx index 1f55216..a738f80 100644 --- a/svgio/source/svgreader/svgpolynode.cxx +++ b/svgio/source/svgreader/svgpolynode.cxx @@ -72,7 +72,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenPoints: diff --git a/svgio/source/svgreader/svgrectnode.cxx b/svgio/source/svgreader/svgrectnode.cxx index 656e22a..ae096d1 100644 --- a/svgio/source/svgreader/svgrectnode.cxx +++ b/svgio/source/svgreader/svgrectnode.cxx @@ -72,7 +72,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenX: diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx index f4f6aa6..b0bf2b0 100644 --- a/svgio/source/svgreader/svgstyleattributes.cxx +++ b/svgio/source/svgreader/svgstyleattributes.cxx @@ -199,7 +199,33 @@ namespace svgio copyToLimiter(rCandidate, sal_Unicode(';'), nPos, aTokenValue, nLen); skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(';'), nPos, nLen); const rtl::OUString aOUTokenName(aTokenName.makeStringAndClear()); - const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear()); + rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear()); + + // check for '!important' CssStyle mark, currently not supported + // but neds to be extracted for correct parsing + static rtl::OUString aTokenImportant(RTL_CONSTASCII_USTRINGPARAM("!important")); + const sal_Int32 nIndexTokenImportant(aOUTokenValue.indexOf(aTokenImportant)); + + if(-1 != nIndexTokenImportant) + { + // if there currently just remove it and remove spaces to have the value only + rtl::OUString aNewOUTokenValue; + + if(nIndexTokenImportant > 0) + { + // copy content before token + aNewOUTokenValue += aOUTokenValue.copy(0, nIndexTokenImportant); + } + + if(aOUTokenValue.getLength() > nIndexTokenImportant + aTokenImportant.getLength()) + { + // copy content after token + aNewOUTokenValue += aOUTokenValue.copy(nIndexTokenImportant + aTokenImportant.getLength()); + } + + // remove spaces + aOUTokenValue = aNewOUTokenValue.trim(); + } parseStyleAttribute(aOUTokenName, StrToSVGToken(aOUTokenName), aOUTokenValue); } diff --git a/svgio/source/svgreader/svgstylenode.cxx b/svgio/source/svgreader/svgstylenode.cxx index 8f62710..de41886 100644 --- a/svgio/source/svgreader/svgstylenode.cxx +++ b/svgio/source/svgreader/svgstylenode.cxx @@ -101,17 +101,42 @@ namespace svgio while(nPos < nLen) { + // read the full style node names (may be multiple) and put to aStyleName const sal_Int32 nInitPos(nPos); - skip_char(aContent, sal_Unicode(' '), sal_Unicode('#'), nPos, nLen); + skip_char(aContent, sal_Unicode(' '), nPos, nLen); copyToLimiter(aContent, sal_Unicode('{'), nPos, aTokenValue, nLen); - const rtl::OUString aStyleName = aTokenValue.makeStringAndClear().trim(); + skip_char(aContent, sal_Unicode(' '), sal_Unicode('{'), nPos, nLen); - if(aStyleName.getLength() && nPos < nLen) + const rtl::OUString aStyleName(aTokenValue.makeStringAndClear().trim()); + const sal_Int32 nLen2(aStyleName.getLength()); + std::vector< rtl::OUString > aStyleNames; + + if(nLen2) + { + // extract names + sal_Int32 nPos2(0); + rtl::OUStringBuffer aSingleName; + + while(nPos2 < nLen2) + { + skip_char(aStyleName, sal_Unicode('#'), nPos2, nLen2); + copyToLimiter(aStyleName, sal_Unicode(' '), nPos2, aSingleName, nLen2); + skip_char(aStyleName, sal_Unicode(' '), nPos2, nLen2); + + const rtl::OUString aOUSingleName(aSingleName.makeStringAndClear().trim()); + + if(aOUSingleName.getLength()) + { + aStyleNames.push_back(aOUSingleName); + } + } + } + + if(aStyleNames.size() && nPos < nLen) { - skip_char(aContent, sal_Unicode(' '), sal_Unicode('{'), nPos, nLen); copyToLimiter(aContent, sal_Unicode('}'), nPos, aTokenValue, nLen); skip_char(aContent, sal_Unicode(' '), sal_Unicode('}'), nPos, nLen); - const rtl::OUString aStyleContent = aTokenValue.makeStringAndClear().trim(); + const rtl::OUString aStyleContent(aTokenValue.makeStringAndClear().trim()); if(aStyleContent.getLength()) { @@ -122,8 +147,16 @@ namespace svgio // fill with content pNewStyle->readStyle(aStyleContent); - // register new style at document - const_cast< SvgDocument& >(getDocument()).addSvgStyleAttributesToMapper(aStyleName, *pNewStyle); + // concatenate combined style name + rtl::OUString aConcatenatedStyleName; + + for(sal_uInt32 a(0); a < aStyleNames.size(); a++) + { + aConcatenatedStyleName += aStyleNames[a]; + } + + // register new style at document for (evtl. concatenated) stylename + const_cast< SvgDocument& >(getDocument()).addSvgStyleAttributesToMapper(aConcatenatedStyleName, *pNewStyle); } } diff --git a/svgio/source/svgreader/svgsvgnode.cxx b/svgio/source/svgreader/svgsvgnode.cxx index d426812..0a16069 100644 --- a/svgio/source/svgreader/svgsvgnode.cxx +++ b/svgio/source/svgreader/svgsvgnode.cxx @@ -76,8 +76,23 @@ namespace svgio if(pStyles && pStyles->getParentStyle()) { - // #125258# no initial values when SVG has a parent style (probably CssStyle) - bSetInitialValues = false; + // SVG has a parent style (probably CssStyle), check if fill is set there anywhere + // already. If yes, do not set the default fill (black) + bool bFillSet(false); + const SvgStyleAttributes* pParentStyle = pStyles->getParentStyle(); + + while(pParentStyle && !bFillSet) + { + bFillSet = pParentStyle->isFillSet(); + pParentStyle = pParentStyle->getParentStyle(); + } + + if(bFillSet) + { + // #125258# no initial values when SVG has a parent style at which a fill + // is already set + bSetInitialValues = false; + } } } @@ -122,7 +137,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenViewBox: diff --git a/svgio/source/svgreader/svgsymbolnode.cxx b/svgio/source/svgreader/svgsymbolnode.cxx index fdbb4c8..e799b2e 100644 --- a/svgio/source/svgreader/svgsymbolnode.cxx +++ b/svgio/source/svgreader/svgsymbolnode.cxx @@ -65,7 +65,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenViewBox: diff --git a/svgio/source/svgreader/svgtextnode.cxx b/svgio/source/svgreader/svgtextnode.cxx index 61980b3..e40a0af 100644 --- a/svgio/source/svgreader/svgtextnode.cxx +++ b/svgio/source/svgreader/svgtextnode.cxx @@ -75,7 +75,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenTransform: diff --git a/svgio/source/svgreader/svgtextpathnode.cxx b/svgio/source/svgreader/svgtextpathnode.cxx index 873b98a..7c0d874 100644 --- a/svgio/source/svgreader/svgtextpathnode.cxx +++ b/svgio/source/svgreader/svgtextpathnode.cxx @@ -306,7 +306,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenStartOffset: diff --git a/svgio/source/svgreader/svgtrefnode.cxx b/svgio/source/svgreader/svgtrefnode.cxx index bc497cd..c6f0746 100644 --- a/svgio/source/svgreader/svgtrefnode.cxx +++ b/svgio/source/svgreader/svgtrefnode.cxx @@ -62,7 +62,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenXlinkHref: diff --git a/svgio/source/svgreader/svgtspannode.cxx b/svgio/source/svgreader/svgtspannode.cxx index 6d4b188..3f280df 100644 --- a/svgio/source/svgreader/svgtspannode.cxx +++ b/svgio/source/svgreader/svgtspannode.cxx @@ -67,7 +67,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } default: diff --git a/svgio/source/svgreader/svgusenode.cxx b/svgio/source/svgreader/svgusenode.cxx index d8d1308..123dffd 100644 --- a/svgio/source/svgreader/svgusenode.cxx +++ b/svgio/source/svgreader/svgusenode.cxx @@ -71,7 +71,7 @@ namespace svgio { case SVGTokenStyle: { - maSvgStyleAttributes.readStyle(aContent); + readLocalCssStyle(aContent); break; } case SVGTokenTransform:
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits