vellum 0.2.0
Breaking: renamed the grid-colliding exports to a
vl_prefix so attaching vellum no longer masks grid:gpar()→vl_gpar(),unit()→vl_unit(),viewport()→vl_viewport(),arrow()→vl_arrow(), andpattern()→vl_pattern(). The old names are removed (no aliases).Multi-line and per-datum rich text.
text_grob()labels may now contain embedded newlines (\n), stacked baseline-to-baseline;md()gained the same and is now vectorised —md(x)returns a single label for a length-1xor a list of labels for a vector, so a label grob can carry one distinct rich label per position. Single-line, single-label output is byte-for-byte unchanged. (Rust is untouched — shaping stays R-side.)-
Accessibility (a11y).
vl_scene(title=, desc=)and the newdescribe()setter attach an accessible name and long description (alt text) to a scene. When set:- the SVG backend marks the root
<svg role="img" aria-labelledby=…>and emits<title>/<desc>(WCAG 1.1.1); - the PDF backend produces a tagged PDF — the chart is a
Figurein the structure tree carrying the description asAlttext. Purely additive: a scene with no title/desc renders byte-for-byte as before. (Strict PDF/UA-1 validation is a planned follow-up; the tag tree + Alt ship now.)
- the SVG backend marks the root
datashade(weight=)now recycles a scalar and errors on a wrong-length vector, instead of silently discarding a mismatched weight and reverting to a plain count.
vellum 0.1.1
-
Compound
native + mm/npc + mmunits. A position unit combined with an absolute unit now forms a compound unit — a data/panel anchor plus an exact absolute offset — instead of erroring.unit(1, "native") + unit(2, "mm")resolves to the native position shifted by exactly 2 mm at render, at any scale or aspect (the offset is applied device-side after the base resolves). This is the deferred “B1” route; it unlocks device-exact label nudges, halos, and drop-shadow offsets in the grammar layer. Mixing two different position bases (e.g.npcandnative) still errors. Unit arithmetic scales the base and the offset together. Additive change: a scene using no compound units renders byte-for-byte as before.
vellum 0.1.0
First release. vellum is a low-level graphics framework for R in the spirit of grid, with a Rust backend: you describe a scene through a small declarative R API, and the scene graph, unit/layout engine, and rendering all run in Rust.
Scenes and rendering
- Build a scene functionally with
vl_scene()and a pipeline ofpush(),draw(), andpop()over an immutable tree. -
render()draws the same scene to PNG, SVG, or PDF, picking the backend from the file extension — raster via tiny-skia, PDF via krilla, SVG hand-rolled. Output is byte-stable and snapshot-testable. -
display()draws a scene into the active graphics device;scene_raster()/scene_svg()return the rendered scene in memory.
Grobs, units, and layout
- Vectorised drawing primitives (rect, circle, points, segments, lines, path, polygon, text, raster, …) that batch internally.
- A unit system (
unit(),grobwidth, …) and nestedviewport()s with their own scales, rotation, and arbitrary-path clipping, plus a row/column layout solver with"null"(flexible) tracks.
Text
- Device-independent shaping and measurement through textshaping / systemfonts — the same stack as ragg/svglite — with per-glyph fallback, justification, and rotation, plus Markdown-style rich labels via
md().
Big data
-
datashade()aggregates millions of points into a density raster in a single pass — cost scales with output pixels, not point count — with no overplotting and small output files.
Retained scene graph
- Because the scene is retained rather than drawn-and-forgotten, it can be queried and edited:
node_names()/get_node()/edit_node(),hit_test()to pick the topmost grob under a point, andscene_model()to serialize a per-element model (data keys, bounding boxes) — the foundation thevellumplotgrammar and thevellumwidgetwidget layer build on.
Interop
-
as_vellum()/render_grid()render an existinggridgrob tree — including ggplot2 and lattice — through the vellum backend.
Under the hood
- The R package wires to a Rust crate via extendr; crates are vendored for offline/CRAN builds.
