resvg

repository·main·Indexed 26 days ago

https://github.com/linebender/resvg

A high-performance, portable SVG rendering library written in Rust designed for correctness, safety, and reproducibility. It targets the static SVG subset and can be used as a Rust library, a C library via resvg-capi (v0.47.0), or a CLI application to render SVG files to PNG images. It includes usvg, a micro SVG parser that simplifies SVG complexity into a strongly-typed tree structure by resolving attributes, geometry, and references.

Tokens
14.9K
Snippets
25
Records
108
Agent score
87%

What's inside resvg

  1. Overview of usvg (micro SVG)

    main

    usvg (micro SVG) is an SVG parser designed to simplify the complexity of SVG for rendering libraries. It acts as a layer between an XML library and a rendering engine by parsing input SVG into a strongly-typed tree structure.

    Key benefits include:

    • Resolved Attributes: All inheritable, implicit, and default attributes are pre-resolved.
    • Simplified Geometry: Basic shapes (like rect and circle) are converted into paths, and all path segments (including ArcTo, implicit, and relative segments) are converted into absolute MoveTo, LineTo, QuadTo, CurveTo, and ClosePath segments.
    • Resolved References: use elements, nested svg elements, and all references (e.g., #elem or url(#elem)) are resolved and replaced with their content.
    • Unit Conversion: Relative length units (e.g., mm, em) are converted into pixels/points.
    • Image Handling: External images are loaded and internal base64 images are decoded.
    • Text Processing: Text elements are fully resolved, including attribute resolution, whitespace preprocessing (xml:space), and text chunks/spans.
    • Filter Support: Supports filters, including filter functions like filter="contrast(50%)".
    • Sanitization: Invalid or malformed elements are removed, and recursive elements are detected and removed.
  2. Overview of resvg

    main

    resvg is an SVG rendering library designed to be fast, small, and portable. It supports the static SVG subset and is built to be highly reproducible across different platforms (e.g., rendering the same pixels on Windows x86 and macOS ARM).

    It can be consumed in three ways:

    1. As a Rust library.
    2. As a C library (via resvg-capi).
    3. As a CLI application for rendering static SVG files to images.

    Key characteristics include:

    • Safety: Written entirely in Rust with minimal unsafe code and protections against endless loops and stack overflows.
    • Zero Bloat: The CLI application is typically under 3MB.
    • Portability: Works anywhere Rust can compile, including WASM.
    • Separation of Concerns: SVG parsing/preprocessing is handled by usvg, while rendering is handled by resvg.
  3. Understand XML post-processing in usvg

    main

    When usvg processes an SVG, it performs several transformations to simplify the tree into a high-performance, static subset. Developers should be aware of these structural changes when working with the resulting tree:

    • Namespace Removal: All elements and attributes are moved into the SVG namespace; namespaces are stripped.
    • SVG-only Elements: Only SVG elements and attributes are preserved. Names are stored as enums rather than strings for performance.
    • Node Types: The tree contains only elements and text nodes (contained within text elements).
    • Whitespace Trimming: Text nodes are trimmed according to SVG rules (including xml:space).
    • Attribute Normalization:
      • style attributes are split into individual attributes (e.g., <rect style="fill:green"/> becomes <rect fill="green"/>).
      • inherit values are resolved to their actual values from parent elements.
    • CSS Application: Supported CSS rules are applied directly to elements. The resulting tree contains no <style> elements or class attributes.
    • Link Handling:
      • Recursive Links: The engine attempts to detect and remove recursive references (e.g., <use xlink:href="#id"/> where id is the same element).
      • <a> Elements: These are converted into <g> (group) elements.
      • tref Resolution: tref elements are automatically resolved and replaced with tspan elements.
      • use Resolution: To simplify style resolution, the referenced elements are copied directly into the <use> element as a child group. Note: Copied elements must not have an id attribute to avoid duplicates in the ID map.
  4. Build and run viewsvg

    main

    To build and run viewsvg (a simple SVG viewer using resvg-qt), you must first build the resvg-capi crate, then use qmake and make to compile the viewer. This tool requires Qt version 5.6 or higher.

    # build C-API first
    cargo build --release --manifest-path ../../crates/c-api/Cargo.toml
    
    # build viewsvg
    qmake
    make
    
    # run
    ./viewsvg
  5. Convert SVG to SVG Micro using usvg

    main

    SVG Micro is a stripped-down subset of SVG Full 1.1 designed for efficiency. It removes XML DTD, CSS, inheritable attributes, and complex path notations. You can use the usvg crate to convert standard SVG files into the SVG Micro format almost losslessly.

    https://github.com/linebender/resvg/tree/main/crates/usvg
  6. `use` element resolution and breaking changes

    main

    usvg resolves <use> elements by copying the referenced elements directly into the <use> element as a child group. This ensures that style properties (like fill) resolve correctly relative to the <use> element's parent rather than the referenced element's parent.

    Example

    <g fill="red">
        <rect id="rect1"/>
    </g>
    <g fill="green">
        <!-- rect's fill should be resolved to green -->
        <use href="#rect1"/>
    </g>

    becomes

    <rect id="rect1"/>
    <use href="#rect1">
        <rect/>
    </use>
    <g fill="green"/>

    Important Limitation: When manually constructing SVGs intended for usvg, ensure that elements intended to be copied via <use> do not have an id attribute. If they do, the duplication process may result in multiple elements sharing the same ID in the internal ID map.

  7. Parse SVG into a simplified tree with usvg

    main

    The usvg crate provides an SVG parser that converts complex SVG XML into a strongly-typed, simplified tree structure. It resolves attributes (inheritable, implicit, and default), applies CSS, converts basic shapes into paths, and resolves elements like <use>, nested <svg>, and <switch>. It also handles unit conversion (e.g., mm to pixels), image decoding (base64), and text element resolution.

    Key transformations performed by usvg:

    • Shapes to Paths: Basic shapes (rect, circle, etc.) are converted into paths containing only absolute MoveTo, LineTo, QuadTo, CurveTo, and ClosePath segments.
    • Reference Resolution: All #id and url(#id) references are resolved.
    • Text Resolution: Handles xml:space, text chunks, and spans.
    • Markers: Converted into regular elements.
    • Filters: Supported, including filter functions like filter="contrast(50%)".
    • Recursion: Recursive elements are detected and removed.

    Limitations:

    • Minimal CSS support.
    • Supports only static SVG features (no <a>, view, cursor, script, events, or animations).
    • Unsupported features are ignored.
  8. Use the usvg CLI to simplify SVGs

    main

    usvg (micro SVG) is a command-line tool used to simplify SVG files. It can read from files or stdin and write to files or stdout.

    Basic Usage

    File to file:

    usvg [OPTIONS] <in-svg> <out-svg>

    File to stdout:

    usvg [OPTIONS] <in-svg> -c

    Stdin to file:

    usvg [OPTIONS] - <out-svg>

    Stdin to stdout:

    usvg [OPTIONS] - -c
  9. Use the resvg CLI to render SVG files

    main

    The resvg CLI application converts SVG files into PNG images. It supports reading from files or stdin and writing to files or stdout.

    Basic Usage Patterns:

    • File to File: resvg [OPTIONS] <in-svg> <out-png>
    • File to Stdout: resvg [OPTIONS] <in-svg> -c
    • Stdin to File: resvg [OPTIONS] - <out-png>
    • Stdin to Stdout: resvg [OPTIONS] - -c
    resvg in.svg out.png
    resvg -z 4 in.svg out.png
    resvg --query-all in.svg