Skip to content

raster: add pure-Go PNG, GIF, PDF, and PPTX rendering - #2868

Open
alixander wants to merge 2 commits into
masterfrom
agent/native-raster-renderer
Open

raster: add pure-Go PNG, GIF, PDF, and PPTX rendering#2868
alixander wants to merge 2 commits into
masterfrom
agent/native-raster-renderer

Conversation

@alixander

@alixander alixander commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Human


AI

Adds pure-Go PNG, GIF, PDF, and PPTX rendering.

The implementation is organized around four packages:

  • d2scene defines a typed drawing model.
  • d2scenebuild translates D2 shapes, text, links, effects, assets, and animation into scenes.
  • d2raster paints scenes with a D2-owned scanline rasterizer.
  • d2svgimport imports the bounded SVG subset used by image assets and MathJax.

PNG renders one frame. GIF samples animated scenes while preserving frame timing. PDF and PPTX preserve pages, slides, and links. Missing images render a deterministic placeholder in their declared box. JPEG assets honor EXIF orientations 1–8, and raster assets are fully decoded only when they are painted.

The rasterizer provides analytic nonzero-winding coverage, adaptive curve flattening, bounded row scratch space, geometry-aware work accounting, and cancellation. Canvas, path, filter, asset, font, animation, and multi-board limits are checked before output is written.

Deterministic resources

  • Emoji fallback uses the pinned Noto Color Emoji 2.051 COLRv1 font. The Brotli payload and decoded font are authenticated, and an exact cmap prefilter avoids loading it for unsupported characters.
  • MathJax's U+00B5 fallback is a small D2-authored vector glyph rather than another font.
  • Paper, grain, and sketch-streak textures have one canonical source shared by SVG and scene rendering.
  • Canonical W3C SVG 1.0 and SVG 1.1 external doctypes are accepted without fetching or applying DTD content. Internal subsets, entities, arbitrary identifiers, and other directives remain rejected.

Release integration

The CLI uses the native renderer directly for PNG, GIF, PDF, and PPTX. Archive CI verifies PNG export on Linux, macOS, and Windows for amd64 and arm64. The release container contains only the runtime dependencies needed by the native binary.

All six exact-head release binaries and archives pass their existing limits and reproduce byte-for-byte across clean builds. Binary growth is 11.53–12.19%; archive growth is 23.24–24.97%. The tightest result is macOS/amd64 at 39,917,376 of 40,000,000 bytes; the largest archive is Windows/amd64 at 17,176,172 of 18,000,000 bytes.

Performance

On an Apple M4, seven representative source-to-image cases took 436.469 ms with native rendering and 548.006 ms with D2-to-SVG plus official resvg 0.47.0. Native rendering used 20.353% less aggregate time. Each case used three warmups and 13 alternating fresh-process samples, and every output was decoded and dimension-checked.

Validation

  • full ./make.sh: formatting, generated-file checks, Go build/vet/tests, end-to-end tests, WebAssembly build, 43 JavaScript unit tests, and two JavaScript integrations
  • focused race tests across the CLI, scene builder, rasterizer, SVG importer, fonts, and image pipeline
  • all 16 fuzz targets covering geometry, SVG/XML, JPEG EXIF, GIF, PNG, WebP, content encodings, assets, and markdown layout
  • govulncheck ./..., module verification, dependency-closure checks, and deterministic six-platform release builds
  • structured class/SQL text parity checks and long-canvas/pixel-limit boundary tests
  • full source E2E visual review against an exact clean base-revision Playwright CLI: 670 frames, 666 full-scale native outputs, zero unexpected renderer errors, four deliberate 64-megapixel safety rejections that render at half scale, and two expected dimension changes from current compiler URL-label behavior

@alixander
alixander force-pushed the agent/native-raster-renderer branch 2 times, most recently from 175cc21 to 705d465 Compare August 29, 2026 23:23
@alixander alixander changed the title raster: replace browser exports with a pure-Go renderer raster: add pure-Go PNG, GIF, PDF, and PPTX rendering Aug 29, 2026
@alixander
alixander force-pushed the agent/native-raster-renderer branch 8 times, most recently from d935139 to 6f14deb Compare September 2, 2026 00:34
@alixander
alixander force-pushed the agent/native-raster-renderer branch from 6f14deb to 235c34a Compare September 2, 2026 00:39
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