Skip to content

Commit 16404bc

Browse files
andiwandclaude
andcommitted
feat(odf): read the enhanced geometry languages, formulas and path alike
`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
1 parent c5ecb74 commit 16404bc

8 files changed

Lines changed: 878 additions & 97 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ set(ODR_SOURCE_FILES
180180
"src/odr/internal/odf/odf_crypto.cpp"
181181
"src/odr/internal/odf/odf_document.cpp"
182182
"src/odr/internal/odf/odf_element_registry.cpp"
183+
"src/odr/internal/odf/odf_enhanced_geometry.cpp"
183184
"src/odr/internal/odf/odf_file.cpp"
184185
"src/odr/internal/odf/odf_flat_file.cpp"
185186
"src/odr/internal/odf/odf_geometry.cpp"

src/odr/internal/odf/PLAN.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,18 @@ label comes out empty.
120120
`vector-effect="non-scaling-stroke"` on the path: the view box scales, and with
121121
`preserveAspectRatio="none"` unevenly, which the stroke must not follow.
122122

123-
### 3 — `draw:enhanced-path` and `draw:equation`, parser only
124-
125-
The formula mini-language (`$N` modifiers, `?fN` references, the eleven
126-
functions the corpus uses plus the rest of 20.36) and the path grammar
127-
(`M L C Z N U X Y` plus the commands 19.145 defines and the corpus does not
128-
use). Pure functions over strings, unit-tested from string literals, no
129-
rendering and no element-model change. The largest single piece.
123+
### 3 — `draw:enhanced-path` and `draw:equation`, parser only — landed
124+
125+
`odf_enhanced_geometry.cpp`: the formula language of 20.36 (`$N` modifiers,
126+
`?name` references, the named view-box values, `abs sqrt sin cos tan atan min
127+
max atan2 if`) and every command of 19.145, converted to an svg `d`. Pure
128+
functions over strings, unit-tested from string literals.
129+
130+
Decisions worth knowing: `sin`/`cos` take radians, which the corpus confirms by
131+
writing `sin(105*(pi/180))`; an arc is emitted in segments of at most a half
132+
turn, so the large-arc flag is never needed and a full `U … 0 360` — which one
133+
svg `A` cannot express — still draws; `F` and `S` are read and dropped, since
134+
painting one subpath differently is more than one `d` can say.
130135

131136
### 4 — enhanced geometry, rendered
132137

0 commit comments

Comments
 (0)