linebender / linebender/tiny-skia
Pixel offset when hairline curve is just outside the canvas
- Dominant language
- Rust
- Stars
- 1.6k
- Forks
- 99
- Avg merge
- 2h 52m
- Merged PRs (30d)
- 1
Description
I've been using tiny-skia (via [resvg](https://github.com/linebender/resvg) and [spreet](https://github.com/flother/spreet)) and I found that some of my icons persistently have rendering glitches.
I've narrowed it down to the icon having an outline stroke of less than 1px (i.e. using the hairline rendering) and when that outline extends just slightly beyond the canvas (not deliberate, just the way I made the icon). This combination of factors seems to trigger a bug. I've rendered the same icons using skia, which seems to rendering them fine.
SVG sources - stroke-width 0.9 and 1.1
```svg
```
```svg
```
I've rendered the svgs onto a green background, and then scaled the result 10x:
As you can see in the grid, if the white outline stroke is wider than 1px, the output looks fine (i.e. a black dot, white outline and green showing through in the corners, i.e. bottom row). But if the outline stroke width is less than 1px, the pixel positions get a bit garbled in tiny-skia (top left of the grid), but look OK in upstream skia (top right).
If the source SVGs are tweaked so that the outline stroke exactly fits within the canvas, the artefacts disappear:
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the two inline SVG reproducers: a 6×6 circle with stroke widths 0.9 and 1.1, rendered through tiny-skia and compared with upstream Skia. Focus on the hairline case whose stroke extends just beyond the canvas, then verify that the pixel artefacts disappear without changing the behaviour of the 1.1px case or the in-canvas version.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100