font-fbk.lmt /size: 16 Kb    last modification: 2021-10-28 13:51
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
font-fbk
'
]
=
{
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
local
cos
,
tan
,
rad
,
format
=
math
.
cos
,
math
.
tan
,
math
.
rad
,
string
.
format
10
local
utfbyte
,
utfchar
=
utf
.
byte
,
utf
.
char
11
local
next
=
next
12 13
--[[ldx-- 14<p>This is very experimental code!</p> 15--ldx]]
--
16 17
local
trace_visualize
=
false
trackers
.
register
(
"
fonts.composing.visualize
"
,
function
(
v
)
trace_visualize
=
v
end
)
18
local
trace_define
=
false
trackers
.
register
(
"
fonts.composing.define
"
,
function
(
v
)
trace_define
=
v
end
)
19 20
local
report
=
logs
.
reporter
(
"
fonts
"
,
"
combining
"
)
21 22
local
allocate
=
utilities
.
storage
.
allocate
23 24
local
fonts
=
fonts
25
local
handlers
=
fonts
.
handlers
26
local
constructors
=
fonts
.
constructors
27
local
helpers
=
fonts
.
helpers
28 29
local
otf
=
handlers
.
otf
30
local
afm
=
handlers
.
afm
31
local
registerotffeature
=
otf
.
features
.
register
32
local
registerafmfeature
=
afm
.
features
.
register
33 34
local
addotffeature
=
otf
.
addfeature
35 36
local
unicodecharacters
=
characters
.
data
37
local
unicodefallbacks
=
characters
.
fallbacks
38 39
local
vfcommands
=
helpers
.
commands
40
local
charcommand
=
vfcommands
.
char
41
local
rightcommand
=
vfcommands
.
right
42
local
downcommand
=
vfcommands
.
down
43
local
upcommand
=
vfcommands
.
up
44
local
push
=
vfcommands
.
push
45
local
pop
=
vfcommands
.
pop
46 47
local
force_combining
=
false
-- just for demo purposes (see mk)
48
local
fraction
=
0
.
15
-- 30 units for lucida
49 50
-- todo: we also need to update the feature hashes ... i'll do that when i'm in the mood
51
-- and/or when i need it
52 53
local
function
composecharacters
(
tfmdata
)
54
-- this assumes that slot 1 is self, there will be a proper self some day
55
local
characters
=
tfmdata
.
characters
56
local
descriptions
=
tfmdata
.
descriptions
57
local
parameters
=
tfmdata
.
parameters
58
local
properties
=
tfmdata
.
properties
59
local
Xdesc
=
descriptions
[
utfbyte
(
"
X
"
)
]
60
local
xdesc
=
descriptions
[
utfbyte
(
"
x
"
)
]
61
if
Xdesc
and
xdesc
then
62
local
scale
=
parameters
.
factor
or
1
63
local
deltaxheight
=
scale
*
(
Xdesc
.
boundingbox
[
4
]
-
xdesc
.
boundingbox
[
4
]
)
64
local
extraxheight
=
fraction
*
deltaxheight
-- maybe use compose value
65
local
italicfactor
=
parameters
.
italicfactor
or
0
66
local
red
,
green
,
blue
,
black
67
if
trace_visualize
then
68
red
=
{
"
startcolor
"
,
"
red
"
}
69
green
=
{
"
startcolor
"
,
"
green
"
}
70
blue
=
{
"
startcolor
"
,
"
blue
"
}
71
black
=
{
"
stopcolor
"
}
72
end
73
local
compose
=
fonts
.
goodies
.
getcompositions
(
tfmdata
)
74
if
compose
and
trace_visualize
then
75
report
(
"
using compose information from goodies file
"
)
76
end
77
local
done
=
false
78
for
i
,
c
in
next
,
unicodecharacters
do
-- loop over all characters ... not that efficient but a specials hash takes memory
79
if
force_combining
or
not
characters
[
i
]
then
80
local
s
=
c
.
specials
81
if
s
and
s
[
1
]
=
=
'
char
'
then
82
local
chr
=
s
[
2
]
83
local
charschr
=
characters
[
chr
]
84
if
charschr
then
85
local
cc
=
c
.
category
86
if
cc
=
=
'
ll
'
or
cc
=
=
'
lu
'
or
cc
=
=
'
lt
'
then
-- characters.is_letter[cc]
87
local
acc
=
s
[
3
]
88
local
t
=
{
}
89
for
k
,
v
in
next
,
charschr
do
90
if
k
~
=
"
commands
"
then
91
t
[
k
]
=
v
92
end
93
end
94
local
charsacc
=
characters
[
acc
]
95
-- local ca = charsacc.category
96
-- if ca == "mn" then
97
-- -- mark nonspacing
98
-- elseif ca == "ms" then
99
-- -- mark spacing combining
100
-- elseif ca == "me" then
101
-- -- mark enclosing
102
-- else
103
if
not
charsacc
then
-- fallback accents
104
acc
=
unicodefallbacks
[
acc
]
105
charsacc
=
acc
and
characters
[
acc
]
106
end
107
local
chr_t
=
charcommand
[
chr
]
108
if
charsacc
then
109
if
trace_define
then
110
report
(
"
composed %C, base %C, accent %C
"
,
i
,
chr
,
acc
)
111
end
112
local
acc_t
=
charcommand
[
acc
]
113
local
cb
=
descriptions
[
chr
]
.
boundingbox
114
local
ab
=
descriptions
[
acc
]
.
boundingbox
115
-- todo: adapt height
116
if
cb
and
ab
then
117
local
c_llx
=
scale
*
cb
[
1
]
118
local
c_lly
=
scale
*
cb
[
2
]
119
local
c_urx
=
scale
*
cb
[
3
]
120
local
c_ury
=
scale
*
cb
[
4
]
121
local
a_llx
=
scale
*
ab
[
1
]
122
local
a_lly
=
scale
*
ab
[
2
]
123
local
a_urx
=
scale
*
ab
[
3
]
124
local
a_ury
=
scale
*
ab
[
4
]
125
local
done
=
false
126
if
compose
then
127
local
i_compose
=
compose
[
i
]
128
local
i_anchored
=
i_compose
and
i_compose
.
anchored
129
if
i_anchored
then
130
local
c_compose
=
compose
[
chr
]
131
local
a_compose
=
compose
[
acc
]
132
local
c_anchors
=
c_compose
and
c_compose
.
anchors
133
local
a_anchors
=
a_compose
and
a_compose
.
anchors
134
if
c_anchors
and
a_anchors
then
135
local
c_anchor
=
c_anchors
[
i_anchored
]
136
local
a_anchor
=
a_anchors
[
i_anchored
]
137
if
c_anchor
and
a_anchor
then
138
local
cx
=
c_anchor
.
x
or
0
139
local
cy
=
c_anchor
.
y
or
0
140
local
ax
=
a_anchor
.
x
or
0
141
local
ay
=
a_anchor
.
y
or
0
142
local
dx
=
cx
-
ax
143
local
dy
=
cy
-
ay
144
if
trace_define
then
145
report
(
"
building %C from %C and %C
"
,
i
,
chr
,
acc
)
146
report
(
"
boundingbox:
"
)
147
report
(
"
chr: %3i %3i %3i %3i
"
,
unpack
(
cb
)
)
148
report
(
"
acc: %3i %3i %3i %3i
"
,
unpack
(
ab
)
)
149
report
(
"
anchors:
"
)
150
report
(
"
chr: %3i %3i
"
,
cx
,
cy
)
151
report
(
"
acc: %3i %3i
"
,
ax
,
ay
)
152
report
(
"
delta:
"
)
153
report
(
"
%s: %3i %3i
"
,
i_anchored
,
dx
,
dy
)
154
end
155
local
right
=
rightcommand
[
scale
*
dx
]
156
local
down
=
upcommand
[
scale
*
dy
]
157
if
trace_visualize
then
158
t
.
commands
=
{
159
push
,
right
,
down
,
160
green
,
acc_t
,
black
,
161
pop
,
chr_t
,
162
}
163
else
164
t
.
commands
=
{
165
push
,
right
,
down
,
166
acc_t
,
pop
,
chr_t
,
167
}
168
end
169
done
=
true
170
end
171
end
172
end
173
end
174
if
not
done
then
175
-- can be sped up for scale == 1
176
local
dx
=
(
c_urx
-
a_urx
-
a_llx
+
c_llx
)
/
2
177
local
dd
=
(
c_urx
-
c_llx
)
*
italicfactor
178
if
a_ury
<
0
then
179
local
right
=
rightcommand
[
dx
-
dd
]
180
if
trace_visualize
then
181
t
.
commands
=
{
182
push
,
right
,
red
,
acc_t
,
183
black
,
pop
,
chr_t
,
184
}
185
else
186
t
.
commands
=
{
187
push
,
right
,
acc_t
,
pop
,
188
chr_t
,
189
}
190
end
191
t
.
depth
=
a_ury
192
elseif
c_ury
>
a_lly
then
-- messy test
193
local
dy
194
if
compose
then
195
-- experimental: we could use sx but all that testing
196
-- takes time and code
197
dy
=
compose
[
i
]
198
if
dy
then
199
dy
=
dy
.
dy
200
end
201
if
not
dy
then
202
dy
=
compose
[
acc
]
203
if
dy
then
204
dy
=
dy
and
dy
.
dy
205
end
206
end
207
if
not
dy
then
208
dy
=
compose
.
dy
209
end
210
if
not
dy
then
211
dy
=
-
deltaxheight
+
extraxheight
212
elseif
dy
>
-1
.
5
and
dy
<
1
.
5
then
213
-- we assume a fraction of (percentage)
214
dy
=
-
dy
*
deltaxheight
215
else
216
-- we assume fontunits (value smaller than 2 make no sense)
217
dy
=
-
dy
*
scale
218
end
219
else
220
dy
=
-
deltaxheight
+
extraxheight
221
end
222
t
.
height
=
a_ury
-
dy
223
local
right
=
rightcommand
[
dx
+
dd
]
224
local
down
=
downcommand
[
dy
]
225
if
trace_visualize
then
226
t
.
commands
=
{
227
push
,
right
,
down
,
green
,
228
acc_t
,
black
,
pop
,
chr_t
,
229
}
230
else
231
t
.
commands
=
{
232
push
,
right
,
down
,
acc_t
,
233
pop
,
chr_t
,
234
}
235
end
236
else
237
local
right
=
rightcommand
[
dx
+
dd
]
238
if
trace_visualize
then
239
t
.
commands
=
{
240
push
,
right
,
blue
,
acc_t
,
241
black
,
pop
,
chr_t
,
242
}
243
else
244
t
.
commands
=
{
245
push
,
right
,
acc_t
,
pop
,
246
chr_t
,
247
}
248
end
249
t
.
height
=
a_ury
250
end
251
end
252
else
253
t
.
commands
=
{
254
chr_t
,
-- else index mess
255
}
256
end
257
else
258
if
trace_define
then
259
report
(
"
%C becomes simplified %C
"
,
i
,
chr
)
260
end
261
t
.
commands
=
{
262
chr_t
,
-- else index mess
263
}
264
end
265
done
=
true
266
characters
[
i
]
=
t
267
local
d
=
{
}
268
for
k
,
v
in
next
,
descriptions
[
chr
]
do
269
d
[
k
]
=
v
270
end
271
descriptions
[
i
]
=
d
272
end
273
end
274
end
275
end
276
end
277
end
278
end
279 280
local
specification
=
{
281
name
=
"
compose
"
,
282
description
=
"
additional composed characters
"
,
283
manipulators
=
{
284
base
=
composecharacters
,
285
node
=
composecharacters
,
286
}
287
}
288 289
registerotffeature
(
specification
)
290
registerafmfeature
(
specification
)
291 292
addotffeature
{
293
name
=
"
char-ligatures
"
,
294
type
=
"
ligature
"
,
295
data
=
characters
.
splits
.
char
,
296
order
=
{
"
char-ligatures
"
}
,
297
prepend
=
true
,
298
}
299 300
addotffeature
{
301
name
=
"
compat-ligatures
"
,
302
type
=
"
ligature
"
,
303
data
=
characters
.
splits
.
compat
,
304
order
=
{
"
compat-ligatures
"
}
,
305
prepend
=
true
,
306
}
307 308
registerotffeature
{
309
name
=
'
char-ligatures
'
,
310
description
=
'
unicode char specials to ligatures
'
,
311
}
312 313
registerotffeature
{
314
name
=
'
compat-ligatures
'
,
315
description
=
'
unicode compat specials to ligatures
'
,
316
}
317 318
-- We now provide the composer in the helpers namespace (too):
319 320
fonts
.
helpers
.
composecharacters
=
composecharacters
321 322
-- We keep this just because we have a few demos but there often are other ways to achieve
323
-- the same. This code installs the builder into the regular virtual font builder, which
324
-- only makes sense as demo. It also shows a bit what the evolution is.
325 326
do
327 328
local
vf
=
handlers
.
vf
329
local
commands
=
vf
.
combiner
.
commands
330 331
vf
.
helpers
.
composecharacters
=
composecharacters
332 333
commands
[
"
compose.trace.enable
"
]
=
function
(
)
trace_visualize
=
true
end
334
commands
[
"
compose.trace.disable
"
]
=
function
(
)
trace_visualize
=
false
end
335
commands
[
"
compose.force.enable
"
]
=
function
(
)
force_combining
=
true
end
336
commands
[
"
compose.force.disable
"
]
=
function
(
)
force_combining
=
false
end
337 338
commands
[
"
compose.trace.set
"
]
=
function
(
g
,
v
)
339
if
v
[
2
]
=
=
nil
then
340
trace_visualize
=
true
341
else
342
trace_visualize
=
v
[
2
]
343
end
344
end
345 346
commands
[
"
compose.apply
"
]
=
function
(
g
,
v
)
347
composecharacters
(
g
)
348
end
349 350
end
351