AGG.rs

July 22, 2026 · View on GitHub

License: BSD-3-Clause Crates.io Tests Modules Demos

Support the Project

Buy Me A Coffee

AGG.rs is open-source and free to use, maintained in spare time as a labor of love. Friends James Smith and Dan Ruskin help out from time to time too.

If you find it useful, here are a few ways to help keep development going:

  • Donations: Buy Me a Coffee — every coffee helps.
  • Star the repo: Costs nothing and helps others find the project.
  • Report issues: Open an issue for bugs or feature ideas.
  • Contribute: PRs welcome — open an issue first to discuss larger changes.

A pure Rust port of Anti-Grain Geometry (AGG) 2.6 — the legendary high-quality 2D software rendering library originally written in C++ by Maxim Shemanarev. Zero external dependencies. Pixel-perfect anti-aliased output. No GPU required.

Try the Interactive Demo — 64 demos running entirely in your browser via WebAssembly.

Crate listing: agg-rust on crates.io.

Part of the rust-apps suite — a collection of Rust graphics and geometry libraries by Lars Brubaker.

AGG.rs Interactive Demo — Lion rendering with anti-aliased vector graphics

Features

AGG is a software rendering engine that produces pixel images in memory from vectorial data. It is platform-independent and achieves exceptional rendering quality through:

  • Anti-Aliasing — subpixel-accurate scanline rasterization
  • Affine & Perspective Transforms — rotation, scaling, skewing, and full perspective warps
  • Gradient Fills — linear, radial, focal-point, and custom gradient functions with multi-stop color interpolation
  • Gouraud Shading — smooth per-vertex color interpolation across triangles and meshes
  • Image Filtering — 17 interpolation filters including bilinear, bicubic, sinc, Blackman, and more
  • 30+ Compositing Modes — full SVG 1.2 compatible Porter-Duff and blend operations
  • Stroke & Dash Generation — configurable line joins, caps, dashes, and markers
  • Alpha Masking — arbitrary clip regions through grayscale alpha masks
  • Stack Blur — fast approximate Gaussian blur with adjustable radius
  • Pattern Fills — tiled and resampled pattern rendering with perspective support
  • Built-in Fonts — 34 embedded bitmap fonts plus vector text via GSV text engine
  • Boolean Operations — scanline-level union, intersection, difference, and XOR

Architecture

AGG uses a five-stage rendering pipeline with interchangeable components:

Vertex Source → Coordinate Conversion → Scanline Rasterizer → Scanline Container → Renderer

Each stage is a trait in the Rust port, allowing components to be freely mixed and matched:

StagePurposeExamples
Vertex SourceGenerates path verticesPathStorage, Ellipse, RoundedRect, GsvText
Coordinate ConversionTransforms and processes pathsConvCurve, ConvStroke, ConvDash, ConvTransform
Scanline RasterizerConverts paths to scanlinesRasterizerScanlineAa, RasterizerCompoundAa
Scanline ContainerStores scanline coverage dataScanlineU8, ScanlineP8, ScanlineBin
RendererWrites pixels to the bufferRendererScanlineAaSolid, RendererBase, pixel formats

Interactive Demos

All 64 demos run in-browser via WebAssembly with no server-side processing. Categories include:

CategoryDemosHighlights
Anti-AliasingAA Demo, Rasterizers, Gamma, AA TestSubpixel rendering quality visualization
RenderingLion, Perspective, Circles, Alpha Masks, BlurComplex vector scenes with transforms
GradientsLinear/Radial, Gouraud, Focal Point, MeshMulti-stop color interpolation
Paths & StrokesStroke, Contour, Dash, Line PatternsJoin/cap styles, dash patterns
CurvesBezier, B-Spline, Text on CurveInteractive control point editing
Images & Filters17 Filter Types, Perspective, ResampleImage transform and filter quality
CompositingSVG Blend Modes, Flash RasterizerPorter-Duff and blend operations
PatternsPattern Fill, Perspective, ResampleTiled pattern rendering
TextGSV Vector Text, 34 Raster FontsBuilt-in font rendering

Browse all demos →

Quick Start

[dependencies]
agg-rust = "1.0"
use agg_rust::*;

// Create a rendering buffer
let mut buf = vec![0u8; width * height * 4];
let mut rbuf = RenderingBuffer::new(&mut buf, width, height, width * 4);

// Set up the pixel format and renderer
let mut pixfmt = PixfmtRgba32::new(&mut rbuf);
let mut ren_base = RendererBase::new(&mut pixfmt);
ren_base.clear(&Rgba8::new(255, 255, 255, 255));

// Create a path and rasterize it
let mut path = PathStorage::new();
path.move_to(10.0, 10.0);
path.line_to(100.0, 50.0);
path.line_to(50.0, 100.0);
path.close_polygon();

let mut ras = RasterizerScanlineAa::new();
let mut sl = ScanlineU8::new();
ras.add_path(&mut path);
render_scanlines_aa_solid(&mut ras, &mut sl, &mut ren_base, &Rgba8::new(200, 80, 80, 255));

Development

Prerequisites

  • Rust 1.70+ (rustup install stable)
  • wasm-pack (for WASM demos)
  • Bun (for demo dev server)

Building & Testing

cargo build
cargo test --workspace --all-features   # 994 tests
cargo clippy -- -D warnings

Running the Demo Locally

cd demo
bun install
bun run build:wasm
bun run dev

Then open http://localhost:3000 in your browser.

Project Status & Goals

AGG.rs began as a strict, byte-for-byte port of AGG 2.6: all 88 core library modules are ported, all 64 applicable demos run via WebAssembly, and 994 tests pass. The byte-identity of the rendering pipeline is locked by the reference-test suite — the Byte-identical column in the benchmarks below is the proof, with every benchmarked demo matching the C++ output exactly. That port is complete.

The project is now beyond the port: new features, Rust-idiomatic APIs, performance work, and bug fixes are all welcome. C++ behavioral matching remains the default baseline. A deliberate divergence is allowed only to fix a demonstrable bug inherited from the C++ original, and it must be documented in the code and locked with a regression test (see the gradient-LUT off-by-one fix in src/gradient_lut.rs for the model). Contributions that clear that bar — a real-world use case, tests proving correctness, and clean idiomatic design — are exactly the kind the project wants. Performance is an active goal: the benchmark table shows where each demo stands against C++ today.

MetricValue
Core modules ported88
Tests passing994
Interactive demos64
External dependencies0
GPU dependencies0

Benchmarks

The Rust port is benchmarked head-to-head against the original AGG 2.6 C++ library on a shared set of demos. Both sides render the same scene at the same size, and timings cover the render call only (no process startup, asset loading, or file I/O). Each demo runs 2 untimed warmups followed by 25 timed iterations; from those samples both the best (minimum) and the median are reported for each side. Best-of is the primary signal — the fastest run is the least contaminated by OS scheduling jitter — with the median as a secondary sanity check. Single runs are noise, and differences under roughly ±2 ms are at the measurement floor on this machine.

Every benchmarked demo is byte-identical to the C++ output: a committed pixel-compare reference test pins the Rust buffer byte-for-byte against C++, so each speed difference reflects the implementation — not a difference in what is drawn.

Measured on an Intel Core i7-7660U @ 2.50GHz (Windows 10 19045), rustc 1.91.0 vs MSVC 19.44 (2026-07-22). Run-to-run variance from OS scheduling is expected:

DemoSizeByte-identicalC++ best (ms)Rust best (ms)Best Rust / C++C++ median (ms)Rust median (ms)Median Rust / C++
simple_line512x512yes0.340.220.66x0.520.290.56x
lion_outline512x512yes2.652.280.86x4.053.100.77x
rasterizers2500x450yes1.862.001.08x2.463.091.26x
conv_dash_marker500x330yes1.401.421.02x1.712.101.22x
perspective600x600yes3.112.990.96x4.423.880.88x
image_perspective600x600yes6.196.060.98x8.798.740.99x
image_transforms430x340yes2.231.620.73x2.922.330.80x
image_filters430x340yes3.913.390.87x5.344.540.85x
compositing2600x400yes4.844.770.99x6.806.710.99x
flash_rasterizer655x520yes2.732.150.79x3.692.930.79x
flash_rasterizer2655x520yes2.581.970.76x3.382.630.78x

The Byte-identical column records, per row, that the demo's Rust output is pinned byte-for-byte against the C++ reference by a committed test — the invariant that makes each timing an apples-to-apples comparison.

Full methodology, machine details, and compiler versions are in docs/BENCHMARKS.md. Regenerate the whole suite (build both sides in release, run every demo, rewrite the doc) with:

cargo build --release -p pixel-compare
cmake -S tools/cpp-renderer -B tools/cpp-renderer/build -A x64
cmake --build tools/cpp-renderer/build --config Release
target\release\pixel-compare bench-compare \
  --cpp tools\cpp-renderer\build\Release\agg-render.exe --passes 4 --iters 25 --out docs\BENCHMARKS.md

License

BSD-3-Clause — see LICENSE.

Based on the original Anti-Grain Geometry library by Maxim Shemanarev, dual-licensed under the Modified BSD License and the Anti-Grain Geometry Public License.

Note: The GPC (General Polygon Clipper) component from the original library is excluded from this port due to its non-commercial license restriction.

Acknowledgments

  • Maxim Shemanarev (1966–2013) — creator of Anti-Grain Geometry, a masterwork of C++ library design
  • ghaerr/agg-2.6 — the GitHub mirror of AGG 2.6 used as reference
  • Ported by Lars Brubaker, sponsored by MatterHackers