svgreader

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 17, 2026 License: BSD-3-Clause Imports: 6 Imported by: 4

README

svgreader

A pure Go SVG-to-PDF renderer. Parses SVG documents and produces PDF content streams — no external tools (like Inkscape or librsvg) needed.

Status: Beta. The library is actively used in boxes and glue for embedding SVG graphics in PDF documents. The API may still change.

Features

  • Basic shapes: <rect>, <circle>, <ellipse>, <line>, <polyline>, <polygon> (including rounded corners)
  • Paths: All SVG path commands (M, L, H, V, C, S, Q, T, A, Z), with arc-to-cubic conversion
  • Groups: <g> with style inheritance
  • Transforms: translate(), rotate(), scale(), matrix(), skewX(), skewY()
  • Styling: fill, stroke, stroke-width, stroke-linecap, stroke-linejoin, fill-rule, opacity; inline CSS via the style attribute
  • Colors: Hex (#rgb, #rrggbb), rgb() function, 148 named CSS colors
  • Text: <text> elements via a pluggable TextRenderer interface for external font shaping
  • Aspect ratio: Automatic scaling from viewBox to output size, with aspect-ratio preservation

Installation

go get github.com/boxesandglue/svgreader

Example

package main

import (
    "fmt"
    "strings"

    "github.com/boxesandglue/svgreader"
)

const mySVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100">
  <rect x="10" y="10" width="180" height="80" rx="8"
        fill="#eef" stroke="#336" stroke-width="2"/>
  <circle cx="100" cy="50" r="30" fill="none" stroke="red"/>
</svg>`

func main() {
    doc, err := svgreader.Parse(strings.NewReader(mySVG))
    if err != nil {
        panic(err)
    }

    fmt.Printf("SVG size: %.0f x %.0f\n", doc.Width, doc.Height)

    stream := doc.RenderPDF(svgreader.RenderOptions{
        Width:  200,
        Height: 100,
    })
    fmt.Println(stream)
}
Using with boxes and glue

When used inside boxes and glue, SVG nodes integrate directly into the page layout:

svgDoc, _ := svgreader.Parse(file)
svgNode := f.Doc.CreateSVGNodeFromDocument(svgDoc, bag.MustSP("80mm"), 0)
p.OutputAt(bag.MustSP("2cm"), bag.MustSP("26cm"), node.Vpack(svgNode))

For SVGs with <text> elements, pass an SVGTextRenderer to enable HarfBuzz-based font shaping:

tr := frontend.NewSVGTextRenderer(f)
tr.DefaultFamily = myFontFamily
svgNode := f.Doc.CreateSVGNodeFromDocument(svgDoc, bag.MustSP("80mm"), 0, tr)

Documentation

Text rendering

SVG <text> elements require a TextRenderer implementation to produce PDF text operators. Without one, text elements are silently skipped.

type TextRenderer interface {
    RenderText(text string, x, y, fontSize float64,
        fontFamily, fontWeight, fontStyle string,
        fill Color) string
}

The RenderText method receives position, font properties, and fill color. It returns PDF operators (e.g. BT ... ET) that are inserted into the content stream.

Package structure

svg.go        SVG parser (Document, Element types, Parse)
pathdata.go   SVG path data parser (M, L, C, A, ... commands)
render.go     PDF content stream renderer
color.go      SVG color parser (hex, rgb(), named colors)
transform.go  SVG transform parser and matrix math

License

Modified BSD License — see License.md

Documentation

Overview

Package svgreader parses SVG documents and renders them as PDF content streams.

The package supports a practical subset of SVG: paths, basic shapes (rect, circle, ellipse, line, polyline, polygon), groups with transforms, and fill/stroke styling. Text elements are parsed and can be rendered using an external text shaper (e.g. textshape).

Usage:

doc, err := svgreader.Parse(reader)
pdfStream := doc.RenderPDF(widthPt, heightPt)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func PathCommandsToString

func PathCommandsToString(cmds []PathCommand) string

String returns the SVG path data string representation of the commands.

func QuadToCubic

func QuadToCubic(qx0, qy0, qx1, qy1, qx2, qy2 float64) (cx1, cy1, cx2, cy2 float64)

QuadToCubic converts a quadratic Bézier (Q) to a cubic Bézier (C). PDF only supports cubic Bézier curves.

Types

type Circle

type Circle struct {
	Cx, Cy    float64
	R         float64
	Style     StyleAttrs
	Transform string
}

Circle represents an SVG <circle> element.

type Color

type Color struct {
	R, G, B float64
	IsNone  bool // true for "none" (transparent)
}

Color represents an SVG color with RGB components (0–1 range).

func ParseColor

func ParseColor(s string) (Color, error)

ParseColor parses an SVG color value. Supported formats: "none", "#rgb", "#rrggbb", "rgb(r,g,b)", named colors.

func (Color) PDFNonstroking

func (c Color) PDFNonstroking() string

PDFNonstroking returns the PDF operator to set this color as the fill color.

func (Color) PDFStroking

func (c Color) PDFStroking() string

PDFStroking returns the PDF operator to set this color as the stroking color.

type Document

type Document struct {
	Width      float64   // Document width in SVG user units
	Height     float64   // Document height in SVG user units
	ViewBox    ViewBox   // ViewBox specification
	Elements   []Element // Child elements in document order
	FontFamily string    // Default font-family from the <svg> element
}

Document represents a parsed SVG document.

func Parse

func Parse(r io.Reader) (*Document, error)

Parse parses an SVG document from a reader.

func (*Document) RenderPDF

func (doc *Document) RenderPDF(opts RenderOptions) string

RenderPDF renders the SVG document as a PDF content stream. The width and height specify the desired output size in PDF points. If both are zero, the SVG dimensions are used as-is.

type Element

type Element interface {
	// contains filtered or unexported methods
}

Element is the interface implemented by all SVG elements.

type Ellipse

type Ellipse struct {
	Cx, Cy    float64
	Rx, Ry    float64
	Style     StyleAttrs
	Transform string
}

Ellipse represents an SVG <ellipse> element.

type Group

type Group struct {
	Style     StyleAttrs
	Transform string
	Children  []Element
}

Group represents an SVG <g> element.

type Line

type Line struct {
	X1, Y1    float64
	X2, Y2    float64
	Style     StyleAttrs
	Transform string
}

Line represents an SVG <line> element.

type Matrix

type Matrix [6]float64

Matrix is a 2D affine transformation matrix in the form:

[a c e]
[b d f]
[0 0 1]

This matches both SVG's matrix(a,b,c,d,e,f) and PDF's a b c d e f cm.

func Identity

func Identity() Matrix

Identity returns the identity matrix.

func ParseTransform

func ParseTransform(s string) Matrix

ParseTransform parses an SVG transform attribute value into a combined matrix. Supported: matrix(), translate(), scale(), rotate(), skewX(), skewY(). Multiple transforms are applied left to right (as per SVG spec).

func Rotate

func Rotate(angleDeg float64) Matrix

Rotate returns a rotation matrix for angle in degrees.

func RotateAround

func RotateAround(angleDeg, cx, cy float64) Matrix

RotateAround returns a rotation matrix around point (cx, cy).

func Scale

func Scale(sx, sy float64) Matrix

Scale returns a scaling matrix.

func SkewX

func SkewX(angleDeg float64) Matrix

SkewX returns a skewX matrix.

func SkewY

func SkewY(angleDeg float64) Matrix

SkewY returns a skewY matrix.

func Translate

func Translate(tx, ty float64) Matrix

Translate returns a translation matrix.

func (Matrix) Multiply

func (m Matrix) Multiply(n Matrix) Matrix

Multiply returns the product m × n.

func (Matrix) PDFOperator

func (m Matrix) PDFOperator() string

PDFOperator returns the PDF content stream operator for this matrix.

func (Matrix) TransformPoint

func (m Matrix) TransformPoint(x, y float64) (float64, float64)

TransformPoint applies the matrix to a point.

type Path

type Path struct {
	D         string
	Style     StyleAttrs
	Transform string
}

Path represents an SVG <path> element.

type PathCommand

type PathCommand struct {
	Cmd  byte      // Command letter: M, L, H, V, C, S, Q, T, A, Z (upper=absolute, lower=relative)
	Args []float64 // Coordinate arguments
}

PathCommand represents a single SVG path command with its arguments.

func ExpandShorthands

func ExpandShorthands(cmds []PathCommand) []PathCommand

ExpandShorthands expands S/T shorthand commands into full C/Q commands by computing the reflected control point from the previous command.

func ParsePathData

func ParsePathData(d string) ([]PathCommand, error)

ParsePathData parses an SVG path data string (the "d" attribute) into a sequence of path commands.

Supported commands: M, L, H, V, C, S, Q, T, A, Z and their relative (lowercase) variants. Implicit command repetition is handled: extra coordinate pairs after M are treated as L, and similarly for other commands.

func ResolveToAbsolute

func ResolveToAbsolute(cmds []PathCommand) []PathCommand

ResolveToAbsolute converts all relative commands to absolute coordinates. This simplifies rendering since PDF only uses absolute coordinates.

type Point

type Point struct {
	X, Y float64
}

Point is a 2D coordinate.

type Polygon

type Polygon struct {
	Points    []Point
	Style     StyleAttrs
	Transform string
}

Polygon represents an SVG <polygon> element.

type Polyline

type Polyline struct {
	Points    []Point
	Style     StyleAttrs
	Transform string
}

Polyline represents an SVG <polyline> element.

type Rect

type Rect struct {
	X, Y          float64
	Width, Height float64
	Rx, Ry        float64
	Style         StyleAttrs
	Transform     string
}

Rect represents an SVG <rect> element.

type RenderOptions

type RenderOptions struct {
	// Width and Height specify the output size in PDF points.
	// If zero, the SVG's own dimensions are used (1 SVG user unit = 1 PDF point).
	Width, Height float64

	// TextRenderer handles <text> elements. If nil, text is skipped.
	TextRenderer TextRenderer
}

RenderOptions controls PDF rendering.

type StyleAttrs

type StyleAttrs struct {
	Fill             string
	FillOpacity      string
	Stroke           string
	StrokeWidth      string
	StrokeOpacity    string
	StrokeLinecap    string
	StrokeLinejoin   string
	StrokeDasharray  string
	StrokeDashoffset string
	Opacity          string
	FillRule         string
	ClipPath         string
}

StyleAttrs holds SVG presentation attributes.

type Text

type Text struct {
	X, Y       float64
	Content    string
	FontFamily string
	FontSize   float64
	FontWeight string
	FontStyle  string
	TextAnchor string // "start", "middle", "end"
	Style      StyleAttrs
	Transform  string
}

Text represents an SVG <text> element. Text rendering requires an external shaper (e.g. textshape).

type TextRenderer

type TextRenderer interface {
	// RenderText returns PDF operators to render text at the given position.
	// fontSize is in PDF points. textAnchor is "start", "middle", or "end".
	// The returned string is inserted into the content stream as-is.
	RenderText(text string, x, y, fontSize float64, fontFamily, fontWeight, fontStyle, textAnchor string, fill Color) string
}

TextRenderer is implemented by external text shapers (e.g. textshape) to render SVG <text> elements into PDF operators. If nil, text elements are skipped.

type ViewBox

type ViewBox struct {
	MinX, MinY    float64
	Width, Height float64
}

ViewBox defines the SVG coordinate system.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL