font-web.lua /size: 6154 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
font-otr
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to font-ini.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
-- Okay, compressing fonts this way is rather simple but one might wonder what the gain
10
-- is in this time of 4K youtube movies and most of the web pages wasting space and
11
-- bandwidth on advertisements. For version 2 we can use "woff2_decompress" from google
12
-- and in a tex environment one can as well store the ttf/otf files in the tex tree. So,
13
-- eventually we might even remove this code when version 1 is obsolete.
14 15
local
ioopen
=
io
.
open
16
local
replacesuffix
=
file
.
replacesuffix
17 18
local
readers
=
fonts
and
fonts
.
handlers
.
otf
.
readers
19 20
local
streamreader
=
readers
and
readers
.
streamreader
or
utilities
.
files
21
local
streamwriter
=
readers
and
readers
.
streamwriter
or
utilities
.
files
22 23
local
readstring
=
streamreader
.
readstring
24
local
readcardinal2
=
streamreader
.
readcardinal2
25
local
readcardinal4
=
streamreader
.
readcardinal4
26
local
getsize
=
streamreader
.
getsize
27
local
setposition
=
streamreader
.
setposition
28
local
getposition
=
streamreader
.
getposition
29 30
local
writestring
=
streamwriter
.
writestring
31
local
writecardinal4
=
streamwriter
.
writecardinal4
32
local
writecardinal2
=
streamwriter
.
writecardinal2
33
local
writebyte
=
streamwriter
.
writebyte
34 35
local
decompress
=
zlib
.
decompress
36 37
directives
.
register
(
"
fonts.streamreader
"
,
function
(
)
38 39
streamreader
=
utilities
.
streams
40 41
readstring
=
streamreader
.
readstring
42
readcardinal2
=
streamreader
.
readcardinal2
43
readcardinal4
=
streamreader
.
readcardinal4
44
getsize
=
streamreader
.
getsize
45
setposition
=
streamreader
.
setposition
46
getposition
=
streamreader
.
getposition
47 48
end
)
49 50
local
infotags
=
{
51
[
"
os/2
"
]
=
true
,
52
[
"
head
"
]
=
true
,
53
[
"
maxp
"
]
=
true
,
54
[
"
hhea
"
]
=
true
,
55
[
"
hmtx
"
]
=
true
,
56
[
"
post
"
]
=
true
,
57
[
"
cmap
"
]
=
true
,
58
}
59 60
local
report
=
logs
.
reporter
(
"
fonts
"
,
"
woff
"
)
61 62
local
runner
=
sandbox
.
registerrunner
{
63
name
=
"
woff2otf
"
,
64
method
=
"
execute
"
,
65
program
=
"
woff2_decompress
"
,
66
template
=
"
%inputfile% %outputfile%
"
,
67
reporter
=
report
,
68
checkers
=
{
69
inputfile
=
"
readable
"
,
70
outputfile
=
"
writable
"
,
71
}
72
}
73 74
local
function
woff2otf
(
inpname
,
outname
,
infoonly
)
75 76
local
outname
=
outname
or
replacesuffix
(
inpname
,
"
otf
"
)
77
local
inp
=
ioopen
(
inpname
,
"
rb
"
)
78 79
if
not
inp
then
80
report
(
"
invalid input file %a
"
,
inpname
)
81
return
82
end
83 84
local
signature
=
readstring
(
inp
,
4
)
85 86
if
not
(
signature
=
=
"
wOFF
"
or
signature
=
=
"
wOF2
"
)
then
87
inp
:
close
(
)
88
report
(
"
invalid signature in %a
"
,
inpname
)
89
return
90
end
91 92
local
flavor
=
readstring
(
inp
,
4
)
93 94
if
not
(
flavor
=
=
"
OTTO
"
or
flavor
=
=
"
true
"
or
flavor
=
=
"
\0\1\0\0
"
)
then
95
inp
:
close
(
)
96
report
(
"
unsupported flavor %a in %a
"
,
flavor
,
inpname
)
97
return
98
end
99 100
if
signature
=
=
"
wOF2
"
then
101
inp
:
close
(
)
102
if
false
then
103
if
runner
then
104
runner
{
105
inputfile
=
inpname
,
106
outputfile
=
outname
,
107
}
108
end
109
return
outname
,
flavor
110
else
111
report
(
"
skipping version 2 file %a
"
,
inpname
)
112
return
113
end
114
end
115 116
local
out
=
ioopen
(
outname
,
"
wb
"
)
117 118
if
not
out
then
119
inp
:
close
(
)
120
report
(
"
invalid output file %a
"
,
outname
)
121
return
122
end
123 124
local
header
=
{
125
signature
=
signature
,
126
flavor
=
flavor
,
127
length
=
readcardinal4
(
inp
)
,
128
numtables
=
readcardinal2
(
inp
)
,
129
reserved
=
readcardinal2
(
inp
)
,
130
totalsfntsize
=
readcardinal4
(
inp
)
,
131
majorversion
=
readcardinal2
(
inp
)
,
132
minorversion
=
readcardinal2
(
inp
)
,
133
metaoffset
=
readcardinal4
(
inp
)
,
134
metalength
=
readcardinal4
(
inp
)
,
135
metaoriglength
=
readcardinal4
(
inp
)
,
136
privoffset
=
readcardinal4
(
inp
)
,
137
privlength
=
readcardinal4
(
inp
)
,
138
}
139 140
local
entries
=
{
}
141 142
for
i
=
1
,
header
.
numtables
do
143
local
entry
=
{
144
tag
=
readstring
(
inp
,
4
)
,
145
offset
=
readcardinal4
(
inp
)
,
146
compressed
=
readcardinal4
(
inp
)
,
147
size
=
readcardinal4
(
inp
)
,
148
checksum
=
readcardinal4
(
inp
)
,
149
}
150
if
not
infoonly
or
infotags
[
lower
(
entry
.
tag
)
]
then
151
entries
[
#
entries
+
1
]
=
entry
152
end
153
end
154 155
local
nofentries
=
#
entries
156
local
entryselector
=
0
-- we don't need these
157
local
searchrange
=
0
-- we don't need these
158
local
rangeshift
=
0
-- we don't need these
159 160
writestring
(
out
,
flavor
)
161
writecardinal2
(
out
,
nofentries
)
162
writecardinal2
(
out
,
entryselector
)
163
writecardinal2
(
out
,
searchrange
)
164
writecardinal2
(
out
,
rangeshift
)
165 166
local
offset
=
12
+
nofentries
*
16
167
local
offsets
=
{
}
168 169
for
i
=
1
,
nofentries
do
170
local
entry
=
entries
[
i
]
171
local
size
=
entry
.
size
172
writestring
(
out
,
entry
.
tag
)
173
writecardinal4
(
out
,
entry
.
checksum
)
174
writecardinal4
(
out
,
offset
)
-- the new offset
175
writecardinal4
(
out
,
size
)
176
offsets
[
i
]
=
offset
177
offset
=
offset
+
size
178
local
p
=
4
-
offset
%
4
179
if
p
>
0
then
180
offset
=
offset
+
p
181
end
182
end
183 184
for
i
=
1
,
nofentries
do
185
local
entry
=
entries
[
i
]
186
local
offset
=
offsets
[
i
]
187
local
size
=
entry
.
size
188
setposition
(
inp
,
entry
.
offset
+
1
)
189
local
data
=
readstring
(
inp
,
entry
.
compressed
)
190
if
#
data
~
=
size
then
191
data
=
decompress
(
data
)
192
end
193
setposition
(
out
,
offset
+
1
)
194
writestring
(
out
,
data
)
195
local
p
=
4
-
offset
+
size
%
4
196
if
p
>
0
then
197
for
i
=
1
,
p
do
198
writebyte
(
out
,
0
)
199
end
200
end
201
end
202 203
inp
:
close
(
)
204
out
:
close
(
)
205 206
return
outname
,
flavor
207 208
end
209 210
if
readers
then
211
readers
.
woff2otf
=
woff2otf
212
else
213
return
woff2otf
214
end
215