diff --git a/src/pixie/fileformats/svg.nim b/src/pixie/fileformats/svg.nim index 015276f..d45f0dc 100644 --- a/src/pixie/fileformats/svg.nim +++ b/src/pixie/fileformats/svg.nim @@ -560,6 +560,48 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) = except: raise currentExceptionAsPixieError() +proc decodeSvg*( + data: string, width = 0, height = 0 +): Image {.raises: [PixieError].} = + ## Render SVG XML and return the image. Defaults to the SVG's view box size. + try: + let root = parseXml(data) + if root.tag != "svg": + failInvalid() + + let + viewBox = root.attr("viewBox") + box = viewBox.split(" ") + viewBoxMinX = parseInt(box[0]) + viewBoxMinY = parseInt(box[1]) + viewBoxWidth = parseInt(box[2]) + viewBoxHeight = parseInt(box[3]) + + var rootCtx = initCtx() + rootCtx = decodeCtx(rootCtx, root) + + if viewBoxMinX != 0 or viewBoxMinY != 0: + let viewBoxMin = vec2(-viewBoxMinX.float32, -viewBoxMinY.float32) + rootCtx.transform = rootCtx.transform * translate(viewBoxMin) + + if width == 0 and height == 0: # Default to the view box size + result = newImage(viewBoxWidth, viewBoxHeight) + else: + result = newImage(width, height) + + let + scaleX = width.float32 / viewBoxWidth.float32 + scaleY = height.float32 / viewBoxHeight.float32 + rootCtx.transform = rootCtx.transform * scale(vec2(scaleX, scaleY)) + + var ctxStack = @[rootCtx] + for node in root: + result.draw(node, ctxStack) + except PixieError as e: + raise e + except: + raise newException(PixieError, "Unable to load SVG") + proc decodeSvg*( root: XmlNode, width = 0, height = 0 ): Image {.raises: [PixieError].} = @@ -600,14 +642,3 @@ proc decodeSvg*( raise e except: raise newException(PixieError, "Unable to load SVG") - -proc decodeSvg*( - data: string, width = 0, height = 0 -): Image {.raises: [PixieError].} = - ## Render SVG data and return the image. Defaults to the SVG's view box size. - let root = - try: - parseXml(data) - except: - raise currentExceptionAsPixieError() - decodeSvg(root) diff --git a/tests/fileformats/svg/flat-color-icons.png b/tests/fileformats/svg/flat-color-icons.png index a20e17f..4adbef3 100644 Binary files a/tests/fileformats/svg/flat-color-icons.png and b/tests/fileformats/svg/flat-color-icons.png differ diff --git a/tests/fileformats/svg/ionicons.png b/tests/fileformats/svg/ionicons.png index f757375..c0565c0 100644 Binary files a/tests/fileformats/svg/ionicons.png and b/tests/fileformats/svg/ionicons.png differ diff --git a/tests/fileformats/svg/simple-icons.png b/tests/fileformats/svg/simple-icons.png index 713afac..c240a57 100644 Binary files a/tests/fileformats/svg/simple-icons.png and b/tests/fileformats/svg/simple-icons.png differ diff --git a/tests/fileformats/svg/tabler-icons.png b/tests/fileformats/svg/tabler-icons.png index 01f016e..afb16a6 100644 Binary files a/tests/fileformats/svg/tabler-icons.png and b/tests/fileformats/svg/tabler-icons.png differ diff --git a/tests/fileformats/svg/twbs-icons.png b/tests/fileformats/svg/twbs-icons.png index abef7c7..cc31391 100644 Binary files a/tests/fileformats/svg/twbs-icons.png and b/tests/fileformats/svg/twbs-icons.png differ