pdf_svg

pdf_svg is a fork of jovial_svg focused on rendering SVG assets into PDF documents with package:pdf.

This fork keeps the robust SVG/AVD parser, the ScalableImage model, and the compact .si binary format from jovial_svg, but replaces the Flutter rendering backend with a PDF backend. It does not provide Flutter widgets.

What Changed From jovial_svg

  • Rendering now targets PdfGraphics from package:pdf, not Flutter Canvas.
  • The package has no Flutter SDK dependency.
  • ScalableImageWidget, ScalableImageCache, ScalableImageSource, ExportedIDLookup, AssetBundle loaders, and image prepare/unprepare lifecycle APIs were removed.
  • Embedded images are decoded and embedded by the PDF renderer during paint.
  • The .si binary format and CLI converters are still supported.

Supported Inputs

ScalableImage can be loaded from:

  • SVG XML strings, streams, or HTTP/data URLs.
  • Android Vector Drawable XML.
  • .si bytes generated by svg_to_si or avd_to_si.

The supported SVG profile is inherited from jovial_svg: SVG Tiny 1.2 features that apply to static images, plus a practical subset of SVG 1.1, including paths, transforms, CSS styling with limitations, gradients, masks, text, embedded images, symbols, and use references.

Basic Usage

Render an SVG into a PDF page:

import 'dart:io';

import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:pdf_svg/pdf_svg.dart';

Future<void> main() async {
  final svg = await File('icon.svg').readAsString();
  final si = ScalableImage.fromSvgString(svg);

  final document = pw.Document();
  document.addPage(
    pw.Page(
      pageFormat: const PdfPageFormat(200, 200),
      build: (_) => pw.CustomPaint(
        size: const PdfPoint(200, 200),
        painter: (canvas, size) {
          si.paint(canvas, document: document.document);
        },
      ),
    ),
  );

  await File('icon.pdf').writeAsBytes(await document.save());
}

ScalableImage.paint handles the SVG-to-PDF coordinate conversion internally, so callers do not need to flip the PDF canvas manually.

Loading APIs

Common entry points:

final fromSvg = ScalableImage.fromSvgString(svgSource);
final fromSi = ScalableImage.fromSIBytes(siBytes);
final fromAvd = ScalableImage.fromAvdString(avdSource);
final fromUrl = await ScalableImage.fromSvgHttpUrl(uri);

Flutter AssetBundle APIs from upstream jovial_svg are intentionally not available in this fork.

Quick Loading Binary Format

The svg_to_si program compiles an SVG file into the compact .si binary format. The avd_to_si program does the same for Android Vector Drawable files.

Run the tools from this package:

dart run pdf_svg:svg_to_si path/to/icon.svg --out output/dir
dart run pdf_svg:avd_to_si path/to/icon.xml --out output/dir

Loading .si bytes is usually much faster than parsing SVG XML at runtime, especially for larger assets.

PDF Rendering Notes

PDF and Flutter have different rendering models, so this fork maps SVG features onto PDF primitives:

  • Paths are emitted with PdfGraphics.drawShape, then filled or stroked.
  • Linear and radial gradients use PdfShadingPattern.
  • Blend modes use PdfGraphicState where PDF supports them.
  • Masks use PDF luminosity soft masks.
  • Text is drawn with PDF fonts. The current fallback is Helvetica unless a richer font path is added by the application/fork.
  • Embedded raster images are inserted as PdfImage objects.

Known limitations:

  • Sweep/conic gradients have no native PDF shading primitive and are currently degraded rather than rendered exactly.
  • SVG masks can differ slightly from browser/Flutter output because PDF soft masks use luminosity semantics.
  • Advanced gradient text may require text-as-path or pattern-fill work for full fidelity.
  • This package is not a Flutter display package. Use package:pdf widgets such as pw.CustomPaint when integrating into PDF page layout.

DOM API

The Dart DOM API from jovial_svg is still available for programmatically modifying SVG assets before building a ScalableImage.

Example:

final dom = SvgDOMManager.fromString(svgSource);
final node = dom.dom.idLookup['accent'] as SvgPaint;
node.paint.fillColor = Colors.blue;

final si = dom.build();

After building, render the resulting ScalableImage into a PDF graphics canvas.

Supported SVG Profile

This fork aims to preserve the jovial_svg static-image profile:

  • SVG paths and transforms.
  • use references.
  • Stroke modifiers such as stroke-linecap, stroke-linejoin, stroke-miterlimit, stroke-dasharray, and stroke-dashoffset.
  • Linear and radial gradients, including xlink:href and gradientTransform.
  • mask and clipPath.
  • Text and tspan.
  • Embedded images.
  • Inheritable properties.
  • Object and group opacity.
  • symbol.
  • Inline CSS via <style> and the style attribute, with the same limitations as upstream jovial_svg.

Not supported:

  • SVG scripting and browser-style animation.
  • Filter effects via filter.
  • Pattern fills.
  • Nested SVG documents.
  • Non-scaling stroke.
  • Full bidirectional text shaping.

Supported AVD Profile

  • Scaling with android:width/android:height requires android:viewportWidth/android:viewportHeight.
  • android:autoMirrored is not supported.
  • android:alpha on a vector tag is not supported.

Credits

This project is explicitly a fork of jovial_svg by William Foote and keeps the original parser, compact representation, and much of the internal architecture. The fork changes the rendering target from Flutter to PDF.

See the original project:

Internal Documentation

The original high-level source overview is still available in doc/index.html. Some Flutter-specific portions of that documentation may be obsolete in this PDF-focused fork.

Libraries

dom
This package provides a document object model to allow programmatic modification of an SVG asset. It can be used for animation/scripting, where the asset is modified then displayed, perhaps many times. This is similar to what some web pages do with JavaScript code modifying an SVG.
pdf_svg
This library offers a ScalableImage that can be loaded from: