thorvg 0.2.0

Safe Rust bindings to the ThorVG vector graphics library
Documentation
//! Demonstrates shape clipping: restricting a shape's rendering to a clip path.
//!
//! Run with: `cargo run --example clipping`
//! Output:   `clipping.png`

#![allow(clippy::cast_precision_loss)]

mod common;

use thorvg::{ColorSpace, ColorStop, EngineOption, Paint, Thorvg};

fn main() {
    let engine = Thorvg::init(0).unwrap();
    let (w, h) = (600u32, 400u32);
    let mut buffer = vec![0u32; (w * h) as usize];
    let mut canvas = engine.sw_canvas(EngineOption::Default).unwrap();
    unsafe { canvas.set_target(&mut buffer, w, w, h, ColorSpace::ABGR8888) }.unwrap();

    // Background
    let mut bg = engine.shape();
    bg.append_rect(0.0, 0.0, w as f32, h as f32, 0.0, 0.0, true)
        .unwrap();
    bg.set_fill_color(30, 30, 50, 255).unwrap();
    canvas.push(bg).unwrap();

    // ── Left: gradient rectangle clipped by a circle ───────────────
    let mut grad = engine.linear_gradient();
    grad.set_bounds(50.0, 50.0, 250.0, 300.0).unwrap();
    grad.set_color_stops(&[
        ColorStop {
            offset: 0.0,
            r: 255,
            g: 100,
            b: 0,
            a: 255,
        },
        ColorStop {
            offset: 1.0,
            r: 0,
            g: 100,
            b: 255,
            a: 255,
        },
    ])
    .unwrap();

    let mut rect = engine.shape();
    rect.append_rect(50.0, 50.0, 200.0, 300.0, 0.0, 0.0, true)
        .unwrap();
    rect.set_linear_gradient(grad).unwrap();

    // Circle clip
    let mut clip1 = engine.shape();
    clip1.append_circle(150.0, 200.0, 90.0, 90.0, true).unwrap();
    rect.set_clip(&clip1).unwrap();

    canvas.push(rect).unwrap();

    // ── Right: star shape clipped by a rounded rectangle ───────────
    let mut star = engine.shape();
    let cx = 440.0f32;
    let cy = 200.0f32;
    let spikes = 6;
    let outer = 120.0f32;
    let inner = 55.0f32;

    for i in 0..(spikes * 2) {
        let angle = core::f32::consts::PI * i as f32 / spikes as f32 - core::f32::consts::FRAC_PI_2;
        let r = if i % 2 == 0 { outer } else { inner };
        let px = cx + angle.cos() * r;
        let py = cy + angle.sin() * r;
        if i == 0 {
            star.move_to(px, py).unwrap();
        } else {
            star.line_to(px, py).unwrap();
        }
    }
    star.close().unwrap();
    star.set_fill_color(255, 220, 0, 255).unwrap();

    // Rounded rectangle clip
    let mut clip2 = engine.shape();
    clip2
        .append_rect(360.0, 100.0, 160.0, 200.0, 20.0, 20.0, true)
        .unwrap();
    star.set_clip(&clip2).unwrap();

    canvas.push(star).unwrap();

    canvas.draw(true).unwrap();
    canvas.sync().unwrap();
    common::save_png("clipping.png", &buffer, w, h);
}