diff options
Diffstat (limited to 'svgio/source/svgreader/svgdocumenthandler.cxx')
-rw-r--r-- | svgio/source/svgreader/svgdocumenthandler.cxx | 760 |
1 files changed, 380 insertions, 380 deletions
diff --git a/svgio/source/svgreader/svgdocumenthandler.cxx b/svgio/source/svgreader/svgdocumenthandler.cxx index d32534d9896e..9123135fa565 100644 --- a/svgio/source/svgreader/svgdocumenthandler.cxx +++ b/svgio/source/svgreader/svgdocumenthandler.cxx @@ -176,455 +176,455 @@ namespace svgio { if (bSkip) return; - if(!aName.isEmpty()) + if(aName.isEmpty()) + return; + + const SVGToken aSVGToken(StrToSVGToken(aName, false)); + + switch(aSVGToken) { - const SVGToken aSVGToken(StrToSVGToken(aName, false)); + /// structural elements + case SVGTokenSymbol: + { + /// new basic node for Symbol. Content gets scanned, but + /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced) + mpTarget = new SvgSymbolNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenDefs: + case SVGTokenG: + { + /// new node for Defs/G + mpTarget = new SvgGNode(aSVGToken, maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenSvg: + { + /// new node for Svg + mpTarget = new SvgSvgNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenUse: + { + /// new node for Use + mpTarget = new SvgUseNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenA: + { + /// new node for A + mpTarget = new SvgANode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } - switch(aSVGToken) + /// shape elements + case SVGTokenCircle: { - /// structural elements - case SVGTokenSymbol: - { - /// new basic node for Symbol. Content gets scanned, but - /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced) - mpTarget = new SvgSymbolNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenDefs: - case SVGTokenG: - { - /// new node for Defs/G - mpTarget = new SvgGNode(aSVGToken, maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenSvg: - { - /// new node for Svg - mpTarget = new SvgSvgNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenUse: - { - /// new node for Use - mpTarget = new SvgUseNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenA: - { - /// new node for A - mpTarget = new SvgANode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } + /// new node for Circle + mpTarget = new SvgCircleNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenEllipse: + { + /// new node for Ellipse + mpTarget = new SvgEllipseNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenLine: + { + /// new node for Line + mpTarget = new SvgLineNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenPath: + { + /// new node for Path + mpTarget = new SvgPathNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenPolygon: + { + /// new node for Polygon + mpTarget = new SvgPolyNode(maDocument, mpTarget, false); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenPolyline: + { + /// new node for Polyline + mpTarget = new SvgPolyNode(maDocument, mpTarget, true); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenRect: + { + /// new node for Rect + mpTarget = new SvgRectNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenImage: + { + /// new node for Image + mpTarget = new SvgImageNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } - /// shape elements - case SVGTokenCircle: - { - /// new node for Circle - mpTarget = new SvgCircleNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenEllipse: - { - /// new node for Ellipse - mpTarget = new SvgEllipseNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenLine: - { - /// new node for Line - mpTarget = new SvgLineNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenPath: - { - /// new node for Path - mpTarget = new SvgPathNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenPolygon: - { - /// new node for Polygon - mpTarget = new SvgPolyNode(maDocument, mpTarget, false); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenPolyline: - { - /// new node for Polyline - mpTarget = new SvgPolyNode(maDocument, mpTarget, true); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenRect: - { - /// new node for Rect - mpTarget = new SvgRectNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenImage: - { - /// new node for Image - mpTarget = new SvgImageNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } + /// title and description + case SVGTokenTitle: + case SVGTokenDesc: + { + /// new node for Title and/or Desc + mpTarget = new SvgTitleDescNode(aSVGToken, maDocument, mpTarget); + break; + } - /// title and description - case SVGTokenTitle: - case SVGTokenDesc: - { - /// new node for Title and/or Desc - mpTarget = new SvgTitleDescNode(aSVGToken, maDocument, mpTarget); - break; - } + /// gradients + case SVGTokenLinearGradient: + case SVGTokenRadialGradient: + { + mpTarget = new SvgGradientNode(aSVGToken, maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } - /// gradients - case SVGTokenLinearGradient: - case SVGTokenRadialGradient: - { - mpTarget = new SvgGradientNode(aSVGToken, maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } + /// gradient stops + case SVGTokenStop: + { + mpTarget = new SvgGradientStopNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } - /// gradient stops - case SVGTokenStop: - { - mpTarget = new SvgGradientStopNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } + /// text + case SVGTokenText: + { + mpTarget = new SvgTextNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenTspan: + { + mpTarget = new SvgTspanNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenTref: + { + mpTarget = new SvgTrefNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenTextPath: + { + mpTarget = new SvgTextPathNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } - /// text - case SVGTokenText: - { - mpTarget = new SvgTextNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenTspan: - { - mpTarget = new SvgTspanNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenTref: + /// styles (as stylesheets) + case SVGTokenStyle: + { + SvgStyleNode* pNew = new SvgStyleNode(maDocument, mpTarget); + mpTarget = pNew; + const sal_uInt32 nAttributes(xAttribs->getLength()); + + if(0 == nAttributes) { - mpTarget = new SvgTrefNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; + // #i125326# no attributes, thus also no type="text/css". This is allowed to be missing, + // thus do mark this style as CssStyle. This is required to read the contained + // text (which defines the css style) + pNew->setTextCss(true); } - case SVGTokenTextPath: + else { - mpTarget = new SvgTextPathNode(maDocument, mpTarget); + // #i125326# there are attributes, read them. This will set isTextCss to true if + // a type="text/css" is contained as exact match, else not mpTarget->parseAttributes(xAttribs); - break; } - /// styles (as stylesheets) - case SVGTokenStyle: + if(pNew->isTextCss()) { - SvgStyleNode* pNew = new SvgStyleNode(maDocument, mpTarget); - mpTarget = pNew; - const sal_uInt32 nAttributes(xAttribs->getLength()); - - if(0 == nAttributes) - { - // #i125326# no attributes, thus also no type="text/css". This is allowed to be missing, - // thus do mark this style as CssStyle. This is required to read the contained - // text (which defines the css style) - pNew->setTextCss(true); - } - else - { - // #i125326# there are attributes, read them. This will set isTextCss to true if - // a type="text/css" is contained as exact match, else not - mpTarget->parseAttributes(xAttribs); - } - - if(pNew->isTextCss()) - { - // if it is a Css style, allow reading text between the start and end tag (see - // SvgDocHdl::characters for details) - maCssContents.emplace_back(); - } - break; + // if it is a Css style, allow reading text between the start and end tag (see + // SvgDocHdl::characters for details) + maCssContents.emplace_back(); } + break; + } - /// structural elements clip-path and mask. Content gets scanned, but - /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced) - case SVGTokenClipPathNode: - { - /// new node for ClipPath - mpTarget = new SvgClipPathNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } - case SVGTokenMask: - { - /// new node for Mask - mpTarget = new SvgMaskNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } + /// structural elements clip-path and mask. Content gets scanned, but + /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced) + case SVGTokenClipPathNode: + { + /// new node for ClipPath + mpTarget = new SvgClipPathNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } + case SVGTokenMask: + { + /// new node for Mask + mpTarget = new SvgMaskNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } - /// structural element marker - case SVGTokenMarker: - { - /// new node for marker - mpTarget = new SvgMarkerNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } + /// structural element marker + case SVGTokenMarker: + { + /// new node for marker + mpTarget = new SvgMarkerNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } - /// structural element pattern - case SVGTokenPattern: - { - /// new node for pattern - mpTarget = new SvgPatternNode(maDocument, mpTarget); - mpTarget->parseAttributes(xAttribs); - break; - } + /// structural element pattern + case SVGTokenPattern: + { + /// new node for pattern + mpTarget = new SvgPatternNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } - // ignore FlowRoot and child nodes - case SVGTokenFlowRoot: - { - bSkip = true; - break; - } + // ignore FlowRoot and child nodes + case SVGTokenFlowRoot: + { + bSkip = true; + break; + } - default: - { - /// invalid token, ignore - SAL_WARN( "svgio", "Unknown Base SvgToken <" + aName + "> (!)" ); - break; - } + default: + { + /// invalid token, ignore + SAL_WARN( "svgio", "Unknown Base SvgToken <" + aName + "> (!)" ); + break; } } } void SvgDocHdl::endElement( const OUString& aName ) { - if(!aName.isEmpty()) + if(aName.isEmpty()) + return; + + const SVGToken aSVGToken(StrToSVGToken(aName, false)); + SvgNode* pWhitespaceCheck(SVGTokenText == aSVGToken ? mpTarget : nullptr); + SvgStyleNode* pCssStyle(SVGTokenStyle == aSVGToken ? static_cast< SvgStyleNode* >(mpTarget) : nullptr); + SvgTitleDescNode* pSvgTitleDescNode(SVGTokenTitle == aSVGToken || SVGTokenDesc == aSVGToken ? static_cast< SvgTitleDescNode* >(mpTarget) : nullptr); + + // if we are in skipping mode and we reach the flowRoot end tag: stop skipping mode + if(bSkip && aSVGToken == SVGTokenFlowRoot) + bSkip = false; + // we are in skipping mode: do nothing until we found the flowRoot end tag + else if(bSkip) + return; + + switch(aSVGToken) { - const SVGToken aSVGToken(StrToSVGToken(aName, false)); - SvgNode* pWhitespaceCheck(SVGTokenText == aSVGToken ? mpTarget : nullptr); - SvgStyleNode* pCssStyle(SVGTokenStyle == aSVGToken ? static_cast< SvgStyleNode* >(mpTarget) : nullptr); - SvgTitleDescNode* pSvgTitleDescNode(SVGTokenTitle == aSVGToken || SVGTokenDesc == aSVGToken ? static_cast< SvgTitleDescNode* >(mpTarget) : nullptr); - - // if we are in skipping mode and we reach the flowRoot end tag: stop skipping mode - if(bSkip && aSVGToken == SVGTokenFlowRoot) - bSkip = false; - // we are in skipping mode: do nothing until we found the flowRoot end tag - else if(bSkip) - return; - - switch(aSVGToken) - { - /// valid tokens for which a new one was created - - /// structural elements - case SVGTokenDefs: - case SVGTokenG: - case SVGTokenSvg: - case SVGTokenSymbol: - case SVGTokenUse: - case SVGTokenA: - - /// shape elements - case SVGTokenCircle: - case SVGTokenEllipse: - case SVGTokenLine: - case SVGTokenPath: - case SVGTokenPolygon: - case SVGTokenPolyline: - case SVGTokenRect: - case SVGTokenImage: - - /// title and description - case SVGTokenTitle: - case SVGTokenDesc: - - /// gradients - case SVGTokenLinearGradient: - case SVGTokenRadialGradient: - - /// gradient stops - case SVGTokenStop: - - /// text - case SVGTokenText: - case SVGTokenTspan: - case SVGTokenTextPath: - case SVGTokenTref: - - /// styles (as stylesheets) - case SVGTokenStyle: - - /// structural elements clip-path and mask - case SVGTokenClipPathNode: - case SVGTokenMask: - - /// structural element marker - case SVGTokenMarker: - - /// structural element pattern - case SVGTokenPattern: - - /// content handling after parsing + /// valid tokens for which a new one was created + + /// structural elements + case SVGTokenDefs: + case SVGTokenG: + case SVGTokenSvg: + case SVGTokenSymbol: + case SVGTokenUse: + case SVGTokenA: + + /// shape elements + case SVGTokenCircle: + case SVGTokenEllipse: + case SVGTokenLine: + case SVGTokenPath: + case SVGTokenPolygon: + case SVGTokenPolyline: + case SVGTokenRect: + case SVGTokenImage: + + /// title and description + case SVGTokenTitle: + case SVGTokenDesc: + + /// gradients + case SVGTokenLinearGradient: + case SVGTokenRadialGradient: + + /// gradient stops + case SVGTokenStop: + + /// text + case SVGTokenText: + case SVGTokenTspan: + case SVGTokenTextPath: + case SVGTokenTref: + + /// styles (as stylesheets) + case SVGTokenStyle: + + /// structural elements clip-path and mask + case SVGTokenClipPathNode: + case SVGTokenMask: + + /// structural element marker + case SVGTokenMarker: + + /// structural element pattern + case SVGTokenPattern: + + /// content handling after parsing + { + if(mpTarget) { - if(mpTarget) - { - if(!mpTarget->getParent()) - { - // last element closing, save this tree - maDocument.appendNode(std::unique_ptr<SvgNode>(mpTarget)); - } - - mpTarget = const_cast< SvgNode* >(mpTarget->getParent()); - } - else + if(!mpTarget->getParent()) { - OSL_ENSURE(false, "Closing token, but no context (!)"); + // last element closing, save this tree + maDocument.appendNode(std::unique_ptr<SvgNode>(mpTarget)); } - break; + + mpTarget = const_cast< SvgNode* >(mpTarget->getParent()); } - default: + else { - /// invalid token, ignore + OSL_ENSURE(false, "Closing token, but no context (!)"); } + break; } - - if(pSvgTitleDescNode && mpTarget) + default: { - const OUString& aText(pSvgTitleDescNode->getText()); + /// invalid token, ignore + } + } - if(!aText.isEmpty()) + if(pSvgTitleDescNode && mpTarget) + { + const OUString& aText(pSvgTitleDescNode->getText()); + + if(!aText.isEmpty()) + { + if(SVGTokenTitle == aSVGToken) { - if(SVGTokenTitle == aSVGToken) - { - mpTarget->parseAttribute(getStrTitle(), aSVGToken, aText); - } - else // if(SVGTokenDesc == aSVGToken) - { - mpTarget->parseAttribute(getStrDesc(), aSVGToken, aText); - } + mpTarget->parseAttribute(getStrTitle(), aSVGToken, aText); + } + else // if(SVGTokenDesc == aSVGToken) + { + mpTarget->parseAttribute(getStrDesc(), aSVGToken, aText); } } + } - if(pCssStyle && pCssStyle->isTextCss()) + if(pCssStyle && pCssStyle->isTextCss()) + { + // css style parsing + if(!maCssContents.empty()) { - // css style parsing - if(!maCssContents.empty()) - { - // need to interpret css styles and remember them as StyleSheets - // #125325# Caution! the Css content may contain block comments - // (see http://www.w3.org/wiki/CSS_basics#CSS_comments). These need - // to be removed first - const OUString aCommentFreeSource(removeBlockComments(*(maCssContents.end() - 1))); - - if(aCommentFreeSource.getLength()) - { - pCssStyle->addCssStyleSheet(aCommentFreeSource); - } + // need to interpret css styles and remember them as StyleSheets + // #125325# Caution! the Css content may contain block comments + // (see http://www.w3.org/wiki/CSS_basics#CSS_comments). These need + // to be removed first + const OUString aCommentFreeSource(removeBlockComments(*(maCssContents.end() - 1))); - maCssContents.pop_back(); - } - else + if(aCommentFreeSource.getLength()) { - OSL_ENSURE(false, "Closing CssStyle, but no collector string on stack (!)"); + pCssStyle->addCssStyleSheet(aCommentFreeSource); } - } - if(pWhitespaceCheck) + maCssContents.pop_back(); + } + else { - // cleanup read strings - whiteSpaceHandling(pWhitespaceCheck, nullptr); + OSL_ENSURE(false, "Closing CssStyle, but no collector string on stack (!)"); } } + + if(pWhitespaceCheck) + { + // cleanup read strings + whiteSpaceHandling(pWhitespaceCheck, nullptr); + } } void SvgDocHdl::characters( const OUString& aChars ) { const sal_uInt32 nLength(aChars.getLength()); - if(mpTarget && nLength) + if(!(mpTarget && nLength)) + return; + + switch(mpTarget->getType()) { - switch(mpTarget->getType()) + case SVGTokenText: + case SVGTokenTspan: + case SVGTokenTextPath: { - case SVGTokenText: - case SVGTokenTspan: - case SVGTokenTextPath: - { - const auto& rChilds = mpTarget->getChildren(); - SvgCharacterNode* pTarget = nullptr; + const auto& rChilds = mpTarget->getChildren(); + SvgCharacterNode* pTarget = nullptr; - if(!rChilds.empty()) - { - pTarget = dynamic_cast< SvgCharacterNode* >(rChilds[rChilds.size() - 1].get()); - } + if(!rChilds.empty()) + { + pTarget = dynamic_cast< SvgCharacterNode* >(rChilds[rChilds.size() - 1].get()); + } - if(pTarget) - { - // concatenate to current character span - pTarget->concatenate(aChars); - } - else - { - // add character span as simplified tspan (no arguments) - // as direct child of SvgTextNode/SvgTspanNode/SvgTextPathNode - new SvgCharacterNode(maDocument, mpTarget, aChars); - } - break; + if(pTarget) + { + // concatenate to current character span + pTarget->concatenate(aChars); } - case SVGTokenStyle: + else { - SvgStyleNode& rSvgStyleNode = static_cast< SvgStyleNode& >(*mpTarget); + // add character span as simplified tspan (no arguments) + // as direct child of SvgTextNode/SvgTspanNode/SvgTextPathNode + new SvgCharacterNode(maDocument, mpTarget, aChars); + } + break; + } + case SVGTokenStyle: + { + SvgStyleNode& rSvgStyleNode = static_cast< SvgStyleNode& >(*mpTarget); - if(rSvgStyleNode.isTextCss()) + if(rSvgStyleNode.isTextCss()) + { + // collect characters for css style + if(!maCssContents.empty()) { - // collect characters for css style - if(!maCssContents.empty()) - { - const OUString aTrimmedChars(aChars.trim()); + const OUString aTrimmedChars(aChars.trim()); - if(!aTrimmedChars.isEmpty()) - { - std::vector< OUString >::iterator aString(maCssContents.end() - 1); - (*aString) += aTrimmedChars; - } - } - else + if(!aTrimmedChars.isEmpty()) { - OSL_ENSURE(false, "Closing CssStyle, but no collector string on stack (!)"); + std::vector< OUString >::iterator aString(maCssContents.end() - 1); + (*aString) += aTrimmedChars; } } - break; + else + { + OSL_ENSURE(false, "Closing CssStyle, but no collector string on stack (!)"); + } } - case SVGTokenTitle: - case SVGTokenDesc: - { - SvgTitleDescNode& rSvgTitleDescNode = static_cast< SvgTitleDescNode& >(*mpTarget); + break; + } + case SVGTokenTitle: + case SVGTokenDesc: + { + SvgTitleDescNode& rSvgTitleDescNode = static_cast< SvgTitleDescNode& >(*mpTarget); - // add text directly to SvgTitleDescNode - rSvgTitleDescNode.concatenate(aChars); - break; - } - default: - { - // characters not used by a known node - break; - } + // add text directly to SvgTitleDescNode + rSvgTitleDescNode.concatenate(aChars); + break; + } + default: + { + // characters not used by a known node + break; } } } |