forked from tinygo-org/tinyfont
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconst2bit.go
More file actions
126 lines (112 loc) · 3.24 KB
/
const2bit.go
File metadata and controls
126 lines (112 loc) · 3.24 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
// Package const2bit is for fonts that use 2 bits per pixel.
package const2bit
import (
"image/color"
"tinygo.org/x/drivers"
"tinygo.org/x/tinyfont"
)
// Glyph is a struct that implements Glypher interface.
type Glyph struct {
Rune rune
Width uint8
Height uint8
XAdvance uint8
XOffset int8
YOffset int8
Bitmaps []byte
}
// Font is a struct that implements Fonter interface.
type Font struct {
BBox [4]int8 // width, height, minX, minY
Glyphs []Glyph
YAdvance uint8
OffsetMap string
Data string
Name string
glyph Glyph
}
// Draw sets a single glyph in the buffer of the display.
// TODO: allow the user to set the color
func (glyph Glyph) Draw(display drivers.Displayer, x int16, y int16, c color.RGBA) {
bitmapOffset := 0
bitmap := byte(0)
if len(glyph.Bitmaps) > 0 {
bitmap = glyph.Bitmaps[bitmapOffset]
}
bit := uint8(0)
for j := int16(0); j < int16(glyph.Height); j++ {
for i := int16(0); i < int16(glyph.Width); i++ {
switch bitmap & 0xC0 {
case 0xC0:
display.SetPixel(x+int16(glyph.XOffset)+i, y+int16(glyph.YOffset)+j, color.RGBA{0x00, 0x00, 0x00, 0xFF})
case 0x80:
display.SetPixel(x+int16(glyph.XOffset)+i, y+int16(glyph.YOffset)+j, color.RGBA{0x80, 0x80, 0x80, 0xFF})
case 0x40:
display.SetPixel(x+int16(glyph.XOffset)+i, y+int16(glyph.YOffset)+j, color.RGBA{0xD0, 0xD0, 0xD0, 0xFF})
default:
}
bitmap <<= 2
bit += 2
if bit > 7 {
bitmapOffset++
if bitmapOffset < len(glyph.Bitmaps) {
bitmap = glyph.Bitmaps[bitmapOffset]
}
bit = 0
}
}
}
}
// Info returns glyph information.
func (glyph Glyph) Info() tinyfont.GlyphInfo {
return tinyfont.GlyphInfo{
Rune: glyph.Rune,
Width: glyph.Width,
Height: glyph.Height,
XAdvance: glyph.XAdvance,
XOffset: glyph.XOffset,
YOffset: glyph.YOffset,
}
}
// GetYAdvance returns YAdvance of f.
func (f *Font) GetYAdvance() uint8 {
return f.YAdvance
}
// GetGlyph returns the glyph corresponding to the specified rune in the font.
// If the rune does not exist in the font, the glyph at index 0 will be returned as a fallback.
// Since there is only one glyph used for the return value in this package,
// concurrent access is not allowed. Normally, there is no issue when using it from tinyfont.
func (font *Font) GetGlyph(r rune) tinyfont.Glypher {
s := 0
e := len(font.OffsetMap)/6 - 1
found := false
for s <= e {
m := (s + e) / 2
r2 := rune(font.OffsetMap[m*6])<<16 + rune(font.OffsetMap[m*6+1])<<8 + rune(font.OffsetMap[m*6+2])
if r2 == r {
s = m
found = true
break
} else if r2 < r {
s = m + 1
} else {
e = m - 1
}
}
if !found {
s = 0
}
offset := uint32(font.OffsetMap[s*6+3])<<16 + uint32(font.OffsetMap[s*6+4])<<8 + uint32(font.OffsetMap[s*6+5])
sz := uint32(len(font.Data[offset+5:]))
if s*6+6 < len(font.OffsetMap) {
sz = uint32(font.OffsetMap[s*6+9])<<16 + uint32(font.OffsetMap[s*6+10])<<8 + uint32(font.OffsetMap[s*6+11]) - offset
}
font.glyph.Rune = r
font.glyph.Width = font.Data[offset+0]
font.glyph.Height = font.Data[offset+1]
font.glyph.XAdvance = font.Data[offset+2]
font.glyph.XOffset = int8(font.Data[offset+3])
font.glyph.YOffset = int8(font.Data[offset+4])
font.glyph.Bitmaps = []byte(font.Data[offset+5 : offset+5+sz])
return &(font.glyph)
}