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