Skip to content

feat(svm): draw the primitives, an arc as an arc - #788

Merged
andiwand merged 1 commit into
mainfrom
feat/svm-primitives
Aug 30, 2026
Merged

feat(svm): draw the primitives, an arc as an arc#788
andiwand merged 1 commit into
mainfrom
feat/svm-primitives

Conversation

@andiwand

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

Stage 6 of #772, stacked on #787#786#785#784#779review those
first
; this branch's base is feat/svm-clipping.

LINE, ELLIPSE, ROUNDRECT, ARC, PIE, CHORD, POINT and PIXEL were
all skipped. Seven of the eight occur nowhere in the 1125 harvested metafiles —
but LINE occurs 47 times in two of them, and it turns out to be what rules
a table
: odt/style+svm-various-2.odt and
odt/style+charset+svm-various-1.odt had their tables come out as floating
numbers with no grid at all. Those two pages are the only reference output this
branch moves.

An arc is svg's A, not a polygon

svgwriter.cxx turns an arc into a polygon of up to 256 points because it has
nothing better. svg has A.

The geometry is ImplPolygon's (tools/source/generic/poly.cxx): centre and
radii from the rectangle, each ray's ellipse parameter
atan2(radius_x·sin θ, radius_y·cos θ) over the angle θ to the point, and vcl
sweeps the mathematically positive way round — counter-clockwise on screen,
which is svg's sweep flag 0. A start ray equal to the end ray is the whole
ellipse rather than nothing (#i73608#), and since svg draws nothing for an
arc that ends where it starts, every arc goes out as its two halves.

Checked against LibreOffice on a metafile written for the purpose:

LibreOffice this branch
arc start (441, 544) (441, 544)
arc end (100, 650) (100, 650)
pie closes through (300, 650), the centre same
chord closes back to (441, 544) same
ellipse cx=300 cy=250 rx=200 ry=150 same
round rect rx=60 ry=40 same

A point is one device pixel

…which no length in the drawing can be, since the drawing scales. Both POINT
and PIXEL go out as a dot of the hairline's own width — a degenerate path
with a round cap — rather than the zero-length <line> svgwriter.cxx writes,
which draws nothing at all. A PIXEL carries its own colour, and nothing else
draws with it.

Verification

5 new tests (34 in the svm suite), the arc one asserting the exact path against
the numbers LibreOffice produced above. Reference output regenerated (2 private
files, no public ones) and the pin advanced here.

`LINE`, `ELLIPSE`, `ROUNDRECT`, `ARC`, `PIE`, `CHORD`, `POINT` and `PIXEL` were
all skipped. The lines matter most: they are what rules a table drawn as a
metafile, and two documents in the fixtures had their tables come out as
floating numbers with no grid at all.

`svgwriter.cxx` turns an arc into a polygon of up to 256 points because it has
nothing better; svg has `A`, so the arc goes out as an arc. The geometry is
`ImplPolygon`'s: centre and radii from the rectangle, each ray's ellipse
parameter `atan2(radius_x·sin θ, radius_y·cos θ)` over the angle θ to the
point, and vcl sweeps the mathematically positive way round - counter-clockwise
on screen, which is svg's sweep flag 0. A start ray equal to the end one is the
whole ellipse rather than nothing, and svg draws nothing for an arc that ends
where it starts, so every arc is written as its two halves.

Checked against LibreOffice on a metafile written for the purpose: for the same
action it puts the arc's ends at (441,544) and (100,650), and so do we; the
pie closes through the centre and the chord straight back, as it does.

A `POINT` and a `PIXEL` are one device pixel, which no length in the drawing
can be. Both go out as a dot of the hairline's own width - a degenerate path
with a round cap - rather than the zero-length `<line>` `svgwriter.cxx` writes,
which draws nothing at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmCr22NW6wPQKiQidk96bq
@andiwand
andiwand force-pushed the feat/svm-primitives branch from 8edc2ad to eec0439 Compare August 30, 2026 17:55
@andiwand
andiwand merged commit d3a70d8 into main Aug 30, 2026
25 of 27 checks passed
@andiwand
andiwand deleted the feat/svm-primitives branch August 30, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant