package caption import ( "image" "image/color" "github.com/golang/freetype/truetype" "golang.org/x/image/draw" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) type Line struct { // collection of all text segments Data []Segment `json:"data"` // applies to all segments; avoid direct assignment and use SetFont instead Font []byte `json:"font"` // applies to all segments; avoid direct assignment and use SetFont instead Options *truetype.Options `json:"options"` // contains reference to parsed font, populated once per instance face font.Face } // SetFont clears line font cache and sets the new font. func (l *Line) SetFont(v []byte, opts *truetype.Options) { l.face = nil; l.Font = v; l.Options = opts } type Segment struct { Value string `json:"value"` Color color.Color `json:"color"` } func (l *Line) Render(frame draw.Image, x, y int) error { if l.face == nil { if len(l.Font) == 0 { l.SetFont(defaultFont, l.Options) } if f, err := truetype.Parse(l.Font); err != nil { return err } else { l.face = truetype.NewFace(f, l.Options) } } drawer := &font.Drawer{Dst: frame, Face: l.face, Dot: fixed.Point26_6{X: fixed.I(x), Y: fixed.I(y)}} for _, seg := range l.Data { drawer.Src = image.NewUniform(seg.Color) drawer.DrawString(seg.Value) } return nil }