summaryrefslogtreecommitdiff
path: root/svgio/source
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2019-01-28 15:09:20 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-01-29 07:11:12 +0100
commit7a576383308edec3d6538986310264bfc0f1c213 (patch)
treec4e5b9bbd8d71f66dab3864513b55a734f502ccf /svgio/source
parent98e60805613ab6ea19c03c34c0f36d00374dab73 (diff)
loplugin:flatten in svgio
Change-Id: I3276c2c368c755e070fd8b19a15a954948a68df7 Reviewed-on: https://gerrit.libreoffice.org/67008 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'svgio/source')
-rw-r--r--svgio/source/svgreader/svganode.cxx24
-rw-r--r--svgio/source/svgreader/svgcharacternode.cxx50
-rw-r--r--svgio/source/svgreader/svgcirclenode.cxx36
-rw-r--r--svgio/source/svgreader/svgclippathnode.cxx230
-rw-r--r--svgio/source/svgreader/svgdocumenthandler.cxx760
-rw-r--r--svgio/source/svgreader/svgellipsenode.cxx38
-rw-r--r--svgio/source/svgreader/svgimagenode.cxx292
-rw-r--r--svgio/source/svgreader/svglinenode.cxx38
-rw-r--r--svgio/source/svgreader/svgmasknode.cxx216
-rw-r--r--svgio/source/svgreader/svgnode.cxx278
-rw-r--r--svgio/source/svgreader/svgpatternnode.cxx90
-rw-r--r--svgio/source/svgreader/svgrectnode.cxx82
-rw-r--r--svgio/source/svgreader/svgstyleattributes.cxx1194
-rw-r--r--svgio/source/svgreader/svgstylenode.cxx204
-rw-r--r--svgio/source/svgreader/svgsvgnode.cxx110
-rw-r--r--svgio/source/svgreader/svgtextnode.cxx78
-rw-r--r--svgio/source/svgreader/svgtextpathnode.cxx152
-rw-r--r--svgio/source/svgreader/svgusenode.cxx80
18 files changed, 1976 insertions, 1976 deletions
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++)
- {
- SvgNode* pCandidate = rChildren[a].get();
+ const sal_uInt32 nCount(rChildren.size());
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ SvgNode* pCandidate = rChildren[a].get();
- if(pCandidate && Display_none != pCandidate->getDisplay())
+ if(pCandidate && Display_none != pCandidate->getDisplay())
+ {
+ const auto& rGrandChildren = pCandidate->getChildren();
+ const SvgStyleAttributes* pChildStyles = pCandidate->getSvgStyleAttributes();
+ // decompose:
+ // - visible terminal nodes
+ // - all non-terminal nodes (might contain visible nodes down the hierarchy)
+ if( !rGrandChildren.empty() || ( pChildStyles && (Visibility_visible == pChildStyles->getVisibility())) )
{
- const auto& rGrandChildren = pCandidate->getChildren();
- const SvgStyleAttributes* pChildStyles = pCandidate->getSvgStyleAttributes();
- // decompose:
- // - visible terminal nodes
- // - all non-terminal nodes (might contain visible nodes down the hierarchy)
- if( !rGrandChildren.empty() || ( pChildStyles && (Visibility_visible == pChildStyles->getVisibility())) )
- {
- drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
- pCandidate->decomposeSvgNode(aNewTarget, bReferenced);
+ drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
+ pCandidate->decomposeSvgNode(aNewTarget, bReferenced);
- if(!aNewTarget.empty())
- {
- rTarget.append(aNewTarget);
- }
+ if(!aNewTarget.empty())
+ {
+ rTarget.append(aNewTarget);
}
}
- else if(!pCandidate)
- {
- OSL_ENSURE(false, "Null-Pointer in child node list (!)");
- }
}
+ else if(!pCandidate)
+ {
+ OSL_ENSURE(false, "Null-Pointer in child node list (!)");
+ }
+ }
- if(!rTarget.empty())
+ if(!rTarget.empty())
+ {
+ const SvgStyleAttributes* pStyles = getSvgStyleAttributes();
+ if(pStyles)
{
- const SvgStyleAttributes* pStyles = getSvgStyleAttributes();
- if(pStyles)
+ // check if we have Title or Desc
+ const OUString& rTitle = pStyles->getTitle();
+ const OUString& rDesc = pStyles->getDesc();
+
+ if(!rTitle.isEmpty() || !rDesc.isEmpty())
{
- // check if we have Title or Desc
- const OUString& rTitle = pStyles->getTitle();
- const OUString& rDesc = pStyles->getDesc();
+ // default object name is empty
+ OUString aObjectName;
- if(!rTitle.isEmpty() || !rDesc.isEmpty())
+ // use path as object name when outmost element
+ if(SVGTokenSvg == getType())
{
- // default object name is empty
- OUString aObjectName;
+ aObjectName = getDocument().getAbsolutePath();
- // use path as object name when outmost element
- if(SVGTokenSvg == getType())
+ if(!aObjectName.isEmpty())
{
- aObjectName = getDocument().getAbsolutePath();
+ INetURLObject aURL(aObjectName);
- if(!aObjectName.isEmpty())
- {
- INetURLObject aURL(aObjectName);
-
- aObjectName = aURL.getName(
- INetURLObject::LAST_SEGMENT,
- true,
- INetURLObject::DecodeMechanism::WithCharset);
- }
+ aObjectName = aURL.getName(
+ INetURLObject::LAST_SEGMENT,
+ true,
+ INetURLObject::DecodeMechanism::WithCharset);
}
+ }
- // pack in ObjectInfoPrimitive2D group
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::ObjectInfoPrimitive2D(
- rTarget,
- aObjectName,
- rTitle,
- rDesc));
+ // pack in ObjectInfoPrimitive2D group
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::ObjectInfoPrimitive2D(
+ rTarget,
+ aObjectName,
+ rTitle,
+ rDesc));
- rTarget = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ rTarget = drawinglayer::primitive2d::Primitive2DContainer { xRef };
}
}
- mbDecomposing = false;
}
+ mbDecomposing = false;
}
const basegfx::B2DRange SvgNode::getCurrentViewPort() const
diff --git a/svgio/source/svgreader/svgpatternnode.cxx b/svgio/source/svgreader/svgpatternnode.cxx
index 0096f7ae5772..bb2317bc7d6f 100644
--- a/svgio/source/svgreader/svgpatternnode.cxx
+++ b/svgio/source/svgreader/svgpatternnode.cxx
@@ -198,63 +198,63 @@ namespace svgio
double fTargetWidth(rGeoRange.getWidth());
double fTargetHeight(rGeoRange.getHeight());
- if(fTargetWidth > 0.0 && fTargetHeight > 0.0)
- {
- const SvgUnits aPatternUnits(getPatternUnits() ? *getPatternUnits() : objectBoundingBox);
+ if(!(fTargetWidth > 0.0 && fTargetHeight > 0.0))
+ return;
- if(objectBoundingBox == aPatternUnits)
- {
- rfW = (getWidth().isSet()) ? getWidth().getNumber() : 0.0;
- rfH = (getHeight().isSet()) ? getHeight().getNumber() : 0.0;
+ const SvgUnits aPatternUnits(getPatternUnits() ? *getPatternUnits() : objectBoundingBox);
- if(Unit_percent == getWidth().getUnit())
- {
- rfW *= 0.01;
- }
+ if(objectBoundingBox == aPatternUnits)
+ {
+ rfW = (getWidth().isSet()) ? getWidth().getNumber() : 0.0;
+ rfH = (getHeight().isSet()) ? getHeight().getNumber() : 0.0;
- if(Unit_percent == getHeight().getUnit())
- {
- rfH *= 0.01;
- }
- }
- else
+ if(Unit_percent == getWidth().getUnit())
{
- rfW = (getWidth().isSet()) ? getWidth().solve(rUser, xcoordinate) : 0.0;
- rfH = (getHeight().isSet()) ? getHeight().solve(rUser, ycoordinate) : 0.0;
-
- // make relative to rGeoRange
- rfW /= fTargetWidth;
- rfH /= fTargetHeight;
+ rfW *= 0.01;
}
- if(rfW > 0.0 && rfH > 0.0)
+ if(Unit_percent == getHeight().getUnit())
{
- if(objectBoundingBox == aPatternUnits)
- {
- rfX = (getX().isSet()) ? getX().getNumber() : 0.0;
- rfY = (getY().isSet()) ? getY().getNumber() : 0.0;
+ rfH *= 0.01;
+ }
+ }
+ else
+ {
+ rfW = (getWidth().isSet()) ? getWidth().solve(rUser, xcoordinate) : 0.0;
+ rfH = (getHeight().isSet()) ? getHeight().solve(rUser, ycoordinate) : 0.0;
- if(Unit_percent == getX().getUnit())
- {
- rfX *= 0.01;
- }
+ // make relative to rGeoRange
+ rfW /= fTargetWidth;
+ rfH /= fTargetHeight;
+ }
- if(Unit_percent == getY().getUnit())
- {
- rfY *= 0.01;
- }
- }
- else
- {
- rfX = (getX().isSet()) ? getX().solve(rUser, xcoordinate) : 0.0;
- rfY = (getY().isSet()) ? getY().solve(rUser, ycoordinate) : 0.0;
+ if(!(rfW > 0.0 && rfH > 0.0))
+ return;
- // make relative to rGeoRange
- rfX = (rfX - rGeoRange.getMinX()) / fTargetWidth;
- rfY = (rfY - rGeoRange.getMinY()) / fTargetHeight;
- }
+ if(objectBoundingBox == aPatternUnits)
+ {
+ rfX = (getX().isSet()) ? getX().getNumber() : 0.0;
+ rfY = (getY().isSet()) ? getY().getNumber() : 0.0;
+
+ if(Unit_percent == getX().getUnit())
+ {
+ rfX *= 0.01;
+ }
+
+ if(Unit_percent == getY().getUnit())
+ {
+ rfY *= 0.01;
}
}
+ else
+ {
+ rfX = (getX().isSet()) ? getX().solve(rUser, xcoordinate) : 0.0;
+ rfY = (getY().isSet()) ? getY().solve(rUser, ycoordinate) : 0.0;
+
+ // make relative to rGeoRange
+ rfX = (rfX - rGeoRange.getMinX()) / fTargetWidth;
+ rfY = (rfY - rGeoRange.getMinY()) / fTargetHeight;
+ }
}
const drawinglayer::primitive2d::Primitive2DContainer& SvgPatternNode::getPatternPrimitives() const
diff --git a/svgio/source/svgreader/svgrectnode.cxx b/svgio/source/svgreader/svgrectnode.cxx
index c0ff40925f2d..d8c9ce6afb91 100644
--- a/svgio/source/svgreader/svgrectnode.cxx
+++ b/svgio/source/svgreader/svgrectnode.cxx
@@ -158,57 +158,57 @@ 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)
- {
- 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 aRange(fX, fY, fX + fWidth, fY + fHeight);
- basegfx::B2DPolygon aPath;
+ const double fWidth(getWidth().solve(*this, xcoordinate));
+ const double fHeight(getHeight().solve(*this, ycoordinate));
- if(getRx().isSet() || getRy().isSet())
- {
- double frX(getRx().isSet() ? getRx().solve(*this, xcoordinate) : 0.0);
- double frY(getRy().isSet() ? getRy().solve(*this, ycoordinate) : 0.0);
+ if(!(fWidth > 0.0 && fHeight > 0.0))
+ return;
- frX = std::max(0.0, frX);
- frY = std::max(0.0, frY);
+ 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 aRange(fX, fY, fX + fWidth, fY + fHeight);
+ basegfx::B2DPolygon aPath;
- if(0.0 == frY && frX > 0.0)
- {
- frY = frX;
- }
- else if(0.0 == frX && frY > 0.0)
- {
- frX = frY;
- }
+ if(getRx().isSet() || getRy().isSet())
+ {
+ double frX(getRx().isSet() ? getRx().solve(*this, xcoordinate) : 0.0);
+ double frY(getRy().isSet() ? getRy().solve(*this, ycoordinate) : 0.0);
+
+ frX = std::max(0.0, frX);
+ frY = std::max(0.0, frY);
+
+ if(0.0 == frY && frX > 0.0)
+ {
+ frY = frX;
+ }
+ else if(0.0 == frX && frY > 0.0)
+ {
+ frX = frY;
+ }
- frX /= fWidth;
- frY /= fHeight;
+ frX /= fWidth;
+ frY /= fHeight;
- frX = std::min(0.5, frX);
- frY = std::min(0.5, frY);
+ frX = std::min(0.5, frX);
+ frY = std::min(0.5, frY);
- aPath = basegfx::utils::createPolygonFromRect(aRange, frX * 2.0, frY * 2.0);
- }
- else
- {
- aPath = basegfx::utils::createPolygonFromRect(aRange);
- }
+ aPath = basegfx::utils::createPolygonFromRect(aRange, frX * 2.0, frY * 2.0);
+ }
+ else
+ {
+ aPath = basegfx::utils::createPolygonFromRect(aRange);
+ }
- drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
+ drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
- pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget, nullptr);
+ pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget, nullptr);
- if(!aNewTarget.empty())
- {
- pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
- }
- }
+ if(!aNewTarget.empty())
+ {
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
}
}
} // end of namespace svgreader
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
index b0c45fb90372..9b6b81cbcdb2 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -262,76 +262,76 @@ namespace svgio
drawinglayer::primitive2d::Primitive2DContainer& rTarget,
drawinglayer::primitive2d::Primitive2DContainer const & rSource) const
{
- if(!rSource.empty())
- {
- // at this point the primitives in rSource are of type TextSimplePortionPrimitive2D
- // or TextDecoratedPortionPrimitive2D and have the Fill Color (pAttributes->getFill())
- // set. When another fill is used and also evtl. stroke is set it gets necessary to
- // dismantle to geometry and add needed primitives
- const basegfx::BColor* pFill = getFill();
- const SvgGradientNode* pFillGradient = getSvgGradientNodeFill();
- const SvgPatternNode* pFillPattern = getSvgPatternNodeFill();
- const basegfx::BColor* pStroke = getStroke();
- const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke();
- const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke();
- basegfx::B2DPolyPolygon aMergedArea;
-
- if(pFillGradient || pFillPattern || pStroke || pStrokeGradient || pStrokePattern)
- {
- // text geometry is needed, create
- // use neutral ViewInformation and create LineGeometryExtractor2D
- const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
- drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D);
-
- // process
- aExtractor.process(rSource);
-
- // get results
- const drawinglayer::processor2d::TextAsPolygonDataNodeVector& rResult = aExtractor.getTarget();
- const sal_uInt32 nResultCount(rResult.size());
- basegfx::B2DPolyPolygonVector aTextFillVector;
- aTextFillVector.reserve(nResultCount);
-
- for(sal_uInt32 a(0); a < nResultCount; a++)
- {
- const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a];
+ if(rSource.empty())
+ return;
- if(rCandidate.getIsFilled())
- {
- aTextFillVector.push_back(rCandidate.getB2DPolyPolygon());
- }
- }
+ // at this point the primitives in rSource are of type TextSimplePortionPrimitive2D
+ // or TextDecoratedPortionPrimitive2D and have the Fill Color (pAttributes->getFill())
+ // set. When another fill is used and also evtl. stroke is set it gets necessary to
+ // dismantle to geometry and add needed primitives
+ const basegfx::BColor* pFill = getFill();
+ const SvgGradientNode* pFillGradient = getSvgGradientNodeFill();
+ const SvgPatternNode* pFillPattern = getSvgPatternNodeFill();
+ const basegfx::BColor* pStroke = getStroke();
+ const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke();
+ const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke();
+ basegfx::B2DPolyPolygon aMergedArea;
- if(!aTextFillVector.empty())
- {
- aMergedArea = basegfx::utils::mergeToSinglePolyPolygon(aTextFillVector);
- }
- }
+ if(pFillGradient || pFillPattern || pStroke || pStrokeGradient || pStrokePattern)
+ {
+ // text geometry is needed, create
+ // use neutral ViewInformation and create LineGeometryExtractor2D
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+ drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D);
- const bool bStrokeUsed(pStroke || pStrokeGradient || pStrokePattern);
+ // process
+ aExtractor.process(rSource);
- // add fill. Use geometry even for simple color fill when stroke
- // is used, else text rendering and the geometry-based stroke will
- // normally not really match optically due to diverse system text
- // renderers
- if(aMergedArea.count() && (pFillGradient || pFillPattern || bStrokeUsed))
- {
- // create text fill content based on geometry
- add_fill(aMergedArea, rTarget, aMergedArea.getB2DRange());
- }
- else if(pFill)
+ // get results
+ const drawinglayer::processor2d::TextAsPolygonDataNodeVector& rResult = aExtractor.getTarget();
+ const sal_uInt32 nResultCount(rResult.size());
+ basegfx::B2DPolyPolygonVector aTextFillVector;
+ aTextFillVector.reserve(nResultCount);
+
+ for(sal_uInt32 a(0); a < nResultCount; a++)
{
- // add the already prepared primitives for single color fill
- rTarget.append(rSource);
+ const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a];
+
+ if(rCandidate.getIsFilled())
+ {
+ aTextFillVector.push_back(rCandidate.getB2DPolyPolygon());
+ }
}
- // add stroke
- if(aMergedArea.count() && bStrokeUsed)
+ if(!aTextFillVector.empty())
{
- // create text stroke content
- add_stroke(aMergedArea, rTarget, aMergedArea.getB2DRange());
+ aMergedArea = basegfx::utils::mergeToSinglePolyPolygon(aTextFillVector);
}
}
+
+ const bool bStrokeUsed(pStroke || pStrokeGradient || pStrokePattern);
+
+ // add fill. Use geometry even for simple color fill when stroke
+ // is used, else text rendering and the geometry-based stroke will
+ // normally not really match optically due to diverse system text
+ // renderers
+ if(aMergedArea.count() && (pFillGradient || pFillPattern || bStrokeUsed))
+ {
+ // create text fill content based on geometry
+ add_fill(aMergedArea, rTarget, aMergedArea.getB2DRange());
+ }
+ else if(pFill)
+ {
+ // add the already prepared primitives for single color fill
+ rTarget.append(rSource);
+ }
+
+ // add stroke
+ if(aMergedArea.count() && bStrokeUsed)
+ {
+ // create text stroke content
+ add_stroke(aMergedArea, rTarget, aMergedArea.getB2DRange());
+ }
}
void SvgStyleAttributes::add_fillGradient(
@@ -346,127 +346,127 @@ namespace svgio
// get the color stops
rFillGradient.collectGradientEntries(aSvgGradientEntryVector);
- if(!aSvgGradientEntryVector.empty())
+ if(aSvgGradientEntryVector.empty())
+ return;
+
+ basegfx::B2DHomMatrix aGeoToUnit;
+ basegfx::B2DHomMatrix aGradientTransform;
+
+ if(rFillGradient.getGradientTransform())
{
- basegfx::B2DHomMatrix aGeoToUnit;
- basegfx::B2DHomMatrix aGradientTransform;
+ aGradientTransform = *rFillGradient.getGradientTransform();
+ }
- if(rFillGradient.getGradientTransform())
- {
- aGradientTransform = *rFillGradient.getGradientTransform();
- }
+ if(userSpaceOnUse == rFillGradient.getGradientUnits())
+ {
+ aGeoToUnit.translate(-rGeoRange.getMinX(), -rGeoRange.getMinY());
+ aGeoToUnit.scale(1.0 / rGeoRange.getWidth(), 1.0 / rGeoRange.getHeight());
+ }
+
+ if(SVGTokenLinearGradient == rFillGradient.getType())
+ {
+ basegfx::B2DPoint aStart(0.0, 0.0);
+ basegfx::B2DPoint aEnd(1.0, 0.0);
if(userSpaceOnUse == rFillGradient.getGradientUnits())
{
- aGeoToUnit.translate(-rGeoRange.getMinX(), -rGeoRange.getMinY());
- aGeoToUnit.scale(1.0 / rGeoRange.getWidth(), 1.0 / rGeoRange.getHeight());
+ // all possible units
+ aStart.setX(rFillGradient.getX1().solve(mrOwner, xcoordinate));
+ aStart.setY(rFillGradient.getY1().solve(mrOwner, ycoordinate));
+ aEnd.setX(rFillGradient.getX2().solve(mrOwner, xcoordinate));
+ aEnd.setY(rFillGradient.getY2().solve(mrOwner, ycoordinate));
+ }
+ else
+ {
+ // fractions or percent relative to object bounds
+ const SvgNumber X1(rFillGradient.getX1());
+ const SvgNumber Y1(rFillGradient.getY1());
+ const SvgNumber X2(rFillGradient.getX2());
+ const SvgNumber Y2(rFillGradient.getY2());
+
+ aStart.setX(Unit_percent == X1.getUnit() ? X1.getNumber() * 0.01 : X1.getNumber());
+ aStart.setY(Unit_percent == Y1.getUnit() ? Y1.getNumber() * 0.01 : Y1.getNumber());
+ aEnd.setX(Unit_percent == X2.getUnit() ? X2.getNumber() * 0.01 : X2.getNumber());
+ aEnd.setY(Unit_percent == Y2.getUnit() ? Y2.getNumber() * 0.01 : Y2.getNumber());
}
- if(SVGTokenLinearGradient == rFillGradient.getType())
+ if(!aGeoToUnit.isIdentity())
{
- basegfx::B2DPoint aStart(0.0, 0.0);
- basegfx::B2DPoint aEnd(1.0, 0.0);
+ aStart *= aGeoToUnit;
+ aEnd *= aGeoToUnit;
+ }
- if(userSpaceOnUse == rFillGradient.getGradientUnits())
- {
- // all possible units
- aStart.setX(rFillGradient.getX1().solve(mrOwner, xcoordinate));
- aStart.setY(rFillGradient.getY1().solve(mrOwner, ycoordinate));
- aEnd.setX(rFillGradient.getX2().solve(mrOwner, xcoordinate));
- aEnd.setY(rFillGradient.getY2().solve(mrOwner, ycoordinate));
- }
- else
- {
- // fractions or percent relative to object bounds
- const SvgNumber X1(rFillGradient.getX1());
- const SvgNumber Y1(rFillGradient.getY1());
- const SvgNumber X2(rFillGradient.getX2());
- const SvgNumber Y2(rFillGradient.getY2());
-
- aStart.setX(Unit_percent == X1.getUnit() ? X1.getNumber() * 0.01 : X1.getNumber());
- aStart.setY(Unit_percent == Y1.getUnit() ? Y1.getNumber() * 0.01 : Y1.getNumber());
- aEnd.setX(Unit_percent == X2.getUnit() ? X2.getNumber() * 0.01 : X2.getNumber());
- aEnd.setY(Unit_percent == Y2.getUnit() ? Y2.getNumber() * 0.01 : Y2.getNumber());
- }
+ rTarget.push_back(
+ new drawinglayer::primitive2d::SvgLinearGradientPrimitive2D(
+ aGradientTransform,
+ rPath,
+ aSvgGradientEntryVector,
+ aStart,
+ aEnd,
+ userSpaceOnUse != rFillGradient.getGradientUnits(),
+ rFillGradient.getSpreadMethod()));
+ }
+ else
+ {
+ basegfx::B2DPoint aStart(0.5, 0.5);
+ basegfx::B2DPoint aFocal;
+ double fRadius(0.5);
+ const SvgNumber* pFx = rFillGradient.getFx();
+ const SvgNumber* pFy = rFillGradient.getFy();
+ const bool bFocal(pFx || pFy);
+
+ if(userSpaceOnUse == rFillGradient.getGradientUnits())
+ {
+ // all possible units
+ aStart.setX(rFillGradient.getCx().solve(mrOwner, xcoordinate));
+ aStart.setY(rFillGradient.getCy().solve(mrOwner, ycoordinate));
+ fRadius = rFillGradient.getR().solve(mrOwner);
- if(!aGeoToUnit.isIdentity())
+ if(bFocal)
{
- aStart *= aGeoToUnit;
- aEnd *= aGeoToUnit;
+ aFocal.setX(pFx ? pFx->solve(mrOwner, xcoordinate) : aStart.getX());
+ aFocal.setY(pFy ? pFy->solve(mrOwner, ycoordinate) : aStart.getY());
}
-
- rTarget.push_back(
- new drawinglayer::primitive2d::SvgLinearGradientPrimitive2D(
- aGradientTransform,
- rPath,
- aSvgGradientEntryVector,
- aStart,
- aEnd,
- userSpaceOnUse != rFillGradient.getGradientUnits(),
- rFillGradient.getSpreadMethod()));
}
else
{
- basegfx::B2DPoint aStart(0.5, 0.5);
- basegfx::B2DPoint aFocal;
- double fRadius(0.5);
- const SvgNumber* pFx = rFillGradient.getFx();
- const SvgNumber* pFy = rFillGradient.getFy();
- const bool bFocal(pFx || pFy);
+ // fractions or percent relative to object bounds
+ const SvgNumber Cx(rFillGradient.getCx());
+ const SvgNumber Cy(rFillGradient.getCy());
+ const SvgNumber R(rFillGradient.getR());
- if(userSpaceOnUse == rFillGradient.getGradientUnits())
- {
- // all possible units
- aStart.setX(rFillGradient.getCx().solve(mrOwner, xcoordinate));
- aStart.setY(rFillGradient.getCy().solve(mrOwner, ycoordinate));
- fRadius = rFillGradient.getR().solve(mrOwner);
+ aStart.setX(Unit_percent == Cx.getUnit() ? Cx.getNumber() * 0.01 : Cx.getNumber());
+ aStart.setY(Unit_percent == Cy.getUnit() ? Cy.getNumber() * 0.01 : Cy.getNumber());
+ fRadius = (Unit_percent == R.getUnit()) ? R.getNumber() * 0.01 : R.getNumber();
- if(bFocal)
- {
- aFocal.setX(pFx ? pFx->solve(mrOwner, xcoordinate) : aStart.getX());
- aFocal.setY(pFy ? pFy->solve(mrOwner, ycoordinate) : aStart.getY());
- }
- }
- else
+ if(bFocal)
{
- // fractions or percent relative to object bounds
- const SvgNumber Cx(rFillGradient.getCx());
- const SvgNumber Cy(rFillGradient.getCy());
- const SvgNumber R(rFillGradient.getR());
-
- aStart.setX(Unit_percent == Cx.getUnit() ? Cx.getNumber() * 0.01 : Cx.getNumber());
- aStart.setY(Unit_percent == Cy.getUnit() ? Cy.getNumber() * 0.01 : Cy.getNumber());
- fRadius = (Unit_percent == R.getUnit()) ? R.getNumber() * 0.01 : R.getNumber();
-
- if(bFocal)
- {
- aFocal.setX(pFx ? (Unit_percent == pFx->getUnit() ? pFx->getNumber() * 0.01 : pFx->getNumber()) : aStart.getX());
- aFocal.setY(pFy ? (Unit_percent == pFy->getUnit() ? pFy->getNumber() * 0.01 : pFy->getNumber()) : aStart.getY());
- }
+ aFocal.setX(pFx ? (Unit_percent == pFx->getUnit() ? pFx->getNumber() * 0.01 : pFx->getNumber()) : aStart.getX());
+ aFocal.setY(pFy ? (Unit_percent == pFy->getUnit() ? pFy->getNumber() * 0.01 : pFy->getNumber()) : aStart.getY());
}
+ }
- if(!aGeoToUnit.isIdentity())
- {
- aStart *= aGeoToUnit;
- fRadius = (aGeoToUnit * basegfx::B2DVector(fRadius, 0.0)).getLength();
+ if(!aGeoToUnit.isIdentity())
+ {
+ aStart *= aGeoToUnit;
+ fRadius = (aGeoToUnit * basegfx::B2DVector(fRadius, 0.0)).getLength();
- if(bFocal)
- {
- aFocal *= aGeoToUnit;
- }
+ if(bFocal)
+ {
+ aFocal *= aGeoToUnit;
}
-
- rTarget.push_back(
- new drawinglayer::primitive2d::SvgRadialGradientPrimitive2D(
- aGradientTransform,
- rPath,
- aSvgGradientEntryVector,
- aStart,
- fRadius,
- userSpaceOnUse != rFillGradient.getGradientUnits(),
- rFillGradient.getSpreadMethod(),
- bFocal ? &aFocal : nullptr));
}
+
+ rTarget.push_back(
+ new drawinglayer::primitive2d::SvgRadialGradientPrimitive2D(
+ aGradientTransform,
+ rPath,
+ aSvgGradientEntryVector,
+ aStart,
+ fRadius,
+ userSpaceOnUse != rFillGradient.getGradientUnits(),
+ rFillGradient.getSpreadMethod(),
+ bFocal ? &aFocal : nullptr));
}
}
@@ -513,85 +513,85 @@ namespace svgio
// fill polyPolygon with given pattern
const drawinglayer::primitive2d::Primitive2DContainer& rPrimitives = rFillPattern.getPatternPrimitives();
- if(!rPrimitives.empty())
- {
- double fTargetWidth(rGeoRange.getWidth());
- double fTargetHeight(rGeoRange.getHeight());
-
- if(fTargetWidth > 0.0 && fTargetHeight > 0.0)
- {
- // get relative values from pattern
- double fX(0.0);
- double fY(0.0);
- double fW(0.0);
- double fH(0.0);
+ if(rPrimitives.empty())
+ return;
- rFillPattern.getValuesRelative(fX, fY, fW, fH, rGeoRange, mrOwner);
+ double fTargetWidth(rGeoRange.getWidth());
+ double fTargetHeight(rGeoRange.getHeight());
- if(fW > 0.0 && fH > 0.0)
- {
- // build the reference range relative to the rGeoRange
- const basegfx::B2DRange aReferenceRange(fX, fY, fX + fW, fY + fH);
+ if(!(fTargetWidth > 0.0 && fTargetHeight > 0.0))
+ return;
- // find out how the content is mapped to the reference range
- basegfx::B2DHomMatrix aMapPrimitivesToUnitRange;
- const basegfx::B2DRange* pViewBox = rFillPattern.getViewBox();
+ // get relative values from pattern
+ double fX(0.0);
+ double fY(0.0);
+ double fW(0.0);
+ double fH(0.0);
- if(pViewBox)
- {
- // use viewBox/preserveAspectRatio
- const SvgAspectRatio& rRatio = rFillPattern.getSvgAspectRatio();
- const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
+ rFillPattern.getValuesRelative(fX, fY, fW, fH, rGeoRange, mrOwner);
- if(rRatio.isSet())
- {
- // let mapping be created from SvgAspectRatio
- aMapPrimitivesToUnitRange = rRatio.createMapping(aUnitRange, *pViewBox);
- }
- else
- {
- // choose default mapping
- aMapPrimitivesToUnitRange = SvgAspectRatio::createLinearMapping(aUnitRange, *pViewBox);
- }
- }
- else
- {
- // use patternContentUnits
- const SvgUnits aPatternContentUnits(rFillPattern.getPatternContentUnits() ? *rFillPattern.getPatternContentUnits() : userSpaceOnUse);
+ if(!(fW > 0.0 && fH > 0.0))
+ return;
- if(userSpaceOnUse == aPatternContentUnits)
- {
- // create relative mapping to unit coordinates
- aMapPrimitivesToUnitRange.scale(1.0 / (fW * fTargetWidth), 1.0 / (fH * fTargetHeight));
- }
- else
- {
- aMapPrimitivesToUnitRange.scale(1.0 / fW, 1.0 / fH);
- }
- }
+ // build the reference range relative to the rGeoRange
+ const basegfx::B2DRange aReferenceRange(fX, fY, fX + fW, fY + fH);
- // apply aMapPrimitivesToUnitRange to content when used
- drawinglayer::primitive2d::Primitive2DContainer aPrimitives(rPrimitives);
+ // find out how the content is mapped to the reference range
+ basegfx::B2DHomMatrix aMapPrimitivesToUnitRange;
+ const basegfx::B2DRange* pViewBox = rFillPattern.getViewBox();
- if(!aMapPrimitivesToUnitRange.isIdentity())
- {
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- aMapPrimitivesToUnitRange,
- aPrimitives));
+ if(pViewBox)
+ {
+ // use viewBox/preserveAspectRatio
+ const SvgAspectRatio& rRatio = rFillPattern.getSvgAspectRatio();
+ const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
- aPrimitives = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ if(rRatio.isSet())
+ {
+ // let mapping be created from SvgAspectRatio
+ aMapPrimitivesToUnitRange = rRatio.createMapping(aUnitRange, *pViewBox);
+ }
+ else
+ {
+ // choose default mapping
+ aMapPrimitivesToUnitRange = SvgAspectRatio::createLinearMapping(aUnitRange, *pViewBox);
+ }
+ }
+ else
+ {
+ // use patternContentUnits
+ const SvgUnits aPatternContentUnits(rFillPattern.getPatternContentUnits() ? *rFillPattern.getPatternContentUnits() : userSpaceOnUse);
- // embed in PatternFillPrimitive2D
- rTarget.push_back(
- new drawinglayer::primitive2d::PatternFillPrimitive2D(
- rPath,
- aPrimitives,
- aReferenceRange));
- }
+ if(userSpaceOnUse == aPatternContentUnits)
+ {
+ // create relative mapping to unit coordinates
+ aMapPrimitivesToUnitRange.scale(1.0 / (fW * fTargetWidth), 1.0 / (fH * fTargetHeight));
}
+ else
+ {
+ aMapPrimitivesToUnitRange.scale(1.0 / fW, 1.0 / fH);
+ }
+ }
+
+ // apply aMapPrimitivesToUnitRange to content when used
+ drawinglayer::primitive2d::Primitive2DContainer aPrimitives(rPrimitives);
+
+ if(!aMapPrimitivesToUnitRange.isIdentity())
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aMapPrimitivesToUnitRange,
+ aPrimitives));
+
+ aPrimitives = drawinglayer::primitive2d::Primitive2DContainer { xRef };
}
+
+ // embed in PatternFillPrimitive2D
+ rTarget.push_back(
+ new drawinglayer::primitive2d::PatternFillPrimitive2D(
+ rPath,
+ aPrimitives,
+ aReferenceRange));
}
void SvgStyleAttributes::add_fill(
@@ -603,50 +603,50 @@ namespace svgio
const SvgGradientNode* pFillGradient = getSvgGradientNodeFill();
const SvgPatternNode* pFillPattern = getSvgPatternNodeFill();
- if(pFill || pFillGradient || pFillPattern)
- {
- const double fFillOpacity(getFillOpacity().solve(mrOwner));
+ if(!(pFill || pFillGradient || pFillPattern))
+ return;
- if(basegfx::fTools::more(fFillOpacity, 0.0))
- {
- drawinglayer::primitive2d::Primitive2DContainer aNewFill;
+ const double fFillOpacity(getFillOpacity().solve(mrOwner));
- if(pFillGradient)
- {
- // create fill content with SVG gradient primitive
- add_fillGradient(rPath, aNewFill, *pFillGradient, rGeoRange);
- }
- else if(pFillPattern)
- {
- // create fill content with SVG pattern primitive
- add_fillPatternTransform(rPath, aNewFill, *pFillPattern, rGeoRange);
- }
- else // if(pFill)
- {
- // create fill content
- aNewFill.resize(1);
- aNewFill[0] = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
- rPath,
- *pFill);
- }
+ if(!basegfx::fTools::more(fFillOpacity, 0.0))
+ return;
- if(!aNewFill.empty())
- {
- if(basegfx::fTools::less(fFillOpacity, 1.0))
- {
- // embed in UnifiedTransparencePrimitive2D
- rTarget.push_back(
- new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
- aNewFill,
- 1.0 - fFillOpacity));
- }
- else
- {
- // append
- rTarget.append(aNewFill);
- }
- }
- }
+ drawinglayer::primitive2d::Primitive2DContainer aNewFill;
+
+ if(pFillGradient)
+ {
+ // create fill content with SVG gradient primitive
+ add_fillGradient(rPath, aNewFill, *pFillGradient, rGeoRange);
+ }
+ else if(pFillPattern)
+ {
+ // create fill content with SVG pattern primitive
+ add_fillPatternTransform(rPath, aNewFill, *pFillPattern, rGeoRange);
+ }
+ else // if(pFill)
+ {
+ // create fill content
+ aNewFill.resize(1);
+ aNewFill[0] = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ rPath,
+ *pFill);
+ }
+
+ if(aNewFill.empty())
+ return;
+
+ if(basegfx::fTools::less(fFillOpacity, 1.0))
+ {
+ // embed in UnifiedTransparencePrimitive2D
+ rTarget.push_back(
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aNewFill,
+ 1.0 - fFillOpacity));
+ }
+ else
+ {
+ // append
+ rTarget.append(aNewFill);
}
}
@@ -659,151 +659,151 @@ namespace svgio
const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke();
const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke();
- if(pStroke || pStrokeGradient || pStrokePattern)
- {
- drawinglayer::primitive2d::Primitive2DContainer aNewStroke;
- const double fStrokeOpacity(getStrokeOpacity().solve(mrOwner));
+ if(!(pStroke || pStrokeGradient || pStrokePattern))
+ return;
- if(basegfx::fTools::more(fStrokeOpacity, 0.0))
- {
- // get stroke width; SVG does not use 0.0 == hairline, so 0.0 is no line at all
- const double fStrokeWidth(getStrokeWidth().isSet() ? getStrokeWidth().solve(mrOwner) : 1.0);
+ drawinglayer::primitive2d::Primitive2DContainer aNewStroke;
+ const double fStrokeOpacity(getStrokeOpacity().solve(mrOwner));
- if(basegfx::fTools::more(fStrokeWidth, 0.0))
- {
- drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive;
+ if(!basegfx::fTools::more(fStrokeOpacity, 0.0))
+ return;
- // if we have a line with two identical points it is not really a line,
- // but used by SVG sometimes to paint a single dot.In that case, create
- // the geometry for a single dot
- if(1 == rPath.count())
- {
- const basegfx::B2DPolygon& aSingle(rPath.getB2DPolygon(0));
+ // get stroke width; SVG does not use 0.0 == hairline, so 0.0 is no line at all
+ const double fStrokeWidth(getStrokeWidth().isSet() ? getStrokeWidth().solve(mrOwner) : 1.0);
- if(2 == aSingle.count() && aSingle.getB2DPoint(0).equal(aSingle.getB2DPoint(1)))
- {
- aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
- basegfx::B2DPolyPolygon(
- basegfx::utils::createPolygonFromCircle(
- aSingle.getB2DPoint(0),
- fStrokeWidth * (1.44 * 0.5))),
- pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0));
- }
- }
+ if(!basegfx::fTools::more(fStrokeWidth, 0.0))
+ return;
- if(!aNewLinePrimitive.is())
- {
- // get LineJoin, LineCap and stroke array
- const basegfx::B2DLineJoin aB2DLineJoin(StrokeLinejoinToB2DLineJoin(getStrokeLinejoin()));
- const css::drawing::LineCap aLineCap(StrokeLinecapToDrawingLineCap(getStrokeLinecap()));
- ::std::vector< double > aDashArray;
+ drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive;
- if(!getStrokeDasharray().empty())
- {
- aDashArray = solveSvgNumberVector(getStrokeDasharray(), mrOwner);
- }
+ // if we have a line with two identical points it is not really a line,
+ // but used by SVG sometimes to paint a single dot.In that case, create
+ // the geometry for a single dot
+ if(1 == rPath.count())
+ {
+ const basegfx::B2DPolygon& aSingle(rPath.getB2DPolygon(0));
- // convert svg:stroke-miterlimit to LineAttrute:mfMiterMinimumAngle
- // The default needs to be set explicitly, because svg default <> Draw default
- double fMiterMinimumAngle;
- if (getStrokeMiterLimit().isSet())
- {
- fMiterMinimumAngle = 2.0 * asin(1.0/getStrokeMiterLimit().getNumber());
- }
- else
- {
- fMiterMinimumAngle = 2.0 * asin(0.25); // 1.0/default 4.0
- }
+ if(2 == aSingle.count() && aSingle.getB2DPoint(0).equal(aSingle.getB2DPoint(1)))
+ {
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(
+ basegfx::utils::createPolygonFromCircle(
+ aSingle.getB2DPoint(0),
+ fStrokeWidth * (1.44 * 0.5))),
+ pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0));
+ }
+ }
- // todo: Handle getStrokeDashOffset()
+ if(!aNewLinePrimitive.is())
+ {
+ // get LineJoin, LineCap and stroke array
+ const basegfx::B2DLineJoin aB2DLineJoin(StrokeLinejoinToB2DLineJoin(getStrokeLinejoin()));
+ const css::drawing::LineCap aLineCap(StrokeLinecapToDrawingLineCap(getStrokeLinecap()));
+ ::std::vector< double > aDashArray;
- // prepare line attribute
- const drawinglayer::attribute::LineAttribute aLineAttribute(
- pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0),
- fStrokeWidth,
- aB2DLineJoin,
- aLineCap,
- fMiterMinimumAngle);
+ if(!getStrokeDasharray().empty())
+ {
+ aDashArray = solveSvgNumberVector(getStrokeDasharray(), mrOwner);
+ }
- if(aDashArray.empty())
- {
- aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
- rPath,
- aLineAttribute);
- }
- else
- {
- const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashArray);
+ // convert svg:stroke-miterlimit to LineAttrute:mfMiterMinimumAngle
+ // The default needs to be set explicitly, because svg default <> Draw default
+ double fMiterMinimumAngle;
+ if (getStrokeMiterLimit().isSet())
+ {
+ fMiterMinimumAngle = 2.0 * asin(1.0/getStrokeMiterLimit().getNumber());
+ }
+ else
+ {
+ fMiterMinimumAngle = 2.0 * asin(0.25); // 1.0/default 4.0
+ }
- aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
- rPath,
- aLineAttribute,
- aStrokeAttribute);
- }
- }
+ // todo: Handle getStrokeDashOffset()
- if(pStrokeGradient || pStrokePattern)
- {
- // put primitive into Primitive2DReference and Primitive2DSequence
- const drawinglayer::primitive2d::Primitive2DContainer aSeq { aNewLinePrimitive };
+ // prepare line attribute
+ const drawinglayer::attribute::LineAttribute aLineAttribute(
+ pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0),
+ fStrokeWidth,
+ aB2DLineJoin,
+ aLineCap,
+ fMiterMinimumAngle);
+
+ if(aDashArray.empty())
+ {
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+ rPath,
+ aLineAttribute);
+ }
+ else
+ {
+ const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashArray);
- // use neutral ViewInformation and create LineGeometryExtractor2D
- const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
- drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D);
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+ rPath,
+ aLineAttribute,
+ aStrokeAttribute);
+ }
+ }
- // process
- aExtractor.process(aSeq);
+ if(pStrokeGradient || pStrokePattern)
+ {
+ // put primitive into Primitive2DReference and Primitive2DSequence
+ const drawinglayer::primitive2d::Primitive2DContainer aSeq { aNewLinePrimitive };
- // check for fill rsults
- const basegfx::B2DPolyPolygonVector& rLineFillVector(aExtractor.getExtractedLineFills());
+ // use neutral ViewInformation and create LineGeometryExtractor2D
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+ drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D);
- if(!rLineFillVector.empty())
- {
- const basegfx::B2DPolyPolygon aMergedArea(
- basegfx::utils::mergeToSinglePolyPolygon(
- rLineFillVector));
+ // process
+ aExtractor.process(aSeq);
- if(aMergedArea.count())
- {
- if(pStrokeGradient)
- {
- // create fill content with SVG gradient primitive. Use original GeoRange,
- // e.g. from circle without LineWidth
- add_fillGradient(aMergedArea, aNewStroke, *pStrokeGradient, rGeoRange);
- }
- else // if(pStrokePattern)
- {
- // create fill content with SVG pattern primitive. Use GeoRange
- // from the expanded data, e.g. circle with extended geo by half linewidth
- add_fillPatternTransform(aMergedArea, aNewStroke, *pStrokePattern, aMergedArea.getB2DRange());
- }
- }
- }
- }
- else // if(pStroke)
+ // check for fill rsults
+ const basegfx::B2DPolyPolygonVector& rLineFillVector(aExtractor.getExtractedLineFills());
+
+ if(!rLineFillVector.empty())
+ {
+ const basegfx::B2DPolyPolygon aMergedArea(
+ basegfx::utils::mergeToSinglePolyPolygon(
+ rLineFillVector));
+
+ if(aMergedArea.count())
+ {
+ if(pStrokeGradient)
{
- aNewStroke.push_back(aNewLinePrimitive);
+ // create fill content with SVG gradient primitive. Use original GeoRange,
+ // e.g. from circle without LineWidth
+ add_fillGradient(aMergedArea, aNewStroke, *pStrokeGradient, rGeoRange);
}
-
- if(!aNewStroke.empty())
+ else // if(pStrokePattern)
{
- if(basegfx::fTools::less(fStrokeOpacity, 1.0))
- {
- // embed in UnifiedTransparencePrimitive2D
- rTarget.push_back(
- new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
- aNewStroke,
- 1.0 - fStrokeOpacity));
- }
- else
- {
- // append
- rTarget.append(aNewStroke);
- }
+ // create fill content with SVG pattern primitive. Use GeoRange
+ // from the expanded data, e.g. circle with extended geo by half linewidth
+ add_fillPatternTransform(aMergedArea, aNewStroke, *pStrokePattern, aMergedArea.getB2DRange());
}
}
}
}
+ else // if(pStroke)
+ {
+ aNewStroke.push_back(aNewLinePrimitive);
+ }
+
+ if(aNewStroke.empty())
+ return;
+
+ if(basegfx::fTools::less(fStrokeOpacity, 1.0))
+ {
+ // embed in UnifiedTransparencePrimitive2D
+ rTarget.push_back(
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aNewStroke,
+ 1.0 - fStrokeOpacity));
+ }
+ else
+ {
+ // append
+ rTarget.append(aNewStroke);
+ }
}
bool SvgStyleAttributes::prepare_singleMarker(
@@ -906,174 +906,174 @@ namespace svgio
const SvgMarkerNode* pMid = accessMarkerMidXLink();
const SvgMarkerNode* pEnd = accessMarkerEndXLink();
- if(pStart || pMid || pEnd)
+ if(!(pStart || pMid || pEnd))
+ return;
+
+ const sal_uInt32 nSubPathCount(rPath.count());
+
+ if(!nSubPathCount)
+ return;
+
+ // remember prepared marker; pStart, pMid and pEnd may all be equal when
+ // only 'marker' was used instead of 'marker-start', 'marker-mid' or 'marker-end',
+ // see 'case SVGTokenMarker' in this file; thus in this case only one common
+ // marker in primitive form will be prepared
+ const SvgMarkerNode* pPrepared = nullptr;
+
+ // values for the prepared marker, results of prepare_singleMarker
+ drawinglayer::primitive2d::Primitive2DContainer aPreparedMarkerPrimitives;
+ basegfx::B2DHomMatrix aPreparedMarkerTransform;
+ basegfx::B2DRange aPreparedMarkerClipRange;
+
+ for (sal_uInt32 a(0); a < nSubPathCount; a++)
{
- const sal_uInt32 nSubPathCount(rPath.count());
+ // iterate over sub-paths
+ const basegfx::B2DPolygon& aSubPolygonPath(rPath.getB2DPolygon(a));
+ const sal_uInt32 nSubPolygonPointCount(aSubPolygonPath.count());
+ const bool bSubPolygonPathIsClosed(aSubPolygonPath.isClosed());
- if(nSubPathCount)
+ if(nSubPolygonPointCount)
{
- // remember prepared marker; pStart, pMid and pEnd may all be equal when
- // only 'marker' was used instead of 'marker-start', 'marker-mid' or 'marker-end',
- // see 'case SVGTokenMarker' in this file; thus in this case only one common
- // marker in primitive form will be prepared
- const SvgMarkerNode* pPrepared = nullptr;
+ // for each sub-path, create one marker per point (when closed, two markers
+ // need to pe created for the 1st point)
+ const sal_uInt32 nTargetMarkerCount(bSubPolygonPathIsClosed ? nSubPolygonPointCount + 1 : nSubPolygonPointCount);
- // values for the prepared marker, results of prepare_singleMarker
- drawinglayer::primitive2d::Primitive2DContainer aPreparedMarkerPrimitives;
- basegfx::B2DHomMatrix aPreparedMarkerTransform;
- basegfx::B2DRange aPreparedMarkerClipRange;
-
- for (sal_uInt32 a(0); a < nSubPathCount; a++)
+ for (sal_uInt32 b(0); b < nTargetMarkerCount; b++)
{
- // iterate over sub-paths
- const basegfx::B2DPolygon& aSubPolygonPath(rPath.getB2DPolygon(a));
- const sal_uInt32 nSubPolygonPointCount(aSubPolygonPath.count());
- const bool bSubPolygonPathIsClosed(aSubPolygonPath.isClosed());
+ const bool bIsFirstMarker(!a && !b);
+ const bool bIsLastMarker(nSubPathCount - 1 == a && nTargetMarkerCount - 1 == b);
+ const SvgMarkerNode* pNeeded = nullptr;
+
+ if(bIsFirstMarker)
+ {
+ // 1st point in 1st sub-polygon, use pStart
+ pNeeded = pStart;
+ }
+ else if(bIsLastMarker)
+ {
+ // last point in last sub-polygon, use pEnd
+ pNeeded = pEnd;
+ }
+ else
+ {
+ // anything in-between, use pMid
+ pNeeded = pMid;
+ }
- if(nSubPolygonPointCount)
+ if(pHelpPointIndices && !pHelpPointIndices->empty())
{
- // for each sub-path, create one marker per point (when closed, two markers
- // need to pe created for the 1st point)
- const sal_uInt32 nTargetMarkerCount(bSubPolygonPathIsClosed ? nSubPolygonPointCount + 1 : nSubPolygonPointCount);
+ const basegfx::utils::PointIndexSet::const_iterator aFound(
+ pHelpPointIndices->find(basegfx::utils::PointIndex(a, b)));
- for (sal_uInt32 b(0); b < nTargetMarkerCount; b++)
+ if(aFound != pHelpPointIndices->end())
{
- const bool bIsFirstMarker(!a && !b);
- const bool bIsLastMarker(nSubPathCount - 1 == a && nTargetMarkerCount - 1 == b);
- const SvgMarkerNode* pNeeded = nullptr;
+ // this point is a pure helper point; do not create a marker for it
+ continue;
+ }
+ }
- if(bIsFirstMarker)
- {
- // 1st point in 1st sub-polygon, use pStart
- pNeeded = pStart;
- }
- else if(bIsLastMarker)
- {
- // last point in last sub-polygon, use pEnd
- pNeeded = pEnd;
- }
- else
- {
- // anything in-between, use pMid
- pNeeded = pMid;
- }
+ if(!pNeeded)
+ {
+ // no marker needs to be created for this point
+ continue;
+ }
- if(pHelpPointIndices && !pHelpPointIndices->empty())
- {
- const basegfx::utils::PointIndexSet::const_iterator aFound(
- pHelpPointIndices->find(basegfx::utils::PointIndex(a, b)));
-
- if(aFound != pHelpPointIndices->end())
- {
- // this point is a pure helper point; do not create a marker for it
- continue;
- }
- }
+ if(pPrepared != pNeeded)
+ {
+ // if needed marker is not yet prepared, do it now
+ if(prepare_singleMarker(aPreparedMarkerPrimitives, aPreparedMarkerTransform, aPreparedMarkerClipRange, *pNeeded))
+ {
+ pPrepared = pNeeded;
+ }
+ else
+ {
+ // error: could not prepare given marker
+ OSL_ENSURE(false, "OOps, could not prepare given marker as primitives (!)");
+ pPrepared = nullptr;
+ continue;
+ }
+ }
- if(!pNeeded)
- {
- // no marker needs to be created for this point
- continue;
- }
+ // prepare complete transform
+ basegfx::B2DHomMatrix aCombinedTransform(aPreparedMarkerTransform);
+
+ // get rotation
+ if(pPrepared->getOrientAuto())
+ {
+ const sal_uInt32 nPointIndex(b % nSubPolygonPointCount);
+
+ // get entering and leaving tangents; this will search backward/forward
+ // in the polygon to find tangents unequal to zero, skipping empty edges
+ // see basegfx descriptions)
+ // Hint: Mozilla, Inkscape and others use only leaving tangent for start marker
+ // and entering tangent for end marker. To achieve this (if wanted) it is possible
+ // to make the fetch of aEntering/aLeaving dependent on bIsFirstMarker/bIsLastMarker.
+ // This is not done here, see comment 14 in task #1232379#
+ // or http://www.w3.org/TR/SVG/painting.html#OrientAttribute
+ basegfx::B2DVector aEntering(
+ basegfx::utils::getTangentEnteringPoint(
+ aSubPolygonPath,
+ nPointIndex));
+ basegfx::B2DVector aLeaving(
+ basegfx::utils::getTangentLeavingPoint(
+ aSubPolygonPath,
+ nPointIndex));
+ const bool bEntering(!aEntering.equalZero());
+ const bool bLeaving(!aLeaving.equalZero());
+
+ if(bEntering || bLeaving)
+ {
+ basegfx::B2DVector aSum(0.0, 0.0);
- if(pPrepared != pNeeded)
+ if(bEntering)
{
- // if needed marker is not yet prepared, do it now
- if(prepare_singleMarker(aPreparedMarkerPrimitives, aPreparedMarkerTransform, aPreparedMarkerClipRange, *pNeeded))
- {
- pPrepared = pNeeded;
- }
- else
- {
- // error: could not prepare given marker
- OSL_ENSURE(false, "OOps, could not prepare given marker as primitives (!)");
- pPrepared = nullptr;
- continue;
- }
+ aSum += aEntering.normalize();
}
- // prepare complete transform
- basegfx::B2DHomMatrix aCombinedTransform(aPreparedMarkerTransform);
-
- // get rotation
- if(pPrepared->getOrientAuto())
+ if(bLeaving)
{
- const sal_uInt32 nPointIndex(b % nSubPolygonPointCount);
-
- // get entering and leaving tangents; this will search backward/forward
- // in the polygon to find tangents unequal to zero, skipping empty edges
- // see basegfx descriptions)
- // Hint: Mozilla, Inkscape and others use only leaving tangent for start marker
- // and entering tangent for end marker. To achieve this (if wanted) it is possible
- // to make the fetch of aEntering/aLeaving dependent on bIsFirstMarker/bIsLastMarker.
- // This is not done here, see comment 14 in task #1232379#
- // or http://www.w3.org/TR/SVG/painting.html#OrientAttribute
- basegfx::B2DVector aEntering(
- basegfx::utils::getTangentEnteringPoint(
- aSubPolygonPath,
- nPointIndex));
- basegfx::B2DVector aLeaving(
- basegfx::utils::getTangentLeavingPoint(
- aSubPolygonPath,
- nPointIndex));
- const bool bEntering(!aEntering.equalZero());
- const bool bLeaving(!aLeaving.equalZero());
-
- if(bEntering || bLeaving)
- {
- basegfx::B2DVector aSum(0.0, 0.0);
-
- if(bEntering)
- {
- aSum += aEntering.normalize();
- }
-
- if(bLeaving)
- {
- aSum += aLeaving.normalize();
- }
-
- if(!aSum.equalZero())
- {
- const double fAngle(atan2(aSum.getY(), aSum.getX()));
-
- // apply rotation
- aCombinedTransform.rotate(fAngle);
- }
- }
+ aSum += aLeaving.normalize();
}
- else
+
+ if(!aSum.equalZero())
{
+ const double fAngle(atan2(aSum.getY(), aSum.getX()));
+
// apply rotation
- aCombinedTransform.rotate(pPrepared->getAngle());
+ aCombinedTransform.rotate(fAngle);
}
+ }
+ }
+ else
+ {
+ // apply rotation
+ aCombinedTransform.rotate(pPrepared->getAngle());
+ }
- // get and apply target position
- const basegfx::B2DPoint aPoint(aSubPolygonPath.getB2DPoint(b % nSubPolygonPointCount));
-
- aCombinedTransform.translate(aPoint.getX(), aPoint.getY());
+ // get and apply target position
+ const basegfx::B2DPoint aPoint(aSubPolygonPath.getB2DPoint(b % nSubPolygonPointCount));
- // prepare marker
- drawinglayer::primitive2d::Primitive2DReference xMarker(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- aCombinedTransform,
- aPreparedMarkerPrimitives));
+ aCombinedTransform.translate(aPoint.getX(), aPoint.getY());
- if(!aPreparedMarkerClipRange.isEmpty())
- {
- // marker needs to be clipped, it's bigger as the mapping
- basegfx::B2DPolyPolygon aClipPolygon(basegfx::utils::createPolygonFromRect(aPreparedMarkerClipRange));
+ // prepare marker
+ drawinglayer::primitive2d::Primitive2DReference xMarker(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aCombinedTransform,
+ aPreparedMarkerPrimitives));
- aClipPolygon.transform(aCombinedTransform);
- xMarker = new drawinglayer::primitive2d::MaskPrimitive2D(
- aClipPolygon,
- drawinglayer::primitive2d::Primitive2DContainer { xMarker });
- }
+ if(!aPreparedMarkerClipRange.isEmpty())
+ {
+ // marker needs to be clipped, it's bigger as the mapping
+ basegfx::B2DPolyPolygon aClipPolygon(basegfx::utils::createPolygonFromRect(aPreparedMarkerClipRange));
- // add marker
- rTarget.push_back(xMarker);
- }
+ aClipPolygon.transform(aCombinedTransform);
+ xMarker = new drawinglayer::primitive2d::MaskPrimitive2D(
+ aClipPolygon,
+ drawinglayer::primitive2d::Primitive2DContainer { xMarker });
}
+
+ // add marker
+ rTarget.push_back(xMarker);
}
}
}
@@ -1153,98 +1153,98 @@ namespace svgio
const drawinglayer::primitive2d::Primitive2DContainer& rSource,
const basegfx::B2DHomMatrix* pTransform) const
{
- if(!rSource.empty())
+ if(rSource.empty())
+ return;
+
+ const double fOpacity(getOpacity().solve(mrOwner));
+
+ if(basegfx::fTools::equalZero(fOpacity))
{
- const double fOpacity(getOpacity().solve(mrOwner));
+ return;
+ }
- if(basegfx::fTools::equalZero(fOpacity))
- {
- return;
- }
+ drawinglayer::primitive2d::Primitive2DContainer aSource(rSource);
- drawinglayer::primitive2d::Primitive2DContainer aSource(rSource);
+ if(basegfx::fTools::less(fOpacity, 1.0))
+ {
+ // embed in UnifiedTransparencePrimitive2D
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aSource,
+ 1.0 - fOpacity));
- if(basegfx::fTools::less(fOpacity, 1.0))
- {
- // embed in UnifiedTransparencePrimitive2D
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
- aSource,
- 1.0 - fOpacity));
+ aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
+ }
- aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ if(pTransform)
+ {
+ // create embedding group element with transformation. This applies the given
+ // transformation to the graphical content, but *not* to mask and/or clip (as needed)
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ *pTransform,
+ aSource));
- if(pTransform)
- {
- // create embedding group element with transformation. This applies the given
- // transformation to the graphical content, but *not* to mask and/or clip (as needed)
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- *pTransform,
- aSource));
+ aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
+ }
- aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ const SvgClipPathNode* pClip = accessClipPathXLink();
+ while(pClip)
+ {
+ // #i124852# transform may be needed when userSpaceOnUse
+ pClip->apply(aSource, pTransform);
+ pClip = pClip->getSvgStyleAttributes()->accessClipPathXLink();
+ }
- const SvgClipPathNode* pClip = accessClipPathXLink();
- while(pClip)
+ if(!aSource.empty()) // test again, applied clipPath may have lead to empty geometry
+ {
+ const SvgMaskNode* pMask = accessMaskXLink();
+ if(pMask)
{
// #i124852# transform may be needed when userSpaceOnUse
- pClip->apply(aSource, pTransform);
- pClip = pClip->getSvgStyleAttributes()->accessClipPathXLink();
+ pMask->apply(aSource, pTransform);
}
+ }
- if(!aSource.empty()) // test again, applied clipPath may have lead to empty geometry
- {
- const SvgMaskNode* pMask = accessMaskXLink();
- if(pMask)
- {
- // #i124852# transform may be needed when userSpaceOnUse
- pMask->apply(aSource, pTransform);
- }
- }
+ // This is part of the SVG import of self-written SVGs from
+ // Draw/Impress containing multiple Slides/Pages. To be able
+ // to later 'break' these to multiple Pages if wanted, embed
+ // each Page-Content in a identifiable Primitive Grouping
+ // Object.
+ // This is the case when the current Node is a GroupNode, has
+ // class="Page" set, has a parent that also is a GroupNode
+ // at which class="Slide" is set.
+ // Multiple Slides/Pages are possible for Draw and Impress.
+ if(SVGTokenG == mrOwner.getType() && mrOwner.getClass())
+ {
+ const OUString aOwnerClass(*mrOwner.getClass());
- // This is part of the SVG import of self-written SVGs from
- // Draw/Impress containing multiple Slides/Pages. To be able
- // to later 'break' these to multiple Pages if wanted, embed
- // each Page-Content in a identifiable Primitive Grouping
- // Object.
- // This is the case when the current Node is a GroupNode, has
- // class="Page" set, has a parent that also is a GroupNode
- // at which class="Slide" is set.
- // Multiple Slides/Pages are possible for Draw and Impress.
- if(SVGTokenG == mrOwner.getType() && mrOwner.getClass())
+ if("Page" == aOwnerClass)
{
- const OUString aOwnerClass(*mrOwner.getClass());
+ const SvgNode* pParent(mrOwner.getParent());
- if("Page" == aOwnerClass)
+ if(nullptr != pParent && SVGTokenG == pParent->getType() && pParent->getClass())
{
- const SvgNode* pParent(mrOwner.getParent());
+ const OUString aParentClass(*pParent->getClass());
- if(nullptr != pParent && SVGTokenG == pParent->getType() && pParent->getClass())
+ if("Slide" == aParentClass)
{
- const OUString aParentClass(*pParent->getClass());
-
- if("Slide" == aParentClass)
- {
- // embed to grouping primitive to identify the
- // Slide/Page information
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::PageHierarchyPrimitive2D(
- aSource));
+ // embed to grouping primitive to identify the
+ // Slide/Page information
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::PageHierarchyPrimitive2D(
+ aSource));
- aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
}
}
}
+ }
- if(!aSource.empty()) // test again, applied mask may have lead to empty geometry
- {
- // append to current target
- rTarget.append(aSource);
- }
+ if(!aSource.empty()) // test again, applied mask may have lead to empty geometry
+ {
+ // append to current target
+ rTarget.append(aSource);
}
}
diff --git a/svgio/source/svgreader/svgstylenode.cxx b/svgio/source/svgreader/svgstylenode.cxx
index 5fdd73e9828b..68a101fb9637 100644
--- a/svgio/source/svgreader/svgstylenode.cxx
+++ b/svgio/source/svgreader/svgstylenode.cxx
@@ -85,100 +85,100 @@ namespace svgio
{
// aSelectors: CssStyle selectors, any combination, no comma separations, no spaces at start/end
// rNewStyle: the already prepared style to register on that name
- if(!aSelectors.isEmpty())
- {
- std::vector< OUString > aSelectorParts;
- const sal_Int32 nLen(aSelectors.getLength());
- sal_Int32 nPos(0);
- OUStringBuffer aToken;
+ if(aSelectors.isEmpty())
+ return;
- // split into single tokens (currently only space separator)
- while(nPos < nLen)
- {
- const sal_Int32 nInitPos(nPos);
- copyToLimiter(aSelectors, u' ', nPos, aToken, nLen);
- skip_char(aSelectors, u' ', nPos, nLen);
- const OUString aSelectorPart(aToken.makeStringAndClear().trim());
+ std::vector< OUString > aSelectorParts;
+ const sal_Int32 nLen(aSelectors.getLength());
+ sal_Int32 nPos(0);
+ OUStringBuffer aToken;
- if(!aSelectorPart.isEmpty())
- {
- aSelectorParts.push_back(aSelectorPart);
- }
+ // split into single tokens (currently only space separator)
+ while(nPos < nLen)
+ {
+ const sal_Int32 nInitPos(nPos);
+ copyToLimiter(aSelectors, u' ', nPos, aToken, nLen);
+ skip_char(aSelectors, u' ', nPos, nLen);
+ const OUString aSelectorPart(aToken.makeStringAndClear().trim());
- if(nInitPos == nPos)
- {
- OSL_ENSURE(false, "Could not interpret on current position (!)");
- nPos++;
- }
+ if(!aSelectorPart.isEmpty())
+ {
+ aSelectorParts.push_back(aSelectorPart);
}
- if(!aSelectorParts.empty())
+ if(nInitPos == nPos)
{
- OUStringBuffer aConcatenatedSelector;
+ OSL_ENSURE(false, "Could not interpret on current position (!)");
+ nPos++;
+ }
+ }
- // re-combine without spaces, create a unique name (for now)
- for(size_t a(0); a < aSelectorParts.size(); a++)
- {
- aConcatenatedSelector.append(aSelectorParts[a]);
- }
+ if(aSelectorParts.empty())
+ return;
- // CssStyles in SVG are currently not completely supported; the current idea for
- // supporting the needed minimal set is to register CssStyles associated to a string
- // which is just the space-char cleaned, concatenated Selectors. The part to 'match'
- // these is in fillCssStyleVectorUsingHierarchyAndSelectors. There, the same string is
- // built up using the priorities of local CssStyle, Id, Class and other info combined
- // with the existing hierarchy. This creates a specificity and priority-sorted local
- // list for each node which is then chained using get/setCssStyleParent.
- // The current solution is capable of solving space-separated selectors which can be
- // mixed between Id, Class and type specifiers.
- // When CssStyles need more specific solving, the start point is here; remember the
- // needed infos not in maIdStyleTokenMapperList at the document, but select evtl.
- // more specific infos there in a class capable of handling more complex matchings.
- // Additionally fillCssStyleVector (or the mechanism above that when a linked list of
- // SvgStyleAttributes will not do it) will have to be adapted to make use of it.
-
- // register new style at document for (evtl. concatenated) stylename
- const_cast< SvgDocument& >(getDocument()).addSvgStyleAttributesToMapper(aConcatenatedSelector.makeStringAndClear(), rNewStyle);
- }
+ OUStringBuffer aConcatenatedSelector;
+
+ // re-combine without spaces, create a unique name (for now)
+ for(size_t a(0); a < aSelectorParts.size(); a++)
+ {
+ aConcatenatedSelector.append(aSelectorParts[a]);
}
+
+ // CssStyles in SVG are currently not completely supported; the current idea for
+ // supporting the needed minimal set is to register CssStyles associated to a string
+ // which is just the space-char cleaned, concatenated Selectors. The part to 'match'
+ // these is in fillCssStyleVectorUsingHierarchyAndSelectors. There, the same string is
+ // built up using the priorities of local CssStyle, Id, Class and other info combined
+ // with the existing hierarchy. This creates a specificity and priority-sorted local
+ // list for each node which is then chained using get/setCssStyleParent.
+ // The current solution is capable of solving space-separated selectors which can be
+ // mixed between Id, Class and type specifiers.
+ // When CssStyles need more specific solving, the start point is here; remember the
+ // needed infos not in maIdStyleTokenMapperList at the document, but select evtl.
+ // more specific infos there in a class capable of handling more complex matchings.
+ // Additionally fillCssStyleVector (or the mechanism above that when a linked list of
+ // SvgStyleAttributes will not do it) will have to be adapted to make use of it.
+
+ // register new style at document for (evtl. concatenated) stylename
+ const_cast< SvgDocument& >(getDocument()).addSvgStyleAttributesToMapper(aConcatenatedSelector.makeStringAndClear(), rNewStyle);
}
void SvgStyleNode::addCssStyleSheet(const OUString& aSelectors, const OUString& aContent)
{
// aSelectors: possible comma-separated list of CssStyle definitions, no spaces at start/end
// aContent: the svg style definitions as string
- if(!aSelectors.isEmpty() && !aContent.isEmpty())
- {
- // create new style and add to local list (for ownership control)
- SvgStyleAttributes* pNewStyle = new SvgStyleAttributes(*this);
- maSvgStyleAttributes.push_back(pNewStyle);
+ if(!(!aSelectors.isEmpty() && !aContent.isEmpty()))
+ return;
- // fill with content
- pNewStyle->readCssStyle(aContent);
+ // create new style and add to local list (for ownership control)
+ SvgStyleAttributes* pNewStyle = new SvgStyleAttributes(*this);
+ maSvgStyleAttributes.push_back(pNewStyle);
- // comma-separated split (Css abbreviation for same style for multiple selectors)
- const sal_Int32 nLen(aSelectors.getLength());
- sal_Int32 nPos(0);
- OUStringBuffer aToken;
+ // fill with content
+ pNewStyle->readCssStyle(aContent);
- while(nPos < nLen)
- {
- const sal_Int32 nInitPos(nPos);
- copyToLimiter(aSelectors, u',', nPos, aToken, nLen);
- skip_char(aSelectors, u' ', u',', nPos, nLen);
+ // comma-separated split (Css abbreviation for same style for multiple selectors)
+ const sal_Int32 nLen(aSelectors.getLength());
+ sal_Int32 nPos(0);
+ OUStringBuffer aToken;
- const OUString aSingleName(aToken.makeStringAndClear().trim());
+ while(nPos < nLen)
+ {
+ const sal_Int32 nInitPos(nPos);
+ copyToLimiter(aSelectors, u',', nPos, aToken, nLen);
+ skip_char(aSelectors, u' ', u',', nPos, nLen);
- if(aSingleName.getLength())
- {
- addCssStyleSheet(aSingleName, *pNewStyle);
- }
+ const OUString aSingleName(aToken.makeStringAndClear().trim());
- if(nInitPos == nPos)
- {
- OSL_ENSURE(false, "Could not interpret on current position (!)");
- nPos++;
- }
+ if(aSingleName.getLength())
+ {
+ addCssStyleSheet(aSingleName, *pNewStyle);
+ }
+
+ if(nInitPos == nPos)
+ {
+ OSL_ENSURE(false, "Could not interpret on current position (!)");
+ nPos++;
}
}
}
@@ -187,41 +187,41 @@ namespace svgio
{
const sal_Int32 nLen(aSelectorsAndContent.getLength());
- if(nLen)
- {
- sal_Int32 nPos(0);
- OUStringBuffer aToken;
+ if(!nLen)
+ return;
- while(nPos < nLen)
- {
- // read the full selectors (may be multiple, comma-separated)
- const sal_Int32 nInitPos(nPos);
- skip_char(aSelectorsAndContent, u' ', nPos, nLen);
- copyToLimiter(aSelectorsAndContent, u'{', nPos, aToken, nLen);
- skip_char(aSelectorsAndContent, u' ', u'{', nPos, nLen);
+ sal_Int32 nPos(0);
+ OUStringBuffer aToken;
- const OUString aSelectors(aToken.makeStringAndClear().trim());
- OUString aContent;
+ while(nPos < nLen)
+ {
+ // read the full selectors (may be multiple, comma-separated)
+ const sal_Int32 nInitPos(nPos);
+ skip_char(aSelectorsAndContent, u' ', nPos, nLen);
+ copyToLimiter(aSelectorsAndContent, u'{', nPos, aToken, nLen);
+ skip_char(aSelectorsAndContent, u' ', u'{', nPos, nLen);
- if(!aSelectors.isEmpty() && nPos < nLen)
- {
- // isolate content as text, embraced by '{' and '}'
- copyToLimiter(aSelectorsAndContent, u'}', nPos, aToken, nLen);
- skip_char(aSelectorsAndContent, u' ', u'}', nPos, nLen);
+ const OUString aSelectors(aToken.makeStringAndClear().trim());
+ OUString aContent;
- aContent = aToken.makeStringAndClear().trim();
- }
+ if(!aSelectors.isEmpty() && nPos < nLen)
+ {
+ // isolate content as text, embraced by '{' and '}'
+ copyToLimiter(aSelectorsAndContent, u'}', nPos, aToken, nLen);
+ skip_char(aSelectorsAndContent, u' ', u'}', nPos, nLen);
- if(!aSelectors.isEmpty() && !aContent.isEmpty())
- {
- addCssStyleSheet(aSelectors, aContent);
- }
+ aContent = aToken.makeStringAndClear().trim();
+ }
- if(nInitPos == nPos)
- {
- OSL_ENSURE(false, "Could not interpret on current position (!)");
- nPos++;
- }
+ if(!aSelectors.isEmpty() && !aContent.isEmpty())
+ {
+ addCssStyleSheet(aSelectors, aContent);
+ }
+
+ if(nInitPos == nPos)
+ {
+ OSL_ENSURE(false, "Could not interpret on current position (!)");
+ nPos++;
}
}
}
diff --git a/svgio/source/svgreader/svgsvgnode.cxx b/svgio/source/svgreader/svgsvgnode.cxx
index 0d42099eff3b..72775f16b9a4 100644
--- a/svgio/source/svgreader/svgsvgnode.cxx
+++ b/svgio/source/svgreader/svgsvgnode.cxx
@@ -50,58 +50,58 @@ namespace svgio
// #i125258#
void SvgSvgNode::initializeStyleAttributes()
{
- if(!mbStyleAttributesInitialized)
+ if(mbStyleAttributesInitialized)
+ return;
+
+ // #i125258# determine if initial values need to be initialized with hard values
+ // for the case that this is the outmost SVG statement and it has no parent
+ // stale (CssStyle for svg may be defined)
+ bool bSetInitialValues(true);
+
+ if(getParent())
{
- // #i125258# determine if initial values need to be initialized with hard values
- // for the case that this is the outmost SVG statement and it has no parent
- // stale (CssStyle for svg may be defined)
- bool bSetInitialValues(true);
+ // #i125258# no initial values when it's a SVG element embedded in SVG
+ bSetInitialValues = false;
+ }
- if(getParent())
- {
- // #i125258# no initial values when it's a SVG element embedded in SVG
- bSetInitialValues = false;
- }
+ if(bSetInitialValues)
+ {
+ const SvgStyleAttributes* pStyles = getSvgStyleAttributes();
- if(bSetInitialValues)
+ if(pStyles && pStyles->getParentStyle())
{
- const SvgStyleAttributes* pStyles = getSvgStyleAttributes();
+ // 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();
- if(pStyles && pStyles->getParentStyle())
+ while(pParentStyle && !bFillSet)
{
- // 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;
- }
+ bFillSet = pParentStyle->isFillSet();
+ pParentStyle = pParentStyle->getParentStyle();
}
- }
- if(bSetInitialValues)
- {
- // #i125258# only set if not yet initialized (SvgSvgNode::parseAttribute is already done,
- // just setting may revert an already set valid value)
- if(!maSvgStyleAttributes.isFillSet())
+ if(bFillSet)
{
- // #i125258# initial fill is black (see SVG1.1 spec)
- maSvgStyleAttributes.setFill(SvgPaint(basegfx::BColor(0.0, 0.0, 0.0), true, true));
+ // #125258# no initial values when SVG has a parent style at which a fill
+ // is already set
+ bSetInitialValues = false;
}
}
+ }
- mbStyleAttributesInitialized = true;
+ if(bSetInitialValues)
+ {
+ // #i125258# only set if not yet initialized (SvgSvgNode::parseAttribute is already done,
+ // just setting may revert an already set valid value)
+ if(!maSvgStyleAttributes.isFillSet())
+ {
+ // #i125258# initial fill is black (see SVG1.1 spec)
+ maSvgStyleAttributes.setFill(SvgPaint(basegfx::BColor(0.0, 0.0, 0.0), true, true));
+ }
}
+
+ mbStyleAttributesInitialized = true;
}
SvgSvgNode::~SvgSvgNode()
@@ -709,22 +709,22 @@ namespace svgio
}
}
- if(aSequence.empty() && !getParent() && getViewBox())
- {
- // tdf#118232 No geometry, Outermost SVG element and we have a ViewBox.
- // Create a HiddenGeometry Primitive containing an expanded
- // hairline geometry to have the size contained
- const drawinglayer::primitive2d::Primitive2DReference xLine(
- new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
- basegfx::utils::createPolygonFromRect(
- *getViewBox()),
- basegfx::BColor(0.0, 0.0, 0.0)));
- const drawinglayer::primitive2d::Primitive2DReference xHidden(
- new drawinglayer::primitive2d::HiddenGeometryPrimitive2D(
- drawinglayer::primitive2d::Primitive2DContainer { xLine }));
-
- rTarget.push_back(xHidden);
- }
+ if(!(aSequence.empty() && !getParent() && getViewBox()))
+ return;
+
+ // tdf#118232 No geometry, Outermost SVG element and we have a ViewBox.
+ // Create a HiddenGeometry Primitive containing an expanded
+ // hairline geometry to have the size contained
+ const drawinglayer::primitive2d::Primitive2DReference xLine(
+ new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
+ basegfx::utils::createPolygonFromRect(
+ *getViewBox()),
+ basegfx::BColor(0.0, 0.0, 0.0)));
+ const drawinglayer::primitive2d::Primitive2DReference xHidden(
+ new drawinglayer::primitive2d::HiddenGeometryPrimitive2D(
+ drawinglayer::primitive2d::Primitive2DContainer { xLine }));
+
+ rTarget.push_back(xHidden);
}
const basegfx::B2DRange SvgSvgNode::getCurrentViewPort() const
diff --git a/svgio/source/svgreader/svgtextnode.cxx b/svgio/source/svgreader/svgtextnode.cxx
index 58e9621420df..bc6d824877df 100644
--- a/svgio/source/svgreader/svgtextnode.cxx
+++ b/svgio/source/svgreader/svgtextnode.cxx
@@ -89,21 +89,21 @@ namespace svgio
drawinglayer::primitive2d::Primitive2DContainer& rTarget,
drawinglayer::primitive2d::Primitive2DContainer const & rSource)
{
- if(!rSource.empty())
- {
- const SvgStyleAttributes* pAttributes = rCandidate.getSvgStyleAttributes();
+ if(rSource.empty())
+ return;
- if(pAttributes)
- {
- // add text with taking all Fill/Stroke attributes into account
- pAttributes->add_text(rTarget, rSource);
- }
- else
- {
- // should not happen, every subnode from SvgTextNode will at least
- // return the attributes from SvgTextNode. Nonetheless, add text
- rTarget.append(rSource);
- }
+ const SvgStyleAttributes* pAttributes = rCandidate.getSvgStyleAttributes();
+
+ if(pAttributes)
+ {
+ // add text with taking all Fill/Stroke attributes into account
+ pAttributes->add_text(rTarget, rSource);
+ }
+ else
+ {
+ // should not happen, every subnode from SvgTextNode will at least
+ // return the attributes from SvgTextNode. Nonetheless, add text
+ rTarget.append(rSource);
}
}
@@ -225,37 +225,37 @@ namespace svgio
// SVGTokenTref and SVGTokenTextPath. These increase a given current text position
const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
- if(pStyle && !getChildren().empty())
- {
- const double fOpacity(pStyle->getOpacity().getNumber());
+ if(!(pStyle && !getChildren().empty()))
+ return;
- if(fOpacity > 0.0)
- {
- SvgTextPosition aSvgTextPosition(nullptr, *this, maSvgTextPositions);
- drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
- const auto& rChildren = getChildren();
- const sal_uInt32 nCount(rChildren.size());
+ const double fOpacity(pStyle->getOpacity().getNumber());
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- const SvgNode& rCandidate = *rChildren[a];
+ if(fOpacity <= 0.0)
+ return;
- DecomposeChild(rCandidate, aNewTarget, aSvgTextPosition);
- }
+ SvgTextPosition aSvgTextPosition(nullptr, *this, maSvgTextPositions);
+ drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
+ const auto& rChildren = getChildren();
+ const sal_uInt32 nCount(rChildren.size());
- if(!aNewTarget.empty())
- {
- drawinglayer::primitive2d::Primitive2DContainer aNewTarget2;
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ const SvgNode& rCandidate = *rChildren[a];
- addTextPrimitives(*this, aNewTarget2, aNewTarget);
- aNewTarget = aNewTarget2;
- }
+ DecomposeChild(rCandidate, aNewTarget, aSvgTextPosition);
+ }
- if(!aNewTarget.empty())
- {
- pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
- }
- }
+ if(!aNewTarget.empty())
+ {
+ drawinglayer::primitive2d::Primitive2DContainer aNewTarget2;
+
+ addTextPrimitives(*this, aNewTarget2, aNewTarget);
+ aNewTarget = aNewTarget2;
+ }
+
+ if(!aNewTarget.empty())
+ {
+ pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
}
}
diff --git a/svgio/source/svgreader/svgtextpathnode.cxx b/svgio/source/svgreader/svgtextpathnode.cxx
index 4e7567566317..f11bc2e7fbd2 100644
--- a/svgio/source/svgreader/svgtextpathnode.cxx
+++ b/svgio/source/svgreader/svgtextpathnode.cxx
@@ -346,96 +346,96 @@ namespace svgio
drawinglayer::primitive2d::Primitive2DContainer& rTarget,
const basegfx::B2DPoint& rTextStart) const
{
- if(!rPathContent.empty())
+ if(rPathContent.empty())
+ return;
+
+ const SvgPathNode* pSvgPathNode = dynamic_cast< const SvgPathNode* >(getDocument().findSvgNodeById(maXLink));
+
+ if(!pSvgPathNode)
+ return;
+
+ const basegfx::B2DPolyPolygon* pPolyPolyPath = pSvgPathNode->getPath();
+
+ if(!(pPolyPolyPath && pPolyPolyPath->count()))
+ return;
+
+ basegfx::B2DPolygon aPolygon(pPolyPolyPath->getB2DPolygon(0));
+
+ if(pSvgPathNode->getTransform())
{
- const SvgPathNode* pSvgPathNode = dynamic_cast< const SvgPathNode* >(getDocument().findSvgNodeById(maXLink));
+ aPolygon.transform(*pSvgPathNode->getTransform());
+ }
- if(pSvgPathNode)
+ const double fBasegfxPathLength(basegfx::utils::getLength(aPolygon));
+
+ if(basegfx::fTools::equalZero(fBasegfxPathLength))
+ return;
+
+ double fUserToBasegfx(1.0); // multiply: user->basegfx, divide: basegfx->user
+
+ if(pSvgPathNode->getPathLength().isSet())
+ {
+ const double fUserLength(pSvgPathNode->getPathLength().solve(*this));
+
+ if(fUserLength > 0.0 && !basegfx::fTools::equal(fUserLength, fBasegfxPathLength))
{
- const basegfx::B2DPolyPolygon* pPolyPolyPath = pSvgPathNode->getPath();
+ fUserToBasegfx = fUserLength / fBasegfxPathLength;
+ }
+ }
- if(pPolyPolyPath && pPolyPolyPath->count())
- {
- basegfx::B2DPolygon aPolygon(pPolyPolyPath->getB2DPolygon(0));
+ double fPosition(0.0);
- if(pSvgPathNode->getTransform())
- {
- aPolygon.transform(*pSvgPathNode->getTransform());
- }
+ if(getStartOffset().isSet())
+ {
+ if(Unit_percent == getStartOffset().getUnit())
+ {
+ // percent are relative to path length
+ fPosition = getStartOffset().getNumber() * 0.01 * fBasegfxPathLength;
+ }
+ else
+ {
+ fPosition = getStartOffset().solve(*this) * fUserToBasegfx;
+ }
+ }
- const double fBasegfxPathLength(basegfx::utils::getLength(aPolygon));
+ if(fPosition < 0.0)
+ return;
- if(!basegfx::fTools::equalZero(fBasegfxPathLength))
- {
- double fUserToBasegfx(1.0); // multiply: user->basegfx, divide: basegfx->user
+ const sal_Int32 nLength(rPathContent.size());
+ sal_Int32 nCurrent(0);
- if(pSvgPathNode->getPathLength().isSet())
- {
- const double fUserLength(pSvgPathNode->getPathLength().solve(*this));
+ while(fPosition < fBasegfxPathLength && nCurrent < nLength)
+ {
+ const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pCandidate = nullptr;
+ const drawinglayer::primitive2d::Primitive2DReference xReference(rPathContent[nCurrent]);
- if(fUserLength > 0.0 && !basegfx::fTools::equal(fUserLength, fBasegfxPathLength))
- {
- fUserToBasegfx = fUserLength / fBasegfxPathLength;
- }
- }
+ if(xReference.is())
+ {
+ pCandidate = dynamic_cast< const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* >(xReference.get());
+ }
- double fPosition(0.0);
+ if(pCandidate)
+ {
+ const pathTextBreakupHelper aPathTextBreakupHelper(
+ *pCandidate,
+ aPolygon,
+ fBasegfxPathLength,
+ fPosition,
+ rTextStart);
- if(getStartOffset().isSet())
- {
- if(Unit_percent == getStartOffset().getUnit())
- {
- // percent are relative to path length
- fPosition = getStartOffset().getNumber() * 0.01 * fBasegfxPathLength;
- }
- else
- {
- fPosition = getStartOffset().solve(*this) * fUserToBasegfx;
- }
- }
+ const drawinglayer::primitive2d::Primitive2DContainer& aResult(
+ aPathTextBreakupHelper.getResult());
- if(fPosition >= 0.0)
- {
- const sal_Int32 nLength(rPathContent.size());
- sal_Int32 nCurrent(0);
-
- while(fPosition < fBasegfxPathLength && nCurrent < nLength)
- {
- const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pCandidate = nullptr;
- const drawinglayer::primitive2d::Primitive2DReference xReference(rPathContent[nCurrent]);
-
- if(xReference.is())
- {
- pCandidate = dynamic_cast< const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* >(xReference.get());
- }
-
- if(pCandidate)
- {
- const pathTextBreakupHelper aPathTextBreakupHelper(
- *pCandidate,
- aPolygon,
- fBasegfxPathLength,
- fPosition,
- rTextStart);
-
- const drawinglayer::primitive2d::Primitive2DContainer& aResult(
- aPathTextBreakupHelper.getResult());
-
- if(!aResult.empty())
- {
- rTarget.append(aResult);
- }
-
- // advance position to consumed
- fPosition = aPathTextBreakupHelper.getPosition();
- }
-
- nCurrent++;
- }
- }
- }
+ if(!aResult.empty())
+ {
+ rTarget.append(aResult);
}
+
+ // advance position to consumed
+ fPosition = aPathTextBreakupHelper.getPosition();
}
+
+ nCurrent++;
}
}
diff --git a/svgio/source/svgreader/svgusenode.cxx b/svgio/source/svgreader/svgusenode.cxx
index 5904a143068a..a54c9fb46c3e 100644
--- a/svgio/source/svgreader/svgusenode.cxx
+++ b/svgio/source/svgreader/svgusenode.cxx
@@ -142,50 +142,50 @@ namespace svgio
// try to access link to content
const SvgNode* pXLink = getDocument().findSvgNodeById(maXLink);
- if (pXLink && Display_none != pXLink->getDisplay() && !mbDecomposingSvgNode)
- {
- // decompose children
- drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
-
- // todo: in case mpXLink is a SVGTokenSvg or SVGTokenSymbol the
- // SVG docs want the getWidth() and getHeight() from this node
- // to be valid for the subtree.
- mbDecomposingSvgNode = true;
- const_cast< SvgNode* >(pXLink)->setAlternativeParent(this);
- pXLink->decomposeSvgNode(aNewTarget, true);
- const_cast< SvgNode* >(pXLink)->setAlternativeParent();
- mbDecomposingSvgNode = false;
-
- if(!aNewTarget.empty())
- {
- basegfx::B2DHomMatrix aTransform;
+ if (!(pXLink && Display_none != pXLink->getDisplay() && !mbDecomposingSvgNode))
+ return;
- if(getX().isSet() || getY().isSet())
- {
- aTransform.translate(
- getX().solve(*this, xcoordinate),
- getY().solve(*this, ycoordinate));
- }
+ // decompose children
+ drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
- if(getTransform())
- {
- aTransform = *getTransform() * aTransform;
- }
+ // todo: in case mpXLink is a SVGTokenSvg or SVGTokenSymbol the
+ // SVG docs want the getWidth() and getHeight() from this node
+ // to be valid for the subtree.
+ mbDecomposingSvgNode = true;
+ const_cast< SvgNode* >(pXLink)->setAlternativeParent(this);
+ pXLink->decomposeSvgNode(aNewTarget, true);
+ const_cast< SvgNode* >(pXLink)->setAlternativeParent();
+ mbDecomposingSvgNode = false;
- if(!aTransform.isIdentity())
- {
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- aTransform,
- aNewTarget));
+ if(aNewTarget.empty())
+ return;
- rTarget.push_back(xRef);
- }
- else
- {
- rTarget.append(aNewTarget);
- }
- }
+ basegfx::B2DHomMatrix aTransform;
+
+ if(getX().isSet() || getY().isSet())
+ {
+ aTransform.translate(
+ getX().solve(*this, xcoordinate),
+ getY().solve(*this, ycoordinate));
+ }
+
+ if(getTransform())
+ {
+ aTransform = *getTransform() * aTransform;
+ }
+
+ if(!aTransform.isIdentity())
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aTransform,
+ aNewTarget));
+
+ rTarget.push_back(xRef);
+ }
+ else
+ {
+ rTarget.append(aNewTarget);
}
}