//! VectorCraft SVG import and export. //! //! * [`export`] writes a [`Document`] as SVG 1.1 with our own writer (presentation attributes, //! inline styles or internal CSS classes; gradients in `` with `userSpaceOnUse`; clip groups as //! ``; embedded images as `data:` URIs; text as ``/``). //! * [`import`] / [`import_with_report`] parse SVG with `usvg` and convert its normalized tree into //! document nodes with all transforms baked into the geometry. //! //! ## Export approximations //! //! * **Stroke alignment** is not expressible in SVG 1.1. An *inside* stroke of a closed path is //! written as a stroke of double width clipped to the path's own shape (``); an //! *outside* stroke as a stroke of double width masked by a `` that hides the path's //! interior. Both are visually exact but re-import as a group (clip group / masked stroke) //! rather than an aligned stroke. Open paths have no inside: their strokes are written centred, //! as the canvas draws them. //! * **Arrowheads, width profiles, dashes fitted to corners and dotted dashes** are written as the //! filled outlines the canvas paints (the line and each arrowhead, grouped under the stroke's //! opacity); **brushed strokes** as their brush art. Both re-import as filled paths. //! * **Multiple fills/strokes** (or per-fill/stroke blend modes) are written as a `` holding one //! `` per appearance item, in paint order. //! * Live geometry effects are written as their result and raster effects (shadows, glows, blurs) //! as SVG filters. Freeform gradients export as linear gradients. //! //! ## Import approximations //! //! * One CSS pixel (user unit) is one point, as on export; a root `width`/`height` in absolute units //! (`in`, `cm`, `mm`, `pt`, `pc`) keeps its physical size (72 pt per inch), so a 210 mm SVG opens on //! a 210 mm artboard. //! * `` imports as a luminance opacity mask; a mask we exported keeps its options and art //! (its `data-vectorcraft-mask="noclip invert"` lists the options that differ from clipping and //! not inverted). Filters are ignored (reported as warnings); nested clip paths use the outer //! clip only. //! * usvg only keeps `` when fonts are loaded; we don't load a font database (too expensive and //! unavailable on wasm), so `` elements are read directly from the XML as live point-type //! [`TextObject`]s (type on a path for a ``) and placed on top of their layer. #![forbid(unsafe_code)] mod export; mod import; pub use vectorcraft_doc::Document; pub use vectorcraft_doc::TextObject; /// How style properties are written (the "Styling" export option). #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub enum Styling { /// `fill="#ff0000"` attributes. #[default] PresentationAttributes, /// `style="fill:#ff0000"`. InlineStyle, /// `class="cls-1"` with a `