// Package svg provides an API for generating Scalable Vector Graphics (SVG)
package svg
// package main
//
// import (
// "github.com/ajstarks/svgo"
// "os"
// )
//
// var (
// width = 500
// height = 500
// canvas = svg.New(os.Stdout)
// )
//
// func main() {
// canvas.Start(width, height)
// canvas.Circle(width/2, height/2, 100)
// canvas.Text(width/2, height/2, "Hello, SVG",
// "text-anchor:middle;font-size:30px;fill:white")
// canvas.End()
// }
//
import (
"fmt"
"io"
"encoding/xml"
"strings"
)
// SVG defines the location of the generated SVG
type SVG struct {
Writer io.Writer
}
// Offcolor defines the offset and color for gradients
type Offcolor struct {
Offset uint8
Color string
Opacity float64
}
// Filterspec defines the specification of SVG filters
type Filterspec struct {
In, In2, Result string
}
const (
svgtop = `
") }
// linkembed defines an element with a specified type,
// (for example "application/javascript", or "text/css").
// if the first variadic argument is a link, use only the link reference.
// Otherwise, treat those arguments as the text of the script (marked up as CDATA).
// if no data is specified, just close the element
func (svg *SVG) linkembed(tag string, scriptype string, data ...string) {
svg.printf(`<%s type="%s"`, tag, scriptype)
switch {
case len(data) == 1 && islink(data[0]):
svg.printf(" %s/>\n", href(data[0]))
case len(data) > 0:
svg.printf(">\n\n%s>\n", tag)
default:
svg.println(`/>`)
}
}
// Script defines a script with a specified type, (for example "application/javascript").
func (svg *SVG) Script(scriptype string, data ...string) {
svg.linkembed("script", scriptype, data...)
}
// Style defines the specified style (for example "text/css")
func (svg *SVG) Style(scriptype string, data ...string) {
svg.linkembed("style", scriptype, data...)
}
// Gstyle begins a group, with the specified style.
// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#GElement
func (svg *SVG) Gstyle(s string) { svg.println(group("style", s)) }
// Gtransform begins a group, with the specified transform
// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute
func (svg *SVG) Gtransform(s string) { svg.println(group("transform", s)) }
// Translate begins coordinate translation, end with Gend()
// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute
func (svg *SVG) Translate(x, y int) { svg.Gtransform(translate(x, y)) }
// Scale scales the coordinate system by n, end with Gend()
// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute
func (svg *SVG) Scale(n float64) { svg.Gtransform(scale(n)) }
// ScaleXY scales the coordinate system by dx and dy, end with Gend()
// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute
func (svg *SVG) ScaleXY(dx, dy float64) { svg.Gtransform(scaleXY(dx, dy)) }
// SkewX skews the x coordinate system by angle a, end with Gend()
// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute
func (svg *SVG) SkewX(a float64) { svg.Gtransform(skewX(a)) }
// SkewY skews the y coordinate system by angle a, end with Gend()
// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute
func (svg *SVG) SkewY(a float64) { svg.Gtransform(skewY(a)) }
// SkewXY skews x and y coordinates by ax, ay respectively, end with Gend()
// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute
func (svg *SVG) SkewXY(ax, ay float64) { svg.Gtransform(skewX(ax) + " " + skewY(ay)) }
// Rotate rotates the coordinate system by r degrees, end with Gend()
// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute
func (svg *SVG) Rotate(r float64) { svg.Gtransform(rotate(r)) }
// TranslateRotate translates the coordinate system to (x,y), then rotates to r degrees, end with Gend()
func (svg *SVG) TranslateRotate(x, y int, r float64) {
svg.Gtransform(translate(x, y) + " " + rotate(r))
}
// RotateTranslate rotates the coordinate system r degrees, then translates to (x,y), end with Gend()
func (svg *SVG) RotateTranslate(x, y int, r float64) {
svg.Gtransform(rotate(r) + " " + translate(x, y))
}
// Group begins a group with arbitrary attributes
func (svg *SVG) Group(s ...string) { svg.printf("`)) }
// Gid begins a group, with the specified id
func (svg *SVG) Gid(s string) {
svg.print(``)
}
// Gend ends a group (must be paired with Gsttyle, Gtransform, Gid).
func (svg *SVG) Gend() { svg.println(``) }
// ClipPath defines a clip path
func (svg *SVG) ClipPath(s ...string) { svg.printf(``)) }
// ClipEnd ends a ClipPath
func (svg *SVG) ClipEnd() {
svg.println(``)
}
// Def begins a defintion block.
// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#DefsElement
func (svg *SVG) Def() { svg.println(``) }
// DefEnd ends a defintion block.
func (svg *SVG) DefEnd() { svg.println(``) }
// Marker defines a marker
// Standard reference: http://www.w3.org/TR/SVG11/painting.html#MarkerElement
func (svg *SVG) Marker(id string, x, y, width, height int, s ...string) {
svg.printf(`\n"))
}
// MarkEnd ends a marker
func (svg *SVG) MarkerEnd() { svg.println(``) }
// Pattern defines a pattern with the specified dimensions.
// The putype can be either "user" or "obj", which sets the patternUnits
// attribute to be either userSpaceOnUse or objectBoundingBox
// Standard reference: http://www.w3.org/TR/SVG11/pservers.html#Patterns
func (svg *SVG) Pattern(id string, x, y, width, height int, putype string, s ...string) {
puattr := "userSpaceOnUse"
if putype != "user" {
puattr = "objectBoundingBox"
}
svg.printf(`\n"))
}
// PatternEnd ends a marker
func (svg *SVG) PatternEnd() { svg.println(``) }
// Desc specified the text of the description tag.
// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#DescElement
func (svg *SVG) Desc(s string) { svg.tt("desc", s) }
// Title specified the text of the title tag.
// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#TitleElement
func (svg *SVG) Title(s string) { svg.tt("title", s) }
// Link begins a link named "name", with the specified title.
// Standard Reference: http://www.w3.org/TR/SVG11/linking.html#Links
func (svg *SVG) Link(href string, title string) {
svg.printf("")
}
// LinkEnd ends a link.
func (svg *SVG) LinkEnd() { svg.println(``) }
// Use places the object referenced at link at the location x, y, with optional style.
// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#UseElement
func (svg *SVG) Use(x int, y int, link string, s ...string) {
svg.printf(`