-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmisc.go
More file actions
139 lines (123 loc) · 4.53 KB
/
misc.go
File metadata and controls
139 lines (123 loc) · 4.53 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package etxt
import (
"strconv"
"github.com/tinne26/etxt/fract"
"golang.org/x/image/font/sfnt"
)
// Helper types, wrappers, aliases and functions.
// A handy type alias for [sfnt.Font] so you don't need to
// import it separately when working with etxt.
type Font = sfnt.Font
// Glyph indices are used to specify which font glyph are we working
// with. They allow us to reference font glyphs that aren't mapped
// to any unicode code point (rune).
//
// This type is a direct alias of [sfnt.GlyphIndex] so you don't have
// to import a separate package when working with custom functions
// for [RendererGlyph.SetDrawFunc](). Everywhere else in the documentation
// [sfnt.GlyphIndex] is used, but they are completely interchangeable.
type GlyphIndex = sfnt.GlyphIndex
// See [RendererTwine.RegisterFont]() and related functions.
//
// When using multiple fonts, you are encouraged to define
// and use your own named constants within the relevant context.
// For example:
//
// const (
// RegularFont etxt.FontIndex = iota
// BoldFont
// ItalicFont
// )
type fontIndex uint8
// Special value for [RendererTwine.RegisterFont]().
//const NextFontIndex FontIndex = 255
// Quantization levels are used to control the trade-off between
// memory usage and glyph positioning precision. Less theoretically:
// - A font is a collection of glyph outlines. Each time we want to
// draw a glyph at a specific size, we need to rasterize its outline
// into a bitmap. That's expensive, so we want to cache the bitmaps.
// - Now we have some text and we want to start drawing each letter
// one after another, but... most of the time, the glyph positions
// won't align to the pixel grid perfectly. Should we force this
// alignment? Or should we rasterize glyph variants for each subposition?
//
// The answer is that it depends on what we are trying to do. Quantization
// levels allow us to adjust the number of positional variants we want to
// consider for each glyph. More variants mean higher memory usage. Less
// variants mean lower positioning precision.
//
// Quantization levels can be adjusted with [RendererFract.SetHorzQuantization]()
// and [RendererFract.SetVertQuantization](), though in general they are not
// something you should be touching unless you know what you are doing.
//
// Only the equispaced quantization values are given. Other values like
// [fract.Unit](22) (which approximates one third of a pixel, ceil(64/3))
// could also work in theory, but in practice they lead to implementation
// complications that are simply not worth it.
const (
QtNone = fract.Unit(1) // full glyph position resolution (1/64ths of a pixel)
Qt32th = fract.Unit(2) // quantize glyph positions to 1/32ths of a pixel
Qt16th = fract.Unit(4) // quantize glyph positions to 1/16ths of a pixel
Qt8th = fract.Unit(8) // quantize glyph positions to 1/ 8ths of a pixel
Qt4th = fract.Unit(16) // quantize glyph positions to 1/ 4ths of a pixel
QtHalf = fract.Unit(32) // quantize glyph positions to half of a pixel
QtFull = fract.Unit(64) // full glyph position quantization
)
// Renderers can have their text direction configured as
// left-to-right or right-to-left. See [Renderer.SetDirection]()
// for further context and details.
//
// If necessary, directions can also be casted directly to
// [unicode/bidi] directions:
//
// bidi.Direction(etxt.LeftToRight).
//
// [unicode/bidi]: https://pkg.go.dev/golang.org/x/text/unicode/bidi
type Direction int8
const (
LeftToRight Direction = iota
RightToLeft
textDirectionUnexportedMixed
textDirectionUnexportedNeutral
)
// Returns the string representation of the [Direction]
// (e.g., "LeftToRight", "RightToLeft").
func (self Direction) String() string {
switch self {
case LeftToRight:
return "LeftToRight"
case RightToLeft:
return "RightToLeft"
case textDirectionUnexportedMixed:
return "Mixed"
case textDirectionUnexportedNeutral:
return "Neutral"
default:
return "UnknownTextDirection"
}
}
// --- misc helpers ---
// can replace with max() when minimum version reaches go1.21
func maxInt(a, b int) int {
if a >= b {
return a
}
return b
}
func runeToUnicodeCode(r rune) string {
return "\\u" + strconv.FormatInt(int64(r), 16)
}
func ensureSliceSize[T any](slice []T, size int) []T {
// easy case: slice is big enough already
if len(slice) >= size {
return slice
}
// see if we have enough capacity...
if cap(slice) >= size {
return slice[:size]
} else { // ...or grow slice otherwise
slice = slice[:cap(slice)]
growth := size - len(slice)
return append(slice, make([]T, growth)...)
}
}