~eliasnaur/gio

054668372093804f555c23890480b49a54207041 — Elias Naur 2 years ago 28f53d8
ui/text: add LayoutOptions

Signed-off-by: Elias Naur <mail@eliasnaur.com>
4 files changed, 22 insertions(+), 19 deletions(-)

M ui/measure/measure.go
M ui/text/editor.go
M ui/text/label.go
M ui/text/measure.go
M ui/measure/measure.go => ui/measure/measure.go +14 -16
@@ 34,11 34,10 @@ type cachedPath struct {
}

type layoutKey struct {
	f          *sfnt.Font
	ppem       fixed.Int26_6
	str        string
	singleLine bool
	maxWidth   int
	f    *sfnt.Font
	ppem fixed.Int26_6
	str  string
	opts text.LayoutOptions
}

type pathKey struct {


@@ 102,21 101,20 @@ func (f *Faces) init() {
	f.layoutCache = make(map[layoutKey]cachedLayout)
}

func (f *textFace) Layout(str string, singleLine bool, maxWidth int) *text.Layout {
func (f *textFace) Layout(str string, opts text.LayoutOptions) *text.Layout {
	ppem := fixed.Int26_6(f.faces.Config.Val(f.size)*64 + .5)
	lk := layoutKey{
		f:          f.font.Font,
		ppem:       ppem,
		str:        str,
		singleLine: singleLine,
		maxWidth:   maxWidth,
		f:    f.font.Font,
		ppem: ppem,
		str:  str,
		opts: opts,
	}
	if l, ok := f.faces.layoutCache[lk]; ok {
		l.active = true
		f.faces.layoutCache[lk] = l
		return l.layout
	}
	l := layoutText(ppem, str, f.font, singleLine, maxWidth)
	l := layoutText(ppem, str, f.font, opts)
	f.faces.layoutCache[lk] = cachedLayout{active: true, layout: l}
	return l
}


@@ 138,7 136,7 @@ func (f *textFace) Path(str text.String) ui.BlockOp {
	return p
}

func layoutText(ppem fixed.Int26_6, str string, f *opentype, singleLine bool, maxWidth int) *text.Layout {
func layoutText(ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOptions) *text.Layout {
	m := f.Metrics(ppem)
	lineTmpl := text.Line{
		Ascent: m.Ascent,


@@ 149,8 147,8 @@ func layoutText(ppem fixed.Int26_6, str string, f *opentype, singleLine bool, ma
	}
	var lines []text.Line
	maxDotX := fixed.Int26_6(math.MaxInt32)
	if maxWidth != ui.Inf {
		maxDotX = fixed.I(maxWidth)
	if opts.MaxWidth != ui.Inf {
		maxDotX = fixed.I(opts.MaxWidth)
	}
	type state struct {
		r     rune


@@ 175,7 173,7 @@ func layoutText(ppem fixed.Int26_6, str string, f *opentype, singleLine bool, ma
	for prev.idx < len(str) {
		c, s := utf8.DecodeRuneInString(str[prev.idx:])
		nl := text.IsNewline(c)
		if singleLine && nl {
		if opts.SingleLine && nl {
			nl = false
			c = ' '
			s = 1

M ui/text/editor.go => ui/text/editor.go +1 -1
@@ 302,7 302,7 @@ func (e *Editor) moveCoord(pos image.Point) {
}

func (e *Editor) layoutText() {
	textLayout := e.Face.Layout(e.rr.String(), e.SingleLine, e.maxWidth)
	textLayout := e.Face.Layout(e.rr.String(), LayoutOptions{SingleLine: e.SingleLine, MaxWidth: e.maxWidth})
	lines := textLayout.Lines
	dims := linesDimens(lines)
	for i := 0; i < len(lines)-1; i++ {

M ui/text/label.go => ui/text/label.go +1 -1
@@ 81,7 81,7 @@ func (l *lineIterator) Next() (String, f32.Point, bool) {
}

func (l Label) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
	textLayout := l.Face.Layout(l.Text, false, cs.Width.Max)
	textLayout := l.Face.Layout(l.Text, LayoutOptions{MaxWidth: cs.Width.Max})
	lines := textLayout.Lines
	if max := l.MaxLines; max > 0 && len(lines) > max {
		lines = lines[:max]

M ui/text/measure.go => ui/text/measure.go +6 -1
@@ 33,8 33,13 @@ type Layout struct {
	Lines []Line
}

type LayoutOptions struct {
	MaxWidth   int
	SingleLine bool
}

type Face interface {
	Layout(str string, singleLine bool, maxWidth int) *Layout
	Layout(str string, opts LayoutOptions) *Layout
	Path(str String) ui.BlockOp
}