LunaSVG Documentation

repository·master·Indexed 22 days ago

https://github.com/sammycage/lunasvg

A lightweight, portable C++ library for rendering and manipulating Scalable Vector Graphics (SVG) files, supporting most features of SVG 1.1 and 1.2 Tiny. It provides capabilities for rendering SVGs to bitmaps, applying dynamic CSS styles, and performing point-based hit testing on elements. The project includes the svg2png CLI tool and utilizes PlutoVG, a standalone 2D vector graphics library written in C.

Tokens
3K
Snippets
9
Records
11
Agent score
29%

What's inside LunaSVG

  1. Overview of PlutoVG features

    master

    PlutoVG is a standalone 2D vector graphics library written in C. It provides a comprehensive set of vector graphics capabilities including:

    • Path Operations: Filling, stroking, and dashing paths.
    • Paints: Support for solid colors, gradients, and textures.
    • Typography: Handling of fonts and text rendering.
    • Composition: Clipping and compositing operations.
    • Transformations: Coordinate system transformations.
    • Assets: Support for images.
  2. Install LunaSVG via CMake

    master

    To install LunaSVG from source using CMake:

    git clone https://github.com/sammycage/lunasvg.git
    cd lunasvg
    cmake -B build .
    cmake --build build
    cmake --install build

    Integrate into your CMake project

    Option 1: Using find_package (if already installed)

    find_package(lunasvg REQUIRED)
    target_link_libraries(your_target_name PRIVATE lunasvg::lunasvg)

    Option 2: Using FetchContent (direct integration)

    include(FetchContent)
    FetchContent_Declare(
        lunasvg
        GIT_REPOSITORY https://github.com/sammycage/lunasvg.git
        GIT_TAG master
    )
    FetchContent_MakeAvailable(lunasvg)
    target_link_libraries(your_target_name PRIVATE lunasvg::lunasvg)
  3. Install LunaSVG via Meson

    master

    To install LunaSVG from source using Meson:

    git clone https://github.com/sammycage/lunasvg.git
    cd lunasvg
    meson setup build
    meson compile -C build
    meson install -C build

    Integrate into your Meson project

    Option 1: Using dependency (if already installed)

    lunasvg_dep = dependency('lunasvg', required: true)

    Option 2: Using Meson Wrap (subproject) Create a lunasvg.wrap file in your subprojects directory:

    [wrap-git]
    url = https://github.com/sammycage/lunasvg.git
    revision = head
    depth = 1
    
    [provide]
    lunasvg = lunasvg_dep

    Then use it in your build file:

    lunasvg_dep = dependency('lunasvg', fallback: ['lunasvg', 'lunasvg_dep'])
  4. CMake Build Options

    master

    When building LunaSVG with CMake, you can configure the following option:

    • USE_SYSTEM_PLUTOVG (default: OFF): If set to ON, the build will attempt to use a system-installed plutovg library (version 1.0.0 or higher) instead of the bundled submodule. If the system library is not found, it falls back to the submodule.

    Example usage:

    cmake -B build -DUSE_SYSTEM_PLUTOVG=ON .
    cmake --build build
  5. Apply dynamic CSS styles to an SVG document

    master

    You can dynamically change the appearance of an SVG by loading it from data using Document::loadFromData and applying a CSS stylesheet via applyStyleSheet. This allows for real-time theme switching (e.g., switching between 'summer' and 'winter' styles) by re-rendering the document after applying a new stylesheet.

    #include <lunasvg.h>
    
    using namespace lunasvg;
    
    // ... (SVG and CSS strings defined here)
    
    int main()
    {
        auto document = Document::loadFromData(kLandspaceContent);
    
        document->applyStyleSheet(kSummerStyle);
        document->renderToBitmap().writeToPng("summer.png");
    
        document->applyStyleSheet(kWinterStyle);
        document->renderToBitmap().writeToPng("winter.png");
        return 0;
    }
  6. Perform hit testing on SVG elements

    master

    LunaSVG supports point-based hit detection using Document::elementFromPoint(x, y). This method returns an Element object if a shape exists at the specified coordinates, allowing you to inspect attributes or modify the element (e.g., changing its stroke, stroke-width, or transform) based on user interaction.

    #include <lunasvg.h>
    #include <utility>
    #include <iostream>
    
    using namespace lunasvg;
    
    // ... (SVG content defined here)
    
    int main()
    {
        auto document = Document::loadFromData(kSVGContent);
        document->renderToBitmap().writeToPng("original.png");
    
        const std::pair<float, float> points[] = {
            {30,  30}, // inside red-rect
            {200, 70}, // center of blue-circle
            {310, 50}, // inside green-rect
            {0,    0}, // outside all shapes
        };
    
        for(const auto& [x, y] : points) {
            if(auto element = document->elementFromPoint(x, y)) {
                std::cout << "Element at (" << x << ", " << y << "): " << element.getAttribute("id") << "\n";
    
                element.setAttribute("stroke", "black");
                element.setAttribute("stroke-width", "3");
                element.setAttribute("transform", "skewX(9)");
            } else {
                std::cout << "No element found at (" << x << ", " << y << ")\n";
            }
        }
    
        document->renderToBitmap().writeToPng("modified.png");
        return 0;
    }
  7. Basic usage of PlutoVG

    master

    To use PlutoVG, you typically create a plutovg_surface_t to hold the pixel data and a plutovg_canvas_t to perform drawing operations. The workflow involves:

    1. Creating a surface with specific dimensions.
    2. Creating a canvas from that surface.
    3. Using canvas functions (like plutovg_canvas_arc, plutovg_canvas_set_rgb, plutovg_canvas_fill, etc.) to draw.
    4. Saving the surface (e.g., plutovg_surface_write_to_png).
    5. Destroying the canvas and surface to free memory.
    #include <plutovg.h>
    
    int main(void)
    {
        const int width = 150;
        const int height = 150;
    
        const float center_x = width / 2.f;
        const float center_y = height / 2.f;
        const float face_radius = 70;
        const float mouth_radius = 50;
        const float eye_radius = 10;
        const float eye_offset_x = 25;
        const float eye_offset_y = 20;
        const float eye_x = center_x - eye_offset_x;
        const float eye_y = center_y - eye_offset_y;
    
        plutovg_surface_t* surface = plutovg_surface_create(width, height);
        plutovg_canvas_t* canvas = plutovg_canvas_create(surface);
    
        plutovg_canvas_save(canvas);
        plutovg_canvas_arc(canvas, center_x, center_y, face_radius, 0, PLUTOVG_TWO_PI, 0);
        plutovg_canvas_set_rgb(canvas, 1, 1, 0);
        plutovg_canvas_fill_preserve(canvas);
        plutovg_canvas_set_rgb(canvas, 0, 0, 0);
        plutovg_canvas_set_line_width(canvas, 5);
        plutovg_canvas_stroke(canvas);
        plutovg_canvas_restore(canvas);
    
        plutovg_canvas_save(canvas);
        plutovg_canvas_arc(canvas, eye_x, eye_y, eye_radius, 0, PLUTOVG_TWO_PI, 0);
        plutovg_canvas_arc(canvas, center_x + eye_offset_x, eye_y, eye_radius, 0, PLUTOVG_TWO_PI, 0);
        plutovg_canvas_set_rgb(canvas, 0, 0, 0);
        plutovg_canvas_fill(canvas);
        plutovg_canvas_restore(canvas);
    
        plutovg_canvas_save(canvas);
        plutovg_canvas_arc(canvas, center_x, center_y, mouth_radius, 0, PLUTOVG_PI, 0);
        plutovg_canvas_set_rgb(canvas, 0, 0, 0);
        plutovg_canvas_set_line_width(canvas, 5);
        plutovg_canvas_stroke(canvas);
        plutovg_canvas_restore(canvas);
    
        plutovg_surface_write_to_png(surface, "smiley.png");
        plutovg_canvas_destroy(canvas);
        plutovg_surface_destroy(surface);
        return 0;
    }
  8. Render SVG to PNG using LunaSVG

    master

    To render an SVG file to a bitmap and save it as a PNG, use Document::loadFromFile to load the file, renderToBitmap() to generate the bitmap, and writeToPng() to save the output. Ensure you check if the document loaded successfully and if the bitmap is valid.

    #include <lunasvg.h>
    
    using namespace lunasvg;
    
    int main()
    {
        auto document = Document::loadFromFile("tiger.svg");
        if(document == nullptr)
            return -1;
        auto bitmap = document->renderToBitmap();
        if(bitmap.isNull())
            return -1;
        bitmap.writeToPng("tiger.png");
        return 0;
    }
  9. Use the `svg2png` CLI tool

    master

    LunaSVG includes a command-line utility svg2png for converting SVG files to PNG format.

    Syntax: svg2png [filename] [resolution] [bgColor]

    Examples:

    # Basic conversion
    $ svg2png input.svg
    
    # Conversion with specific resolution
    $ svg2png input.svg 512x512
    
    # Conversion with resolution and background color (hex format)
    $ svg2png input.svg 512x512 0xff00ffff
    $ svg2png input.svg
    $ svg2png input.svg 512x512
    $ svg2png input.svg 512x512 0xff00ffff