SerenityOS / serenity

The Serenity Operating System 🐞
https://serenityos.org
BSD 2-Clause "Simplified" License
29.73k stars 3.15k forks source link

Path renderer needs support for butt linecaps #23621

Open nico opened 3 months ago

nico commented 3 months ago

Both PDFs and SVGs allow setting linecaps to:

We currently only the first (in Path::stroke_to_fill() in Path.cpp).

Implementation-wise, this should be easier to do than the round circles: At the start, add a point perpendicular to the start direction (and initialize the angle right). Then at the other end, add two points, and back at the start the missing one.

Some PDFs use wide lines with butt caps to draw rectangles for some reason. In some PDFs, tables draw their vertical lines as very wide horizontal lines with butt caps. Since we currently only support round caps, this results in:

Screenshot 2024-03-17 at 8 53 46 PM

(At slightly different page sizes, it sometimes looks like so instead, suggesting the round cap rendering is somewhat sensitive to floating point stuff and not always quite right: Screenshot 2024-03-17 at 8 54 08 PM But that's a separate bug.)

It's not always so dramatic. Here, the blue roundrects are supposed to be rectangles:

Screenshot 2024-03-17 at 9 08 50 PM
MacDue commented 3 months ago

(stroke to fill, imo, is a surprisingly tricky problem, where it's pretty easy to get a solution that is pretty brittle, there's an interesting paper + video here: https://w3.impa.br/~diego/projects/Neh20/)