Skip to content

feat(odf): read the enhanced geometry languages, formulas and path alike - #798

Merged
andiwand merged 1 commit into
mainfrom
odf-drawings/enhanced-geometry
Aug 31, 2026
Merged

feat(odf): read the enhanced geometry languages, formulas and path alike#798
andiwand merged 1 commit into
mainfrom
odf-drawings/enhanced-geometry

Conversation

@andiwand

@andiwand andiwand commented Aug 31, 2026

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

Stage 3 of #771, on main now that #797 has landed.

draw:enhanced-geometry is what makes a custom shape an arrow, a callout or a
star, and it says so in two small languages: draw:formula (20.36) and
draw:enhanced-path (19.145). Neither was read, so all 350 of them in the test
corpus rendered as rectangles.

odf_enhanced_geometry.cpp implements both as pure functions over strings.
Nothing is wired into the element model here — that is the next PR, which
keeps this one reviewable on its own and changes no output.

  • evaluate_formula is recursive descent over 20.36: $N modifiers, ?name
    equation references resolved through a caller-supplied lookup, the named
    view-box values, and abs sqrt sin cos tan atan min max atan2 if. The
    trigonometric functions take radians; the corpus settles it by writing
    sin(105*(pi/180)).
  • convert_enhanced_path turns every command of 19.145 into an svg d.

Both readers run off odf_scanner.hpp, which is odf_geometry.cpp's scanner
promoted to a header now that it has a second user: a std::string_view cursor
whose reads are bounded by what remains, so no reader here holds a buffer or a
const char *. A comma is filler in a coordinate list and an argument
separator in a formula, so consume skips only spaces.

Two things worth knowing about the path conversion

  • An arc is emitted in segments of at most a half turn, which means the
    large-arc flag is never needed and U 10800 10800 10800 10800 0 360 — a full
    turn, which a single svg A cannot express, and 116 of the corpus's commands
    — still draws.
  • F and S are read and dropped: painting one subpath with a different fill
    or stroke is more than one d can say.

Verification

odf_enhanced_geometry_test.cpp, from string literals: the geometry needs no
fixture to exercise. No rendered output changes, so no reference-output work
and no CHANGELOG.md entry — the next PR carries both.

@andiwand
andiwand force-pushed the odf-drawings/shapes branch from 1a92fc7 to 3620672 Compare August 31, 2026 06:07
@andiwand
andiwand force-pushed the odf-drawings/enhanced-geometry branch from 19a4a54 to 004227b Compare August 31, 2026 06:07
@andiwand
andiwand force-pushed the odf-drawings/shapes branch from 3620672 to 7b7778d Compare August 31, 2026 06:10
@andiwand
andiwand force-pushed the odf-drawings/enhanced-geometry branch from 004227b to a75a25e Compare August 31, 2026 06:10
@andiwand
andiwand force-pushed the odf-drawings/shapes branch from 7b7778d to c5ecb74 Compare August 31, 2026 19:17
Base automatically changed from odf-drawings/shapes to main August 31, 2026 19:26
@andiwand
andiwand force-pushed the odf-drawings/enhanced-geometry branch from a75a25e to 16404bc Compare August 31, 2026 19:38
`draw:enhanced-geometry` is what makes a custom shape an arrow, a callout or a
star, and it says so in two small languages: `draw:formula` (20.36) and
`draw:enhanced-path` (19.145). Neither was read, so all 350 of them in the test
corpus rendered as rectangles.

`odf_enhanced_geometry.cpp` implements both as pure functions over strings —
nothing is wired into the element model yet, that is the next change:

- `evaluate_formula` is recursive descent over 20.36: `$N` modifiers, `?name`
  equation references resolved through a caller-supplied lookup, the named
  view-box values, and `abs sqrt sin cos tan atan min max atan2 if`. The
  trigonometric functions take radians; the corpus settles it by writing
  `sin(105*(pi/180))`.
- `convert_enhanced_path` turns every command of 19.145 into an svg `d`.

Two things worth knowing about the path conversion. An arc is emitted in
segments of at most a half turn, which means the large-arc flag is never needed
and `U 10800 10800 10800 10800 0 360` — a full turn, which a single svg `A`
cannot express, and 116 of the corpus's commands — still draws. And `F` and `S`
are read and dropped: painting one subpath with a different fill or stroke is
more than one `d` can say.

Tested from string literals; the geometry needs no fixture to exercise.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017XABfEapaADjFQCt1vjmDF
@andiwand
andiwand force-pushed the odf-drawings/enhanced-geometry branch from 16404bc to e4f645c Compare August 31, 2026 19:41
@andiwand
andiwand merged commit b26e0e2 into main Aug 31, 2026
29 checks passed
@andiwand
andiwand deleted the odf-drawings/enhanced-geometry branch August 31, 2026 19:43
andiwand added a commit that referenced this pull request Aug 31, 2026
`PLAN.md` said to delete it once nothing was left under *Today*, and #771's
four goals are on main: `draw:transform` (#796), the shape elements with no
parser (#797), `draw:enhanced-geometry` (#798, #799) and the `draw:object`
chart (#800). What remains of drawings is the unticked boxes in `README.md`;
the two decisions the plan held that the checklist cannot express — preset
`draw:type` shapes and connector routing — move to `AGENTS.md`.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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