Skip to content

SVG picture fallback: restate the root's size with ooxml-common's svgimage - #16

Merged
uvrt merged 2 commits into
mainfrom
gaps-svg-units
Oct 11, 2026
Merged

uvrt merged 2 commits into
mainfrom
gaps-svg-units

Conversation

@uvrt

@uvrt uvrt commented Oct 11, 2026

Copy link
Copy Markdown
Owner

What

edit/svgpicture.rasterise used its own workaround for resvg-py's "SVG has an invalid size". It parsed the SVG with lxml, set width/height to native_size (or to the placed size when the SVG stated none), and re-serialised the whole tree. It now calls the shared ooxml_common.svgimage.with_pixel_size (ooxml-common 0.12.0, uvrt/ooxml-common#23). pptx2svg now uses the same function for the SVG pictures inside a page (uvrt/pptx2svg#25).

Behaviour

  • px, pt, pc, in, cm, mm: the same pixels as before.
  • em: 12 px, or the root's font-size. This is PowerPoint's value (CSS uses 16, and the old code skipped em entirely).
  • % or no size: the viewBox's size, or 500 px when there is no viewBox, where the placed size was used before. All measured on PowerPoint 16's PDF export: 30 of 30 probes match (see pptx2svg's tools/make_svg_size_probe.py). The fallback PNG now matches what PowerPoint draws from the vector.
  • Rewrite scope: only those attributes in the root start tag change. The SVG is no longer re-serialised through lxml.
  • Encoding: a Latin-1 or UTF-16 SVG is re-encoded instead of refused.
  • Unchanged: native_size, which sizes the frame when the picture is inserted.

Tests

  • New: the fallback draws pt, cm/in and pc/mm-sized SVGs (both halves of a split-colour viewBox are in place).
  • New: a no-viewBox 6em SVG is drawn with PowerPoint's 12 px em. This one fails before the change.
  • Full suite: 2358 passed, 29 skipped.

Merge order

  1. SVG pictures: natural size as PowerPoint reads it, restated in pixels (0.12.0) ooxml-common#23 first.
  2. Then point .github/workflows/ci.yml back at @main (the # TEMPORARY (gaps) line) and merge this. It does not depend on Draw an SVG picture in PNG output whatever unit its root's size is in pptx2svg#25.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WCxhY1fvWQPiWCwz7SYUVh

uvrt and others added 2 commits October 11, 2026 15:05
…image

rasterise() rewrote the SVG's root width and height through lxml itself,
because resvg-py draws nothing for width="72pt". ooxml-common 0.12.0's
svgimage.with_pixel_size does the same as PowerPoint reads it, for the page
pptx2svg rasterises as well: the same pixels for px, pt, pc, in, cm and mm,
and now PowerPoint's for an em (12 px or the root's font-size), a percentage
or no size (the viewBox's size; 500 px without one, where the placed size
was used). It rewrites those attributes in place instead of re-serialising
the SVG, and re-encodes a Latin-1 or UTF-16 SVG instead of refusing it.

Requires ooxml-common 0.12.0; CI installs it from its gaps-svg-units
branch until that pull request merges (TEMPORARY (gaps)).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCxhY1fvWQPiWCwz7SYUVh
@uvrt
uvrt merged commit 7c90509 into main Oct 11, 2026
19 checks passed
@uvrt
uvrt deleted the gaps-svg-units branch October 11, 2026 13:19
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