TinyVG / specification

The specification for TinyVG. This is the central authority for the file system

Home Page:https://tinyvg.tech/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Proposal] Add dashed lines

neinseg opened this issue · comments

commented

Dashed (or dotted) lines are a great feature in SVG that I often use. Given that their rendering is reasonably simple to implement, and that emulating them with multiple paths would cause a significant file size increase, I think they would be a good addition to TinyVG.

I wonder how i would implement them in my renderer (which uses a signed distance function for lines)

Which line caps would the dashes/dots have?

commented

Which line caps would the dashes/dots have?

In SVG, per spec dashes are basically just a shorthand for drawing a number of individual paths. The algorithm is described at https://www.w3.org/TR/SVG2/painting.html#StrokeShape This means that according to spec dashes use the stroke's end caps.

I wonder how i would implement them in my renderer (which uses a signed distance function for lines)

They aren't too bad to render. In svg-flatten I take the starting point of the path, then I add segments as long as the resulting partial path is shorter than the dash. The next segment is one overlapping the end of the dash, so I split that where the dash ends. For illustration:

   dashes: ==========          ==========          ==========          ==========
  egments: [1][2][  3  ][    4    ][5][    6   ][     7     ][    8   ][  10  ]
new paths: [1][2][ 3]          [4 ][5][6]          [   7    ]          [  10  ]
discarded:           [3][  4  ]          [  6  ][7]          [    8   ]

Draw the resulting new paths individually, discard the gaps. The only hard thing here is that you need both forward and inverse arc length functions. While trivial for straight lines and easy for circular arcs, this is a bit finicky for cubic beziers. It comes built-in to many graphics libraries, though. This arc length function should be decent, since errors accumulate. If a long path consisting of long or many short cubic beziers is dashed that way using short dashes, errors can build up to a point where the results are visually obvious in a side-by-side comparison since towards the end of the path, dashes can accumulate a significant offset. However I'd say that that kind of rendering artifact is to be expected, and should rarely matter in practice. I have attached an example file that shows this difference, along with renders from Inkscape and Firefox.

Inkscape
Firefox
dashes-test.svg.tar.gz (because Github doesn't like SVG)

Here's a nice post on the maths: https://tacodewolff.nl/posts/20190525-arc-length/

Dashed lines are still under consideration, need to think some more about it. Tempted to accept them though, as they are a really useful feature for technical drawings.

I got a really nice idea on encoding right now:
The encoding for the dashed lines consists of a single byte pattern as well as a length unit for pattern length.

With this, 256 different line patterns can be encode via the bit sequence:

11110000	────    ────    ────
11001100	──  ──  ──  ──  ──  ──
11001111	──  ──────  ──────  ────
10101010	─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
11100100	───  ─  ───  ─  ───  ─
11111111	────────────────────────
10000000	─       ─       ─
11000000	──      ──      ──
11100000	───     ───     ───
11111110	─────── ─────── ───────
...

This should allow a lot of nice patterns for lines while being encoded reasonable small (only 3 additional bytes + 1 flag bit)

By duplicating all line drawing commans into "draw lines, draw dashed lines" we can save a lot of encoding space