srwiley / oksvg Goto Github PK
View Code? Open in Web Editor NEWPartial implementation of SVG 2.0 specification in golang.
License: BSD 3-Clause "New" or "Revised" License
Partial implementation of SVG 2.0 specification in golang.
License: BSD 3-Clause "New" or "Revised" License
go mod why -m golang.org/x/net
github.com/srwiley/oksvg
golang.org/x/net/html/charset
Dependency go:golang.org/x/net:v0.6.0 is vulnerable, safe version v0.21.0
CVE-2022-41723 7.5 Uncontrolled Resource Consumption vulnerability with High severity found
CVE-2023-44487 5.3 Uncontrolled Resource Consumption vulnerability with Medium severity found
CVE-2023-39325 7.5 Uncontrolled Resource Consumption vulnerability with High severity found
Hello,
An svg I'm trying to parse uses the defs tag. I was thinking it could grab the elements defined in defs and save them in the SvgIcon's Ids, like it does for gradients.
If there was the ability to plug in different back-ends this project would be super useful for all sorts of different renderings, such as PDF's, or even GUI applications. Even if this project could support Canvas as a back-end there's already a variety of places it could render, even GioUI.
This project was an early attempt to do what I'm describing above. https://github.com/benoitkugler/oksvg
Hi !
This is not an issue, but rather a proposal; feel free to close it if not interested !
I would like to use oksvg to render svg files to an other target than an image: I have in mind a PDF file, but it could be any other target.
To do so, I propose an intermediate package which handles the svg parsing but do not import rasterx (or any other backend package). Instead it delegates the drawing to a Driver
interface.
This interface is then easily implemented by a thin wrapper around rasterx, but may also be implemented by a PDF writter.
It's true that a PDF writer could directly implement the Scanner interface, but it would be rather inefficient since PDF directly supports high-level path painting operators.
I have a proof of concept at https://github.com/benoitkugler/oksvg : the raster backend is complete, and the PDF one is
in progress, but already support a large number of features.
If you considerer this idea interesting, we can discuss the details of a possible PR...
I am getting strange colors when trying to convert svg icons to png.
The test files and code are attached.
Am I missing something obvious?
Hi,
I'm trying to convert an SVG file to a large PNG.
But it takes a lot of time. So I'm trying to profile the CPU usage to provide a PR. Maybe you could give me a hint?
I found this comment:
// This draws the entire bounds of the image, because
// at this point the alpha mask does not shift with the
// placement of the target rectangle in the vector rasterizer
Indeed, why is it that to draw a single SvgPath we need to iterate over the pixels of the whole canvas?
Please consider supporting percentages in stoke-width as per https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-width
Cause: strconv.ParseFloat: parsing "14%": invalid syntax
I'm trying to convert a svg
file to png
, but the output file ended with a black background instead of white.
package converter
import (
"image"
"image/png"
"net/http"
"os"
"github.com/srwiley/oksvg"
"github.com/srwiley/rasterx"
)
func ConvertSvgToPng() error {
url := "https://s.glbimg.com/es/sde/f/organizacoes/2020/02/12/botsvg.svg"
w, h := 512, 512
response, err := http.Get(url)
if err != nil {
return err
}
defer response.Body.Close()
icon, _ := oksvg.ReadIconStream(response.Body)
icon.SetTarget(0, 0, float64(w), float64(h))
rgba := image.NewRGBA(image.Rect(0, 0, w, h))
icon.Draw(rasterx.NewDasher(w, h, rasterx.NewScannerGV(w, h, rgba, rgba.Bounds())), 1)
out, err := os.Create("out.png")
if err != nil {
return err
}
defer out.Close()
err = png.Encode(out, rgba)
if err != nil {
return err
}
return err
}
SVG file: https://s.glbimg.com/es/sde/f/organizacoes/2020/02/12/botsvg.svg
hello :)
wondering if the converter supports text or Im doing something wrong :|
have this svg that I create in the code, so in the end I have the svg string.
canvas := svg.New(&buf)
canvas.Start(width, height)
canvas.Text(width/2, height/2, "aloha, SVG", "text-anchor:middle;font-size:30px;fill:white")
canvas.Circle(width/2, height/2, 100, "fill: green")
canvas.End()
but when Im running the repo code to generate a png, I get only a circle.
So want to make sure if text is supported, as it mentions in the readme that not all svg options are available.
If you have the content <rect fill="none" height="24" width="24"/>
then it hits a ParseError on "" (empty string).
It should, however, default to 0.
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/rect
Stack is approximately:
fyne.io/fynedesk/vendor/github.com/srwiley/oksvg.parseFloat(0xc00390ff90, 0x5, 0x40, 0x4014000000000000, 0x0, 0x0)
/home/andy/Code/Go/src/fyne.io/fynedesk/vendor/github.com/srwiley/oksvg/svgd.go:525 +0xbe
fyne.io/fynedesk/vendor/github.com/srwiley/oksvg.(*PathCursor).ReadFloat(0xc002a56f00, 0xc00390ff90, 0x5, 0x0, 0x0)
/home/andy/Code/Go/src/fyne.io/fynedesk/vendor/github.com/srwiley/oksvg/svgp.go:104 +0x236
fyne.io/fynedesk/vendor/github.com/srwiley/oksvg.(*PathCursor).GetPoints(0xc002a56f00, 0xc00390ff90, 0x5, 0x1, 0x0)
/home/andy/Code/Go/src/fyne.io/fynedesk/vendor/github.com/srwiley/oksvg/svgp.go:136 +0x235
fyne.io/fynedesk/vendor/github.com/srwiley/oksvg.(*PathCursor).addSeg(0xc002a56f00, 0xc00390ff8f, 0x6, 0x0, 0x0)
/home/andy/Code/Go/src/fyne.io/fynedesk/vendor/github.com/srwiley/oksvg/svgp.go:165 +0x78
fyne.io/fynedesk/vendor/github.com/srwiley/oksvg.(*PathCursor).CompilePath(0xc002a56f00, 0xc00390fe40, 0x156, 0xc000096f18, 0x4629fc)
/home/andy/Code/Go/src/fyne.io/fynedesk/vendor/github.com/srwiley/oksvg/svgp.go:384 +0x10c
Preface
I am very inexperienced when it comes to parsing svg-definitions and am not really familiar with the spec, so I apologize if I am completely misunderstanding what is happening here or I use the wrong terminology.
Issue
Any circular sub-path enclosed by an arbitrary different path is not rendered properly.
Examples (left svg rendered by browser, right by oksvg):
These examples only use a path-object with z
, Z
, m
, M
and a
operators inside a viewbox.
Steps to Reproduce
Add either the following minimal example (circle with donut-hole) or any svg from fontawesome.com with a hole as a svg-file to the existing testdata
folder of oksvg
add the reference to the file in svgdraw_test.go
:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#000000" d="M256 512a256 256 0 1 0 0-512 256 256 0 1 0 0 512zm0-352a96 96 0 1 1 0 192 96 96 0 1 1 0-192z"/></svg>
Specifically tested and incorrectly rendered files from fontawesome:
Steps Taken
I got a local development environment for oksvg
running and fiddled with the svg-files themselves as well as the code handling z
, Z
, m
and M
. I assumed it might be an edge-case for handling the closing of arcs that was misbehaving, but failed to identify anything meaningful.
Notes
oksvg
. When I tried to add more icons to the existing selection, the icons I added rendered incorrectly with the same issues as shown above.Various icons in the material collection specify the fill as "current", which crashes out.
For example: https://github.com/fyne-io/defyne/blob/main/Icon.svg
Clip paths are currently not supported. These could be stored in the SvgIcon's Ids like gradients are currently.
By
Line 179 in be6e887
Hey @srwiley,
This is not an issue so feel free to close, but I just wanted to tell you about a simple SVG Editor I was able to create thanks to oksvg and rasterx.
Keep up the great work!
LICENSE states that the library is distributed under BSD but doc/LICENSE is referring to GPLv2+ or Freetype. So which one do apply?
Thanks.
I noticed that in some cases the relative move-to 'm' command seems to be incorrect.
For example the svg flile at https://fonts.gstatic.com/s/i/materialicons/skip_previous/v4/24px.svg should be the mirror image of https://fonts.gstatic.com/s/i/materialicons/skip_next/v4/24px.svg but the arrow's middle point is offset on Y value for some reason.
I could not find a fix quickly or I would have submitted a PR, sorry.
look at the svg bellow:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 361.75 338.01">
<defs>
<style>.cls-2{fill:blue;}</style>
</defs>
<title>test</title>
<path class="cls-2" d="M141.1,283.87s-28,30.76-45.12,15c-5.16-4.75-6.84-10.25-18.46-9.57l4.78-6.84s6.15-2.05,15,4.78c7.29,5.61,19.14,8.89,28.71-11.62Z"/>
</svg>
the "class"
in <path>
has no effect.
https://security.snyk.io/vuln/SNYK-GOLANG-GOLANGORGXTEXTINTERNALLANGUAGE-2400718
All versions of golang.org/x/text
below 0.3.7
are vulnerable. Updating to a later golang.org/x/net
should solve this issue for the project.
Cheers.
When using the "stroke-dasharray" attribute short lines render correctly, but long lines break
Left: Chrome
Right: Fyne (using OKSVG)
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="480" height="640" viewBox="0 0 480 640">
<g stroke="red">
<line x1="60" y1="0" x2="60" y2="40" stroke-dasharray="4" />
<line x1="120" y1="0" x2="120" y2="140" stroke-dasharray="4" />
<line x1="180" y1="0" x2="180" y2="240" stroke-dasharray="4" />
<line x1="240" y1="0" x2="240" y2="340" stroke-dasharray="4" />
<line x1="300" y1="0" x2="300" y2="440" stroke-dasharray="4" />
<line x1="360" y1="0" x2="360" y2="540" stroke-dasharray="4" />
<line x1="420" y1="0" x2="420" y2="640" stroke-dasharray="4" />
</g>
</svg>
//go:generate fyne bundle -o bundled.go dasharray.svg
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
)
func main() {
a := app.New()
w := a.NewWindow("Dashes")
w.SetContent(&canvas.Image{
Resource: resourceDasharraySvg,
FillMode: canvas.ImageFillOriginal,
})
w.ShowAndRun()
}
go generate ./...
go run ./...
I run demo code in the test case, just modified my svg file, like this,
`
str := []string{"00dbdcf748734ed890fbf39ca76ce266",
"1ade369b862d44118c126ff8f80bbd1b",
"1bedfd263a1f4ca58c660806e03e80e7",
"1d7d7deed0ae484a8e893950ad700582",
"1e6c8acc04134b5a91cf1ecc1d43c433",
"1ed618bb2816400bbc29e40fffae8114",
"1fbd523827844e4ebea89657ea16c3de",
"2be84432e3ea4e01a919be01ec79fff5",
"2c2766e105bf4081b7f46d50a840d017",
"4c8536828410457ebd2996e3b2437863",
"4d1078d7548045d7921329e9ea91fe0c",
"4f0f35b1b5454a4482cecb693564c98b",
"4fe9018d54ec43da999f6712e2b4afc9",
"5abbd764d36b470c804a4d0b51353eae",
"5ec8889735b04398a7e17a54761f0c31"}
for _, s := range str {
iconPath := "gg_demo/icons2/" + s + ".svg"
icon, errSvg := oksvg.ReadIcon(iconPath, oksvg.WarnErrorMode)
if errSvg != nil {
fmt.Println(errSvg)
return
}
w, h := int(icon.ViewBox.W), int(icon.ViewBox.H)
img := image.NewRGBA(image.Rect(0, 0, w, h))
tb := img.Bounds()
tb.Max.X /= 2
scannerGV := rasterx.NewScannerGV(w, h, img, img.Bounds())
raster := rasterx.NewDasher(w, h, scannerGV)
icon.Draw(raster, 1.0)
if img != nil {
p := strings.Split(iconPath, "/")
err := SaveToPngFile(fmt.Sprintf("gg_demo/targets/%s.png", p[len(p)-1]), img)
if err != nil {
fmt.Println(err)
return
}
}
}
`
and the final result like this:
source code is
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 83.51 83.46"> <title>资源 35</title> <path d="M.06 62.2V45.36c0-1.12.76-1.57 1.48-2.14 7.31-5.68 15.49-6.79 24.3-4.61 8.35 2.06 16 6.09 24 9.09a48.68 48.68 0 0 0 14.71 3.53 26 26 0 0 0 16.61-5c.59-.42 1.09-1.31 1.89-1s.42 1.32.43 2v13a3.67 3.67 0 0 1-1.71 3.31C73.14 70 63.77 70.08 54 67c-8-2.53-15.44-6.52-23.38-9.21-8.37-2.85-16.68-3.84-24.89.51a32.29 32.29 0 0 0-5.67 3.9z" fill="#146fb7"/> <path d="M.07 39.11V22.39c0-1.12.78-1.58 1.5-2.13 7.15-5.56 15.17-6.73 23.82-4.69 8 1.88 15.25 5.65 22.83 8.6 6.06 2.37 12.18 4.42 18.85 4.12a26.13 26.13 0 0 0 14.3-5.22c.51-.36 1-1.14 1.71-.73s.33 1.21.33 1.83c0 4.33-.05 8.66 0 13a3.88 3.88 0 0 1-1.85 3.51c-7.6 5.68-16 6.43-24.89 4.1-8.39-2.19-16-6.37-24.15-9.28-6.38-2.28-12.84-4-19.75-2.67-4.57.89-8.54 3.01-12.7 6.28z" fill="#ec2032"/> <path d="M.09 15.6V1.26A1.05 1.05 0 0 1 1.31.06h78.94c2.45 0 3.4.5 3.23 3.14-.25 3.73-.12 7.49 0 11.24a3.48 3.48 0 0 1-1.55 3.13c-7.7 5.93-16.23 6.69-25.32 4.28-8.39-2.23-16-6.4-24.17-9.31-6.14-2.2-12.36-3.83-19-2.71a28.08 28.08 0 0 0-11.53 5c-.51.28-.82.86-1.82.77z" fill="#ec2032"/> <path d="M41.47 83.41H2.53C.6 83.47-.08 83 0 81c.16-3.9.1-7.82 0-11.73a3.46 3.46 0 0 1 1.52-3.14c8.28-6.36 17.36-6.76 27-3.85 7.09 2.15 13.7 5.51 20.61 8.14 5.52 2.1 11.1 3.87 17.14 3.79a26.07 26.07 0 0 0 14.86-5c.58-.41 1.1-1.3 1.9-.91s.39 1.34.4 2c0 3.58-.12 7.16.07 10.73.11 2.12-.75 2.45-2.59 2.45-13.15-.1-26.3-.07-39.44-.07z" fill="#146fb7"/> </svg>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.