Files
prevara/text.go

80 lines
1.7 KiB
Go

package gel
import (
"image"
"gioui.org/font"
l "gioui.org/layout"
"gioui.org/op"
"gioui.org/op/clip"
"gioui.org/text"
"gioui.org/unit"
"golang.org/x/image/math/fixed"
)
// Text is a widget for laying out and drawing text.
type Text struct {
*Window
// alignment specify the text alignment.
alignment text.Alignment
// maxLines limits the number of lines. Zero means no limit.
maxLines int
}
func (w *Window) Text() *Text {
return &Text{Window: w}
}
// Alignment sets the alignment for the text
func (t *Text) Alignment(alignment text.Alignment) *Text {
t.alignment = alignment
return t
}
// MaxLines sets the alignment for the text
func (t *Text) MaxLines(maxLines int) *Text {
t.maxLines = maxLines
return t
}
func (t *Text) Fn(gtx l.Context, s *text.Shaper, fnt font.Font, size unit.Sp, txt string) l.Dimensions {
cs := gtx.Constraints
textSize := fixed.I(gtx.Sp(size))
s.LayoutString(text.Parameters{
Font: fnt,
PxPerEm: textSize,
MaxLines: t.maxLines,
Alignment: t.alignment,
MaxWidth: cs.Max.X,
MinWidth: cs.Min.X,
Locale: gtx.Locale,
}, txt)
m := op.Record(gtx.Ops)
viewport := image.Rectangle{Max: cs.Max}
it := GlyphIterator{
Viewport: viewport,
MaxLines: t.maxLines,
}
var glyphs [32]text.Glyph
line := glyphs[:0]
for g, ok := s.NextGlyph(); ok; g, ok = s.NextGlyph() {
var ok bool
if line, ok = it.PaintGlyph(gtx, s, g, line); !ok {
break
}
}
call := m.Stop()
viewport.Min = viewport.Min.Add(it.Padding.Min)
viewport.Max = viewport.Max.Add(it.Padding.Max)
clipStack := clip.Rect(viewport).Push(gtx.Ops)
call.Add(gtx.Ops)
dims := l.Dimensions{Size: it.Bounds.Size()}
dims.Size = cs.Constrain(dims.Size)
dims.Baseline = dims.Size.Y - it.Baseline
clipStack.Pop()
return dims
}