Skip to content

ODF drawings beyond SVM: enhanced geometry, the missing shape elements, embedded chart objects, and transforms #771

Closed

Description

@andiwand

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

  1. draw:transform on the shapes we already parse — smallest change, visible on real files.
  2. The missing shape elements above, rendered as SVG.
  3. draw:enhanced-geometry → SVG path (support odf custom-shape #159).
  4. draw:object chart 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:handle
  • odg/SpotfaceCoord40270-L.odg — 5 × enhanced-geometry, 1 × draw:path
  • odg/Sealver Measurements.odg — 25 × enhanced-geometry, 27 × draw:measure, 3 × draw:path
  • ods/Bloods.ods, ods/style+svm-chart-1.ods, ods/style+svm-chart-2.ods — draw:object charts

Related

References

Activity

  1. added a commit that references this issue on Aug 31, 2026
  2. andiwand commented on Aug 31, 2026

    @andiwand
    MemberAuthor

    Closed by the five stages, in the order the corpus argued for:

    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 with draw:opacity and 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, preset draw:type shapes and connector re-routing are deliberately not decoded; the reasoning is in odf/AGENTS.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions