rasterx icon indicating copy to clipboard operation
rasterx copied to clipboard

Scaled transform breaks dashing

Open Qendolin opened this issue 2 years ago • 1 comments

When rasterizing an SVG with a scaled transformation matrix dashing does not behave correctly. My goal is to create a high resolution png render of the svg.

At scale 1.0 (correct): Not Scaled SVG

At scale 2.0: image

Code used:

package main

import (
	"image"
	"image/png"
	"os"

	"github.com/srwiley/oksvg"
	"github.com/srwiley/rasterx"
)

func main() {
	scale := 2.0

	in, err := os.Open("in.svg")
	check(err)
	defer in.Close()

	icon, err := oksvg.ReadIconStream(in)
	check(err)

	w, h := int(icon.ViewBox.W*scale), int(icon.ViewBox.H*scale)

	icon.SetTarget(0, 0, float64(w), float64(h))
	rgba := image.NewRGBA(image.Rect(0, 0, w, h))
	dasher := rasterx.NewDasher(w, h, rasterx.NewScannerGV(w, h, rgba, rgba.Bounds()))
	icon.Draw(dasher, 1)

	out, err := os.Create("out.png")
	check(err)
	defer out.Close()

	err = png.Encode(out, rgba)
	check(err)
}

func check(err error) {
	if err != nil {
		panic(err)
	}
}

SVG used:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-5 -5 110 110">
    <path d="
      M 50, 50
	  l 0 -50
    " stroke="teal" fill="none" />
    <path d="
      M 0, 50
      a 50,50 0 1,0 100,0
      a 50,50 0 1,0 -100,0
    " stroke="teal" fill="none" stroke-dasharray="314" stroke-dashoffset="157" />
</svg>

Qendolin avatar Jun 19 '23 11:06 Qendolin

As a workaround adding

for i := range icon.SVGPaths {
	sp := &icon.SVGPaths[i]
	sp.DashOffset *= scale
	for j := range sp.Dash {
		sp.Dash[j] *= scale
	}
}

before drawing works.

Qendolin avatar Jun 19 '23 12:06 Qendolin