func (svg *SVG) FeDistantLight(fs Filterspec, azimuth, elevation float64, s ...string) {
	svg.printf(`<feDistantLight %s azimuth="%g" elevation="%g" %s`,
		fsattr(fs), azimuth, elevation, endstyle(s, emptyclose))
}
FeDistantLight specifies a feDistantLight filter primitive
Standard reference: http://www.w3.org/TR/SVG11/filters.html#feDistantLightElement
package svg
import (
	"fmt"
	"io"
	"encoding/xml"
	"strings"
)
type SVG struct {
	Writer io.Writer
}
type Offcolor struct {
	Offset  uint8
	Color   string
	Opacity float64
}
type Filterspec struct {
	In, In2, Result string
}
const (
	svgtop = `<?xml version="1.0"?>
<!-- Generated by SVGo -->
<svg`
	svginitfmt = `%s width="%d%s" height="%d%s"`
	svgns      = `
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">`
	vbfmt = `viewBox="%d %d %d %d"`
	emptyclose = "/>\n"
)
func New(w io.Writer) *SVG { return &SVG{w} }
func (svg *SVG) print(a ...interface{}) (n int, errno error) {
	return fmt.Fprint(svg.Writer, a...)
}
func (svg *SVG) println(a ...interface{}) (n int, errno error) {
	return fmt.Fprintln(svg.Writer, a...)
}
func (svg *SVG) printf(format string, a ...interface{}) (n int, errno error) {
	return fmt.Fprintf(svg.Writer, format, a...)
}
func (svg *SVG) genattr(ns []string) {
	for _, v := range ns {
		svg.printf("\n     %s", v)
	}
	svg.println(svgns)
}
func (svg *SVG) Start(w int, h int, ns ...string) {
	svg.printf(svginitfmt, svgtop, w, "", h, "")
	svg.genattr(ns)
}
func (svg *SVG) Startunit(w int, h int, unit string, ns ...string) {
	svg.printf(svginitfmt, svgtop, w, unit, h, unit)
	svg.genattr(ns)
}
func (svg *SVG) Startpercent(w int, h int, ns ...string) {
	svg.printf(svginitfmt, svgtop, w, "%", h, "%")
	svg.genattr(ns)
}
func (svg *SVG) Startview(w, h, minx, miny, vw, vh int) {
	svg.Start(w, h, fmt.Sprintf(vbfmt, minx, miny, vw, vh))
}
func (svg *SVG) StartviewUnit(w, h int, unit string, minx, miny, vw, vh int) {
	svg.Startunit(w, h, unit, fmt.Sprintf(vbfmt, minx, miny, vw, vh))
}
func (svg *SVG) Startraw(ns ...string) {
	svg.printf(svgtop)
	svg.genattr(ns)
}
func (svg *SVG) End() { svg.println("</svg>") }
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<![CDATA[\n")
		for _, v := range data {
			svg.println(v)
		}
		svg.printf("]]>\n</%s>\n", tag)
	default:
		svg.println(`/>`)
	}
}
func (svg *SVG) Script(scriptype string, data ...string) {
	svg.linkembed("script", scriptype, data...)
}
func (svg *SVG) Style(scriptype string, data ...string) {
	svg.linkembed("style", scriptype, data...)
}
func (svg *SVG) Gstyle(s string) { svg.println(group("style", s)) }
func (svg *SVG) Gtransform(s string) { svg.println(group("transform", s)) }
func (svg *SVG) Translate(x, y int) { svg.Gtransform(translate(x, y)) }
func (svg *SVG) Scale(n float64) { svg.Gtransform(scale(n)) }
func (svg *SVG) ScaleXY(dx, dy float64) { svg.Gtransform(scaleXY(dx, dy)) }
func (svg *SVG) SkewX(a float64) { svg.Gtransform(skewX(a)) }
func (svg *SVG) SkewY(a float64) { svg.Gtransform(skewY(a)) }
func (svg *SVG) SkewXY(ax, ay float64) { svg.Gtransform(skewX(ax) + " " + skewY(ay)) }
func (svg *SVG) Rotate(r float64) { svg.Gtransform(rotate(r)) }
func (svg *SVG) TranslateRotate(x, y int, r float64) {
	svg.Gtransform(translate(x, y) + " " + rotate(r))
}
func (svg *SVG) RotateTranslate(x, y int, r float64) {
	svg.Gtransform(rotate(r) + " " + translate(x, y))
}
func (svg *SVG) Group(s ...string) { svg.printf("<g %s\n", endstyle(s, `>`)) }
func (svg *SVG) Gid(s string) {
	svg.print(`<g id="`)
	xml.Escape(svg.Writer, []byte(s))
	svg.println(`">`)
}
func (svg *SVG) Gend() { svg.println(`</g>`) }
func (svg *SVG) ClipPath(s ...string) { svg.printf(`<clipPath %s`, endstyle(s, `>`)) }
func (svg *SVG) ClipEnd() {
	svg.println(`</clipPath>`)
}
func (svg *SVG) Def() { svg.println(`<defs>`) }
func (svg *SVG) DefEnd() { svg.println(`</defs>`) }
func (svg *SVG) Marker(id string, x, y, width, height int, s ...string) {
	svg.printf(`<marker id="%s" refX="%d" refY="%d" markerWidth="%d" markerHeight="%d" %s`,
		id, x, y, width, height, endstyle(s, ">\n"))
}
func (svg *SVG) MarkerEnd() { svg.println(`</marker>`) }
func (svg *SVG) Pattern(id string, x, y, width, height int, putype string, s ...string) {
	puattr := "userSpaceOnUse"
	if putype != "user" {
		puattr = "objectBoundingBox"
	}
	svg.printf(`<pattern id="%s" x="%d" y="%d" width="%d" height="%d" patternUnits="%s" %s`,
		id, x, y, width, height, puattr, endstyle(s, ">\n"))
}
func (svg *SVG) PatternEnd() { svg.println(`</pattern>`) }
func (svg *SVG) Desc(s string) { svg.tt("desc", s) }
func (svg *SVG) Title(s string) { svg.tt("title", s) }
func (svg *SVG) Link(href string, title string) {
	svg.printf("<a xlink:href=\"%s\" xlink:title=\"", href)
	xml.Escape(svg.Writer, []byte(title))
	svg.println("\">")
}
func (svg *SVG) LinkEnd() { svg.println(`</a>`) }
func (svg *SVG) Use(x int, y int, link string, s ...string) {
	svg.printf(`<use %s %s %s`, loc(x, y), href(link), endstyle(s, emptyclose))
}
func (svg *SVG) Mask(id string, x int, y int, w int, h int, s ...string) {
	svg.printf(`<mask id="%s" x="%d" y="%d" width="%d" height="%d" %s`, id, x, y, w, h, endstyle(s, `>`))
}
func (svg *SVG) MaskEnd() { svg.println(`</mask>`) }
func (svg *SVG) Circle(x int, y int, r int, s ...string) {
	svg.printf(`<circle cx="%d" cy="%d" r="%d" %s`, x, y, r, endstyle(s, emptyclose))
}
func (svg *SVG) Ellipse(x int, y int, w int, h int, s ...string) {
	svg.printf(`<ellipse cx="%d" cy="%d" rx="%d" ry="%d" %s`,
		x, y, w, h, endstyle(s, emptyclose))
}
func (svg *SVG) Polygon(x []int, y []int, s ...string) {
	svg.poly(x, y, "polygon", s...)
}
func (svg *SVG) Rect(x int, y int, w int, h int, s ...string) {
	svg.printf(`<rect %s %s`, dim(x, y, w, h), endstyle(s, emptyclose))
}
func (svg *SVG) CenterRect(x int, y int, w int, h int, s ...string) {
	svg.Rect(x-(w/2), y-(h/2), w, h, s...)
}
func (svg *SVG) Roundrect(x int, y int, w int, h int, rx int, ry int, s ...string) {
	svg.printf(`<rect %s rx="%d" ry="%d" %s`, dim(x, y, w, h), rx, ry, endstyle(s, emptyclose))
}
func (svg *SVG) Square(x int, y int, l int, s ...string) {
	svg.Rect(x, y, l, l, s...)
}
func (svg *SVG) Path(d string, s ...string) {
	svg.printf(`<path d="%s" %s`, d, endstyle(s, emptyclose))
}
func (svg *SVG) Arc(sx int, sy int, ax int, ay int, r int, large bool, sweep bool, ex int, ey int, s ...string) {
	svg.printf(`%s A%s %d %s %s %s" %s`,
		ptag(sx, sy), coord(ax, ay), r, onezero(large), onezero(sweep), coord(ex, ey), endstyle(s, emptyclose))
}
// Bezier draws a cubic bezier curve, with optional style, beginning at sx,sy, ending at ex,ey
// with control points at cx,cy and px,py.
// Standard Reference: http://www.w3.org/TR/SVG11/paths.html#PathDataCubicBezierCommands
func (svg *SVG) Bezier(sx int, sy int, cx int, cy int, px int, py int, ex int, ey int, s ...string) {
	svg.printf(`%s C%s %s %s" %s`,
		ptag(sx, sy), coord(cx, cy), coord(px, py), coord(ex, ey), endstyle(s, emptyclose))
}
func (svg *SVG) Qbez(sx int, sy int, cx int, cy int, ex int, ey int, s ...string) {
	svg.printf(`%s Q%s %s" %s`,
		ptag(sx, sy), coord(cx, cy), coord(ex, ey), endstyle(s, emptyclose))
}
// Qbezier draws a Quadratic Bezier curve, with optional style, beginning at sx, sy, ending at tx,ty
// with control points are at cx,cy, ex,ey.
// Standard Reference: http://www.w3.org/TR/SVG11/paths.html#PathDataQuadraticBezierCommands
func (svg *SVG) Qbezier(sx int, sy int, cx int, cy int, ex int, ey int, tx int, ty int, s ...string) {
	svg.printf(`%s Q%s %s T%s" %s`,
		ptag(sx, sy), coord(cx, cy), coord(ex, ey), coord(tx, ty), endstyle(s, emptyclose))
}
func (svg *SVG) Line(x1 int, y1 int, x2 int, y2 int, s ...string) {
	svg.printf(`<line x1="%d" y1="%d" x2="%d" y2="%d" %s`, x1, y1, x2, y2, endstyle(s, emptyclose))
}
func (svg *SVG) Polyline(x []int, y []int, s ...string) {
	svg.poly(x, y, "polyline", s...)
}
func (svg *SVG) Image(x int, y int, w int, h int, link string, s ...string) {
	svg.printf(`<image %s %s %s`, dim(x, y, w, h), href(link), endstyle(s, emptyclose))
}
func (svg *SVG) Text(x int, y int, t string, s ...string) {
	svg.printf(`<text %s %s`, loc(x, y), endstyle(s, ">"))
	xml.Escape(svg.Writer, []byte(t))
	svg.println(`</text>`)
}
func (svg *SVG) Textpath(t string, pathid string, s ...string) {
	svg.printf("<text %s<textPath xlink:href=\"%s\">", endstyle(s, ">"), pathid)
	xml.Escape(svg.Writer, []byte(t))
	svg.println(`</textPath></text>`)
}
func (svg *SVG) Textlines(x, y int, s []string, size, spacing int, fill, align string) {
	svg.Gstyle(fmt.Sprintf("font-size:%dpx;fill:%s;text-anchor:%s", size, fill, align))
	for _, t := range s {
		svg.Text(x, y, t)
		y += spacing
	}
	svg.Gend()
}
func (svg *SVG) RGB(r int, g int, b int) string {
	return fmt.Sprintf(`fill:rgb(%d,%d,%d)`, r, g, b)
}
func (svg *SVG) RGBA(r int, g int, b int, a float64) string {
	return fmt.Sprintf(`fill-opacity:%.2f; %s`, a, svg.RGB(r, g, b))
}
func (svg *SVG) LinearGradient(id string, x1, y1, x2, y2 uint8, sc []Offcolor) {
	svg.printf("<linearGradient id=\"%s\" x1=\"%d%%\" y1=\"%d%%\" x2=\"%d%%\" y2=\"%d%%\">\n",
		id, pct(x1), pct(y1), pct(x2), pct(y2))
	svg.stopcolor(sc)
	svg.println("</linearGradient>")
}
func (svg *SVG) RadialGradient(id string, cx, cy, r, fx, fy uint8, sc []Offcolor) {
	svg.printf("<radialGradient id=\"%s\" cx=\"%d%%\" cy=\"%d%%\" r=\"%d%%\" fx=\"%d%%\" fy=\"%d%%\">\n",
		id, pct(cx), pct(cy), pct(r), pct(fx), pct(fy))
	svg.stopcolor(sc)
	svg.println("</radialGradient>")
}
func (svg *SVG) stopcolor(oc []Offcolor) {
	for _, v := range oc {
		svg.printf("<stop offset=\"%d%%\" stop-color=\"%s\" stop-opacity=\"%.2f\"/>\n",
			pct(v.Offset), v.Color, v.Opacity)
	}
}
func (svg *SVG) Filter(id string, s ...string) {
	svg.printf(`<filter id="%s" %s`, id, endstyle(s, ">\n"))
}
func (svg *SVG) Fend() {
	svg.println(`</filter>`)
}
func (svg *SVG) FeBlend(fs Filterspec, mode string, s ...string) {
	switch mode {
	case "normal", "multiply", "screen", "darken", "lighten":
		break
	default:
		mode = "normal"
	}
	svg.printf(`<feBlend %s mode="%s" %s`,
		fsattr(fs), mode, endstyle(s, emptyclose))
}
func (svg *SVG) FeColorMatrix(fs Filterspec, values [20]float64, s ...string) {
	svg.printf(`<feColorMatrix %s type="matrix" values="`, fsattr(fs))
	for _, v := range values {
		svg.printf(`%g `, v)
	}
	svg.printf(`" %s`, endstyle(s, emptyclose))
}
func (svg *SVG) FeColorMatrixHue(fs Filterspec, value float64, s ...string) {
	if value < -360 || value > 360 {
		value = 0
	}
	svg.printf(`<feColorMatrix %s type="hueRotate" values="%g" %s`,
		fsattr(fs), value, endstyle(s, emptyclose))
}
func (svg *SVG) FeColorMatrixSaturate(fs Filterspec, value float64, s ...string) {
	if value < 0 || value > 1 {
		value = 1
	}
	svg.printf(`<feColorMatrix %s type="saturate" values="%g" %s`,
		fsattr(fs), value, endstyle(s, emptyclose))
}
func (svg *SVG) FeColorMatrixLuminence(fs Filterspec, s ...string) {
	svg.printf(`<feColorMatrix %s type="luminenceToAlpha" %s`,
		fsattr(fs), endstyle(s, emptyclose))
}
func (svg *SVG) FeComponentTransfer() {
	svg.println(`<feComponentTransfer>`)
}
func (svg *SVG) FeCompEnd() {
	svg.println(`</feComponentTransfer>`)
}
func (svg *SVG) FeComposite(fs Filterspec, operator string, k1, k2, k3, k4 int, s ...string) {
	switch operator {
	case "over", "in", "out", "atop", "xor", "arithmetic":
		break
	default:
		operator = "over"
	}
	svg.printf(`<feComposite %s operator="%s" k1="%d" k2="%d" k3="%d" k4="%d" %s`,
		fsattr(fs), operator, k1, k2, k3, k4, endstyle(s, emptyclose))
}
func (svg *SVG) FeConvolveMatrix(fs Filterspec, matrix [9]int, s ...string) {
	svg.printf(`<feConvolveMatrix %s kernelMatrix="%d %d %d %d %d %d %d %d %d" %s`,
		fsattr(fs),
		matrix[0], matrix[1], matrix[2],
		matrix[3], matrix[4], matrix[5],
		matrix[6], matrix[7], matrix[8], endstyle(s, emptyclose))
}
func (svg *SVG) FeDiffuseLighting(fs Filterspec, scale, constant float64, s ...string) {
	svg.printf(`<feDiffuseLighting %s surfaceScale="%g" diffuseConstant="%g" %s`,
		fsattr(fs), scale, constant, endstyle(s, `>`))
}
func (svg *SVG) FeDiffEnd() {
	svg.println(`</feDiffuseLighting>`)
}
func (svg *SVG) FeDisplacementMap(fs Filterspec, scale float64, xchannel, ychannel string, s ...string) {
	svg.printf(`<feDisplacementMap %s scale="%g" xChannelSelector="%s" yChannelSelector="%s" %s`,
		fsattr(fs), scale, imgchannel(xchannel), ychannel, endstyle(s, emptyclose))
}