1package glyph
2
3import (
4 "os"
5 "testing"
6)
7
8func testFace(t *testing.T) *Face {
9 t.Helper()
10 paths, err := FindFonts("monospace")
11 if err != nil {
12 t.Skip(err)
13 }
14 if _, err := os.Stat(paths[0]); err != nil {
15 t.Skip(err)
16 }
17 f, err := Load(paths, 16)
18 if err != nil {
19 t.Skip(err)
20 }
21 t.Cleanup(f.Close)
22 return f
23}
24
25func rowSum(f *Face, bmp []byte, y int) (sum int) {
26 for x := 0; x < f.CellW; x++ {
27 sum += int(bmp[y*f.CellW+x])
28 }
29 return
30}
31
32func TestUnderlineAndStrikeDrawFullWidthLines(t *testing.T) {
33 f := testFace(t)
34 plain := make([]byte, f.CellW*f.CellH)
35 f.Rasterize(' ', 0, plain) // a space: only the lines can ink
36 for _, b := range plain {
37 if b != 0 {
38 t.Fatal("a plain space must be empty")
39 }
40 }
41 for name, style := range map[string]Style{"underline": Underline, "strike": Strike} {
42 bmp := make([]byte, len(plain))
43 f.Rasterize(' ', style, bmp)
44 full := 0
45 for y := 0; y < f.CellH; y++ {
46 if rowSum(f, bmp, y) == 255*f.CellW {
47 full++
48 }
49 }
50 if full != f.thick {
51 t.Errorf("%s: %d full rows, want %d", name, full, f.thick)
52 }
53 }
54 both := make([]byte, len(plain))
55 f.Rasterize(' ', Underline|Strike, both)
56 var u, s []byte = make([]byte, len(plain)), make([]byte, len(plain))
57 f.Rasterize(' ', Underline, u)
58 f.Rasterize(' ', Strike, s)
59 for i := range both {
60 if both[i] != max(u[i], s[i]) {
61 t.Fatal("underline and strike must not overlap or cancel")
62 }
63 }
64}
65
66func TestItalicAndBoldPickAFontFile(t *testing.T) {
67 paths, err := FindFonts("monospace")
68 if err != nil {
69 t.Skip(err)
70 }
71 f := testFace(t)
72 // Each style slot must be usable even when the family lacks the file.
73 for style := Style(0); style <= fontBits; style++ {
74 bmp := make([]byte, f.CellW*f.CellH)
75 f.Rasterize('A', style, bmp)
76 ink := 0
77 for _, b := range bmp {
78 ink += int(b)
79 }
80 if ink == 0 {
81 t.Errorf("style %02b drew nothing (files: %v)", style, paths)
82 }
83 }
84}