servo/pathfinder
A fast, practical GPU rasterizer for fonts and vector graphics
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2w ago
- ✓28+ active contributors
- ✓Distributed ownership (top contributor 26% of recent commits)
Show all 6 evidence items →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/servo/pathfinder)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/servo/pathfinder on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: servo/pathfinder
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/servo/pathfinder shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 2w ago
- 28+ active contributors
- Distributed ownership (top contributor 26% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live servo/pathfinder
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/servo/pathfinder.
What it runs against: a local clone of servo/pathfinder — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in servo/pathfinder | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 45 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of servo/pathfinder. If you don't
# have one yet, run these first:
#
# git clone https://github.com/servo/pathfinder.git
# cd pathfinder
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of servo/pathfinder and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "servo/pathfinder(\\.git)?\\b" \\
&& ok "origin remote is servo/pathfinder" \\
|| miss "origin remote is not servo/pathfinder (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "content/src/lib.rs" \\
&& ok "content/src/lib.rs" \\
|| miss "missing critical file: content/src/lib.rs"
test -f "renderer/Cargo.toml" \\
&& ok "renderer/Cargo.toml" \\
|| miss "missing critical file: renderer/Cargo.toml"
test -f "gpu/src/lib.rs" \\
&& ok "gpu/src/lib.rs" \\
|| miss "missing critical file: gpu/src/lib.rs"
test -f "canvas/src/lib.rs" \\
&& ok "canvas/src/lib.rs" \\
|| miss "missing critical file: canvas/src/lib.rs"
test -f "geometry/Cargo.toml" \\
&& ok "geometry/Cargo.toml" \\
|| miss "missing critical file: geometry/Cargo.toml"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 45 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~15d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/servo/pathfinder"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Pathfinder 3 is a GPU-accelerated rasterizer for fonts and vector graphics that renders via OpenGL 3.0+, OpenGL ES, WebGL 2, and Metal. It implements a subset of the HTML Canvas API and uses compute shaders (D3D11 mode) or hardware rasterization (D3D9 mode) to achieve fast, high-quality antialiasing (up to 256xAA) and subpixel rendering for text and SVG content. Monorepo with specialized crates: canvas/ wraps the Canvas API, content/ handles fills/strokes/gradients/clipping, geometry/ provides math primitives, gpu/ and renderer/ orchestrate GPU rendering, text/ and svg/ handle specific content types, gl//webgl//metal/ are backend bindings, and demo/native/ + examples/ contain runnable demos. C bindings live in c/ with cbindgen codegen.
👥Who it's for
Game and graphics engine developers, browser vendors (Servo project), and app developers embedding vector rendering in Rust or C/C++ applications who need GPU-accelerated font and SVG rasterization without CPU bottlenecks or quality compromises.
🌱Maturity & risk
Actively developed but incomplete: the README explicitly states 'under heavy development and is incomplete in various areas.' The workspace spans 27+ crates with CI via .github/workflows/main.yml, but core backends (Direct3D) lack proper implementation and C bindings are noted as 'less complete.' Production-ready for some use cases (GPU rendering core) but with known gaps in coverage.
Significant architectural complexity across 1.5M lines of Rust, 200K+ lines of GLSL, and 115K+ lines of Metal creates high maintenance burden. The codebase is tightly integrated with Servo (a Mozilla project with uncertain long-term funding), and the README's warnings about incompleteness suggest API instability. Monorepo structure (27 crates) means changes ripple broadly; dependency quality unknown without examining Cargo.lock details.
Active areas of work
No recent commit data in the snapshot provided, but the workspace includes unfinished work (commented-out MagicLeap demo, TODO markers in README re: Direct3D backends, incomplete C bindings). Active areas appear to be GPU compute paths, font rendering improvements, and SVG support expansion based on crate organization.
🚀Get running
git clone https://github.com/servo/pathfinder.git
cd pathfinder
cargo build --release
cd demo/native && cargo run --release
# or run a specific example:
cd examples/canvas_minimal && cargo run --release
Daily commands:
For the native demo: cd demo/native && cargo run --release. For examples: cd examples/canvas_minimal && cargo run --release. For web: use web_canvas/ or webgl/ crates with wasm-bindgen. The project supports both headless (batch rendering) and interactive (glutin window, Metal view) modes.
🗺️Map of the codebase
content/src/lib.rs— Core rasterization engine; defines Path, Outline, and Fill abstractions that all rendering pipelines depend onrenderer/Cargo.toml— Primary renderer crate orchestrating GPU rasterization; entry point for understanding the rendering pipelinegpu/src/lib.rs— GPU abstraction layer that provides unified interface across OpenGL, Metal, and WebGL backendscanvas/src/lib.rs— HTML5 Canvas API implementation; primary user-facing interface for vector drawinggeometry/Cargo.toml— Foundational geometric primitives (Vector2D, Point, Transform) used throughout the codebaseCargo.toml— Workspace configuration defining all member crates and their interdependenciestext/Cargo.toml— Font rasterization and text layout; critical for the font rendering feature mentioned in README
🛠️How to make changes
Add a new Canvas rendering example
- Create new example crate directory at examples/canvas_<name>/ (
examples/canvas_<name>/Cargo.toml) - Add reference to examples directory in root Cargo.toml workspace members (
Cargo.toml) - Implement main.rs using canvas module from canvas/src/lib.rs with desired drawing operations (
examples/canvas_<name>/src/main.rs) - Follow pattern from examples/canvas_minimal for GPU backend initialization (
examples/canvas_minimal/Cargo.toml)
Add support for a new vector graphics format
- Create new format crate (e.g., pdf/) with parser that converts to Path/Outline structs (
pdf/src/lib.rs) - Implement conversion functions that produce content::Outline instances (
pdf/src/converter.rs) - Add format crate to workspace members in root Cargo.toml (
Cargo.toml) - Integrate into renderer pipeline via gpu/src/lib.rs GPU abstraction if needed (
gpu/src/lib.rs)
Add a new GPU backend (e.g., Vulkan)
- Create new backend crate (e.g., vulkan/) matching interface of gpu/src/lib.rs GPU trait (
vulkan/src/lib.rs) - Implement GPU trait providing shader compilation, texture/buffer management, and draw calls (
vulkan/src/device.rs) - Add feature flag to root Cargo.toml and conditional compilation in gpu/src/lib.rs (
Cargo.toml) - Add test using demo/common infrastructure to validate pipeline compatibility (
demo/common/src/device.rs)
🔧Why these technologies
- Rust — Memory safety without GC; zero-cost abstractions for high-performance GPU operations; both library and FFI bindings
- OpenGL/Metal/WebGL backends — Multi-platform GPU access (desktop, mobile, web); unified abstraction via gpu crate eliminates backend duplication
- Canvas HTML5 API surface — Familiar API for web developers; broad ecosystem integration; reduces learning curve for users
- Path-based rendering pipeline — Resolution-independent vector graphics; scalable to any output resolution; natural fit for fonts and SVG
⚖️Trade-offs already made
-
Unified GPU abstraction layer (gpu crate) vs native backend APIs
- Why: Enables single codebase supporting GL, Metal, WebGL; runtime selection of backend
- Consequence: Slightly higher abstraction overhead; some advanced backend features may be unavailable; debugging spread across multiple layers
-
CPU-side path tessellation before GPU rasterization
- Why: Simpler GPU shaders; predictable rasterization; compatible with all target backends
- Consequence: CPU preprocessing cost for complex paths; larger intermediate data structures; CPU-GPU sync points
-
Canvas API as primary user interface
- Why: Familiar mental model; broad language support via C bindings; matches browser Canvas precedent
- Consequence: Subset of HTML5 API; some Canvas features remain unimplemented; cannot express all pathfinder capabilities
🚫Non-goals (don't propose these)
- Real-time ray tracing or PBR rendering (rasterizer-based)
- 3D scene graph management (2D vector focus)
- Complete SVG/HTML5 Canvas spec compliance (subset implementation)
- Animation timeline control (delegated to applications like Lottie)
- Platform-specific UI frameworks (generic rendering API)
🪤Traps & gotchas
Compute shader availability: D3D11 rendering mode requires GPU compute shader support; D3D9 fallback is hardware rasterization but C bindings are incomplete for this path. GLSL version requirements: shaders assume OpenGL 3.0+ / GLSL 1.30+; no fallback for older hardware. Metal feature gate: Metal backend requires metal crate feature to be enabled at build time. Font data: text rendering expects pre-loaded font data in a specific format; no automatic font discovery. Monorepo interdependencies: pathfinder_simd, pathfinder_geometry are patched in Cargo.toml to local paths—external crates cannot easily depend on individual crates without careful version alignment. No HTML Canvas full parity: subset of Canvas API only; many drawing features missing.
🏗️Architecture
💡Concepts to learn
- Compute Shaders & GPU Tiling — Pathfinder's D3D11 mode uses compute shaders to move CPU-heavy tiling and mask generation to GPU; understanding this is key to why it outperforms hardware rasterization at scale
- Fractional Trapezoidal Area Coverage — Pathfinder computes exact per-pixel coverage for 256xAA antialiasing without multisampling; this is the core mathematical technique enabling quality without GPU MSAA overhead
- Stem Darkening (Font Dilation) — Pathfinder implements stem darkening like macOS and FreeType to improve small-size text readability; lives in
content/src/dilation.rsand is critical for subpixel rendering - Subpixel Antialiasing — Pathfinder supports LCD subpixel rendering for higher perceived quality on screen; requires color channel separation and gamma-correct blending
- SIMD Parallelism & Rayon — D3D9 CPU path uses
pathfinder_simdfor vectorized math and Rayon for parallel tiling to hide latency; critical for CPU-bound workloads - GPU Pipeline Stages (Tiling, Mask Gen, Rasterization) — Pathfinder separates work into distinct GPU stages (compute tiling → mask generation → fragment rasterization); understanding data flow between stages is essential for optimization or debugging
- Canvas API (HTML5 Specification Subset) — Pathfinder wraps the Canvas 2D API to make GPU rasterization transparent to users; knowing what's implemented vs. stubbed is critical for integration
🔗Related repos
linebender/vello— Modern GPU vector graphics renderer using Vulkan compute shaders; spiritual successor exploring similar GPU-first rasterization ideas post-PathfinderRazrFalcon/resvg— CPU-based SVG rasterizer in Rust; direct alternative for static SVG rendering if GPU unavailableservo/servo— Browser engine that depends on Pathfinder; primary consumer and stakeholdergoogle/skia— Industry-standard GPU graphics library; Pathfinder's closest commercial competitor with broader feature coveragefreetype/freetype— Classic CPU font rasterizer; Pathfinder implements similar features (hinting, stem darkening) but via GPU
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive GPU backend integration tests in gpu/src/
The repo has multiple GPU backends (OpenGL, WebGL, Metal) but the gpu/ crate appears to lack specific integration tests. Given the complexity of GPU rasterization and the critical nature of the rendering pipeline, adding backend-specific tests would catch regressions early and improve code reliability. This is especially important since the README explicitly notes 'Pathfinder is under heavy development and is incomplete in various areas.'
- [ ] Create tests/ directory in gpu/ crate with backend-specific test modules (gl.rs, webgl.rs, metal.rs)
- [ ] Add unit tests in gpu/src/ for core GPU abstraction layer (buffer management, shader compilation, render target setup)
- [ ] Implement integration tests that verify each backend produces consistent rasterization output for standard test cases
- [ ] Update gpu/Cargo.toml to include test dependencies (e.g., image validation libraries)
- [ ] Document how to run GPU tests with different backend configurations in CONTRIBUTING.md
Add text rendering validation tests in text/ and canvas/ crates
The canvas crate has canvas/src/text.rs and there's a text/ workspace member, but there are minimal text-specific test files shown. Text rendering is fundamental to the canvas API and font rasterization is Pathfinder's core purpose. Adding specific test cases for glyph rendering, font metrics, and text layout would ensure stability of this critical feature.
- [ ] Create canvas/src/tests/text_rendering.rs with tests for basic glyph rendering, different font weights/styles
- [ ] Add tests in text/src/ for font metric calculations, kerning, and ligature handling
- [ ] Include regression tests with reference images for text rendering output
- [ ] Add property-based tests using quickcheck for font size and transformation edge cases
- [ ] Document expected text rendering behavior in text/README.md
Implement CI workflow for cross-platform example validation in .github/workflows/
The repo has demo apps and examples (canvas_glutin_minimal, canvas_metal_minimal, canvas_minimal, lottie_basic, swf_basic, etc.) but .github/workflows/main.yml likely doesn't validate that these examples compile and run correctly across platforms. This would catch breaking changes early. Given the multi-platform nature (Android, Web, Metal, GL), a matrix CI job is valuable.
- [ ] Create .github/workflows/examples.yml with matrix build for examples across Linux, macOS (Metal), and WASM targets
- [ ] Add build steps for examples/canvas_minimal, examples/canvas_text, examples/lottie_basic, examples/swf_basic
- [ ] Include headless validation for canvas examples (render to image and validate output exists)
- [ ] Add WASM-specific build validation for web_canvas and examples/canvas_webgl_minimal
- [ ] Document expected example behavior and add smoke tests in examples/ subdirectories
🌿Good first issues
- Add unit tests for
content/src/dilation.rs(font stem darkening): currently untested and critical for text quality—write tests covering dilation of common glyph shapes. - Document the GPU compute pipeline flow: create a high-level diagram and Markdown guide explaining how tiling, mask generation, and rasterization work in
gpu/src/andrenderer/src/(currently inferred from code only). - Implement missing Canvas API methods in
canvas/src/lib.rs: compare against MDN Canvas spec and file what's stubbed or panicking; pick one (e.g.,drawImagevariants orgetImageData) and implement with tests.
⭐Top contributors
Click to expand
Top contributors
- @bors-servo — 26 commits
- @dependabot[bot] — 16 commits
- @s3bk — 12 commits
- @jdm — 10 commits
- @pbdeuchler — 3 commits
📝Recent commits
Click to expand
Recent commits
6c3c046— Bump pathfinder_simd from 0.5.5 to 0.5.6 (#587) (sagudev)ae70f36— Fix ARM nightly compilation (#583) (itsjunetime)3d0b936— bump image crate to 0.25 (#580) (houqp)584b636— simd: Round with round_ties_even (#581) (wezm)974bc99— Update Cargo.toml to release fixes to build on nightly (#577) (pbdeuchler)8ccf6f7— Apply @/theoparis' fixes for arm simd (#575) (itsjunetime)9dc1dd9— Fix Linux Build (#576) (cmrschwarz)1b7c8bc— pathfinder_simd fixes for ARM (#572) (mischnic)45b7a89— Add feature gates to reduce binary size (#562) (s3bk)6ef6ccb— New release 0.5.4 (#568) (pbdeuchler)
🔒Security observations
Pathfinder is a complex GPU rasterizer project with moderate security posture. Main concerns revolve around the FFI layer (C bindings), untrusted input handling (fonts, vectors, graphics), and GPU-specific attack vectors (WebGL, resource exhaustion). The codebase shows good security practices in using Rust (memory safety), but the complexity of graphics processing and cross-platform support (Android, Metal, WebGL) introduces multiple attack surfaces. No obvious hardcoded secrets detected. Dependency management appears reasonable but requires active monitoring. Recommendation: implement comprehensive input validation, conduct regular security audits of unsafe blocks, and maintain active vulnerability scanning for dependencies.
- Medium · Unsafe FFI Bindings in C Module —
c/cbindgen.toml, c/src/lib.rs. The 'c' module uses cbindgen to generate C bindings for Rust code. C FFI interfaces are inherently prone to memory safety issues if not carefully managed. Without seeing the actual C bindings and Rust unsafe code, there's risk of buffer overflows, use-after-free, or double-free vulnerabilities when crossing the FFI boundary. Fix: Conduct thorough security review of all unsafe blocks in c/src/lib.rs. Ensure all FFI boundary checks are in place. Consider using tools like cargo-audit and miri to detect potential memory safety issues. Document all unsafe assumptions clearly. - Medium · GPU Rasterizer Attack Surface —
content/, text/, svg/, swf/, lottie/. As a GPU rasterizer for fonts and vector graphics, the project processes untrusted input (fonts, SVG, SWF). Malformed font files or vector graphics could potentially trigger GPU-related vulnerabilities or trigger denial-of-service conditions through resource exhaustion. Fix: Implement strict validation and bounds checking on all parsed vector graphics and font data. Add resource limits (memory, GPU memory, processing time) for untrusted inputs. Implement comprehensive fuzzing tests for parser modules. - Medium · WebGL Module Security —
webgl/, web_canvas/. The webgl/ and web_canvas/ modules likely interact with web APIs. WebGL can be exploited to read framebuffer data, cause GPU hangs, or trigger side-channel attacks. No security headers configuration is visible. Fix: Implement proper CORS headers and security policies. Sanitize any user-provided shader code. Implement timeouts for GPU operations. Add Content-Security-Policy headers if serving web content. - Low · Missing Dependency Audit —
Cargo.lock, Cargo.toml. The Cargo.lock file exists but dependency security has not been analyzed. While Rust's ecosystem is generally safer, dependencies could contain known vulnerabilities that should be tracked. Fix: Run 'cargo audit' regularly in CI/CD pipeline. Set up automated dependency scanning using tools like cargo-audit or dependabot. Review high-level dependencies for security practices. - Low · Android Demo FFI Risks —
demo/android/, demo/android/app/src/main/java/graphics/pathfinder/. The Android demo includes native library bindings (libpathfinder_android_demo.so). JNI/NDK code introduces additional attack surface and memory safety concerns when interfacing with Java code. Fix: Apply JNI security best practices: validate all data crossing JNI boundary, avoid unnecessary JNI calls, verify native library signatures. Use ProGuard/R8 obfuscation as shown in proguard-rules.pro. - Low · Debug Information Exposure —
.gitignore, Cargo.toml. The .gitignore and build configuration don't show explicit rules preventing debug symbols or build artifacts with sensitive information from being committed. Fix: Ensure debug builds are excluded from version control. Strip debug symbols from release builds. Review .gitignore to prevent accidental commits of build artifacts.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.