-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathocbf.lua
More file actions
118 lines (89 loc) · 2.75 KB
/
ocbf.lua
File metadata and controls
118 lines (89 loc) · 2.75 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
local unicode = require("unicode")
local ocbf = {}
local charpattern = utf8 and utf8.charpattern or "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
local function readstr(f)
local count, reason = f:read(1)
if not count then return nil, reason or "unexpected EOF" end
count = string.unpack(">B", count)
local data, reason = f:read(count)
if not data or #data ~= count then return nil, reason or "unexpected EOF" end
return data
end
function readchr(f)
local c1, reason = f:read(1)
if not c1 then return nil, reason or "unexpected EOF" end
local ctr, c = -1, math.max(c1:byte(), 128)
repeat
ctr = ctr + 1
c = (c - 128) * 2
until c < 128
local crest, reason = f:read(ctr)
if not crest or #crest ~= ctr then return nil, reason or "unexpected EOF" end
return c1 .. crest
end
function ocbf.load(path)
local font = {sizes = {}}
local f, reason = io.open(path, "rb")
if not f then return nil, reason end
if f:read(4) ~= "ocbf" then return nil, "bad signature" end
font.family, reason = readstr(f)
if not font.family then return nil, reason end
font.style, reason = readstr(f)
if not font.style then return nil, reason end
while true do
local char = readchr(f)
if not char then break end
local sizewidth, reason = f:read(2)
if not sizewidth or #sizewidth ~= 2 then
return nil, reason or "unexpected EOF"
end
local size, width = string.unpack(">BB", sizewidth)
local len = math.ceil(size * width / 8)
local data = f:read(len)
if not data or #data ~= len then return nil, reason or "unexpected EOF" end
if not font.sizes[size] then font.sizes[size] = {} end
font.sizes[size][char] = {}
font.sizes[size][char] = {width = width, data = data}
end
f:close()
return font
end
function ocbf.drawchar(set, font, size, char, x, y)
local char = font.sizes[size][char]
local i = 0
for by = 0, size - 1 do
for bx = 0, char.width - 1 do
local bytei = math.floor((by * char.width + bx) / 8)
local biti = 7 - (by * char.width + bx) % 8
local byte = string.byte(char.data:sub(bytei + 1, bytei + 1))
if byte >> biti & 1 == 1 then
set(bx + x, by + y, 1)
else
set(bx + x, by + y, 0)
end
i = i + 1
end
end
end
function ocbf.draw(set, font, size, str, x, y)
local ix = x
for i = 1, unicode.len(str) do
local char = unicode.sub(str, i, i)
if char == "\n" then
x = ix
y = y + size
else
ocbf.drawchar(set, font, size, char, x, y)
x = x + font.sizes[size][char].width
end
end
end
function ocbf.width(font, size, str)
local width = 0
for i = 1, unicode.len(str) do
local char = unicode.sub(str, i, i)
width = width + font.sizes[size][char].width
end
return width
end
return braille