math-vfu.lmt /size: 48 Kb    last modification: 2021-10-28 13:51
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
math-vfu
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to math-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
-- All these math vectors .. thanks to Aditya and Mojca they become better and
10
-- better. If you have problems with math fonts or miss characters report it to the
11
-- ConTeXt mailing list. Also thanks to Boguslaw for finding a couple of errors.
12
-- This mechanism will eventually disappear.
13 14
-- 20D6 -> 2190
15
-- 20D7 -> 2192
16 17
local
type
,
next
,
tonumber
=
type
,
next
,
tonumber
18
local
max
=
math
.
max
19
local
fastcopy
=
table
.
copy
20 21
local
fonts
,
nodes
,
mathematics
=
fonts
,
nodes
,
mathematics
22 23
local
trace_virtual
=
false
trackers
.
register
(
"
math.virtual
"
,
function
(
v
)
trace_virtual
=
v
end
)
24
local
trace_timings
=
false
trackers
.
register
(
"
math.timings
"
,
function
(
v
)
trace_timings
=
v
end
)
25 26
local
add_optional
=
false
directives
.
register
(
"
math.virtual.optional
"
,
function
(
v
)
add_optional
=
v
end
)
27 28
local
report_virtual
=
logs
.
reporter
(
"
fonts
"
,
"
virtual math
"
)
29 30
local
allocate
=
utilities
.
storage
.
allocate
31
local
setmetatableindex
=
table
.
setmetatableindex
32
local
formatters
=
string
.
formatters
33 34
local
chardata
=
characters
.
data
35 36
local
mathencodings
=
allocate
(
)
37
fonts
.
encodings
.
math
=
mathencodings
-- better is then: fonts.encodings.vectors
38
local
vfmath
=
allocate
(
)
39
fonts
.
handlers
.
vf
.
math
=
vfmath
40 41
local
helpers
=
fonts
.
helpers
42
local
vfcommands
=
helpers
.
commands
43
local
rightcommand
=
vfcommands
.
right
44
local
leftcommand
=
vfcommands
.
left
45
local
downcommand
=
vfcommands
.
down
46
local
upcommand
=
vfcommands
.
up
47
local
push
=
vfcommands
.
push
48
local
pop
=
vfcommands
.
pop
49 50
local
shared
=
{
}
51 52
-- local back = { "slot", 1, 0x2215 }
53
--
54
-- local function negate(main,characters,id,size,unicode,basecode)
55
-- if not characters[unicode] then
56
-- local basechar = characters[basecode]
57
-- if basechar then
58
-- local ht, wd = basechar.height, basechar.width
59
-- characters[unicode] = {
60
-- width = wd,
61
-- height = ht,
62
-- depth = basechar.depth,
63
-- italic = basechar.italic,
64
-- kerns = basechar.kerns,
65
-- commands = {
66
-- { "slot", 1, basecode },
67
-- push,
68
-- downcommand[ht/5],
69
-- leftcommand[wd/2],
70
-- back,
71
-- push,
72
-- }
73
-- }
74
-- end
75
-- end
76
-- end
77
--
78
-- \Umathchardef\braceld="0 "1 "FF07A
79
-- \Umathchardef\bracerd="0 "1 "FF07B
80
-- \Umathchardef\bracelu="0 "1 "FF07C
81
-- \Umathchardef\braceru="0 "1 "FF07D
82 83
local
function
brace
(
main
,
characters
,
id
,
size
,
unicode
,
first
,
rule
,
left
,
right
,
rule
,
last
)
84
if
not
characters
[
unicode
]
then
85
characters
[
unicode
]
=
{
86
horiz_variants
=
{
87
{
extender
=
0
,
glyph
=
first
}
,
88
{
extender
=
1
,
glyph
=
rule
}
,
89
{
extender
=
0
,
glyph
=
left
}
,
90
{
extender
=
0
,
glyph
=
right
}
,
91
{
extender
=
1
,
glyph
=
rule
}
,
92
{
extender
=
0
,
glyph
=
last
}
,
93
}
94
}
95
end
96
end
97 98
local
function
extension
(
main
,
characters
,
id
,
size
,
unicode
,
first
,
middle
,
last
)
99
local
chr
=
characters
[
unicode
]
100
if
not
chr
then
101
return
-- skip
102
end
103
local
fw
=
characters
[
first
]
104
if
not
fw
then
105
return
106
end
107
local
mw
=
characters
[
middle
]
108
if
not
mw
then
109
return
110
end
111
local
lw
=
characters
[
last
]
112
if
not
lw
then
113
return
114
end
115
fw
=
fw
.
width
116
mw
=
mw
.
width
117
lw
=
lw
.
width
118
if
fw
=
=
0
then
119
fw
=
1
120
end
121
if
lw
=
=
0
then
122
lw
=
1
123
end
124
chr
.
horiz_variants
=
{
125
{
extender
=
0
,
glyph
=
first
,
[
"
end
"
]
=
fw
/
2
,
start
=
0
,
advance
=
fw
}
,
126
{
extender
=
1
,
glyph
=
middle
,
[
"
end
"
]
=
mw
/
2
,
start
=
mw
/
2
,
advance
=
mw
}
,
127
{
extender
=
0
,
glyph
=
last
,
[
"
end
"
]
=
0
,
start
=
lw
/
2
,
advance
=
lw
}
,
128
}
129
end
130 131
local
function
parent
(
main
,
characters
,
id
,
size
,
unicode
,
first
,
rule
,
last
)
132
if
not
characters
[
unicode
]
then
133
characters
[
unicode
]
=
{
134
horiz_variants
=
{
135
{
extender
=
0
,
glyph
=
first
}
,
136
{
extender
=
1
,
glyph
=
rule
}
,
137
{
extender
=
0
,
glyph
=
last
}
,
138
}
139
}
140
end
141
end
142 143
local
step
=
0
.
2
-- 0.1 is nicer but gives larger files
144 145
local
function
make
(
main
,
characters
,
id
,
size
,
n
,
m
)
146
local
old
=
0xFF000
+
n
147
local
c
=
characters
[
old
]
148
if
c
then
149
local
upslot
=
0xFF100
+
n
150
local
dnslot
=
0xFF200
+
n
151
local
uprule
=
0xFF300
+
m
152
local
dnrule
=
0xFF400
+
m
153
local
xu
=
main
.
parameters
.
x_height
+
0
.
3
*
size
154
local
xd
=
0
.
3
*
size
155
local
w
=
c
.
width
or
0
156
local
h
=
c
.
height
or
0
157
local
d
=
c
.
depth
or
0
158
local
thickness
=
h
-
d
159
local
rulewidth
=
step
*
size
-- we could use an overlap
160
local
slot
=
{
"
slot
"
,
id
,
old
}
161
local
rule
=
{
"
rule
"
,
thickness
,
rulewidth
}
162
local
up
=
upcommand
[
xu
]
163
local
dn
=
downcommand
[
xd
]
164
local
ht
=
xu
+
3
*
thickness
165
local
dp
=
0
166
if
not
characters
[
uprule
]
then
167
characters
[
uprule
]
=
{
168
width
=
rulewidth
,
169
height
=
ht
,
170
depth
=
dp
,
171
commands
=
{
push
,
up
,
rule
,
pop
}
,
172
}
173
end
174
characters
[
upslot
]
=
{
175
width
=
w
,
176
height
=
ht
,
177
depth
=
dp
,
178
commands
=
{
push
,
up
,
slot
,
pop
}
,
179
}
180
local
ht
=
0
181
local
dp
=
xd
+
3
*
thickness
182
if
not
characters
[
dnrule
]
then
183
characters
[
dnrule
]
=
{
184
width
=
rulewidth
,
185
height
=
ht
,
186
depth
=
dp
,
187
commands
=
{
push
,
dn
,
rule
,
pop
}
188
}
189
end
190
characters
[
dnslot
]
=
{
191
width
=
w
,
192
height
=
ht
,
193
depth
=
dp
,
194
commands
=
{
push
,
dn
,
slot
,
pop
}
,
195
}
196
end
197
end
198 199
local
function
clipped
(
main
,
characters
,
id
,
size
,
unicode
,
original
)
-- push/pop needed?
200
local
minus
=
characters
[
original
]
201
if
minus
then
202
local
mu
=
size
/
18
203
local
step
=
3
*
mu
204
local
width
=
minus
.
width
205
if
width
>
step
then
206
width
=
width
-
step
207
step
=
step
/
2
208
else
209
width
=
width
/
2
210
step
=
width
211
end
212
characters
[
unicode
]
=
{
213
width
=
width
,
214
height
=
minus
.
height
,
215
depth
=
minus
.
depth
,
216
commands
=
{
217
push
,
218
leftcommand
[
step
]
,
219
{
"
slot
"
,
id
,
original
}
,
220
pop
,
221
}
222
}
223
end
224
end
225 226
local
function
raise
(
main
,
characters
,
id
,
size
,
unicode
,
private
,
n
,
id_of_smaller
)
-- this is a real fake mess
227
local
raised
=
fonts
.
hashes
.
characters
[
main
.
fonts
[
id_of_smaller
]
.
id
]
[
private
]
-- characters[private]
228
if
raised
then
229
local
up
=
0
.
85
*
main
.
parameters
.
x_height
230
local
slot
=
{
"
slot
"
,
id_of_smaller
,
private
}
231
local
commands
=
{
232
push
,
upcommand
[
up
]
,
slot
,
233
}
234
for
i
=
2
,
n
do
235
commands
[
#
commands
+
1
]
=
slot
236
end
237
commands
[
#
commands
+
1
]
=
pop
238
characters
[
unicode
]
=
{
239
width
=
n
*
raised
.
width
,
240
height
=
(
raised
.
height
or
0
)
+
up
,
241
depth
=
(
raised
.
depth
or
0
)
-
up
,
242
italic
=
raised
.
italic
,
243
commands
=
commands
,
244
}
245
end
246
end
247 248
local
function
dots
(
main
,
characters
,
id
,
size
,
unicode
)
249
local
c
=
characters
[
0x002E
]
250
if
c
then
251
local
w
=
c
.
width
252
local
h
=
c
.
height
253
local
d
=
c
.
depth
254
local
mu
=
size
/
18
255
local
right3mu
=
rightcommand
[
3
*
mu
]
256
local
right1mu
=
rightcommand
[
1
*
mu
]
257
local
up1size
=
upcommand
[
.
1
*
size
]
258
local
up4size
=
upcommand
[
.
4
*
size
]
259
local
up7size
=
upcommand
[
.
7
*
size
]
260
local
right2muw
=
rightcommand
[
2
*
mu
+
w
]
261
local
slot
=
{
"
slot
"
,
id
,
0x002E
}
262
if
unicode
=
=
0x22EF
then
263
local
c
=
characters
[
0x022C5
]
264
if
c
then
265
local
width
=
c
.
width
266
local
height
=
c
.
height
267
local
depth
=
c
.
depth
268
local
slot
=
{
"
slot
"
,
id
,
0x022C5
}
269
characters
[
unicode
]
=
{
270
width
=
3
*
width
+
2
*
3
*
mu
,
271
height
=
height
,
272
depth
=
depth
,
273
commands
=
{
274
push
,
slot
,
right3mu
,
slot
,
right3mu
,
slot
,
pop
,
275
}
276
}
277
end
278
elseif
unicode
=
=
0x22EE
then
279
-- weird height !
280
characters
[
unicode
]
=
{
281
width
=
w
,
282
height
=
h
+
(
1
.
4
)
*
size
,
283
depth
=
0
,
284
commands
=
{
285
push
,
push
,
slot
,
pop
,
up4size
,
push
,
slot
,
pop
,
up4size
,
slot
,
pop
,
286
}
287
}
288
elseif
unicode
=
=
0x22F1
then
289
characters
[
unicode
]
=
{
290
width
=
3
*
w
+
6
*
size
/
18
,
291
height
=
1
.
5
*
size
,
292
depth
=
0
,
293
commands
=
{
294
push
,
295
right1mu
,
296
push
,
up7size
,
slot
,
pop
,
297
right2muw
,
298
push
,
up4size
,
slot
,
pop
,
299
right2muw
,
300
push
,
up1size
,
slot
,
pop
,
301
right1mu
,
302
pop
303
}
304
}
305
elseif
unicode
=
=
0x22F0
then
306
characters
[
unicode
]
=
{
307
width
=
3
*
w
+
6
*
size
/
18
,
308
height
=
1
.
5
*
size
,
309
depth
=
0
,
310
commands
=
{
311
push
,
312
right1mu
,
313
push
,
up1size
,
slot
,
pop
,
314
right2muw
,
315
push
,
up4size
,
slot
,
pop
,
316
right2muw
,
317
push
,
up7size
,
slot
,
pop
,
318
right1mu
,
319
pop
320
}
321
}
322
else
323
characters
[
unicode
]
=
{
324
width
=
3
*
w
+
2
*
3
*
mu
,
325
height
=
h
,
326
depth
=
d
,
327
commands
=
{
328
push
,
slot
,
right3mu
,
slot
,
right3mu
,
slot
,
pop
,
329
}
330
}
331
end
332
end
333
end
334 335
local
function
vertbar
(
main
,
characters
,
id
,
size
,
parent
,
scale
,
unicode
)
336
local
cp
=
characters
[
parent
]
337
if
cp
then
338
local
sc
=
scale
*
size
339
local
pc
=
{
"
slot
"
,
id
,
parent
}
340
characters
[
unicode
]
=
{
341
width
=
cp
.
width
,
342
height
=
cp
.
height
+
sc
,
343
depth
=
cp
.
depth
+
sc
,
344
next
=
cp
.
next
,
-- can be extensible
345
commands
=
{
346
push
,
upcommand
[
sc
]
,
pc
,
pop
,
347
push
,
downcommand
[
sc
]
,
pc
,
pop
,
348
pc
,
349
}
,
350
}
351
cp
.
next
=
unicode
352
end
353
end
354 355
local
function
jointwo
(
main
,
characters
,
id
,
size
,
unicode
,
u1
,
d12
,
u2
,
what
)
356
local
c1
=
characters
[
u1
]
357
local
c2
=
characters
[
u2
]
358
if
c1
and
c2
then
359
local
w1
=
c1
.
width
360
local
w2
=
c2
.
width
361
local
mu
=
size
/
18
362
characters
[
unicode
]
=
{
363
width
=
w1
+
w2
-
d12
*
mu
,
364
height
=
max
(
c1
.
height
or
0
,
c2
.
height
or
0
)
,
365
depth
=
max
(
c1
.
depth
or
0
,
c2
.
depth
or
0
)
,
366
commands
=
{
367
{
"
slot
"
,
id
,
u1
}
,
368
leftcommand
[
d12
*
mu
]
,
369
{
"
slot
"
,
id
,
u2
}
,
370
}
,
371
}
372
end
373
end
374 375
local
function
jointhree
(
main
,
characters
,
id
,
size
,
unicode
,
u1
,
d12
,
u2
,
d23
,
u3
)
376
local
c1
=
characters
[
u1
]
377
local
c2
=
characters
[
u2
]
378
local
c3
=
characters
[
u3
]
379
if
c1
and
c2
and
c3
then
380
local
w1
=
c1
.
width
381
local
w2
=
c2
.
width
382
local
w3
=
c3
.
width
383
local
mu
=
size
/
18
384
characters
[
unicode
]
=
{
385
width
=
w1
+
w2
+
w3
-
d12
*
mu
-
d23
*
mu
,
386
height
=
max
(
c1
.
height
or
0
,
c2
.
height
or
0
,
c3
.
height
or
0
)
,
387
depth
=
max
(
c1
.
depth
or
0
,
c2
.
depth
or
0
,
c3
.
depth
or
0
)
,
388
commands
=
{
389
{
"
slot
"
,
id
,
u1
}
,
390
leftcommand
[
d12
*
mu
]
,
391
{
"
slot
"
,
id
,
u2
}
,
392
leftcommand
[
d23
*
mu
]
,
393
{
"
slot
"
,
id
,
u3
}
,
394
}
395
}
396
end
397
end
398 399
local
function
stack
(
main
,
characters
,
id
,
size
,
unicode
,
u1
,
d12
,
u2
)
400
local
c1
=
characters
[
u1
]
401
if
not
c1
then
402
return
403
end
404
local
c2
=
characters
[
u2
]
405
if
not
c2
then
406
return
407
end
408
local
w1
=
c1
.
width
or
0
409
local
h1
=
c1
.
height
or
0
410
local
d1
=
c1
.
depth
or
0
411
local
w2
=
c2
.
width
or
0
412
local
h2
=
c2
.
height
or
0
413
local
d2
=
c2
.
depth
or
0
414
local
mu
=
size
/
18
415
characters
[
unicode
]
=
{
416
width
=
w1
,
417
height
=
h1
+
h2
+
d12
,
418
depth
=
d1
,
419
commands
=
{
420
{
"
slot
"
,
id
,
u1
}
,
421
leftcommand
[
w1
/
2
+
w2
/
2
]
,
422
downcommand
[
-
h1
+
d2
-
d12
*
mu
]
,
423
{
"
slot
"
,
id
,
u2
}
,
424
}
425
}
426
end
427 428
local
function
repeated
(
main
,
characters
,
id
,
size
,
unicode
,
u
,
n
,
private
,
fraction
)
-- math-fbk.lua
429
local
c
=
characters
[
u
]
430
if
c
then
431
local
width
=
c
.
width
432
local
italic
=
fraction
*
width
-- c.italic or 0 -- larger ones have funny italics
433
local
tc
=
{
"
slot
"
,
id
,
u
}
434
local
tr
=
leftcommand
[
italic
]
-- see hack elsewhere
435
local
commands
=
{
}
436
for
i
=
1
,
n
-1
do
437
commands
[
#
commands
+
1
]
=
tc
438
commands
[
#
commands
+
1
]
=
tr
439
end
440
commands
[
#
commands
+
1
]
=
tc
441
local
next
=
c
.
next
442
if
next
then
443
repeated
(
main
,
characters
,
id
,
size
,
private
,
next
,
n
,
private
+
1
,
fraction
)
444
next
=
private
445
end
446
characters
[
unicode
]
=
{
447
width
=
width
+
(
n
-1
)
*
(
width
-
italic
)
,
448
height
=
c
.
height
,
449
depth
=
c
.
depth
,
450
italic
=
italic
,
451
commands
=
commands
,
452
next
=
next
,
453
}
454
end
455
end
456 457
local
function
cloned
(
main
,
characters
,
id
,
size
,
source
,
target
)
458
local
data
=
characters
[
source
]
459
if
data
then
460
characters
[
target
]
=
data
461
return
true
462
end
463
end
464 465
-- we use the fact that context defines the smallest sizes first .. a real dirty and ugly hack
466 467
local
data_of_smaller
=
nil
468
local
size_of_smaller
=
0
469 470
function
vfmath
.
addmissing
(
main
,
id
,
size
)
471 472
local
id_of_smaller
=
nil
473 474
if
size
<
size_of_smaller
or
size_of_smaller
=
=
0
then
475
data_of_smaller
=
main
.
fonts
[
id
]
476
id_of_smaller
=
id
477
else
478
id_of_smaller
=
#
main
.
fonts
+
1
479
main
.
fonts
[
id_of_smaller
]
=
data_of_smaller
480
end
481 482
-- here id is the index in fonts (normally 14 or so) and that slot points to self
483 484
local
characters
=
main
.
characters
485
local
shared
=
main
.
shared
486
local
variables
=
main
.
goodies
.
mathematics
and
main
.
goodies
.
mathematics
.
variables
or
{
}
487
local
joinrelfactor
=
variables
.
joinrelfactor
or
3
488 489
for
i
=
0x7A
,
0x7D
do
490
make
(
main
,
characters
,
id
,
size
,
i
,
1
)
491
end
492 493
brace
(
main
,
characters
,
id
,
size
,
0x23DE
,
0xFF17A
,
0xFF301
,
0xFF17D
,
0xFF17C
,
0xFF301
,
0xFF17B
)
494
brace
(
main
,
characters
,
id
,
size
,
0x23DF
,
0xFF27C
,
0xFF401
,
0xFF27B
,
0xFF27A
,
0xFF401
,
0xFF27D
)
495 496
parent
(
main
,
characters
,
id
,
size
,
0x23DC
,
0xFF17A
,
0xFF301
,
0xFF17B
)
497
parent
(
main
,
characters
,
id
,
size
,
0x23DD
,
0xFF27C
,
0xFF401
,
0xFF27D
)
498 499
-- negate (main,characters,id,size,0x2260,0x003D)
500
dots
(
main
,
characters
,
id
,
size
,
0x2026
)
-- ldots
501
dots
(
main
,
characters
,
id
,
size
,
0x22EE
)
-- vdots
502
dots
(
main
,
characters
,
id
,
size
,
0x22EF
)
-- cdots
503
dots
(
main
,
characters
,
id
,
size
,
0x22F1
)
-- ddots
504
dots
(
main
,
characters
,
id
,
size
,
0x22F0
)
-- udots
505 506
vertbar
(
main
,
characters
,
id
,
size
,
0x0007C
,
0
.
10
,
0xFF601
)
-- big : 0.85 bodyfontsize
507
vertbar
(
main
,
characters
,
id
,
size
,
0xFF601
,
0
.
30
,
0xFF602
)
-- Big : 1.15 bodyfontsize
508
vertbar
(
main
,
characters
,
id
,
size
,
0xFF602
,
0
.
30
,
0xFF603
)
-- bigg : 1.45 bodyfontsize
509
vertbar
(
main
,
characters
,
id
,
size
,
0xFF603
,
0
.
30
,
0xFF604
)
-- Bigg : 1.75 bodyfontsize
510
vertbar
(
main
,
characters
,
id
,
size
,
0x02016
,
0
.
10
,
0xFF605
)
511
vertbar
(
main
,
characters
,
id
,
size
,
0xFF605
,
0
.
30
,
0xFF606
)
512
vertbar
(
main
,
characters
,
id
,
size
,
0xFF606
,
0
.
30
,
0xFF607
)
513
vertbar
(
main
,
characters
,
id
,
size
,
0xFF607
,
0
.
30
,
0xFF608
)
514 515
clipped
(
main
,
characters
,
id
,
size
,
0xFF501
,
0x0002D
)
-- minus
516
clipped
(
main
,
characters
,
id
,
size
,
0xFF502
,
0x02190
)
-- lefthead
517
clipped
(
main
,
characters
,
id
,
size
,
0xFF503
,
0x02192
)
-- righthead
518
clipped
(
main
,
characters
,
id
,
size
,
0xFF504
,
0xFE321
)
-- mapsto
519
clipped
(
main
,
characters
,
id
,
size
,
0xFF505
,
0xFE322
)
-- lhook
520
clipped
(
main
,
characters
,
id
,
size
,
0xFF506
,
0xFE323
)
-- rhook
521
clipped
(
main
,
characters
,
id
,
size
,
0xFF507
,
0xFE324
)
-- mapsfrom
522
clipped
(
main
,
characters
,
id
,
size
,
0xFF508
,
0x021D0
)
-- double lefthead
523
clipped
(
main
,
characters
,
id
,
size
,
0xFF509
,
0x021D2
)
-- double righthead
524
clipped
(
main
,
characters
,
id
,
size
,
0xFF50A
,
0x0003D
)
-- equal
525
clipped
(
main
,
characters
,
id
,
size
,
0xFF50B
,
0x0219E
)
-- lefttwohead
526
clipped
(
main
,
characters
,
id
,
size
,
0xFF50C
,
0x021A0
)
-- righttwohead
527
clipped
(
main
,
characters
,
id
,
size
,
0xFF50D
,
0xFF350
)
-- lr arrow combi snippet
528
clipped
(
main
,
characters
,
id
,
size
,
0xFF50E
,
0xFF351
)
-- lr arrow combi snippet
529
clipped
(
main
,
characters
,
id
,
size
,
0xFF50F
,
0xFF352
)
-- lr arrow combi snippet
530
clipped
(
main
,
characters
,
id
,
size
,
0xFF510
,
0x02261
)
-- equiv
531 532
extension
(
main
,
characters
,
id
,
size
,
0x2190
,
0xFF502
,
0xFF501
,
0xFF501
)
-- \leftarrow
533
extension
(
main
,
characters
,
id
,
size
,
0x2192
,
0xFF501
,
0xFF501
,
0xFF503
)
-- \rightarrow
534 535
extension
(
main
,
characters
,
id
,
size
,
0x002D
,
0xFF501
,
0xFF501
,
0xFF501
)
-- \rel
536
extension
(
main
,
characters
,
id
,
size
,
0x003D
,
0xFF50A
,
0xFF50A
,
0xFF50A
)
-- \equal
537
extension
(
main
,
characters
,
id
,
size
,
0x2261
,
0xFF510
,
0xFF510
,
0xFF510
)
-- \equiv
538 539
jointwo
(
main
,
characters
,
id
,
size
,
0x21A6
,
0xFE321
,
0
,
0x02192
)
-- \mapstochar\rightarrow
540
jointwo
(
main
,
characters
,
id
,
size
,
0x21A9
,
0x02190
,
joinrelfactor
,
0xFE323
)
-- \leftarrow\joinrel\rhook
541
jointwo
(
main
,
characters
,
id
,
size
,
0x21AA
,
0xFE322
,
joinrelfactor
,
0x02192
)
-- \lhook\joinrel\rightarrow
542
jointwo
(
main
,
characters
,
id
,
size
,
0x27F5
,
0x02190
,
joinrelfactor
,
0x0002D
)
-- \leftarrow\joinrel\relbar
543
jointwo
(
main
,
characters
,
id
,
size
,
0x27F6
,
0x0002D
,
joinrelfactor
,
0x02192
,
2
)
-- \relbar\joinrel\rightarrow
544
jointwo
(
main
,
characters
,
id
,
size
,
0x27F7
,
0x02190
,
joinrelfactor
,
0x02192
)
-- \leftarrow\joinrel\rightarrow
545
jointwo
(
main
,
characters
,
id
,
size
,
0x27F8
,
0x021D0
,
joinrelfactor
,
0x0003D
)
-- \Leftarrow\joinrel\Relbar
546
jointwo
(
main
,
characters
,
id
,
size
,
0x27F9
,
0x0003D
,
joinrelfactor
,
0x021D2
)
-- \Relbar\joinrel\Rightarrow
547
jointwo
(
main
,
characters
,
id
,
size
,
0x27FA
,
0x021D0
,
joinrelfactor
,
0x021D2
)
-- \Leftarrow\joinrel\Rightarrow
548
jointhree
(
main
,
characters
,
id
,
size
,
0x27FB
,
0x02190
,
joinrelfactor
,
0x0002D
,
0
,
0xFE324
)
-- \leftarrow\joinrel\relbar\mapsfromchar
549
jointhree
(
main
,
characters
,
id
,
size
,
0x27FC
,
0xFE321
,
0
,
0x0002D
,
joinrelfactor
,
0x02192
)
-- \mapstochar\relbar\joinrel\rightarrow
550 551
extension
(
main
,
characters
,
id
,
size
,
0x21A6
,
0xFF504
,
0xFF501
,
0xFF503
)
-- \mapstochar\rightarrow
552
extension
(
main
,
characters
,
id
,
size
,
0x21A9
,
0xFF502
,
0xFF501
,
0xFF506
)
-- \leftarrow\joinrel\rhook
553
extension
(
main
,
characters
,
id
,
size
,
0x21AA
,
0xFF505
,
0xFF501
,
0xFF503
)
-- \lhook\joinrel\rightarrow
554
extension
(
main
,
characters
,
id
,
size
,
0x27F5
,
0xFF502
,
0xFF501
,
0xFF501
)
-- \leftarrow\joinrel\relbar
555
extension
(
main
,
characters
,
id
,
size
,
0x27F6
,
0xFF501
,
0xFF501
,
0xFF503
)
-- \relbar\joinrel\rightarrow
556
extension
(
main
,
characters
,
id
,
size
,
0x27F7
,
0xFF502
,
0xFF501
,
0xFF503
)
-- \leftarrow\joinrel\rightarrow
557
extension
(
main
,
characters
,
id
,
size
,
0x27F8
,
0xFF508
,
0xFF50A
,
0xFF50A
)
-- \Leftarrow\joinrel\Relbar
558
extension
(
main
,
characters
,
id
,
size
,
0x27F9
,
0xFF50A
,
0xFF50A
,
0xFF509
)
-- \Relbar\joinrel\Rightarrow
559
extension
(
main
,
characters
,
id
,
size
,
0x27FA
,
0xFF508
,
0xFF50A
,
0xFF509
)
-- \Leftarrow\joinrel\Rightarrow
560
extension
(
main
,
characters
,
id
,
size
,
0x27FB
,
0xFF502
,
0xFF501
,
0xFF507
)
-- \leftarrow\joinrel\relbar\mapsfromchar
561
extension
(
main
,
characters
,
id
,
size
,
0x27FC
,
0xFF504
,
0xFF501
,
0xFF503
)
-- \mapstochar\relbar\joinrel\rightarrow
562 563
extension
(
main
,
characters
,
id
,
size
,
0x219E
,
0xFF50B
,
0xFF501
,
0xFF501
)
-- \twoheadleftarrow\joinrel\relbar
564
extension
(
main
,
characters
,
id
,
size
,
0x21A0
,
0xFF501
,
0xFF501
,
0xFF50C
)
-- \relbar\joinrel\twoheadrightarrow
565
extension
(
main
,
characters
,
id
,
size
,
0x21C4
,
0xFF50D
,
0xFF50E
,
0xFF50F
)
-- leftoverright
566 567
-- 21CB leftrightharpoon
568
-- 21CC rightleftharpoon
569 570
stack
(
main
,
characters
,
id
,
size
,
0x2259
,
0x0003D
,
3
,
0x02227
)
-- \buildrel\wedge\over=
571 572
jointwo
(
main
,
characters
,
id
,
size
,
0x22C8
,
0x022B3
,
joinrelfactor
,
0x022B2
)
-- \mathrel\triangleright\joinrel\mathrel\triangleleft (4 looks better than 3)
573
jointwo
(
main
,
characters
,
id
,
size
,
0x22A7
,
0x0007C
,
joinrelfactor
,
0x0003D
)
-- \mathrel|\joinrel=
574
jointwo
(
main
,
characters
,
id
,
size
,
0x2260
,
0x00338
,
0
,
0x0003D
)
-- \not\equal
575
jointwo
(
main
,
characters
,
id
,
size
,
0x2284
,
0x00338
,
0
,
0x02282
)
-- \not\subset
576
jointwo
(
main
,
characters
,
id
,
size
,
0x2285
,
0x00338
,
0
,
0x02283
)
-- \not\supset
577
jointwo
(
main
,
characters
,
id
,
size
,
0x2209
,
0x00338
,
0
,
0x02208
)
-- \not\in
578
jointwo
(
main
,
characters
,
id
,
size
,
0x2254
,
0x03A
,
0
,
0x03D
)
-- := (≔)
579 580
repeated
(
main
,
characters
,
id
,
size
,
0x222C
,
0x222B
,
2
,
0xFF800
,
1
/
3
)
581
repeated
(
main
,
characters
,
id
,
size
,
0x222D
,
0x222B
,
3
,
0xFF810
,
1
/
3
)
582 583
if
cloned
(
main
,
characters
,
id
,
size
,
0x2032
,
0xFE325
)
then
584
raise
(
main
,
characters
,
id
,
size
,
0x2032
,
0xFE325
,
1
,
id_of_smaller
)
-- prime
585
raise
(
main
,
characters
,
id
,
size
,
0x2033
,
0xFE325
,
2
,
id_of_smaller
)
-- double prime
586
raise
(
main
,
characters
,
id
,
size
,
0x2034
,
0xFE325
,
3
,
id_of_smaller
)
-- triple prime
587
-- to satisfy the prime resolver
588
characters
[
0xFE932
]
=
characters
[
0x2032
]
589
characters
[
0xFE933
]
=
characters
[
0x2033
]
590
characters
[
0xFE934
]
=
characters
[
0x2034
]
591
end
592 593
-- there are more (needs discussion first):
594 595
-- characters[0x20D6] = characters[0x2190]
596
-- characters[0x20D7] = characters[0x2192]
597 598
characters
[
0x02B9
]
=
characters
[
0x2032
]
-- we're nice
599 600
data_of_smaller
=
main
.
fonts
[
id
]
601
size_of_smaller
=
size
602 603
end
604 605
local
unique
=
0
-- testcase: \startTEXpage \math{!\text{-}\text{-}\text{-}} \stopTEXpage
606 607
local
reported
=
{
}
608
local
reverse
=
{
}
-- index -> unicode
609 610
setmetatableindex
(
reverse
,
function
(
t
,
name
)
611
if
trace_virtual
then
612
report_virtual
(
"
initializing math vector %a
"
,
name
)
613
end
614
local
m
=
mathencodings
[
name
]
615
local
r
=
{
}
616
for
u
,
i
in
next
,
m
do
617
r
[
i
]
=
u
618
end
619
reverse
[
name
]
=
r
620
return
r
621
end
)
622 623
local
function
copy_glyph
(
main
,
target
,
original
,
unicode
,
slot
)
624
local
addprivate
=
fonts
.
helpers
.
addprivate
625
local
olddata
=
original
[
unicode
]
626
if
olddata
then
627
local
newdata
=
{
628
width
=
olddata
.
width
,
629
height
=
olddata
.
height
,
630
depth
=
olddata
.
depth
,
631
italic
=
olddata
.
italic
,
632
kerns
=
olddata
.
kerns
,
633
tounicode
=
olddata
.
tounicode
,
634
commands
=
{
{
"
slot
"
,
slot
,
unicode
}
}
,
635
}
636
local
glyphdata
=
newdata
637
local
nextglyph
=
olddata
.
next
638
while
nextglyph
do
639
local
oldnextdata
=
original
[
nextglyph
]
640
if
oldnextdata
then
641
local
newnextdata
=
{
642
width
=
oldnextdata
.
width
,
643
height
=
oldnextdata
.
height
,
644
depth
=
oldnextdata
.
depth
,
645
tounicode
=
olddata
.
tounicode
,
646
commands
=
{
{
"
slot
"
,
slot
,
nextglyph
}
}
,
647
}
648
local
newnextglyph
=
addprivate
(
main
,
formatters
[
"
M-N-%H
"
]
(
nextglyph
)
,
newnextdata
)
649
newdata
.
next
=
newnextglyph
650
local
nextnextglyph
=
oldnextdata
.
next
651
if
nextnextglyph
=
=
nextglyph
then
652
break
653
else
654
olddata
=
oldnextdata
655
newdata
=
newnextdata
656
nextglyph
=
nextnextglyph
657
end
658
else
659
break
-- safeguard (when testing stuff)
660
end
661
end
662
local
hv
=
olddata
.
horiz_variants
663
if
hv
then
664
hv
=
fastcopy
(
hv
)
665
newdata
.
horiz_variants
=
hv
666
for
i
=
1
,
#
hv
do
667
local
hvi
=
hv
[
i
]
668
local
oldglyph
=
hvi
.
glyph
669
local
olddata
=
original
[
oldglyph
]
670
local
newdata
=
{
671
width
=
olddata
.
width
,
672
height
=
olddata
.
height
,
673
depth
=
olddata
.
depth
,
674
tounicode
=
olddata
.
tounicode
,
675
commands
=
{
{
"
slot
"
,
slot
,
oldglyph
}
}
,
676
}
677
hvi
.
glyph
=
addprivate
(
main
,
formatters
[
"
M-H-%H
"
]
(
oldglyph
)
,
newdata
)
678
end
679
end
680
local
vv
=
olddata
.
vert_variants
681
if
vv
then
682
vv
=
fastcopy
(
vv
)
683
newdata
.
vert_variants
=
vv
684
for
i
=
1
,
#
vv
do
685
local
vvi
=
vv
[
i
]
686
local
oldglyph
=
vvi
.
glyph
687
local
olddata
=
original
[
oldglyph
]
688
local
newdata
=
{
689
width
=
olddata
.
width
,
690
height
=
olddata
.
height
,
691
depth
=
olddata
.
depth
,
692
tounicode
=
olddata
.
tounicode
,
693
commands
=
{
{
"
slot
"
,
slot
,
oldglyph
}
}
,
694
}
695
vvi
.
glyph
=
addprivate
(
main
,
formatters
[
"
M-V-%H
"
]
(
oldglyph
)
,
newdata
)
696
end
697
end
698
return
newdata
699
end
700
end
701 702
vfmath
.
copy_glyph
=
copy_glyph
703 704
-- It's time to get rid of this type 1 mess ... take iwona: uppercase /A .. Z but
705
-- lowercase /a.math ... /z.math ... anyway, we now follow a slightly different
706
-- route: use the "order" field. I can probably make it a bit leaner but it's not
707
-- worth spending much time on now.
708 709
function
vfmath
.
define
(
specification
,
set
,
goodies
)
710
local
name
=
specification
.
name
-- symbolic name
711
local
size
=
specification
.
size
-- given size
712
local
loaded
=
{
}
713
local
fontlist
=
{
}
714
local
names
=
{
}
715
local
main
=
nil
716
local
start
=
(
trace_virtual
or
trace_timings
)
and
os
.
clock
(
)
717
local
okset
=
{
}
718
local
n
=
0
719
for
s
=
1
,
#
set
do
720
local
ss
=
set
[
s
]
721
local
ssname
=
ss
.
name
722
if
add_optional
and
ss
.
optional
then
723
if
trace_virtual
then
724
report_virtual
(
"
loading font %a subfont %s with name %a at %p is skipped
"
,
name
,
s
,
ssname
,
size
)
725
end
726
else
727
if
ss
.
features
then
728
ssname
=
ssname
.
.
"
*
"
.
.
ss
.
features
729
end
730
if
ss
.
main
then
731
main
=
s
732
end
733
local
alreadyloaded
=
names
[
ssname
]
-- for px we load one twice (saves .04 sec)
734
local
f
,
id
735
if
alreadyloaded
then
736
f
,
id
=
alreadyloaded
.
f
,
alreadyloaded
.
id
737
if
trace_virtual
then
738
report_virtual
(
"
loading font %a subfont %s with name %a is reused
"
,
name
,
s
,
ssname
)
739
end
740
else
741
f
,
id
=
fonts
.
constructors
.
readanddefine
(
ssname
,
size
)
742
names
[
ssname
]
=
{
f
=
f
,
id
=
id
}
743
end
744
if
not
f
or
id
=
=
0
then
745
report_virtual
(
"
loading font %a subfont %s with name %a at %p is skipped, not found
"
,
name
,
s
,
ssname
,
size
)
746
else
747
n
=
n
+
1
748
okset
[
n
]
=
ss
749
loaded
[
n
]
=
f
750
fontlist
[
n
]
=
{
id
=
id
,
size
=
size
}
751
if
not
shared
[
s
]
then
752
shared
[
n
]
=
{
}
753
end
754
if
trace_virtual
then
755
report_virtual
(
"
loading font %a subfont %s with name %a at %p as id %s using encoding %a
"
,
name
,
s
,
ssname
,
size
,
id
,
ss
.
vector
)
756
end
757
end
758
end
759
end
760
-- beware, loaded[1] is already passed to tex (we need to make a simple copy then .. todo)
761
local
parent
=
loaded
[
1
]
or
{
}
-- a text font
762
local
characters
=
{
}
763
local
parameters
=
{
}
764
local
mathparameters
=
{
}
765
local
descriptions
=
{
}
766
local
metadata
=
{
}
767
local
properties
=
{
768
hasitalics
=
true
,
769
hasmath
=
true
,
770
}
771
local
goodies
=
{
}
772
local
main
=
{
773
metadata
=
metadata
,
774
properties
=
properties
,
775
characters
=
characters
,
776
descriptions
=
descriptions
,
777
parameters
=
parameters
,
778
mathparameters
=
mathparameters
,
779
fonts
=
fontlist
,
780
goodies
=
goodies
,
781
--
782
fullname
=
properties
.
fullname
,
783
nomath
=
false
,
784
}
785
--
786
for
key
,
value
in
next
,
parent
do
787
if
type
(
value
)
~
=
"
table
"
then
788
main
[
key
]
=
value
789
end
790
end
791
--
792
if
parent
.
characters
then
793
for
unicode
,
character
in
next
,
parent
.
characters
do
794
characters
[
unicode
]
=
character
795
end
796
else
797
report_virtual
(
"
font %a has no characters
"
,
name
)
798
end
799
--
800
if
parent
.
parameters
then
801
for
key
,
value
in
next
,
parent
.
parameters
do
802
parameters
[
key
]
=
value
803
end
804
else
805
report_virtual
(
"
font %a has no parameters
"
,
name
)
806
end
807
--
808
local
description
=
{
name
=
"
<unset>
"
}
809
setmetatableindex
(
descriptions
,
function
(
)
return
description
end
)
810
--
811
if
parent
.
properties
then
812
setmetatableindex
(
properties
,
parent
.
properties
)
813
end
814
--
815
if
parent
.
goodies
then
816
setmetatableindex
(
goodies
,
parent
.
goodies
)
817
end
818
--
819
local
fullname
=
properties
.
fullname
-- parent via mt
820
if
fullname
then
821
unique
=
unique
+
1
822
properties
.
fullname
=
fullname
.
.
"
-
"
.
.
unique
823
end
824
--
825
if
not
parameters
.
x_height
then
826
parameters
.
x_height
=
0
827
end
828
--
829
local
already_reported
=
false
830
local
parameters_done
=
false
831
for
s
=
1
,
n
do
832
local
ss
,
fs
=
okset
[
s
]
,
loaded
[
s
]
833
if
not
fs
then
834
-- skip, error
835
elseif
add_optional
and
ss
.
optional
then
836
-- skip, redundant
837
else
838
local
newparameters
=
fs
.
parameters
839
local
newmathparameters
=
fs
.
mathparameters
840
if
newmathparameters
then
841
if
not
parameters_done
or
ss
.
parameters
then
842
mathparameters
=
newmathparameters
843
parameters_done
=
true
844
end
845
elseif
not
newparameters
then
846
report_virtual
(
"
no parameters set in font %a
"
,
name
)
847
elseif
ss
.
extension
then
848
mathparameters
.
math_x_height
=
newparameters
.
x_height
or
0
-- math_x_height : height of x
849
mathparameters
.
default_rule_thickness
=
newparameters
[
8
]
or
0
-- default_rule_thickness : thickness of \over bars
850
mathparameters
.
big_op_spacing1
=
newparameters
[
9
]
or
0
-- big_op_spacing1 : minimum clearance above a displayed op
851
mathparameters
.
big_op_spacing2
=
newparameters
[
10
]
or
0
-- big_op_spacing2 : minimum clearance below a displayed op
852
mathparameters
.
big_op_spacing3
=
newparameters
[
11
]
or
0
-- big_op_spacing3 : minimum baselineskip above displayed op
853
mathparameters
.
big_op_spacing4
=
newparameters
[
12
]
or
0
-- big_op_spacing4 : minimum baselineskip below displayed op
854
mathparameters
.
big_op_spacing5
=
newparameters
[
13
]
or
0
-- big_op_spacing5 : padding above and below displayed limits
855
-- report_virtual("loading and virtualizing font %a at size %p, setting ex parameters",name,size)
856
elseif
ss
.
parameters
then
857
mathparameters
.
x_height
=
newparameters
.
x_height
or
mathparameters
.
x_height
858
mathparameters
.
x_height
=
mathparameters
.
x_height
or
fp
.
x_height
or
0
-- x_height : height of x
859
mathparameters
.
num1
=
newparameters
[
8
]
or
0
-- num1 : numerator shift-up in display styles
860
mathparameters
.
num2
=
newparameters
[
9
]
or
0
-- num2 : numerator shift-up in non-display, non-\atop
861
mathparameters
.
num3
=
newparameters
[
10
]
or
0
-- num3 : numerator shift-up in non-display \atop
862
mathparameters
.
denom1
=
newparameters
[
11
]
or
0
-- denom1 : denominator shift-down in display styles
863
mathparameters
.
denom2
=
newparameters
[
12
]
or
0
-- denom2 : denominator shift-down in non-display styles
864
mathparameters
.
sup1
=
newparameters
[
13
]
or
0
-- sup1 : superscript shift-up in uncramped display style
865
mathparameters
.
sup2
=
newparameters
[
14
]
or
0
-- sup2 : superscript shift-up in uncramped non-display
866
mathparameters
.
sup3
=
newparameters
[
15
]
or
0
-- sup3 : superscript shift-up in cramped styles
867
mathparameters
.
sub1
=
newparameters
[
16
]
or
0
-- sub1 : subscript shift-down if superscript is absent
868
mathparameters
.
sub2
=
newparameters
[
17
]
or
0
-- sub2 : subscript shift-down if superscript is present
869
mathparameters
.
sup_drop
=
newparameters
[
18
]
or
0
-- sup_drop : superscript baseline below top of large box
870
mathparameters
.
sub_drop
=
newparameters
[
19
]
or
0
-- sub_drop : subscript baseline below bottom of large box
871
mathparameters
.
delim1
=
newparameters
[
20
]
or
0
-- delim1 : size of \atopwithdelims delimiters in display styles
872
mathparameters
.
delim2
=
newparameters
[
21
]
or
0
-- delim2 : size of \atopwithdelims delimiters in non-displays
873
mathparameters
.
axis_height
=
newparameters
[
22
]
or
0
-- axis_height : height of fraction lines above the baseline
874
-- report_virtual("loading and virtualizing font %a at size %p, setting sy parameters",name,size)
875
end
876
if
ss
.
overlay
then
877
local
fc
=
fs
.
characters
878
local
first
=
ss
.
first
879
if
first
then
880
local
last
=
ss
.
last
or
first
881
for
unicode
=
first
,
last
do
882
characters
[
unicode
]
=
copy_glyph
(
main
,
characters
,
fc
,
unicode
,
s
)
883
end
884
else
885
for
unicode
,
data
in
next
,
fc
do
886
characters
[
unicode
]
=
copy_glyph
(
main
,
characters
,
fc
,
unicode
,
s
)
887
end
888
end
889
else
890
local
vectorname
=
ss
.
vector
891
if
vectorname
then
892
local
offset
=
0xFF000
-- todo: -- private
893
local
vector
=
mathencodings
[
vectorname
]
894
local
rotcev
=
reverse
[
vectorname
]
895
local
isextension
=
ss
.
extension
896
if
vector
and
rotcev
then
897
local
fc
=
fs
.
characters
898
local
fd
=
fs
.
descriptions
899
local
si
=
shared
[
s
]
900
local
fontname
=
fs
.
properties
.
name
or
"
unknown
"
901
local
skewchar
=
ss
.
skewchar
902
local
backmap
=
ss
.
backmap
903
-- we need to know the original order because the loader has made a
904
-- unicode font of it and weird glyphnames have spoiled that a bit
905
if
backmap
then
906
backmap
=
{
}
907
for
unicode
,
character
in
next
,
fc
do
908
backmap
[
character
.
order
or
character
.
index
or
unicode
]
=
unicode
909
end
910
end
911
for
unicode
,
i
in
next
,
vector
do
912
-- So, here we can have an extra remapping (compared to mkiv).
913
local
index
=
backmap
and
backmap
[
i
]
or
i
914
local
fci
=
fc
[
index
]
915
if
not
fci
then
916
local
rf
=
reported
[
fontname
]
917
if
not
rf
then
rf
=
{
}
reported
[
fontname
]
=
rf
end
918
local
rv
=
rf
[
vectorname
]
919
if
not
rv
then
rv
=
{
}
rf
[
vectorname
]
=
rv
end
920
local
ru
=
rv
[
unicode
]
921
if
not
ru
then
922
if
trace_virtual
then
923
local
d
=
chardata
[
unicode
]
.
description
924
if
index
then
925
report_virtual
(
"
character %C has no index %H in vector %a for font %a (%S)
"
,
unicode
,
index
,
vectorname
,
fontname
,
d
)
926
else
927
report_virtual
(
"
character %C has no entry in vector %a for font %a (%S)
"
,
unicode
,
vectorname
,
fontname
,
d
)
928
end
929
elseif
not
already_reported
then
930
report_virtual
(
"
the mapping is incomplete for %a at %p
"
,
name
,
size
)
931
already_reported
=
true
932
end
933
rv
[
unicode
]
=
true
934
end
935
else
936
local
ref
=
si
[
index
]
937
if
not
ref
then
938
ref
=
{
{
'
slot
'
,
s
,
index
}
}
939
si
[
index
]
=
ref
940
end
941
local
kerns
=
fci
.
kerns
942
local
width
=
fci
.
width
943
local
italic
=
fci
.
italic
944
-- if trace_virtual then
945
-- report_virtual("character %C uses index %H in vector %a for font %a, %s, %s",
946
-- unicode,index,vectorname,fontname,
947
-- kerns and "adding kerns" or "no kerns",
948
-- kerns and "adding italic" or "no italic"
949
-- )
950
-- end
951
if
italic
and
italic
>
0
then
952
-- int_a^b
953
if
isextension
then
954
width
=
width
+
italic
-- for obscure reasons the integral as a width + italic correction
955
end
956
end
957
if
kerns
then
958
local
krn
=
{
}
959
for
k
,
v
in
next
,
kerns
do
-- kerns is sparse
960
local
rk
=
rotcev
[
k
]
961
if
rk
then
962
krn
[
rk
]
=
v
-- kerns[k]
963
end
964
end
965
if
not
next
(
krn
)
then
966
krn
=
nil
967
end
968
local
t
=
{
969
width
=
width
,
970
height
=
fci
.
height
,
971
depth
=
fci
.
depth
,
972
italic
=
italic
,
973
kerns
=
krn
,
974
commands
=
ref
,
975
}
976
if
skewchar
then
977
local
k
=
kerns
[
skewchar
]
978
if
k
then
979
t
.
top_accent
=
width
/
2
+
k
980
end
981
end
982
characters
[
unicode
]
=
t
983
else
984
characters
[
unicode
]
=
{
985
width
=
width
,
986
height
=
fci
.
height
,
987
depth
=
fci
.
depth
,
988
italic
=
italic
,
989
commands
=
ref
,
990
}
991
end
992
end
993
end
994
if
isextension
then
995
-- todo: if multiple ex, then 256 offsets per instance
996
local
extension
=
mathencodings
[
"
large-to-small
"
]
997
local
variants_done
=
fs
.
variants_done
998
for
index
,
fci
in
next
,
fc
do
-- the raw ex file
999
if
type
(
index
)
=
=
"
number
"
then
1000
local
ref
=
si
[
index
]
1001
if
not
ref
then
1002
ref
=
{
{
'
slot
'
,
s
,
index
}
}
1003
si
[
index
]
=
ref
1004
end
1005
local
italic
=
fci
.
italic
1006
local
t
=
{
1007
width
=
fci
.
width
,
1008
height
=
fci
.
height
,
1009
depth
=
fci
.
depth
,
1010
italic
=
italic
,
1011
commands
=
ref
,
1012
}
1013
local
n
=
fci
.
next
1014
if
n
then
1015
t
.
next
=
offset
+
n
1016
elseif
variants_done
then
1017
local
vv
=
fci
.
vert_variants
1018
if
vv
then
1019
t
.
vert_variants
=
vv
1020
end
1021
local
hv
=
fci
.
horiz_variants
1022
if
hv
then
1023
t
.
horiz_variants
=
hv
1024
end
1025
else
1026
local
vv
=
fci
.
vert_variants
1027
if
vv
then
1028
for
i
=
1
,
#
vv
do
1029
local
vvi
=
vv
[
i
]
1030
vvi
.
glyph
=
vvi
.
glyph
+
offset
1031
end
1032
t
.
vert_variants
=
vv
1033
end
1034
local
hv
=
fci
.
horiz_variants
1035
if
hv
then
1036
for
i
=
1
,
#
hv
do
1037
local
hvi
=
hv
[
i
]
1038
hvi
.
glyph
=
hvi
.
glyph
+
offset
1039
end
1040
t
.
horiz_variants
=
hv
1041
end
1042
end
1043
characters
[
offset
+
index
]
=
t
1044
end
1045
end
1046
fs
.
variants_done
=
true
1047
for
unicode
,
index
in
next
,
extension
do
1048
local
cu
=
characters
[
unicode
]
1049
if
cu
then
1050
cu
.
next
=
offset
+
index
1051
else
1052
local
fci
=
fc
[
index
]
1053
if
not
fci
then
1054
-- do nothing
1055
else
1056
-- probably never entered
1057
local
ref
=
si
[
index
]
1058
if
not
ref
then
1059
ref
=
{
{
'
slot
'
,
s
,
index
}
}
1060
si
[
index
]
=
ref
1061
end
1062
local
kerns
=
fci
.
kerns
1063
if
kerns
then
1064
local
krn
=
{
}
1065
-- for k=1,#kerns do
1066
-- krn[offset + k] = kerns[k]
1067
-- end
1068
for
k
,
v
in
next
,
kerns
do
-- is kerns sparse?
1069
krn
[
offset
+
k
]
=
v
1070
end
1071
characters
[
unicode
]
=
{
1072
width
=
fci
.
width
,
1073
height
=
fci
.
height
,
1074
depth
=
fci
.
depth
,
1075
italic
=
fci
.
italic
,
1076
commands
=
ref
,
1077
kerns
=
krn
,
1078
next
=
offset
+
index
,
1079
}
1080
else
1081
characters
[
unicode
]
=
{
1082
width
=
fci
.
width
,
1083
height
=
fci
.
height
,
1084
depth
=
fci
.
depth
,
1085
italic
=
fci
.
italic
,
1086
commands
=
ref
,
1087
next
=
offset
+
index
,
1088
}
1089
end
1090
end
1091
end
1092
end
1093
end
1094
else
1095
report_virtual
(
"
error in loading %a, problematic vector %a
"
,
name
,
vectorname
)
1096
end
1097
end
1098
end
1099
mathematics
.
extras
.
copy
(
main
)
--not needed here (yet)
1100
end
1101
end
1102
-- inspect(characters[0x1D465])
1103
-- inspect(fonts.encodings.math["tex-it"])
1104
-- inspect(fontlist)
1105
--
1106
main
.
mathparameters
=
mathparameters
-- still traditional ones
1107
-- This should change (some day) as it's the only place where we look forward,
1108
-- so better is to also reserve the id already which then involves some more
1109
-- management (so not now).
1110
fontlist
[
#
fontlist
+
1
]
=
{
1111
-- id = font.nextid(),
1112
id
=
0
,
-- self
1113
size
=
size
,
1114
}
1115
vfmath
.
addmissing
(
main
,
#
fontlist
,
size
)
1116
--
1117
mathematics
.
addfallbacks
(
main
)
1118
--
1119
main
.
properties
.
math_is_scaled
=
true
-- signal
1120
fonts
.
constructors
.
assignmathparameters
(
main
,
main
)
1121
--
1122
main
.
MathConstants
=
main
.
mathparameters
-- we directly pass it to TeX (bypasses the scaler) so this is needed
1123
--
1124
if
trace_virtual
or
trace_timings
then
1125
report_virtual
(
"
loading and virtualizing font %a at size %p took %0.3f seconds
"
,
name
,
size
,
os
.
clock
(
)
-
start
)
1126
end
1127
--
1128
main
.
oldmath
=
true
1129
return
main
1130
end
1131 1132
function
mathematics
.
makefont
(
name
,
set
,
goodies
)
1133
fonts
.
definers
.
methods
.
variants
[
name
]
=
function
(
specification
)
1134
return
vfmath
.
define
(
specification
,
set
,
goodies
)
1135
end
1136
end
1137 1138
-- helpers
1139 1140
function
vfmath
.
setletters
(
font_encoding
,
name
,
uppercase
,
lowercase
)
1141
local
enc
=
font_encoding
[
name
]
1142
for
i
=
0
,
25
do
1143
enc
[
uppercase
+
i
]
=
i
+
0x41
1144
enc
[
lowercase
+
i
]
=
i
+
0x61
1145
end
1146
end
1147 1148
function
vfmath
.
setdigits
(
font_encoding
,
name
,
digits
)
1149
local
enc
=
font_encoding
[
name
]
1150
for
i
=
0
,
9
do
1151
enc
[
digits
+
i
]
=
i
+
0x30
1152
end
1153
end
1154