Repository navigation
ODF drawings beyond SVM: enhanced geometry, the missing shape elements, embedded chart objects, and transforms #771
Description
ODF drawings only render as far as a bounding box or an SVM replacement image. Everything the shape geometry itself carries — the enhanced-geometry path, draw:object chart XML, the less common shape elements, draw:transform — is dropped. This is the umbrella issue for closing that gap; the sub-topics already filed are listed at the bottom.
Where we are today
parse_element_tree (src/odr/internal/odf/odf_parser.cpp:302) knows exactly nine drawing elements:
draw:frame draw:image draw:rect draw:line draw:circle
draw:custom-shape draw:text-box draw:g draw:a
draw:custom-shape maps to ElementType::custom_shape, and html::translate_custom_shape
(src/odr/internal/html/document_element.cpp:652) emits a positioned <div> with fill and
stroke — the box, never the shape. Anything not in that table falls through
parse_element_tree's final return {null_element_id, ...} and vanishes with its subtree.
What is dropped
Enhanced geometry. draw:enhanced-geometry (with draw:enhanced-path, draw:equation,
draw:handle, draw:modifiers, view box, mirror/text rotation) is what makes a custom shape an
arrow, a callout, a star. We parse none of it, so every one of them renders as a rectangle.
draw:enhanced-path is close enough to an SVG path that an SVG-based renderer is plausible.
Shape elements with no parser at all:
draw:path · draw:polygon · draw:polyline · draw:ellipse · draw:measure ·
draw:connector · draw:caption · draw:regular-polygon · dr3d:scene
Embedded objects (draw:object / draw:object-ole). A LibreOffice chart is
<draw:frame><draw:object xlink:href="./Object 1"/><draw:image xlink:href="./ObjectReplacements/Object 1"/></draw:frame>.
We ignore draw:object and render the sibling draw:image, which is the SVM raster-ish
replacement. So a chart is only ever as good as LibreOffice's replacement image, and where no
replacement was written the chart is simply absent. The real content — Object 1/content.xml,
a full <chart:chart> with series, axes, and a table:table of the plotted data — is right
there in the package and unused.
Transforms. draw:transform (rotate/translate/skew/scale) is not read at all, so
anything rotated or flipped is drawn in its unrotated position.
Why "beyond SVM" matters
SVM is a fallback with three problems: it is LibreOffice-specific and optional, it is a flattened
metafile so the output has no text to select and no structure to style, and its own coverage is
incomplete (bitmaps are unimplemented, #194). Drawing straight from the ODF markup gives real
vector output, selectable text, and something that survives a producer that never wrote a
replacement image.
Suggested order
draw:transformon the shapes we already parse — smallest change, visible on real files.- The missing shape elements above, rendered as SVG.
draw:enhanced-geometry→ SVG path (support odf custom-shape #159).draw:objectchart XML → a rendered chart, with the SVM replacement kept as the fallback (ods chart missing #179).
Test files
odg/sample.odg— 6 ×custom-shape/enhanced-geometry, 51 ×draw:equation, 6 ×draw:handleodg/SpotfaceCoord40270-L.odg— 5 ×enhanced-geometry, 1 ×draw:pathodg/Sealver Measurements.odg— 25 ×enhanced-geometry, 27 ×draw:measure, 3 ×draw:pathods/Bloods.ods,ods/style+svm-chart-1.ods,ods/style+svm-chart-2.ods—draw:objectcharts
Related
- support odf custom-shape #159 support odf custom-shape (enhanced geometry)
- ods chart missing #179 ods chart missing (
draw:object/ chart XML) - svm support bitmaps #194 svm support bitmaps (the fallback's own gap)
- alignment in ODG #214 alignment in ODG
Activity
docs(odf): plan the drawing work #771 asks for, in the order the corp…
andiwand commentedon Aug 31, 2026
Closed by the five stages, in the order the corpus argued for:
draw:transformputs it #796 —draw:transform, its operation list composed to one matrix. The list applies left to right androtateis counter-clockwise, both settled against libreoffice's own svg export rather than the spec text.draw:path,draw:polygon,draw:polyline,draw:regular-polygon,draw:connector,draw:ellipse,draw:measure,draw:caption, mapped onto the types that already exist and drawn as svg.draw:formula(20.36) anddraw:enhanced-path(19.145) as pure functions over strings, unit-tested from literals.CustomShape::path(), so a custom shape draws as the shape. Closes support odf custom-shape #159.odf_chart.cpprenders the embedded part's<chart:chart>, and thedraw:imagereplacement stays the fallback. Closes ods chart missing #179.What remains of ODF drawings is tracked as the unticked boxes in
odf/README.md:draw:text-areas,draw:handle,F/S, gradient and hatch fills withdraw:opacityand stroke dashes, arrowheads (draw:marker),draw:mirror-*on a shape with no enhanced geometry, and the chart features — stacked and percentage plots, secondary axes, trend lines, data labels, and the number format an axis names.dr3d:scene,draw:object-ole, presetdraw:typeshapes and connector re-routing are deliberately not decoded; the reasoning is inodf/AGENTS.md.docs(odf): retire the drawings plan, its stages having landed (#802)