stoc/source/corereflection/criface.cxx | 33 stoc/source/defaultregistry/defaultregistry.cxx | 18 stoc/source/implementationregistration/implreg.cxx | 492 ++++---- stoc/source/invocation/invocation.cxx | 28 stoc/source/javavm/javavm.cxx | 196 +-- stoc/source/proxy_factory/proxyfac.cxx | 26 stoc/source/security/access_controller.cxx | 94 - stoc/source/security/permissions.cxx | 102 - stoc/source/servicemanager/servicemanager.cxx | 54 store/source/storcach.cxx | 58 - svgio/source/svgreader/svganode.cxx | 24 svgio/source/svgreader/svgcharacternode.cxx | 50 svgio/source/svgreader/svgcirclenode.cxx | 36 svgio/source/svgreader/svgclippathnode.cxx | 230 ++-- svgio/source/svgreader/svgdocumenthandler.cxx | 760 ++++++------- svgio/source/svgreader/svgellipsenode.cxx | 38 svgio/source/svgreader/svgimagenode.cxx | 292 ++--- svgio/source/svgreader/svglinenode.cxx | 38 svgio/source/svgreader/svgmasknode.cxx | 216 +-- svgio/source/svgreader/svgnode.cxx | 278 ++-- svgio/source/svgreader/svgpatternnode.cxx | 90 - svgio/source/svgreader/svgrectnode.cxx | 82 - svgio/source/svgreader/svgstyleattributes.cxx | 1194 ++++++++++----------- svgio/source/svgreader/svgstylenode.cxx | 204 +-- svgio/source/svgreader/svgsvgnode.cxx | 110 - svgio/source/svgreader/svgtextnode.cxx | 78 - svgio/source/svgreader/svgtextpathnode.cxx | 152 +- svgio/source/svgreader/svgusenode.cxx | 80 - 28 files changed, 2524 insertions(+), 2529 deletions(-)
New commits: commit 7a576383308edec3d6538986310264bfc0f1c213 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Mon Jan 28 15:09:20 2019 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Tue Jan 29 07:11:12 2019 +0100 loplugin:flatten in svgio Change-Id: I3276c2c368c755e070fd8b19a15a954948a68df7 Reviewed-on: https://gerrit.libreoffice.org/67008 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/svgio/source/svgreader/svganode.cxx b/svgio/source/svgreader/svganode.cxx index 8aac10dd1a3c..d2d64d04c359 100644 --- a/svgio/source/svgreader/svganode.cxx +++ b/svgio/source/svgreader/svganode.cxx @@ -81,21 +81,21 @@ namespace svgio // #i125258# for SVGTokenA decompose children const SvgStyleAttributes* pStyle = getSvgStyleAttributes(); - if(pStyle) - { - const double fOpacity(pStyle->getOpacity().getNumber()); + if(!pStyle) + return; - if(fOpacity > 0.0 && Display_none != getDisplay()) - { - drawinglayer::primitive2d::Primitive2DContainer aContent; + const double fOpacity(pStyle->getOpacity().getNumber()); - // decompose children - SvgNode::decomposeSvgNode(aContent, bReferenced); + if(fOpacity > 0.0 && Display_none != getDisplay()) + { + drawinglayer::primitive2d::Primitive2DContainer aContent; - if(!aContent.empty()) - { - pStyle->add_postProcess(rTarget, aContent, getTransform()); - } + // decompose children + SvgNode::decomposeSvgNode(aContent, bReferenced); + + if(!aContent.empty()) + { + pStyle->add_postProcess(rTarget, aContent, getTransform()); } } } diff --git a/svgio/source/svgreader/svgcharacternode.cxx b/svgio/source/svgreader/svgcharacternode.cxx index 70e99384b440..edd77e2921eb 100644 --- a/svgio/source/svgreader/svgcharacternode.cxx +++ b/svgio/source/svgreader/svgcharacternode.cxx @@ -503,36 +503,36 @@ namespace svgio rSvgTextPosition, rSvgStyleAttributes)); - if(xRef.is() && (Visibility_visible == rSvgStyleAttributes.getVisibility())) - { - if(!rSvgTextPosition.isRotated()) - { - rTarget.push_back(xRef); - } - else - { - // need to apply rotations to each character as given - const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pCandidate = - dynamic_cast< const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* >(xRef.get()); + if(!(xRef.is() && (Visibility_visible == rSvgStyleAttributes.getVisibility()))) + return; - if(pCandidate) - { - const localTextBreakupHelper alocalTextBreakupHelper(*pCandidate, rSvgTextPosition); - const drawinglayer::primitive2d::Primitive2DContainer& aResult( - alocalTextBreakupHelper.getResult()); + if(!rSvgTextPosition.isRotated()) + { + rTarget.push_back(xRef); + } + else + { + // need to apply rotations to each character as given + const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pCandidate = + dynamic_cast< const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* >(xRef.get()); - if(!aResult.empty()) - { - rTarget.append(aResult); - } + if(pCandidate) + { + const localTextBreakupHelper alocalTextBreakupHelper(*pCandidate, rSvgTextPosition); + const drawinglayer::primitive2d::Primitive2DContainer& aResult( + alocalTextBreakupHelper.getResult()); - // also consume for the implied single space - rSvgTextPosition.consumeRotation(); - } - else + if(!aResult.empty()) { - OSL_ENSURE(false, "Used primitive is not a text primitive (!)"); + rTarget.append(aResult); } + + // also consume for the implied single space + rSvgTextPosition.consumeRotation(); + } + else + { + OSL_ENSURE(false, "Used primitive is not a text primitive (!)"); } } } diff --git a/svgio/source/svgreader/svgcirclenode.cxx b/svgio/source/svgreader/svgcirclenode.cxx index b2b6b4a07b99..3684615691fb 100644 --- a/svgio/source/svgreader/svgcirclenode.cxx +++ b/svgio/source/svgreader/svgcirclenode.cxx @@ -115,28 +115,28 @@ namespace svgio { const SvgStyleAttributes* pStyle = getSvgStyleAttributes(); - if(pStyle && getR().isSet()) - { - const double fR(getR().solve(*this)); + if(!(pStyle && getR().isSet())) + return; - if(fR > 0.0) - { - const basegfx::B2DPolygon aPath( - basegfx::utils::createPolygonFromCircle( - basegfx::B2DPoint( - getCx().isSet() ? getCx().solve(*this, xcoordinate) : 0.0, - getCy().isSet() ? getCy().solve(*this, ycoordinate) : 0.0), - fR)); + const double fR(getR().solve(*this)); - drawinglayer::primitive2d::Primitive2DContainer aNewTarget; + if(fR <= 0.0) + return; - pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget, nullptr); + const basegfx::B2DPolygon aPath( + basegfx::utils::createPolygonFromCircle( + basegfx::B2DPoint( + getCx().isSet() ? getCx().solve(*this, xcoordinate) : 0.0, + getCy().isSet() ? getCy().solve(*this, ycoordinate) : 0.0), + fR)); - if(!aNewTarget.empty()) - { - pStyle->add_postProcess(rTarget, aNewTarget, getTransform()); - } - } + drawinglayer::primitive2d::Primitive2DContainer aNewTarget; + + pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget, nullptr); + + if(!aNewTarget.empty()) + { + pStyle->add_postProcess(rTarget, aNewTarget, getTransform()); } } } // end of namespace svgreader diff --git a/svgio/source/svgreader/svgclippathnode.cxx b/svgio/source/svgreader/svgclippathnode.cxx index bda50ab3777f..090a795da3ac 100644 --- a/svgio/source/svgreader/svgclippathnode.cxx +++ b/svgio/source/svgreader/svgclippathnode.cxx @@ -103,23 +103,23 @@ namespace svgio // decompose children SvgNode::decomposeSvgNode(aNewTarget, bReferenced); - if(!aNewTarget.empty()) + if(aNewTarget.empty()) + return; + + if(getTransform()) { - if(getTransform()) - { - // create embedding group element with transformation - const drawinglayer::primitive2d::Primitive2DReference xRef( - new drawinglayer::primitive2d::TransformPrimitive2D( - *getTransform(), - aNewTarget)); + // create embedding group element with transformation + const drawinglayer::primitive2d::Primitive2DReference xRef( + new drawinglayer::primitive2d::TransformPrimitive2D( + *getTransform(), + aNewTarget)); - rTarget.push_back(xRef); - } - else - { - // append to current target - rTarget.append(aNewTarget); - } + rTarget.push_back(xRef); + } + else + { + // append to current target + rTarget.append(aNewTarget); } } @@ -127,132 +127,132 @@ namespace svgio drawinglayer::primitive2d::Primitive2DContainer& rContent, const basegfx::B2DHomMatrix* pTransform) const { - if(!rContent.empty() && Display_none != getDisplay()) - { - const drawinglayer::geometry::ViewInformation2D aViewInformation2D; - drawinglayer::primitive2d::Primitive2DContainer aClipTarget; - basegfx::B2DPolyPolygon aClipPolyPolygon; + if(!(!rContent.empty() && Display_none != getDisplay())) + return; - // get clipPath definition as primitives - decomposeSvgNode(aClipTarget, true); + const drawinglayer::geometry::ViewInformation2D aViewInformation2D; + drawinglayer::primitive2d::Primitive2DContainer aClipTarget; + basegfx::B2DPolyPolygon aClipPolyPolygon; - if(!aClipTarget.empty()) - { - // extract filled polygons as base for a mask PolyPolygon - drawinglayer::processor2d::ContourExtractor2D aExtractor(aViewInformation2D, true); + // get clipPath definition as primitives + decomposeSvgNode(aClipTarget, true); - aExtractor.process(aClipTarget); + if(!aClipTarget.empty()) + { + // extract filled polygons as base for a mask PolyPolygon + drawinglayer::processor2d::ContourExtractor2D aExtractor(aViewInformation2D, true); - const basegfx::B2DPolyPolygonVector& rResult(aExtractor.getExtractedContour()); - const sal_uInt32 nSize(rResult.size()); + aExtractor.process(aClipTarget); - if(nSize > 1) - { - // merge to single clipPolyPolygon - aClipPolyPolygon = basegfx::utils::mergeToSinglePolyPolygon(rResult); - } - else - { - aClipPolyPolygon = rResult[0]; - } + const basegfx::B2DPolyPolygonVector& rResult(aExtractor.getExtractedContour()); + const sal_uInt32 nSize(rResult.size()); + + if(nSize > 1) + { + // merge to single clipPolyPolygon + aClipPolyPolygon = basegfx::utils::mergeToSinglePolyPolygon(rResult); + } + else + { + aClipPolyPolygon = rResult[0]; } + } - if(aClipPolyPolygon.count()) + if(aClipPolyPolygon.count()) + { + if(objectBoundingBox == getClipPathUnits()) { - if(objectBoundingBox == getClipPathUnits()) - { - // clip is object-relative, transform using content transformation - const basegfx::B2DRange aContentRange(rContent.getB2DRange(aViewInformation2D)); + // clip is object-relative, transform using content transformation + const basegfx::B2DRange aContentRange(rContent.getB2DRange(aViewInformation2D)); - aClipPolyPolygon.transform( - basegfx::utils::createScaleTranslateB2DHomMatrix( - aContentRange.getRange(), - aContentRange.getMinimum())); - } - else // userSpaceOnUse + aClipPolyPolygon.transform( + basegfx::utils::createScaleTranslateB2DHomMatrix( + aContentRange.getRange(), + aContentRange.getMinimum())); + } + else // userSpaceOnUse + { + // #i124852# + if(pTransform) { - // #i124852# - if(pTransform) - { - aClipPolyPolygon.transform(*pTransform); - } + aClipPolyPolygon.transform(*pTransform); } + } - // #i124313# try to avoid creating an embedding to a MaskPrimitive2D if - // possible; MaskPrimitive2D processing is potentially expensive - bool bCreateEmbedding(true); - bool bAddContent(true); - - if(basegfx::utils::isRectangle(aClipPolyPolygon)) - { - // ClipRegion is a rectangle, thus it is not expensive to tell - // if the content is completely inside or outside of it; get ranges - const basegfx::B2DRange aClipRange(aClipPolyPolygon.getB2DRange()); - const basegfx::B2DRange aContentRange( - rContent.getB2DRange( - aViewInformation2D)); + // #i124313# try to avoid creating an embedding to a MaskPrimitive2D if + // possible; MaskPrimitive2D processing is potentially expensive + bool bCreateEmbedding(true); + bool bAddContent(true); - if(aClipRange.isInside(aContentRange)) - { - // completely contained, no need to clip at all, so no need for embedding - bCreateEmbedding = false; - } - else if(aClipRange.overlaps(aContentRange)) - { - // overlap; embedding needed. ClipRegion can be minimized by using - // the intersection of the ClipRange and the ContentRange. Minimizing - // the ClipRegion potentially enhances further processing since - // usually clip operations are expensive. - basegfx::B2DRange aCommonRange(aContentRange); + if(basegfx::utils::isRectangle(aClipPolyPolygon)) + { + // ClipRegion is a rectangle, thus it is not expensive to tell + // if the content is completely inside or outside of it; get ranges + const basegfx::B2DRange aClipRange(aClipPolyPolygon.getB2DRange()); + const basegfx::B2DRange aContentRange( + rContent.getB2DRange( + aViewInformation2D)); - aCommonRange.intersect(aClipRange); - aClipPolyPolygon = basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(aCommonRange)); - } - else - { - // not inside and no overlap -> completely outside - // no need for embedding, no need for content at all - bCreateEmbedding = false; - bAddContent = false; - } - } - else + if(aClipRange.isInside(aContentRange)) { - // ClipRegion is not a simple rectangle, it would be possible but expensive to - // tell if the content needs clipping or not. It is also dependent of - // the content's decomposition. To do this, a processor would be needed that - // is capable if processing the given sequence of primitives and decide - // if all is inside or all is outside. Such a ClipProcessor could be written, - // but for now just create the embedding + // completely contained, no need to clip at all, so no need for embedding + bCreateEmbedding = false; } - - if(bCreateEmbedding) + else if(aClipRange.overlaps(aContentRange)) { - // redefine target. Use MaskPrimitive2D with created clip - // geometry. Using the automatically set mbIsClipPathContent at - // SvgStyleAttributes the clip definition is without fill, stroke, - // and strokeWidth and forced to black - const drawinglayer::primitive2d::Primitive2DReference xEmbedTransparence( - new drawinglayer::primitive2d::MaskPrimitive2D( - aClipPolyPolygon, - rContent)); + // overlap; embedding needed. ClipRegion can be minimized by using + // the intersection of the ClipRange and the ContentRange. Minimizing + // the ClipRegion potentially enhances further processing since + // usually clip operations are expensive. + basegfx::B2DRange aCommonRange(aContentRange); - rContent = drawinglayer::primitive2d::Primitive2DContainer { xEmbedTransparence }; + aCommonRange.intersect(aClipRange); + aClipPolyPolygon = basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(aCommonRange)); } else { - if(!bAddContent) - { - rContent.clear(); - } + // not inside and no overlap -> completely outside + // no need for embedding, no need for content at all + bCreateEmbedding = false; + bAddContent = false; } } else { - // An empty clipping path will completely clip away the element that had - // the clip-path property applied. (Svg spec) - rContent.clear(); + // ClipRegion is not a simple rectangle, it would be possible but expensive to + // tell if the content needs clipping or not. It is also dependent of + // the content's decomposition. To do this, a processor would be needed that + // is capable if processing the given sequence of primitives and decide + // if all is inside or all is outside. Such a ClipProcessor could be written, + // but for now just create the embedding } + + if(bCreateEmbedding) + { + // redefine target. Use MaskPrimitive2D with created clip + // geometry. Using the automatically set mbIsClipPathContent at + // SvgStyleAttributes the clip definition is without fill, stroke, + // and strokeWidth and forced to black + const drawinglayer::primitive2d::Primitive2DReference xEmbedTransparence( + new drawinglayer::primitive2d::MaskPrimitive2D( + aClipPolyPolygon, + rContent)); + + rContent = drawinglayer::primitive2d::Primitive2DContainer { xEmbedTransparence }; + } + else + { + if(!bAddContent) + { + rContent.clear(); + } + } + } + else + { + // An empty clipping path will completely clip away the element that had + // the clip-path property applied. (Svg spec) + rContent.clear(); } } 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; } } } diff --git a/svgio/source/svgreader/svgellipsenode.cxx b/svgio/source/svgreader/svgellipsenode.cxx index c76b5c538c03..4454b9d696f2 100644 --- a/svgio/source/svgreader/svgellipsenode.cxx +++ b/svgio/source/svgreader/svgellipsenode.cxx @@ -129,29 +129,29 @@ namespace svgio { const SvgStyleAttributes* pStyle = getSvgStyleAttributes(); - if(pStyle && getRx().isSet() && getRy().isSet()) - { - const double fRx(getRx().solve(*this, xcoordinate)); - const double fRy(getRy().solve(*this, ycoordinate)); + if(!(pStyle && getRx().isSet() && getRy().isSet())) + return; - if(fRx > 0.0 && fRy > 0.0) - { - const basegfx::B2DPolygon aPath( - basegfx::utils::createPolygonFromEllipse( - basegfx::B2DPoint( - getCx().isSet() ? getCx().solve(*this, xcoordinate) : 0.0, - getCy().isSet() ? getCy().solve(*this, ycoordinate) : 0.0), - fRx, fRy)); + const double fRx(getRx().solve(*this, xcoordinate)); + const double fRy(getRy().solve(*this, ycoordinate)); - drawinglayer::primitive2d::Primitive2DContainer aNewTarget; + if(!(fRx > 0.0 && fRy > 0.0)) + return; - pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget, nullptr); + const basegfx::B2DPolygon aPath( + basegfx::utils::createPolygonFromEllipse( + basegfx::B2DPoint( + getCx().isSet() ? getCx().solve(*this, xcoordinate) : 0.0, + getCy().isSet() ? getCy().solve(*this, ycoordinate) : 0.0), + fRx, fRy)); - if(!aNewTarget.empty()) - { - pStyle->add_postProcess(rTarget, aNewTarget, getTransform()); - } - } + drawinglayer::primitive2d::Primitive2DContainer aNewTarget; + + pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget, nullptr); + + if(!aNewTarget.empty()) + { + pStyle->add_postProcess(rTarget, aNewTarget, getTransform()); } } } // end of namespace svgreader diff --git a/svgio/source/svgreader/svgimagenode.cxx b/svgio/source/svgreader/svgimagenode.cxx index 7224eabb8f2d..1e0861c86b03 100644 --- a/svgio/source/svgreader/svgimagenode.cxx +++ b/svgio/source/svgreader/svgimagenode.cxx @@ -193,169 +193,169 @@ namespace svgio // get size range and create path const SvgStyleAttributes* pStyle = getSvgStyleAttributes(); - if(pStyle && getWidth().isSet() && getHeight().isSet()) - { - const double fWidth(getWidth().solve(*this, xcoordinate)); - const double fHeight(getHeight().solve(*this, ycoordinate)); + if(!(pStyle && getWidth().isSet() && getHeight().isSet())) + return; - if(fWidth > 0.0 && fHeight > 0.0) - { - BitmapEx aBitmapEx; - drawinglayer::primitive2d::Primitive2DContainer aNewTarget; + const double fWidth(getWidth().solve(*this, xcoordinate)); + const double fHeight(getHeight().solve(*this, ycoordinate)); - // prepare Target and ViewBox for evtl. AspectRatio mappings - const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0); - const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0); - const basegfx::B2DRange aTarget(fX, fY, fX + fWidth, fY + fHeight); - basegfx::B2DRange aViewBox(aTarget); + if(!(fWidth > 0.0 && fHeight > 0.0)) + return; - if(!maMimeType.isEmpty() && !maData.isEmpty()) - { - // use embedded base64 encoded data - css::uno::Sequence< sal_Int8 > aPass; - ::comphelper::Base64::decode(aPass, maData); + BitmapEx aBitmapEx; + drawinglayer::primitive2d::Primitive2DContainer aNewTarget; - if(aPass.hasElements()) - { - SvMemoryStream aStream(aPass.getArray(), aPass.getLength(), StreamMode::READ); - Graphic aGraphic; - - if(ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic( - aGraphic, - OUString(), - aStream)) - { - extractFromGraphic(aGraphic, aNewTarget, aViewBox, aBitmapEx); - } - } - } - else if(!maUrl.isEmpty()) - { - const OUString& rPath = getDocument().getAbsolutePath(); - OUString aAbsUrl; - try { - aAbsUrl = rtl::Uri::convertRelToAbs(rPath, maUrl); - } catch (rtl::MalformedUriException & e) { - SAL_WARN( - "svg", - "caught rtl::MalformedUriException \"" - << e.getMessage() << "\""); - } + // prepare Target and ViewBox for evtl. AspectRatio mappings + const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0); + const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0); + const basegfx::B2DRange aTarget(fX, fY, fX + fWidth, fY + fHeight); + basegfx::B2DRange aViewBox(aTarget); - if (!aAbsUrl.isEmpty() && rPath != aAbsUrl) - { - SvFileStream aStream(aAbsUrl, StreamMode::STD_READ); - Graphic aGraphic; - - if(ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic( - aGraphic, - aAbsUrl, - aStream)) - { - extractFromGraphic(aGraphic, aNewTarget, aViewBox, aBitmapEx); - } - } - } - else if(!maXLink.isEmpty()) - { - const SvgNode* pXLink = getDocument().findSvgNodeById(maXLink); - - if(pXLink && Display_none != pXLink->getDisplay()) - { - pXLink->decomposeSvgNode(aNewTarget, true); + if(!maMimeType.isEmpty() && !maData.isEmpty()) + { + // use embedded base64 encoded data + css::uno::Sequence< sal_Int8 > aPass; + ::comphelper::Base64::decode(aPass, maData); - if(!aNewTarget.empty()) - { - aViewBox = aNewTarget.getB2DRange(drawinglayer::geometry::ViewInformation2D()); - } - } - } + if(aPass.hasElements()) + { + SvMemoryStream aStream(aPass.getArray(), aPass.getLength(), StreamMode::READ); + Graphic aGraphic; - if(!aBitmapEx.IsEmpty() && 0 != aBitmapEx.GetSizePixel().Width() && 0 != aBitmapEx.GetSizePixel().Height()) + if(ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic( + aGraphic, + OUString(), + aStream)) { - // calculate centered unit size - const double fAspectRatio = static_cast<double>(aBitmapEx.GetSizePixel().Width()) / static_cast<double>(aBitmapEx.GetSizePixel().Height()); + extractFromGraphic(aGraphic, aNewTarget, aViewBox, aBitmapEx); + } + } + } + else if(!maUrl.isEmpty()) + { + const OUString& rPath = getDocument().getAbsolutePath(); + OUString aAbsUrl; + try { + aAbsUrl = rtl::Uri::convertRelToAbs(rPath, maUrl); + } catch (rtl::MalformedUriException & e) { + SAL_WARN( + "svg", + "caught rtl::MalformedUriException \"" + << e.getMessage() << "\""); + } - if(basegfx::fTools::equal(fAspectRatio, 0.0)) - { - // use unit range - aViewBox = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0); - } - else if(basegfx::fTools::more(fAspectRatio, 0.0)) - { - // width bigger height - const double fHalfHeight((1.0 / fAspectRatio) * 0.5); - aViewBox = basegfx::B2DRange( - 0.0, - 0.5 - fHalfHeight, - 1.0, - 0.5 + fHalfHeight); - } - else - { - // height bigger width - const double fHalfWidth(fAspectRatio * 0.5); - aViewBox = basegfx::B2DRange( - 0.5 - fHalfWidth, - 0.0, - 0.5 + fHalfWidth, - 1.0); - } + if (!aAbsUrl.isEmpty() && rPath != aAbsUrl) + { + SvFileStream aStream(aAbsUrl, StreamMode::STD_READ); + Graphic aGraphic; - // create content from created bitmap, use calculated unit range size - // as transformation to map the picture data correctly - aNewTarget.resize(1); - aNewTarget[0] = new drawinglayer::primitive2d::BitmapPrimitive2D( - aBitmapEx, - basegfx::utils::createScaleTranslateB2DHomMatrix( - aViewBox.getRange(), - aViewBox.getMinimum())); + if(ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic( + aGraphic, + aAbsUrl, + aStream)) + { + extractFromGraphic(aGraphic, aNewTarget, aViewBox, aBitmapEx); } + } + } + else if(!maXLink.isEmpty()) + { + const SvgNode* pXLink = getDocument().findSvgNodeById(maXLink); + + if(pXLink && Display_none != pXLink->getDisplay()) + { + pXLink->decomposeSvgNode(aNewTarget, true); if(!aNewTarget.empty()) { - if(aTarget.equal(aViewBox)) - { - // just add to rTarget - rTarget.append(aNewTarget); - } - else - { - // create mapping - const SvgAspectRatio& rRatio = maSvgAspectRatio; - - // even when ratio is not set, use the defaults - // let mapping be created from SvgAspectRatio - const basegfx::B2DHomMatrix aEmbeddingTransform(rRatio.createMapping(aTarget, aViewBox)); - - if(!aEmbeddingTransform.isIdentity()) - { - const drawinglayer::primitive2d::Primitive2DReference xRef( - new drawinglayer::primitive2d::TransformPrimitive2D( - aEmbeddingTransform, - aNewTarget)); - - aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xRef }; - } - - if(!rRatio.isMeetOrSlice()) - { - // need to embed in MaskPrimitive2D to ensure clipping - const drawinglayer::primitive2d::Primitive2DReference xMask( - new drawinglayer::primitive2d::MaskPrimitive2D( - basegfx::B2DPolyPolygon( - basegfx::utils::createPolygonFromRect(aTarget)), - aNewTarget)); - - aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xMask }; - } - - // embed and add to rTarget, take local extra-transform into account - pStyle->add_postProcess(rTarget, aNewTarget, getTransform()); - } + aViewBox = aNewTarget.getB2DRange(drawinglayer::geometry::ViewInformation2D()); } } } + + if(!aBitmapEx.IsEmpty() && 0 != aBitmapEx.GetSizePixel().Width() && 0 != aBitmapEx.GetSizePixel().Height()) + { + // calculate centered unit size + const double fAspectRatio = static_cast<double>(aBitmapEx.GetSizePixel().Width()) / static_cast<double>(aBitmapEx.GetSizePixel().Height()); + + if(basegfx::fTools::equal(fAspectRatio, 0.0)) + { + // use unit range + aViewBox = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0); + } + else if(basegfx::fTools::more(fAspectRatio, 0.0)) + { + // width bigger height + const double fHalfHeight((1.0 / fAspectRatio) * 0.5); + aViewBox = basegfx::B2DRange( + 0.0, + 0.5 - fHalfHeight, + 1.0, + 0.5 + fHalfHeight); + } + else + { + // height bigger width + const double fHalfWidth(fAspectRatio * 0.5); + aViewBox = basegfx::B2DRange( + 0.5 - fHalfWidth, + 0.0, + 0.5 + fHalfWidth, + 1.0); + } + + // create content from created bitmap, use calculated unit range size + // as transformation to map the picture data correctly + aNewTarget.resize(1); + aNewTarget[0] = new drawinglayer::primitive2d::BitmapPrimitive2D( + aBitmapEx, + basegfx::utils::createScaleTranslateB2DHomMatrix( + aViewBox.getRange(), + aViewBox.getMinimum())); + } + + if(aNewTarget.empty()) + return; + + if(aTarget.equal(aViewBox)) + { + // just add to rTarget + rTarget.append(aNewTarget); + } + else + { + // create mapping + const SvgAspectRatio& rRatio = maSvgAspectRatio; + + // even when ratio is not set, use the defaults + // let mapping be created from SvgAspectRatio + const basegfx::B2DHomMatrix aEmbeddingTransform(rRatio.createMapping(aTarget, aViewBox)); + + if(!aEmbeddingTransform.isIdentity()) + { + const drawinglayer::primitive2d::Primitive2DReference xRef( + new drawinglayer::primitive2d::TransformPrimitive2D( + aEmbeddingTransform, + aNewTarget)); + + aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xRef }; + } + + if(!rRatio.isMeetOrSlice()) + { + // need to embed in MaskPrimitive2D to ensure clipping + const drawinglayer::primitive2d::Primitive2DReference xMask( + new drawinglayer::primitive2d::MaskPrimitive2D( + basegfx::B2DPolyPolygon( + basegfx::utils::createPolygonFromRect(aTarget)), + aNewTarget)); + + aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xMask }; + } + + // embed and add to rTarget, take local extra-transform into account + pStyle->add_postProcess(rTarget, aNewTarget, getTransform()); + } } } // end of namespace svgreader diff --git a/svgio/source/svgreader/svglinenode.cxx b/svgio/source/svgreader/svglinenode.cxx index bce24f675334..bb3eae92adee 100644 --- a/svgio/source/svgreader/svglinenode.cxx +++ b/svgio/source/svgreader/svglinenode.cxx @@ -123,31 +123,31 @@ namespace svgio { const SvgStyleAttributes* pStyle = getSvgStyleAttributes(); - if(pStyle) - { - const basegfx::B2DPoint X( - getX1().isSet() ? getX1().solve(*this, xcoordinate) : 0.0, - getY1().isSet() ? getY1().solve(*this, ycoordinate) : 0.0); - const basegfx::B2DPoint Y( - getX2().isSet() ? getX2().solve(*this, xcoordinate) : 0.0, - getY2().isSet() ? getY2().solve(*this, ycoordinate) : 0.0); + if(!pStyle) + return; - // X and Y may be equal, do not drop them. Markers or linecaps 'round' and 'square' - // need to be drawn for zero-length lines too. + const basegfx::B2DPoint X( + getX1().isSet() ? getX1().solve(*this, xcoordinate) : 0.0, + getY1().isSet() ? getY1().solve(*this, ycoordinate) : 0.0); + const basegfx::B2DPoint Y( + getX2().isSet() ? getX2().solve(*this, xcoordinate) : 0.0, + getY2().isSet() ? getY2().solve(*this, ycoordinate) : 0.0); - basegfx::B2DPolygon aPath; + // X and Y may be equal, do not drop them. Markers or linecaps 'round' and 'square' + // need to be drawn for zero-length lines too. - aPath.append(X); - aPath.append(Y); + basegfx::B2DPolygon aPath; - drawinglayer::primitive2d::Primitive2DContainer aNewTarget; + aPath.append(X); + aPath.append(Y); - pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget, nullptr); + drawinglayer::primitive2d::Primitive2DContainer aNewTarget; - if(!aNewTarget.empty()) - { - pStyle->add_postProcess(rTarget, aNewTarget, getTransform()); - } + pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget, nullptr); + + if(!aNewTarget.empty()) + { + pStyle->add_postProcess(rTarget, aNewTarget, getTransform()); } } } // end of namespace svgreader diff --git a/svgio/source/svgreader/svgmasknode.cxx b/svgio/source/svgreader/svgmasknode.cxx index 85d9b7f2e4b5..f2a919c4582f 100644 --- a/svgio/source/svgreader/svgmasknode.cxx +++ b/svgio/source/svgreader/svgmasknode.cxx @@ -170,148 +170,148 @@ namespace svgio // decompose children SvgNode::decomposeSvgNode(aNewTarget, bReferenced); - if(!aNewTarget.empty()) - { - if(getTransform()) - { - // create embedding group element with transformation - const drawinglayer::primitive2d::Primitive2DReference xRef( - new drawinglayer::primitive2d::TransformPrimitive2D( - *getTransform(), - aNewTarget)); + if(aNewTarget.empty()) + return; - aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xRef }; - } + if(getTransform()) + { + // create embedding group element with transformation + const drawinglayer::primitive2d::Primitive2DReference xRef( + new drawinglayer::primitive2d::TransformPrimitive2D( + *getTransform(), + aNewTarget)); - // append to current target - rTarget.append(aNewTarget); + aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xRef }; } + + // append to current target + rTarget.append(aNewTarget); } void SvgMaskNode::apply( drawinglayer::primitive2d::Primitive2DContainer& rTarget, const basegfx::B2DHomMatrix* pTransform) const { - if(!rTarget.empty() && Display_none != getDisplay()) - { - drawinglayer::primitive2d::Primitive2DContainer aMaskTarget; + if(!(!rTarget.empty() && Display_none != getDisplay())) + return; + + drawinglayer::primitive2d::Primitive2DContainer aMaskTarget; - // get mask definition as primitives - decomposeSvgNode(aMaskTarget, true); + // get mask definition as primitives + decomposeSvgNode(aMaskTarget, true); - if(!aMaskTarget.empty()) + if(!aMaskTarget.empty()) + { + // get range of content to be masked + const basegfx::B2DRange aContentRange( + rTarget.getB2DRange( + drawinglayer::geometry::ViewInformation2D())); + const double fContentWidth(aContentRange.getWidth()); + const double fContentHeight(aContentRange.getHeight()); + + if(fContentWidth > 0.0 && fContentHeight > 0.0) { - // get range of content to be masked - const basegfx::B2DRange aContentRange( - rTarget.getB2DRange( - drawinglayer::geometry::ViewInformation2D())); - const double fContentWidth(aContentRange.getWidth()); - const double fContentHeight(aContentRange.getHeight()); - - if(fContentWidth > 0.0 && fContentHeight > 0.0) + // create OffscreenBufferRange + basegfx::B2DRange aOffscreenBufferRange; + + if(objectBoundingBox == maMaskUnits) { - // create OffscreenBufferRange - basegfx::B2DRange aOffscreenBufferRange; + // fractions or percentages of the bounding box of the element to which the mask is applied + const double fX(Unit_percent == getX().getUnit() ? getX().getNumber() * 0.01 : getX().getNumber()); + const double fY(Unit_percent == getY().getUnit() ? getY().getNumber() * 0.01 : getY().getNumber()); + const double fW(Unit_percent == getWidth().getUnit() ? getWidth().getNumber() * 0.01 : getWidth().getNumber()); + const double fH(Unit_percent == getHeight().getUnit() ? getHeight().getNumber() * 0.01 : getHeight().getNumber()); + + aOffscreenBufferRange = basegfx::B2DRange( + aContentRange.getMinX() + (fX * fContentWidth), + aContentRange.getMinY() + (fY * fContentHeight), + aContentRange.getMinX() + ((fX + fW) * fContentWidth), + aContentRange.getMinY() + ((fY + fH) * fContentHeight)); + } + else + { + const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0); + const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0); + + aOffscreenBufferRange = basegfx::B2DRange( + fX, + fY, + fX + (getWidth().isSet() ? getWidth().solve(*this, xcoordinate) : 0.0), + fY + (getHeight().isSet() ? getHeight().solve(*this, ycoordinate) : 0.0)); + } - if(objectBoundingBox == maMaskUnits) - { - // fractions or percentages of the bounding box of the element to which the mask is applied - const double fX(Unit_percent == getX().getUnit() ? getX().getNumber() * 0.01 : getX().getNumber()); - const double fY(Unit_percent == getY().getUnit() ? getY().getNumber() * 0.01 : getY().getNumber()); - const double fW(Unit_percent == getWidth().getUnit() ? getWidth().getNumber() * 0.01 : getWidth().getNumber()); - const double fH(Unit_percent == getHeight().getUnit() ? getHeight().getNumber() * 0.01 : getHeight().getNumber()); - - aOffscreenBufferRange = basegfx::B2DRange( - aContentRange.getMinX() + (fX * fContentWidth), - aContentRange.getMinY() + (fY * fContentHeight), - aContentRange.getMinX() + ((fX + fW) * fContentWidth), - aContentRange.getMinY() + ((fY + fH) * fContentHeight)); - } - else - { - const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0); - const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0); - - aOffscreenBufferRange = basegfx::B2DRange( - fX, - fY, - fX + (getWidth().isSet() ? getWidth().solve(*this, xcoordinate) : 0.0), - fY + (getHeight().isSet() ? getHeight().solve(*this, ycoordinate) : 0.0)); - } + if(objectBoundingBox == maMaskContentUnits) + { + // mask is object-relative, embed in content transformation + const drawinglayer::primitive2d::Primitive2DReference xTransform( + new drawinglayer::primitive2d::TransformPrimitive2D( + basegfx::utils::createScaleTranslateB2DHomMatrix( + aContentRange.getRange(), + aContentRange.getMinimum()), + aMaskTarget)); - if(objectBoundingBox == maMaskContentUnits) + aMaskTarget = drawinglayer::primitive2d::Primitive2DContainer { xTransform }; + } + else // userSpaceOnUse + { + // #i124852# + if(pTransform) { - // mask is object-relative, embed in content transformation const drawinglayer::primitive2d::Primitive2DReference xTransform( new drawinglayer::primitive2d::TransformPrimitive2D( - basegfx::utils::createScaleTranslateB2DHomMatrix( - aContentRange.getRange(), - aContentRange.getMinimum()), + *pTransform, aMaskTarget)); aMaskTarget = drawinglayer::primitive2d::Primitive2DContainer { xTransform }; } - else // userSpaceOnUse - { - // #i124852# - if(pTransform) - { - const drawinglayer::primitive2d::Primitive2DReference xTransform( - new drawinglayer::primitive2d::TransformPrimitive2D( - *pTransform, - aMaskTarget)); - - aMaskTarget = drawinglayer::primitive2d::Primitive2DContainer { xTransform }; - } - } - - // embed content to a ModifiedColorPrimitive2D since the definitions - // how content is used as alpha is special for Svg - { - const drawinglayer::primitive2d::Primitive2DReference xInverseMask( - new drawinglayer::primitive2d::ModifiedColorPrimitive2D( - aMaskTarget, - basegfx::BColorModifierSharedPtr( - new basegfx::BColorModifier_luminance_to_alpha()))); + } - aMaskTarget = drawinglayer::primitive2d::Primitive2DContainer { xInverseMask }; - } + // embed content to a ModifiedColorPrimitive2D since the definitions + // how content is used as alpha is special for Svg + { + const drawinglayer::primitive2d::Primitive2DReference xInverseMask( + new drawinglayer::primitive2d::ModifiedColorPrimitive2D( + aMaskTarget, + basegfx::BColorModifierSharedPtr( + new basegfx::BColorModifier_luminance_to_alpha()))); - // prepare new content - drawinglayer::primitive2d::Primitive2DReference xNewContent( - new drawinglayer::primitive2d::TransparencePrimitive2D( - rTarget, - aMaskTarget)); + aMaskTarget = drawinglayer::primitive2d::Primitive2DContainer { xInverseMask }; + } - // output up to now is defined by aContentRange and mask is oriented - // relative to it. It is possible that aOffscreenBufferRange defines - // a smaller area. In that case, embed to a mask primitive - if(!aOffscreenBufferRange.isInside(aContentRange)) - { - xNewContent = new drawinglayer::primitive2d::MaskPrimitive2D( - basegfx::B2DPolyPolygon( - basegfx::utils::createPolygonFromRect( - aOffscreenBufferRange)), - drawinglayer::primitive2d::Primitive2DContainer { xNewContent }); - } + // prepare new content + drawinglayer::primitive2d::Primitive2DReference xNewContent( + new drawinglayer::primitive2d::TransparencePrimitive2D( + rTarget, + aMaskTarget)); - // redefine target. Use TransparencePrimitive2D with created mask - // geometry - rTarget = drawinglayer::primitive2d::Primitive2DContainer { xNewContent }; - } - else + // output up to now is defined by aContentRange and mask is oriented + // relative to it. It is possible that aOffscreenBufferRange defines + // a smaller area. In that case, embed to a mask primitive + if(!aOffscreenBufferRange.isInside(aContentRange)) { - // content is geometrically empty - rTarget.clear(); + xNewContent = new drawinglayer::primitive2d::MaskPrimitive2D( + basegfx::B2DPolyPolygon( + basegfx::utils::createPolygonFromRect( + aOffscreenBufferRange)), + drawinglayer::primitive2d::Primitive2DContainer { xNewContent }); } + + // redefine target. Use TransparencePrimitive2D with created mask + // geometry + rTarget = drawinglayer::primitive2d::Primitive2DContainer { xNewContent }; } else { - // An empty clipping path will completely clip away the element that had - // the clip-path property applied. (Svg spec) + // content is geometrically empty rTarget.clear(); } } + else + { + // An empty clipping path will completely clip away the element that had + // the clip-path property applied. (Svg spec) + rTarget.clear(); + } } } // end of namespace svgreader diff --git a/svgio/source/svgreader/svgnode.cxx b/svgio/source/svgreader/svgnode.cxx index 61b0a9138fa9..88b9a72ec196 100644 --- a/svgio/source/svgreader/svgnode.cxx +++ b/svgio/source/svgreader/svgnode.cxx @@ -47,118 +47,118 @@ namespace svgio { const SvgDocument& rDocument = getDocument(); - if(rDocument.hasGlobalCssStyleAttributes()) + if(!rDocument.hasGlobalCssStyleAttributes()) + return; + + const SvgNode* pParent = rCurrent.getParent(); + + // check for ID (highest priority) + if(rCurrent.getId()) { - const SvgNode* pParent = rCurrent.getParent(); + const OUString& rId = *rCurrent.getId(); - // check for ID (highest priority) - if(rCurrent.getId()) + if(rId.getLength()) { - const OUString& rId = *rCurrent.getId(); + const OUString aNewConcatenated( + "#" + rId + aConcatenated); - if(rId.getLength()) + if(pParent) { - const OUString aNewConcatenated( - "#" + rId + aConcatenated); - - if(pParent) - { - // check for combined selectors at parent firstso that higher specificity will be in front - fillCssStyleVectorUsingHierarchyAndSelectors(rClassStr, *pParent, aNewConcatenated); - } + // check for combined selectors at parent firstso that higher specificity will be in front + fillCssStyleVectorUsingHierarchyAndSelectors(rClassStr, *pParent, aNewConcatenated); + } - const SvgStyleAttributes* pNew = rDocument.findGlobalCssStyleAttributes(aNewConcatenated); + const SvgStyleAttributes* pNew = rDocument.findGlobalCssStyleAttributes(aNewConcatenated); - if(pNew) - { - // add CssStyle if found - maCssStyleVector.push_back(pNew); - } + if(pNew) + { + // add CssStyle if found + maCssStyleVector.push_back(pNew); } } + } - // check for 'class' references (a list of entries is allowed) - if(rCurrent.getClass()) + // check for 'class' references (a list of entries is allowed) + if(rCurrent.getClass()) + { + const OUString& rClassList = *rCurrent.getClass(); + const sal_Int32 nLen(rClassList.getLength()); + + if(nLen) { - const OUString& rClassList = *rCurrent.getClass(); - const sal_Int32 nLen(rClassList.getLength()); + std::vector< OUString > aParts; + sal_Int32 nPos(0); + OUStringBuffer aToken; - if(nLen) + while(nPos < nLen) { - std::vector< OUString > aParts; - sal_Int32 nPos(0); - OUStringBuffer aToken; + const sal_Int32 nInitPos(nPos); + copyToLimiter(rClassList, u' ', nPos, aToken, nLen); + skip_char(rClassList, u' ', nPos, nLen); + const OUString aPart(aToken.makeStringAndClear().trim()); - while(nPos < nLen) + if(aPart.getLength()) { - const sal_Int32 nInitPos(nPos); - copyToLimiter(rClassList, u' ', nPos, aToken, nLen); - skip_char(rClassList, u' ', nPos, nLen); - const OUString aPart(aToken.makeStringAndClear().trim()); - - if(aPart.getLength()) - { - aParts.push_back(aPart); - } - - if(nInitPos == nPos) - { - OSL_ENSURE(false, "Could not interpret on current position (!)"); - nPos++; - } + aParts.push_back(aPart); } - for(size_t a(0); a < aParts.size(); a++) + if(nInitPos == nPos) { - const OUString aNewConcatenated( - "." + aParts[a] + aConcatenated); + OSL_ENSURE(false, "Could not interpret on current position (!)"); + nPos++; + } + } - if(pParent) - { - // check for combined selectors at parent firstso that higher specificity will be in front - fillCssStyleVectorUsingHierarchyAndSelectors(rClassStr, *pParent, aNewConcatenated); - } + for(size_t a(0); a < aParts.size(); a++) + { + const OUString aNewConcatenated( + "." + aParts[a] + aConcatenated); - const SvgStyleAttributes* pNew = rDocument.findGlobalCssStyleAttributes(aNewConcatenated); + if(pParent) + { + // check for combined selectors at parent firstso that higher specificity will be in front + fillCssStyleVectorUsingHierarchyAndSelectors(rClassStr, *pParent, aNewConcatenated); + } - if(pNew) - { - // add CssStyle if found - maCssStyleVector.push_back(pNew); - } + const SvgStyleAttributes* pNew = rDocument.findGlobalCssStyleAttributes(aNewConcatenated); + + if(pNew) + { + // add CssStyle if found + maCssStyleVector.push_back(pNew); } } } + } - // check for class-dependent references to CssStyles - if(!rClassStr.isEmpty()) - { - OUString aNewConcatenated(aConcatenated); + // check for class-dependent references to CssStyles + if(rClassStr.isEmpty()) + return; - if(!rCurrent.getId() && !rCurrent.getClass() && 0 == aConcatenated.indexOf(rClassStr)) - { - // no new CssStyle Selector and already starts with rClassStr, do not concatenate; - // we pass an 'empty' node (in the sense of CssStyle Selector) - } - else - { - aNewConcatenated = rClassStr + aConcatenated; - } + OUString aNewConcatenated(aConcatenated); - if(pParent) - { - // check for combined selectors at parent firstso that higher specificity will be in front - fillCssStyleVectorUsingHierarchyAndSelectors(rClassStr, *pParent, aNewConcatenated); - } + if(!rCurrent.getId() && !rCurrent.getClass() && 0 == aConcatenated.indexOf(rClassStr)) + { + // no new CssStyle Selector and already starts with rClassStr, do not concatenate; + // we pass an 'empty' node (in the sense of CssStyle Selector) + } + else + { + aNewConcatenated = rClassStr + aConcatenated; + } - const SvgStyleAttributes* pNew = rDocument.findGlobalCssStyleAttributes(aNewConcatenated); + if(pParent) + { + // check for combined selectors at parent firstso that higher specificity will be in front + fillCssStyleVectorUsingHierarchyAndSelectors(rClassStr, *pParent, aNewConcatenated); + } - if(pNew) - { - // add CssStyle if found - maCssStyleVector.push_back(pNew); - } - } + const SvgStyleAttributes* pNew = rDocument.findGlobalCssStyleAttributes(aNewConcatenated); + + if(pNew) + { + // add CssStyle if found + maCssStyleVector.push_back(pNew); } } @@ -500,84 +500,84 @@ namespace svgio const auto& rChildren = getChildren(); - if(!rChildren.empty()) - { - mbDecomposing = true; + if(rChildren.empty()) + return; - const sal_uInt32 nCount(rChildren.size()); + mbDecomposing = true; - for(sal_uInt32 a(0); a < nCount; a++) - { ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits