Architecture
JairoSVG is a pure Java SVG 1.1 renderer using Java2D.
Module Overview
| Java Class | Responsibility |
|---|---|
JairoSVG |
Public API and ConversionBuilder |
Surface |
Core Java2D rendering engine |
PngSurface |
PNG output via javax.imageio |
JpegSurface |
JPEG output via javax.imageio |
TiffSurface |
TIFF output via javax.imageio |
PdfSurface |
PDF output via Apache PDFBox |
PsSurface |
PostScript/EPS output via PrinterJob |
Node |
SVG DOM tree with CSS application (SAX-based) |
PathDrawer |
SVG path command parser (M, L, C, Q, A, H, V, …) |
ShapeDrawer |
Basic shapes (rect, circle, ellipse, line, polygon, polyline) |
TextDrawer |
Text, tspan, and textPath rendering |
Defs |
Clip paths, <use>, <symbol> handling |
GradientPainter |
Linear and radial gradient rendering with href chains |
PatternPainter |
Pattern fill rendering with patternTransform |
FilterRenderer |
SVG filter pipeline (feGaussianBlur, feBlend, feMerge, …) |
BlendCompositor |
Pixel-level blend mode compositing |
GaussianBlur |
Optimized box-blur Gaussian approximation |
MarkerDrawer |
Marker rendering on paths and shapes |
MaskPainter |
Luminance-based mask compositing |
ImageHandler |
Embedded raster and SVG image handling |
Colors |
SVG/CSS color parsing (170+ named, hex, rgb, hsl) |
Helpers |
Units, transforms, size calculations, path normalization |
CssProcessor |
CSS stylesheet parsing and selector matching |
BoundingBox |
Element bounding box computation |
Features |
SVG conditional feature detection |
UrlHelper |
URL resolution, fetching, and data URI parsing |
SvgDrawer |
Root <svg> element handler |
SvgFont |
SVG font glyph parsing and caching |
Main |
CLI entry point |
Key Technologies
| Technology | Usage |
|---|---|
java.awt.Graphics2D |
2D rendering context |
java.awt.image.BufferedImage |
Raster image buffer |
java.awt.geom.AffineTransform |
Coordinate transforms |
java.awt.LinearGradientPaint |
Linear gradient rendering |
java.awt.RadialGradientPaint |
Radial gradient rendering |
java.awt.BasicStroke |
Stroke styling |
javax.imageio.ImageIO |
PNG/JPEG/TIFF encoding |
| Apache PDFBox 3.0 | PDF output (optional) |
| SAX parser | Secure XML parsing |
| Custom CSS parser | SVG stylesheet support |
Rendering Pipeline
SVG Input (bytes/file/URL/string/stream)
↓
SAX Parsing (secure, with gzip auto-detection)
↓
Node Tree (DOM-like with attribute inheritance)
↓
CSS Application (stylesheets + inline styles + cascade)
↓
Surface.draw() — recursive element rendering
├── ShapeDrawer (rect, circle, ellipse, line, polygon, polyline)
├── PathDrawer (M, L, C, S, Q, T, A, H, V, Z)
├── TextDrawer (text, tspan, textPath)
├── ImageHandler (embedded raster/SVG images)
├── SvgDrawer (nested <svg> elements)
├── GradientPainter (linearGradient, radialGradient)
├── PatternPainter (pattern fills)
├── FilterRenderer → BlendCompositor, GaussianBlur
│ (feGaussianBlur, feOffset, feFlood, feBlend, feMerge,
│ feDropShadow, feImage, feTile, feColorMatrix,
│ feComposite, feComponentTransfer, feMorphology,
│ feConvolveMatrix, feDisplacementMap, feTurbulence,
│ feDiffuseLighting, feSpecularLighting)
├── MaskPainter (luminance-based masks)
├── MarkerDrawer (marker-start/mid/end)
└── Defs (clipPath, use, symbol)
↓
Output Surface
├── PngSurface → BufferedImage → ImageIO.write("png")
├── JpegSurface → BufferedImage → ImageIO.write("jpeg")
├── TiffSurface → BufferedImage → ImageIO.write("tiff")
├── PdfSurface → BufferedImage → PDFBox PDPage
└── PsSurface → BufferedImage → PrinterJob
Key Design Decisions
- Java2D over JavaFX: Java2D is available in all JDK distributions without extra modules
- SAX over DOM: SAX parsing builds the Node tree directly, avoiding the overhead of a full DOM
- PDFBox for PDF: Mature, well-maintained, pure Java PDF library (optional dependency)
- No external CSS library: SVG CSS needs are limited; a minimal parser avoids heavy dependencies
- Secure by default: XML parsing hardened against XXE, with opt-in
unsafemode - Static API + Builder: Simple cases use static methods; complex cases use the builder pattern
- Granular draw classes: Filter, gradient, pattern, mask, and marker logic extracted into focused classes
Performance Optimizations
- Pre-compiled regex patterns as static fields (Helpers, PathDrawer, CssProcessor)
- Cached SAX parser factory singletons (secure and unsafe variants)
GeneralPath.reset()reuse instead of allocation per elementindexOf-based token extraction replacingString.split()in hot paths- Sub-region effect buffers for filters and masks (BoundingBox-based)
- Optimized three-pass box blur for Gaussian approximation (GaussianBlur)
