1
2
3
4
5 package font_test
6
7 import (
8 "errors"
9 "testing"
10
11 stdfnt "golang.org/x/image/font"
12 "golang.org/x/image/font/sfnt"
13 "golang.org/x/image/math/fixed"
14 "gonum.org/v1/plot/font"
15 "gonum.org/v1/plot/font/liberation"
16 )
17
18 func TestFontExtends(t *testing.T) {
19 cache := font.NewCache(liberation.Collection())
20 for _, tc := range []struct {
21 font font.Font
22 want map[font.Length]font.Extents
23 }{
24
25
26 {
27 font: font.Font{Typeface: "Liberation", Variant: "Serif"},
28 want: map[font.Length]font.Extents{
29 10: {
30 Ascent: 8.9111328125,
31 Descent: 2.1630859375,
32 Height: 11.4990234375,
33 },
34 12: {
35 Ascent: 10.693359375,
36 Descent: 2.595703125,
37 Height: 13.798828125,
38 },
39 24: {
40 Ascent: 21.38671875,
41 Descent: 5.19140625,
42 Height: 27.59765625,
43 },
44 },
45 },
46 {
47 font: font.Font{Typeface: "Liberation", Variant: "Serif", Weight: stdfnt.WeightBold},
48 want: map[font.Length]font.Extents{
49 10: {
50 Ascent: 8.9111328125,
51 Descent: 2.1630859375,
52 Height: 11.4990234375,
53 },
54 12: {
55 Ascent: 10.693359375,
56 Descent: 2.595703125,
57 Height: 13.798828125,
58 },
59 24: {
60 Ascent: 21.38671875,
61 Descent: 5.19140625,
62 Height: 27.59765625,
63 },
64 },
65 },
66 {
67 font: font.Font{Typeface: "Liberation", Variant: "Serif", Style: stdfnt.StyleItalic},
68 want: map[font.Length]font.Extents{
69 10: {
70 Ascent: 8.9111328125,
71 Descent: 2.1630859375,
72 Height: 11.4990234375,
73 },
74 12: {
75 Ascent: 10.693359375,
76 Descent: 2.595703125,
77 Height: 13.798828125,
78 },
79 24: {
80 Ascent: 21.38671875,
81 Descent: 5.19140625,
82 Height: 27.59765625,
83 },
84 },
85 },
86 {
87 font: font.Font{Typeface: "Liberation", Variant: "Serif", Style: stdfnt.StyleItalic, Weight: stdfnt.WeightBold},
88 want: map[font.Length]font.Extents{
89 10: {
90 Ascent: 8.9111328125,
91 Descent: 2.1630859375,
92 Height: 11.4990234375,
93 },
94 12: {
95 Ascent: 10.693359375,
96 Descent: 2.595703125,
97 Height: 13.798828125,
98 },
99 24: {
100 Ascent: 21.38671875,
101 Descent: 5.19140625,
102 Height: 27.59765625,
103 },
104 },
105 },
106 } {
107 for _, size := range []font.Length{10, 12, 24} {
108 fnt := cache.Lookup(tc.font, size)
109 got := fnt.Extents()
110 if got, want := got, tc.want[size]; got != want {
111 t.Errorf(
112 "invalid font extents for %q, size=%v:\ngot= %#v\nwant=%#v",
113 tc.font.Name(), size, got, want,
114 )
115 }
116 }
117 }
118 }
119
120 func TestFontWidth(t *testing.T) {
121 cache := font.NewCache(liberation.Collection())
122 fnt := cache.Lookup(font.Font{Typeface: "Liberation", Variant: "Serif"}, 12)
123
124 for _, tc := range []struct {
125 txt string
126 want font.Length
127 }{
128
129
130 {" ", 3},
131 {"i", 3.333984375},
132 {"q", 6},
133 {"A", 8.666015625},
134 {"F", 6.673828125},
135 {"T", 7.330078125},
136 {"V", 8.666015625},
137 {"Δ", 7.716796875},
138 {"∇", 9.333984375},
139 {" ", 6},
140 {"AA", 17.33203125},
141 {"Aq", 14.666015625},
142 {"Fi", 10.0078125},
143 {"Ti", 10.2421875},
144 {"AV", 15.78515625},
145 {"A∇", 18},
146 {"VA", 15.78515625},
147 {"VΔ", 16.3828125},
148 {"∇Δ", 17.05078125},
149 {" ", 9},
150 {"T T", 17.2265625},
151 } {
152 t.Run(tc.txt, func(t *testing.T) {
153 got := fnt.Width(tc.txt)
154 if got, want := got, tc.want; got != want {
155 t.Fatalf(
156 "invalid width: got=%v, want=%v",
157 got, want,
158 )
159 }
160 })
161 }
162 }
163
164 func TestFontKern(t *testing.T) {
165 cache := font.NewCache(liberation.Collection())
166 fnt := cache.Lookup(font.Font{Typeface: "Liberation", Variant: "Serif"}, 12)
167
168 for _, tc := range []struct {
169 txt string
170 want fixed.Int26_6
171 }{
172
173
174 {"AV", -264},
175 {"A∇", 0},
176 {"AΔ", 0},
177 {"AA", 0},
178 {"VA", -264},
179 {"∇A", 0},
180 {"∇Δ", 0},
181 } {
182 t.Run(tc.txt, func(t *testing.T) {
183 var (
184 t0 = rune(tc.txt[0])
185 t1 = rune(tc.txt[1])
186
187 buf sfnt.Buffer
188 ppem = fixed.Int26_6(fnt.Face.UnitsPerEm())
189 )
190
191 i0, err := fnt.Face.GlyphIndex(&buf, t0)
192 if err != nil {
193 t.Fatalf("could not find glyph %q: %+v", t0, err)
194 }
195 i1, err := fnt.Face.GlyphIndex(&buf, t1)
196 if err != nil {
197 t.Fatalf("could not find glyph %q: %+v", t1, err)
198 }
199 kern, err := fnt.Face.Kern(&buf, i0, i1, ppem, stdfnt.HintingNone)
200 switch {
201 case err == nil:
202
203 case errors.Is(err, sfnt.ErrNotFound):
204 kern = 0
205 default:
206 t.Fatalf("could not find kerning for %q/%q: %+v", t0, t1, err)
207 }
208
209 if got, want := kern, tc.want; got != want {
210 t.Fatalf("invalid kerning: got=%v, want=%v", got, want)
211 }
212 })
213 }
214 }
215
216 func TestFontName(t *testing.T) {
217 for _, tc := range []struct {
218 font *font.Font
219 want string
220 }{
221 {
222 font: &font.Font{
223 Typeface: "Liberation",
224 Variant: "Sans",
225 Style: stdfnt.StyleNormal,
226 Weight: stdfnt.WeightNormal,
227 },
228 want: "LiberationSans-Regular",
229 },
230 {
231 font: &font.Font{
232 Typeface: "Liberation",
233 Variant: "Sans",
234 Style: stdfnt.StyleItalic,
235 Weight: stdfnt.WeightNormal,
236 },
237 want: "LiberationSans-Italic",
238 },
239 {
240 font: &font.Font{
241 Typeface: "Liberation",
242 Variant: "Sans",
243 Style: stdfnt.StyleNormal,
244 Weight: stdfnt.WeightBold,
245 },
246 want: "LiberationSans-Bold",
247 },
248 {
249 font: &font.Font{
250 Typeface: "Liberation",
251 Variant: "Sans",
252 Style: stdfnt.StyleItalic,
253 Weight: stdfnt.WeightBold,
254 },
255 want: "LiberationSans-BoldItalic",
256 },
257 {
258 font: &font.Font{
259 Typeface: "Liberation",
260 Variant: "Mono",
261 Style: stdfnt.StyleNormal,
262 Weight: stdfnt.WeightNormal,
263 },
264 want: "LiberationMono-Regular",
265 },
266 {
267 font: &font.Font{
268 Typeface: "Liberation",
269 Variant: "Mono",
270 Style: stdfnt.StyleItalic,
271 Weight: stdfnt.WeightNormal,
272 },
273 want: "LiberationMono-Italic",
274 },
275 {
276 font: &font.Font{
277 Typeface: "Liberation",
278 Variant: "Mono",
279 Style: stdfnt.StyleNormal,
280 Weight: stdfnt.WeightBold,
281 },
282 want: "LiberationMono-Bold",
283 },
284 {
285 font: &font.Font{
286 Typeface: "Liberation",
287 Variant: "Mono",
288 Style: stdfnt.StyleItalic,
289 Weight: stdfnt.WeightBold,
290 },
291 want: "LiberationMono-BoldItalic",
292 },
293 } {
294 got := tc.font.Name()
295 if got != tc.want {
296 t.Errorf("invalid name: got=%q, want=%q", got, tc.want)
297 }
298 }
299 }
300
View as plain text