From 993fa0750eeb1e8a9fcd65ad6de99e3a89ecd2e0 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sat, 21 May 2022 19:33:57 -0500 Subject: [PATCH] svg ref obj --- src/pixie/fileformats/svg.nim | 99 +++++++++++++++++------------------ 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/src/pixie/fileformats/svg.nim b/src/pixie/fileformats/svg.nim index b226c9b..5bb9cdf 100644 --- a/src/pixie/fileformats/svg.nim +++ b/src/pixie/fileformats/svg.nim @@ -11,6 +11,10 @@ const svgSignature* = " @@ -353,7 +317,7 @@ proc parseSvgElement( let props = node.parseSvgProperties(propertiesStack[^1]) propertiesStack.add(props) for child in node: - result.add child.parseSvgElement(propertiesStack) + result.add child.parseSvgElement(svg, propertiesStack) discard propertiesStack.pop() of "path": @@ -529,7 +493,7 @@ proc parseSvgElement( else: raise newException(PixieError, "Unexpected SVG tag: " & child.tag) - props.linearGradients[id] = linearGradient + svg.linearGradients[id] = linearGradient else: raise newException(PixieError, "Unsupported SVG tag: " & node.tag) @@ -568,16 +532,51 @@ proc decodeSvg*( scaleY = height.float32 / viewBoxHeight.float32 rootprops.transform = rootprops.transform * scale(vec2(scaleX, scaleY)) - var - propertiesStack = @[rootProps] - renderInfos: seq[(Path, SvgProperties)] + let svg = Svg() + + var propertiesStack = @[rootProps] for node in root.items: - renderInfos.add node.parseSvgElement(propertiesStack) - for (path, props) in renderInfos: + svg.elements.add node.parseSvgElement(svg, propertiesStack) + + for (path, props) in svg.elements: if props.display and props.opacity > 0: - result.fill(path, props) + if props.fill != "none": + var paint: Paint + if props.fill.startsWith("url("): + let closingParen = props.fill.find(")", 5) + if closingParen == -1: + raise newException(PixieError, "Malformed fill: " & props.fill) + let id = props.fill[5 .. closingParen - 1] + if id in svg.linearGradients: + let linearGradient = svg.linearGradients[id] + paint = newPaint(LinearGradientPaint) + paint.gradientHandlePositions = @[ + props.transform * vec2(linearGradient.x1, linearGradient.y1), + props.transform * vec2(linearGradient.x2, linearGradient.y2) + ] + paint.gradientStops = linearGradient.stops + else: + raise newException(PixieError, "Missing SVG resource " & id) + else: + paint = parseHtmlColor(props.fill).rgbx + + paint.opacity = props.fillOpacity * props.opacity + + result.fillPath(path, paint, props.transform, props.fillRule) + if props.stroke != rgbx(0, 0, 0, 0) and props.strokeWidth > 0: - result.stroke(path, props) + let paint = newPaint(props.stroke) + paint.color.a *= (props.opacity * props.strokeOpacity) + result.strokePath( + path, + paint, + props.transform, + props.strokeWidth, + props.strokeLineCap, + props.strokeLineJoin, + miterLimit = props.strokeMiterLimit, + dashes = props.strokeDashArray + ) except PixieError as e: raise e except: