ref: 628a97cd712e306c4748ed0ece977e7785e22421 gio/ui/text/measure.go -rw-r--r-- 1.7 KiB View raw
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// SPDX-License-Identifier: Unlicense OR MIT

package text

import (
	"fmt"
	"image"

	"gioui.org/ui"
	"gioui.org/ui/layout"
	"golang.org/x/image/math/fixed"
)

type Line struct {
	Text String
	// Width is the width of the line.
	Width fixed.Int26_6
	// Ascent is the height above the baseline.
	Ascent fixed.Int26_6
	// Descent is the height below the baseline, including
	// the line gap.
	Descent fixed.Int26_6
	// Bounds is the visible bounds of the line.
	Bounds fixed.Rectangle26_6
}

type String struct {
	String   string
	Advances []fixed.Int26_6
}

type Layout struct {
	Lines []Line
}

type LayoutOptions struct {
	MaxWidth   int
	SingleLine bool
}

type Face interface {
	Layout(str string, opts LayoutOptions) *Layout
	Path(str String) ui.MacroOp
}

type Alignment uint8

const (
	Start Alignment = iota
	End
	Center
)

func linesDimens(lines []Line) layout.Dimens {
	var width fixed.Int26_6
	var h int
	var baseline int
	if len(lines) > 0 {
		baseline = lines[0].Ascent.Ceil()
		var prevDesc fixed.Int26_6
		for _, l := range lines {
			h += (prevDesc + l.Ascent).Ceil()
			prevDesc = l.Descent
			if l.Width > width {
				width = l.Width
			}
		}
		h += lines[len(lines)-1].Descent.Ceil()
	}
	w := width.Ceil()
	return layout.Dimens{
		Size: image.Point{
			X: w,
			Y: h,
		},
		Baseline: baseline,
	}
}

func IsNewline(r rune) bool {
	return r == '\n'
}

func align(align Alignment, width fixed.Int26_6, maxWidth int) fixed.Int26_6 {
	mw := fixed.I(maxWidth)
	switch align {
	case Center:
		return fixed.I(((mw - width) / 2).Floor())
	case End:
		return fixed.I((mw - width).Floor())
	case Start:
		return 0
	default:
		panic(fmt.Errorf("unknown alignment %v", align))
	}
}