Documentation ¶
Overview ¶
Package svg provides SVG rendering classes, I/O parsing: full SVG rendering
SVG currently supports most of SVG, but not:
- Flow
- Filter Effects
- 3D Perspective transforms
See gi/examples/svg for a basic SVG viewer app, using the svg.Editor, which will ultimately be expanded to support more advanced editing. Also in that directory are a number of test files that stress different aspects of rendering.
svg.NodeBase is the base type for all SVG elements -- unlike Widget nodes, SVG nodes do not use layout logic, and just draw directly into a parent SVG viewport, with cumulative transforms determining drawing position, etc. The BBox values are only valid after rendering for these nodes.
It uses srwiley/rasterx for SVG-compatible rasterization, and the gi.Paint interface for drawing.
The Path element uses a compiled bytecode version of the Data path for increased speed.
Index ¶
- Variables
- func ApplyCSSSVG(node gi.Node2D, key string, css ki.Props) bool
- func PathDataEnd(data []PathData) (vec gi.Vec2D, ang float32)
- func PathDataIterFunc(data []PathData, ...)
- func PathDataMinMax(data []PathData) (min, max gi.Vec2D)
- func PathDataNext(data []PathData, i *int) float32
- func PathDataRender(data []PathData, pc *gi.Paint, rs *gi.RenderState)
- func PathDataStart(data []PathData) (vec gi.Vec2D, ang float32)
- func PathDataValidate(pc *gi.Paint, data *[]PathData, errstr string) error
- func StyleCSS(node gi.Node2D, css ki.Props)
- func StyleSVG(gii gi.Node2D)
- type Circle
- type ClipPath
- type Editor
- type Ellipse
- type Filter
- type Flow
- type Group
- type Icon
- type IconMgr
- type IconSet
- type Line
- type Marker
- type MarkerUnits
- type NodeBase
- func (g *NodeBase) AsSVGNode() *NodeBase
- func (g *NodeBase) BBox2D() image.Rectangle
- func (g *NodeBase) ChildrenBBox2D() image.Rectangle
- func (g *NodeBase) ComputeBBox2D(parBBox image.Rectangle, delta image.Point)
- func (g *NodeBase) ComputeBBoxSVG()
- func (g *NodeBase) FindSVGURL(url string) gi.Node2D
- func (g *NodeBase) Init2D()
- func (g *NodeBase) Init2DBase()
- func (g *NodeBase) Layout2D(parBBox image.Rectangle, iter int) bool
- func (g *NodeBase) Marker(marker string) *Marker
- func (g *NodeBase) Move2D(delta image.Point, parBBox image.Rectangle)
- func (g *NodeBase) Paint() *gi.Paint
- func (g *NodeBase) ParentSVG() *SVG
- func (g *NodeBase) Render2D()
- func (g *NodeBase) Size2D(iter int)
- func (g *NodeBase) Style2D()
- type Path
- type PathCmds
- type PathData
- type Polygon
- type Polyline
- type Rect
- type SVG
- func (svg *SVG) DeleteAll()
- func (svg *SVG) FindNamedElement(name string) gi.Node2D
- func (svg *SVG) Init2D()
- func (svg *SVG) Layout2D(parBBox image.Rectangle, iter int) bool
- func (svg *SVG) OpenXML(filename string) error
- func (g *SVG) Paint() *gi.Paint
- func (svg *SVG) ReadXML(reader io.Reader) error
- func (svg *SVG) Render2D()
- func (svg *SVG) SetDPIXForm()
- func (svg *SVG) SetNormXForm()
- func (svg *SVG) Size2D(iter int)
- func (svg *SVG) Style2D()
- func (svg *SVG) StyleSVG()
- func (svg *SVG) UnmarshalXML(decoder *xml.Decoder, se xml.StartElement) error
- type Text
- type ViewBox
- type ViewBoxAlign
- type ViewBoxMeetOrSlice
- type ViewBoxPreserveAspectRatio
Constants ¶
This section is empty.
Variables ¶
var IconAutoOpen = true
IconAutoOpen controls auto-loading of icons -- can turn this off for debugging etc
var IconProps = ki.Props{ "background-color": color.Transparent, }
var KiT_Circle = kit.Types.AddType(&Circle{}, nil)
var KiT_ClipPath = kit.Types.AddType(&ClipPath{}, nil)
var KiT_Editor = kit.Types.AddType(&Editor{}, nil)
var KiT_Ellipse = kit.Types.AddType(&Ellipse{}, nil)
var KiT_Filter = kit.Types.AddType(&Filter{}, nil)
var KiT_Flow = kit.Types.AddType(&Flow{}, nil)
var KiT_Group = kit.Types.AddType(&Group{}, nil)
var KiT_Icon = kit.Types.AddType(&Icon{}, IconProps)
var KiT_Line = kit.Types.AddType(&Line{}, nil)
var KiT_Marker = kit.Types.AddType(&Marker{}, nil)
var KiT_MarkerUnits = kit.Enums.AddEnumAltLower(MarkerUnitsN, false, gi.StylePropProps, "")
var KiT_NodeBase = kit.Types.AddType(&NodeBase{}, NodeBaseProps)
var KiT_Path = kit.Types.AddType(&Path{}, nil)
var KiT_Polygon = kit.Types.AddType(&Polygon{}, nil)
var KiT_Polyline = kit.Types.AddType(&Polyline{}, nil)
var KiT_Rect = kit.Types.AddType(&Rect{}, nil)
var KiT_SVG = kit.Types.AddType(&SVG{}, nil)
var KiT_Text = kit.Types.AddType(&Text{}, nil)
var NodeBaseProps = ki.Props{ "base-type": true, }
var PathCmdMap = map[rune]PathCmds{ 'M': PcM, 'm': Pcm, 'L': PcL, 'l': Pcl, 'H': PcH, 'h': Pch, 'V': PcV, 'v': Pcv, 'C': PcC, 'c': Pcc, 'S': PcS, 's': Pcs, 'Q': PcQ, 'q': Pcq, 'T': PcT, 't': Pct, 'A': PcA, 'a': Pca, 'Z': PcZ, 'z': Pcz, }
PathCmdMap maps rune to path command
var PathCmdNMap = map[PathCmds]int{ PcM: 2, Pcm: 2, PcL: 2, Pcl: 2, PcH: 1, Pch: 1, PcV: 1, Pcv: 1, PcC: 6, Pcc: 6, PcS: 4, Pcs: 4, PcQ: 4, Pcq: 4, PcT: 2, Pct: 2, PcA: 7, Pca: 7, PcZ: 0, Pcz: 0, }
PathCmdNMap gives the number of points per each command
Functions ¶
func ApplyCSSSVG ¶
ApplyCSSSVG applies css styles to given node, using key to select sub-props from overall properties list
func PathDataEnd ¶
PathDataEnd gets the ending coords and angle from the path
func PathDataIterFunc ¶
func PathDataIterFunc(data []PathData, fun func(idx int, cmd PathCmds, ptIdx int, cx, cy float32) bool)
PathDataIterFunc traverses the path data and calls given function on each coordinate point, passing overall starting index of coords in data stream, command, index of the points within that command, and coord values (absolute, not relative, regardless of the command type) -- if function returns false, then traversal is aborted
func PathDataMinMax ¶
PathDataMinMax traverses the path data and extracts the min and max point coords
func PathDataNext ¶
PathDataNext gets the next path data point, incrementing the index -- ++ not an expression so its clunky
func PathDataRender ¶
func PathDataRender(data []PathData, pc *gi.Paint, rs *gi.RenderState)
PathDataRender traverses the path data and renders it using paint and render state -- we assume all the data has been validated and that n's are sufficient, etc
func PathDataStart ¶
PathDataStart gets the starting coords and angle from the path
func PathDataValidate ¶
PathDataValidate validates the path data and emits error messages on log
Types ¶
type Circle ¶
type Circle struct { NodeBase Pos gi.Vec2D `xml:"{cx,cy}" desc:"position of the center of the circle"` Radius float32 `xml:"r" desc:"radius of the circle"` }
Circle is a SVG circle
type ClipPath ¶
type ClipPath struct {
NodeBase
}
ClipPath is used for holding a path that renders as a clip path
type Editor ¶
type Editor struct { SVG Trans gi.Vec2D `desc:"view translation offset (from dragging)"` Scale float32 `desc:"view scaling (from zooming)"` SetDragCursor bool `desc:"has dragging cursor been set yet?"` }
Editor supports editing of SVG elements
func (*Editor) EditorEvents ¶
func (svg *Editor) EditorEvents()
EditorEvents handles svg editing events
func (*Editor) InitScale ¶
func (svg *Editor) InitScale()
InitScale ensures that Scale is initialized and non-zero
func (*Editor) SetTransform ¶
func (svg *Editor) SetTransform()
SetTransform sets the transform based on Trans and Scale values
type Ellipse ¶
type Ellipse struct { NodeBase Pos gi.Vec2D `xml:"{cx,cy}" desc:"position of the center of the ellipse"` Radii gi.Vec2D `xml:"{rx,ry}" desc:"radii of the ellipse in the horizontal, vertical axes"` }
Ellipse is a SVG ellipse
type Group ¶
type Group struct {
NodeBase
}
Group groups together SVG elements -- doesn't do much but provide a locus for properties etc
func (*Group) BBoxFromChildren ¶
BBoxFromChildren sets the Group BBox from children
type Icon ¶
type Icon struct { SVG Filename string `desc:"file name with full path for icon if loaded from file"` Rendered bool `` /* 160-byte string literal not displayed */ RendSize image.Point `json:"-" xml:"-" desc:"size at which we previously rendered"` }
svg.Icon is the actual SVG for a gi.Icon -- it should contain no color information -- it should just be a filled shape where the fill and stroke colors come from the surrounding context / paint settings. The rendered version is cached for a given size. Icons are always copied from an original source icon and then can be customized from there.
func (*Icon) CopyFromIcon ¶
CopyFromIcon copies from a source icon, typically one from a library -- preserves all the existing render state etc for the current icon, so that only a new render is required
func (*Icon) NeedsReRender ¶
NeedsReRender tests whether the last render parameters (size, color) have changed or not
type IconMgr ¶
type IconMgr struct { }
svg.IconMgr is THE implementation of the gi.IconMgr interface
func (*IconMgr) IconByName ¶
IconByName is main function to get icon by name -- looks in CurIconSet and falls back to DefaultIconSet if not found there -- returns error and logs a message if not found
type IconSet ¶
IconSet is a collection of icons
var CurIconSet *IconSet
CurIconSet is the current icon set -- defaults to default but can be changed to whatever you want
var DefaultIconSet *IconSet
DefaultIconSet is the default icon set, initialized by default
func MakeDefaultIcons ¶
func MakeDefaultIcons() *IconSet
func (*IconSet) OpenDefaultIcons ¶
func (*IconSet) OpenIconsFromPath ¶
OpenIconsFromPath scans for .svg icon files in given path, adding them to the given IconSet, just storing the filename for later lazy loading
type Line ¶
type Line struct { NodeBase Start gi.Vec2D `xml:"{x1,y1}" desc:"position of the start of the line"` End gi.Vec2D `xml:"{x2,y2}" desc:"position of the end of the line"` }
Line is a SVG line
type Marker ¶
type Marker struct { NodeBase RefPos gi.Vec2D `xml:"{refX,refY}" desc:"reference position to align the vertex position with, specified in ViewBox coordinates"` Size gi.Vec2D `xml:"{markerWidth,markerHeight}" desc:"size of marker to render, in Units units"` Units MarkerUnits `xml:"markerUnits" desc:"units to use"` ViewBox ViewBox `desc:"viewbox defines the internal coordinate system for the drawing elements within the marker"` Orient string `xml:"orient" desc:"orientation of the marker -- either 'auto' or an angle"` VertexPos gi.Vec2D `desc:"current vertex position"` VertexAngle float32 `desc:"current vertex angle in radians"` StrokeWidth float32 `desc:"current stroke width"` XForm gi.Matrix2D `desc:"net transform computed from settings and current values -- applied prior to rendering"` EffSize gi.Vec2D `desc:"effective size for actual rendering"` }
Marker represents marker elements that can be drawn along paths (arrow heads, etc)
type MarkerUnits ¶
type MarkerUnits int32
MarkerUnits specifies units to use for svg marker elements
const ( StrokeWidth MarkerUnits = iota UserSpaceOnUse MarkerUnitsN )
func (*MarkerUnits) FromString ¶
func (i *MarkerUnits) FromString(s string) error
func (MarkerUnits) MarshalJSON ¶
func (ev MarkerUnits) MarshalJSON() ([]byte, error)
func (MarkerUnits) String ¶
func (i MarkerUnits) String() string
func (*MarkerUnits) UnmarshalJSON ¶
func (ev *MarkerUnits) UnmarshalJSON(b []byte) error
type NodeBase ¶
type NodeBase struct { gi.Node2DBase Pnt gi.Paint `json:"-" xml:"-" desc:"full paint information for this node"` }
svg.NodeBase is an element within the SVG sub-scenegraph -- does not use layout logic -- just renders into parent SVG viewport
func (*NodeBase) ChildrenBBox2D ¶
func (*NodeBase) ComputeBBox2D ¶
func (*NodeBase) ComputeBBoxSVG ¶
func (g *NodeBase) ComputeBBoxSVG()
ComputeBBoxSVG is called by default in render to compute bounding boxes for gui interaction -- can only be done in rendering because that is when all the proper xforms are all in place -- VpBBox is intersected with parent SVG
func (*NodeBase) FindSVGURL ¶
FindSVGURL finds a url element in the parent SVG -- returns nil if not found -- can pass full 'url(#Name)' string
func (*NodeBase) Init2DBase ¶
func (g *NodeBase) Init2DBase()
Init2DBase handles basic node initialization -- Init2D can then do special things
func (*NodeBase) Marker ¶
Marker checks for a marker property of given name, or generic "marker" type, and if set, attempts to find that marker and return it
type Path ¶
type Path struct { NodeBase Data []PathData `` /* 171-byte string literal not displayed */ DataStr string `xml:"d" desc:"string version of the path data"` MinCoord gi.Vec2D `desc:"minimum coord in path -- computed in BBox2D"` MaxCoord gi.Vec2D `desc:"maximum coord in path -- computed in BBox2D"` }
Path renders SVG data sequences that can render just about anything
type PathCmds ¶
type PathCmds byte
PathCmds are the commands within the path SVG drawing data type
const ( // move pen, abs coords PcM PathCmds = iota // move pen, rel coords Pcm // lineto, abs PcL // lineto, rel Pcl // horizontal lineto, abs PcH // relative lineto, rel Pch // vertical lineto, abs PcV // vertical lineto, rel Pcv // Bezier curveto, abs PcC // Bezier curveto, rel Pcc // smooth Bezier curveto, abs PcS // smooth Bezier curveto, rel Pcs // quadratic Bezier curveto, abs PcQ // quadratic Bezier curveto, rel Pcq // smooth quadratic Bezier curveto, abs PcT // smooth quadratic Bezier curveto, rel Pct // elliptical arc, abs PcA // elliptical arc, rel Pca // close path PcZ // close path Pcz // error -- invalid command PcErr )
func PathDataNextCmd ¶
PathDataNextCmd gets the next path data command, incrementing the index -- ++ not an expression so its clunky
func PathDecodeCmd ¶
PathDecodeCmd decodes rune into corresponding command
func (*PathCmds) FromString ¶
func (PathCmds) MarshalJSON ¶
func (*PathCmds) UnmarshalJSON ¶
type PathData ¶
type PathData float32
PathData encodes the svg path data, using 32-bit floats which are converted into uint32 for path commands, and contain the command as the first 5 bits, and the remaining 27 bits are the number of data points following the path command to interpret as numbers.
func PathDataParse ¶
PathDataParse parses a string representation of the path data into compiled path data
type Polyline ¶
type Polyline struct { NodeBase Points []gi.Vec2D `xml:"points" desc:"the coordinates to draw -- does a moveto on the first, then lineto for all the rest"` }
Polyline is a SVG multi-line shape
type Rect ¶
type Rect struct { NodeBase Pos gi.Vec2D `xml:"{x,y}" desc:"position of the top-left of the rectangle"` Size gi.Vec2D `xml:"{width,height}" desc:"size of the rectangle"` Radius gi.Vec2D `xml:"{rx,ry}" desc:"radii for curved corners, as a proportion of width, height"` }
Rect is a SVG rectangle, optionally with rounded corners
type SVG ¶
type SVG struct { gi.Viewport2D ViewBox ViewBox `desc:"viewbox defines the coordinate system for the drawing"` Norm bool `` /* 130-byte string literal not displayed */ InvertY bool `` /* 181-byte string literal not displayed */ Pnt gi.Paint `json:"-" xml:"-" desc:"paint styles -- inherited by nodes"` Defs Group `desc:"all defs defined elements go here (gradients, symbols, etc)"` Title string `xml:"title" desc:"the title of the svg"` Desc string `xml:"desc" desc:"the description of the svg"` }
SVG is a viewport for containing SVG drawing objects, corresponding to the svg tag in html -- it provides its own bitmap for drawing into
func (*SVG) DeleteAll ¶
func (svg *SVG) DeleteAll()
DeleteAll deletes any existing elements in this svg
func (*SVG) ReadXML ¶
ReadXML reads XML-formatted SVG input from io.Reader, and uses xml.Decoder to create the SVG scenegraph for corresponding SVG drawing. Removes any existing content in SVG first. To process a byte slice, pass: bytes.NewReader([]byte(str)) -- all errors are logged and also returned.
func (*SVG) SetDPIXForm ¶
func (svg *SVG) SetDPIXForm()
SetDPIXForm sets a scaling transform to compensate for the dpi -- svg rendering is done within a 96 DPI context
func (*SVG) SetNormXForm ¶
func (svg *SVG) SetNormXForm()
SetNormXForm sets a scaling transform to make the entire viewbox to fit the viewport
func (*SVG) UnmarshalXML ¶
UnmarshalXML unmarshals the svg using xml.Decoder
type Text ¶
type Text struct { NodeBase Pos gi.Vec2D `xml:"{x,y}" desc:"position of the left, baseline of the text"` Width float32 `xml:"width" desc:"width of text to render if using word-wrapping"` Text string `xml:"text" desc:"text string to render"` Render gi.TextRender `xml:"-" json:"-" desc:"render version of text"` CharPosX []float32 `desc:"character positions along X axis, if specified"` CharPosY []float32 `desc:"character positions along Y axis, if specified"` CharPosDX []float32 `desc:"character delta-positions along X axis, if specified"` CharPosDY []float32 `desc:"character delta-positions along Y axis, if specified"` CharRots []float32 `desc:"character rotations, if specified"` TextLength float32 `desc:"author's computed text length, if specified -- we attempt to match"` AdjustGlyphs bool `desc:"in attempting to match TextLength, should we adjust glyphs in addition to spacing?"` }
Text renders SVG text-- it handles both text and tspan elements (a tspan is just nested under a parent text)
type ViewBox ¶
type ViewBox struct { Min gi.Vec2D `desc:"offset or starting point in parent Viewport2D"` Size gi.Vec2D `desc:"size of viewbox within parent Viewport2D"` PreserveAspectRatio ViewBoxPreserveAspectRatio `desc:"how to scale the view box within parent Viewport2D"` }
ViewBox is used in SVG to define the coordinate system
type ViewBoxAlign ¶
type ViewBoxAlign int32
ViewBoxAlign defines values for the PreserveAspectRatio alignment factor
const ( None ViewBoxAlign = 1 << iota // do not preserve uniform scaling XMin // align ViewBox.Min with smallest values of Viewport XMid // align ViewBox.Min with midpoint values of Viewport XMax // align ViewBox.Min+Size with maximum values of Viewport XMask ViewBoxAlign = XMin + XMid + XMax // mask for X values -- clear all X before setting new one YMin ViewBoxAlign = 1 << iota // align ViewBox.Min with smallest values of Viewport YMid // align ViewBox.Min with midpoint values of Viewport YMax // align ViewBox.Min+Size with maximum values of Viewport YMask ViewBoxAlign = YMin + YMid + YMax // mask for Y values -- clear all Y before setting new one )
type ViewBoxMeetOrSlice ¶
type ViewBoxMeetOrSlice int32
ViewBoxMeetOrSlice defines values for the PreserveAspectRatio meet or slice factor
const ( // Meet means the entire ViewBox is visible within Viewport, and it is // scaled up as much as possible to meet the align constraints Meet ViewBoxMeetOrSlice = iota // Slice means the entire ViewBox is covered by the ViewBox, and the // ViewBox is scaled down as much as possible, while still meeting the // align constraints Slice )
func (*ViewBoxMeetOrSlice) FromString ¶
func (i *ViewBoxMeetOrSlice) FromString(s string) error
func (ViewBoxMeetOrSlice) String ¶
func (i ViewBoxMeetOrSlice) String() string
type ViewBoxPreserveAspectRatio ¶
type ViewBoxPreserveAspectRatio struct { Align ViewBoxAlign `svg:"align" desc:"how to align x,y coordinates within viewbox"` MeetOrSlice ViewBoxMeetOrSlice `svg:"meetOrSlice" desc:"how to scale the view box relative to the viewport"` }
ViewBoxPreserveAspectRatio determines how to scale the view box within parent Viewport2D