Add SVG and PPTX renderers#16
Merged
Merged
Conversation
Render canvases to vector and document formats alongside PNG/JPEG/WEBP: - canvas.render() detects .svg/.html/.pptx extensions; new to_svg(), to_html(), and to_pptx() methods - Backgrounds, gradients, outlines, shapes, and text (wrapping, rich parts, letter spacing, effects, rotation) export as native, editable primitives using the same layout math as the raster pipeline - Raster images, image glyph fills, blend modes, and custom layers are embedded as pixel-exact PNG fragments; layers below the last blend/custom layer are flattened so blending sees its backdrop - Optional embed_fonts inlines used fonts as @font-face data URLs - PPTX export maps text to editable text boxes and shapes to autoshapes via the new optional quickthumb[pptx] extra (python-pptx) https://claude.ai/code/session_01XRy5d1z14AgR3caayjjATH
Each snapshot stacks the PIL raster render (top) against the export rasterized back to pixels (bottom) with a magenta divider, so export fidelity can be judged visually like the existing rendering snapshots. - Five SVG comparison scenes: shapes/gradients/outline, text styles and effects, rich text and gradient fills, auto-layout groups, and blend-mode flattening with embedded images - PPTX comparisons rasterize through LibreOffice and skip when it is unavailable; regenerate with --inline-snapshot=create - conftest pins fontconfig to the repo fonts so cairosvg resolves the same font files as the PIL pipeline on any machine https://claude.ai/code/session_01XRy5d1z14AgR3caayjjATH
Review follow-up. No behavior change for rendered pixels: - Consolidate _export_svg imports to module top (compute_text_layout, parse_padding, Align) instead of per-method local imports - Skip the wrapping <g> for non-rotated, fully opaque text so the SVG carries no empty groups - Add regression tests for two verified-but-fragile cases: a PPTX text run with both a gradient fill and a stroke keeps valid DrawingML rPr child order (ln → fill → latin), and right/bottom-aligned percentage text matches the raster render within anti-aliasing noise https://claude.ai/code/session_01XRy5d1z14AgR3caayjjATH
The HTML renderer was only wrapping the SVG export in a page shell, not a distinct output format, so drop it until it earns its place. - Remove Canvas.to_html(), the .html/.htm render dispatch, and quickthumb/_export_html.py - Drop the HTML tests and trim docs (exports page, canvas API, installation, README, CLI help) back to SVG + PPTX .svg and .pptx still render by extension; .html now falls through to the normal unsupported-format error. https://claude.ai/code/session_01XRy5d1z14AgR3caayjjATH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
quickthumb currently focuses on raster image output. SVG and PPTX exports let the same canvas specs produce vector documents and editable slides without rebuilding designs elsewhere.
Changes
.svgand.pptxoutput detection incanvas.render(), pluscanvas.to_svg()andcanvas.to_pptx().RenderingError.tyand Pyright, and tighten typing around JSON parsing, SVG/PPTX helpers, and exporter tests.quickthumb[pptx]extra.