math-act.lua /size: 30 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
math-act
'
]
=
{
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
-- Here we tweak some font properties (if needed).
10 11
local
type
,
next
=
type
,
next
12
local
fastcopy
,
insert
,
remove
=
table
.
fastcopy
,
table
.
insert
,
table
.
remove
13
local
formatters
=
string
.
formatters
14 15
local
trace_defining
=
false
trackers
.
register
(
"
math.defining
"
,
function
(
v
)
trace_defining
=
v
end
)
16
local
trace_collecting
=
false
trackers
.
register
(
"
math.collecting
"
,
function
(
v
)
trace_collecting
=
v
end
)
17 18
local
report_math
=
logs
.
reporter
(
"
mathematics
"
,
"
initializing
"
)
19 20
local
context
=
context
21
local
commands
=
commands
22
local
mathematics
=
mathematics
23
local
texsetdimen
=
tex
.
setdimen
24
local
abs
=
math
.
abs
25 26
local
helpers
=
fonts
.
helpers
27
local
upcommand
=
helpers
.
commands
.
up
28
local
rightcommand
=
helpers
.
commands
.
right
29
local
charcommand
=
helpers
.
commands
.
char
30
local
prependcommands
=
helpers
.
prependcommands
31 32
local
sequencers
=
utilities
.
sequencers
33
local
appendgroup
=
sequencers
.
appendgroup
34
local
appendaction
=
sequencers
.
appendaction
35 36
local
fontchars
=
fonts
.
hashes
.
characters
37
local
fontproperties
=
fonts
.
hashes
.
properties
38 39
local
mathfontparameteractions
=
sequencers
.
new
{
40
name
=
"
mathparameters
"
,
41
arguments
=
"
target,original
"
,
42
}
43 44
appendgroup
(
"
mathparameters
"
,
"
before
"
)
-- user
45
appendgroup
(
"
mathparameters
"
,
"
system
"
)
-- private
46
appendgroup
(
"
mathparameters
"
,
"
after
"
)
-- user
47 48
function
fonts
.
constructors
.
assignmathparameters
(
original
,
target
)
49
local
runner
=
mathfontparameteractions
.
runner
50
if
runner
then
51
runner
(
original
,
target
)
52
end
53
end
54 55
function
mathematics
.
initializeparameters
(
target
,
original
)
56
local
mathparameters
=
original
.
mathparameters
57
if
mathparameters
and
next
(
mathparameters
)
then
58
mathparameters
=
mathematics
.
dimensions
(
mathparameters
)
59
if
not
mathparameters
.
SpaceBeforeScript
then
60
mathparameters
.
SpaceBeforeScript
=
mathparameters
.
SpaceAfterScript
61
end
62
target
.
mathparameters
=
mathparameters
63
end
64
end
65 66
sequencers
.
appendaction
(
"
mathparameters
"
,
"
system
"
,
"
mathematics.initializeparameters
"
)
67 68
local
how
=
{
69
-- RadicalKernBeforeDegree = "horizontal",
70
-- RadicalKernAfterDegree = "horizontal",
71
ScriptPercentScaleDown
=
"
unscaled
"
,
72
ScriptScriptPercentScaleDown
=
"
unscaled
"
,
73
RadicalDegreeBottomRaisePercent
=
"
unscaled
"
,
74
NoLimitSupFactor
=
"
unscaled
"
,
75
NoLimitSubFactor
=
"
unscaled
"
,
76
}
77 78
function
mathematics
.
scaleparameters
(
target
,
original
)
79
if
not
target
.
properties
.
math_is_scaled
then
80
local
mathparameters
=
target
.
mathparameters
81
if
mathparameters
and
next
(
mathparameters
)
then
82
local
parameters
=
target
.
parameters
83
local
factor
=
parameters
.
factor
84
local
hfactor
=
parameters
.
hfactor
85
local
vfactor
=
parameters
.
vfactor
86
for
name
,
value
in
next
,
mathparameters
do
87
local
h
=
how
[
name
]
88
if
h
=
=
"
unscaled
"
then
89
-- kept
90
elseif
h
=
=
"
horizontal
"
then
91
value
=
value
*
hfactor
92
elseif
h
=
=
"
vertical
"
then
93
value
=
value
*
vfactor
94
else
95
value
=
value
*
factor
96
end
97
mathparameters
[
name
]
=
value
98
end
99
end
100
target
.
properties
.
math_is_scaled
=
true
101
end
102
end
103 104
-- AccentBaseHeight vs FlattenedAccentBaseHeight
105 106
function
mathematics
.
checkaccentbaseheight
(
target
,
original
)
107
local
mathparameters
=
target
.
mathparameters
108
if
mathparameters
and
mathparameters
.
AccentBaseHeight
=
=
0
then
109
mathparameters
.
AccentBaseHeight
=
target
.
parameters
.
x_height
-- needs checking
110
end
111
end
112 113
function
mathematics
.
checkprivateparameters
(
target
,
original
)
114
local
mathparameters
=
target
.
mathparameters
115
if
mathparameters
then
116
local
parameters
=
target
.
parameters
117
local
properties
=
target
.
properties
118
if
parameters
then
119
local
size
=
parameters
.
size
120
if
size
then
121
if
not
mathparameters
.
FractionDelimiterSize
then
122
mathparameters
.
FractionDelimiterSize
=
1
.
01
*
size
123
end
124
if
not
mathparameters
.
FractionDelimiterDisplayStyleSize
then
125
mathparameters
.
FractionDelimiterDisplayStyleSize
=
2
.
40
*
size
126
end
127
elseif
properties
then
128
report_math
(
"
invalid parameters in font %a
"
,
properties
.
fullname
or
"
?
"
)
129
else
130
report_math
(
"
invalid parameters in font
"
)
131
end
132
elseif
properties
then
133
report_math
(
"
no parameters in font %a
"
,
properties
.
fullname
or
"
?
"
)
134
else
135
report_math
(
"
no parameters and properties in font
"
)
136
end
137
end
138
end
139 140
function
mathematics
.
overloadparameters
(
target
,
original
)
141
local
mathparameters
=
target
.
mathparameters
142
if
mathparameters
and
next
(
mathparameters
)
then
143
local
goodies
=
target
.
goodies
144
if
goodies
then
145
for
i
=
1
,
#
goodies
do
146
local
goodie
=
goodies
[
i
]
147
local
mathematics
=
goodie
.
mathematics
148
local
parameters
=
mathematics
and
mathematics
.
parameters
149
if
parameters
then
150
if
trace_defining
then
151
report_math
(
"
overloading math parameters in %a @ %p
"
,
target
.
properties
.
fullname
,
target
.
parameters
.
size
)
152
end
153
for
name
,
value
in
next
,
parameters
do
154
local
tvalue
=
type
(
value
)
155
if
tvalue
=
=
"
string
"
then
156
report_math
(
"
comment for math parameter %a: %s
"
,
name
,
value
)
157
else
158
local
oldvalue
=
mathparameters
[
name
]
159
local
newvalue
=
oldvalue
160
if
oldvalue
then
161
if
tvalue
=
=
"
number
"
then
162
newvalue
=
value
163
elseif
tvalue
=
=
"
function
"
then
164
newvalue
=
value
(
oldvalue
,
target
,
original
)
165
elseif
not
tvalue
then
166
newvalue
=
nil
167
end
168
if
trace_defining
and
oldvalue
~
=
newvalue
then
169
report_math
(
"
overloading math parameter %a: %S => %S
"
,
name
,
oldvalue
,
newvalue
)
170
end
171
else
172
report_math
(
"
invalid math parameter %a
"
,
name
)
173
end
174
mathparameters
[
name
]
=
newvalue
175
end
176
end
177
end
178
end
179
end
180
end
181
end
182 183
local
function
applytweaks
(
when
,
target
,
original
)
184
local
goodies
=
original
.
goodies
185
if
goodies
then
186
for
i
=
1
,
#
goodies
do
187
local
goodie
=
goodies
[
i
]
188
local
mathematics
=
goodie
.
mathematics
189
local
tweaks
=
mathematics
and
mathematics
.
tweaks
190
if
type
(
tweaks
)
=
=
"
table
"
then
191
tweaks
=
tweaks
[
when
]
192
if
type
(
tweaks
)
=
=
"
table
"
then
193
if
trace_defining
then
194
report_math
(
"
tweaking math of %a @ %p (%s)
"
,
target
.
properties
.
fullname
,
target
.
parameters
.
size
,
when
)
195
end
196
for
i
=
1
,
#
tweaks
do
197
local
tweak
=
tweaks
[
i
]
198
local
tvalue
=
type
(
tweak
)
199
if
tvalue
=
=
"
function
"
then
200
tweak
(
target
,
original
)
201
end
202
end
203
end
204
end
205
end
206
end
207
end
208 209
function
mathematics
.
tweakbeforecopyingfont
(
target
,
original
)
210
local
mathparameters
=
target
.
mathparameters
-- why not hasmath
211
if
mathparameters
then
212
applytweaks
(
"
beforecopying
"
,
target
,
original
)
213
end
214
end
215 216
function
mathematics
.
tweakaftercopyingfont
(
target
,
original
)
217
local
mathparameters
=
target
.
mathparameters
-- why not hasmath
218
if
mathparameters
then
219
applytweaks
(
"
aftercopying
"
,
target
,
original
)
220
end
221
end
222 223
sequencers
.
appendaction
(
"
mathparameters
"
,
"
system
"
,
"
mathematics.scaleparameters
"
)
224
sequencers
.
appendaction
(
"
mathparameters
"
,
"
system
"
,
"
mathematics.checkaccentbaseheight
"
)
-- should go in lfg instead
225
sequencers
.
appendaction
(
"
mathparameters
"
,
"
system
"
,
"
mathematics.checkprivateparameters
"
)
-- after scaling !
226
sequencers
.
appendaction
(
"
mathparameters
"
,
"
system
"
,
"
mathematics.overloadparameters
"
)
227 228
sequencers
.
appendaction
(
"
beforecopyingcharacters
"
,
"
system
"
,
"
mathematics.tweakbeforecopyingfont
"
)
229
sequencers
.
appendaction
(
"
aftercopyingcharacters
"
,
"
system
"
,
"
mathematics.tweakaftercopyingfont
"
)
230 231
local
virtualized
=
mathematics
.
virtualized
232 233
function
mathematics
.
overloaddimensions
(
target
,
original
,
set
)
234
local
goodies
=
target
.
goodies
235
if
goodies
then
236
for
i
=
1
,
#
goodies
do
237
local
goodie
=
goodies
[
i
]
238
local
mathematics
=
goodie
.
mathematics
239
local
dimensions
=
mathematics
and
mathematics
.
dimensions
240
if
dimensions
then
241
if
trace_defining
then
242
report_math
(
"
overloading dimensions in %a @ %p
"
,
target
.
properties
.
fullname
,
target
.
parameters
.
size
)
243
end
244
local
characters
=
target
.
characters
245
local
descriptions
=
target
.
descriptions
246
local
parameters
=
target
.
parameters
247
local
factor
=
parameters
.
factor
248
local
hfactor
=
parameters
.
hfactor
249
local
vfactor
=
parameters
.
vfactor
250
-- to be sure
251
target
.
type
=
"
virtual
"
252
target
.
properties
.
virtualized
=
true
253
--
254
local
function
overload
(
dimensions
)
255
for
unicode
,
data
in
next
,
dimensions
do
256
local
character
=
characters
[
unicode
]
257
if
not
character
then
258
local
c
=
virtualized
[
unicode
]
259
if
c
then
260
character
=
characters
[
c
]
261
end
262
end
263
if
character
then
264
--
265
local
width
=
data
.
width
266
local
height
=
data
.
height
267
local
depth
=
data
.
depth
268
if
trace_defining
and
(
width
or
height
or
depth
)
then
269
report_math
(
"
overloading dimensions of %C, width %p, height %p, depth %p
"
,
270
unicode
,
width
or
0
,
height
or
0
,
depth
or
0
)
271
end
272
if
width
then
character
.
width
=
width
*
hfactor
end
273
if
height
then
character
.
height
=
height
*
vfactor
end
274
if
depth
then
character
.
depth
=
depth
*
vfactor
end
275
--
276
local
xoffset
=
data
.
xoffset
277
local
yoffset
=
data
.
yoffset
278
if
xoffset
=
=
"
llx
"
then
279
local
d
=
descriptions
[
unicode
]
280
if
d
then
281
xoffset
=
-
d
.
boundingbox
[
1
]
*
hfactor
282
character
.
width
=
character
.
width
+
xoffset
283
xoffset
=
rightcommand
[
xoffset
]
284
else
285
xoffset
=
nil
286
end
287
elseif
xoffset
and
xoffset
~
=
0
then
288
xoffset
=
rightcommand
[
xoffset
*
hfactor
]
289
else
290
xoffset
=
nil
291
end
292
if
yoffset
and
yoffset
~
=
0
then
293
yoffset
=
upcommand
[
yoffset
*
vfactor
]
294
else
295
yoffset
=
nil
296
end
297
if
xoffset
or
yoffset
then
298
local
commands
=
characters
.
commands
299
if
commands
then
300
prependcommands
(
commands
,
yoffset
,
xoffset
)
301
else
302
local
slot
=
charcommand
[
unicode
]
303
if
xoffset
and
yoffset
then
304
character
.
commands
=
{
xoffset
,
yoffset
,
slot
}
305
elseif
xoffset
then
306
character
.
commands
=
{
xoffset
,
slot
}
307
else
308
character
.
commands
=
{
yoffset
,
slot
}
309
end
310
end
311
end
312
elseif
trace_defining
then
313
report_math
(
"
no overloading dimensions of %C, not in font
"
,
unicode
)
314
end
315
end
316
end
317
if
set
=
=
nil
then
318
set
=
{
"
default
"
}
319
end
320
if
set
=
=
"
all
"
or
set
=
=
true
then
321
for
name
,
set
in
next
,
dimensions
do
322
overload
(
set
)
323
end
324
else
325
if
type
(
set
)
=
=
"
string
"
then
326
set
=
utilities
.
parsers
.
settings_to_array
(
set
)
327
end
328
if
type
(
set
)
=
=
"
table
"
then
329
for
i
=
1
,
#
set
do
330
local
d
=
dimensions
[
set
[
i
]
]
331
if
d
then
332
overload
(
d
)
333
end
334
end
335
end
336
end
337
end
338
end
339
end
340
end
341 342
-- no, it's a feature now (see good-mth):
343
--
344
-- sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions")
345 346
-- a couple of predefined tweaks:
347 348
local
tweaks
=
{
}
349
mathematics
.
tweaks
=
tweaks
350 351
-- function tweaks.fixbadprime(target,original)
352
-- target.characters[0xFE325] = target.characters[0x2032]
353
-- end
354 355
-- these could go to math-fbk
356 357
-- local function accent_to_extensible(target,newchr,original,oldchr,height,depth,swap)
358
-- local characters = target.characters
359
-- -- if not characters[newchr] then -- xits needs an enforce
360
-- local addprivate = fonts.helpers.addprivate
361
-- local olddata = characters[oldchr]
362
-- if olddata then
363
-- if swap then
364
-- swap = characters[swap]
365
-- height = swap.depth
366
-- depth = 0
367
-- else
368
-- height = height or 0
369
-- depth = depth or 0
370
-- end
371
-- local correction = swap and { "down", (olddata.height or 0) - height } or { "down", olddata.height }
372
-- local newdata = {
373
-- commands = { correction, { "slot", 1, oldchr } },
374
-- width = olddata.width,
375
-- height = height,
376
-- depth = depth,
377
-- }
378
-- characters[newchr] = newdata
379
-- local nextglyph = olddata.next
380
-- while nextglyph do
381
-- local oldnextdata = characters[nextglyph]
382
-- local newnextdata = {
383
-- commands = { correction, { "slot", 1, nextglyph } },
384
-- width = oldnextdata.width,
385
-- height = height,
386
-- depth = depth,
387
-- }
388
-- local newnextglyph = addprivate(target,formatters["original-%H"](nextglyph),newnextdata)
389
-- newdata.next = newnextglyph
390
-- local nextnextglyph = oldnextdata.next
391
-- if nextnextglyph == nextglyph then
392
-- break
393
-- else
394
-- olddata = oldnextdata
395
-- newdata = newnextdata
396
-- nextglyph = nextnextglyph
397
-- end
398
-- end
399
-- local hv = olddata.horiz_variants
400
-- if hv then
401
-- hv = fastcopy(hv)
402
-- newdata.horiz_variants = hv
403
-- for i=1,#hv do
404
-- local hvi = hv[i]
405
-- local oldglyph = hvi.glyph
406
-- local olddata = characters[oldglyph]
407
-- local newdata = {
408
-- commands = { correction, { "slot", 1, oldglyph } },
409
-- width = olddata.width,
410
-- height = height,
411
-- depth = depth,
412
-- }
413
-- hvi.glyph = addprivate(target,formatters["original-%H"](oldglyph),newdata)
414
-- end
415
-- end
416
-- end
417
-- -- end
418
-- end
419 420
-- function tweaks.fixoverline(target,original)
421
-- local height, depth = 0, 0
422
-- local mathparameters = target.mathparameters
423
-- if mathparameters then
424
-- height = mathparameters.OverbarVerticalGap
425
-- depth = mathparameters.UnderbarVerticalGap
426
-- else
427
-- height = target.parameters.xheight/4
428
-- depth = height
429
-- end
430
-- accent_to_extensible(target,0x203E,original,0x0305,height,depth)
431
-- -- also crappy spacing for our purpose: push to top of baseline
432
-- accent_to_extensible(target,0xFE3DE,original,0x23DE,height,depth,0x23DF)
433
-- accent_to_extensible(target,0xFE3DC,original,0x23DC,height,depth,0x23DD)
434
-- accent_to_extensible(target,0xFE3B4,original,0x23B4,height,depth,0x23B5)
435
-- -- for symmetry
436
-- target.characters[0xFE3DF] = original.characters[0x23DF]
437
-- target.characters[0xFE3DD] = original.characters[0x23DD]
438
-- target.characters[0xFE3B5] = original.characters[0x23B5]
439
-- -- inspect(fonts.helpers.expandglyph(target.characters,0x203E))
440
-- -- inspect(fonts.helpers.expandglyph(target.characters,0x23DE))
441
-- end
442 443
-- sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweaks.fixoverline") -- for the moment always
444 445
-- helpers
446 447
local
setmetatableindex
=
table
.
setmetatableindex
448 449
local
getfontoffamily
=
tex
.
getfontoffamily
450 451
local
fontcharacters
=
fonts
.
hashes
.
characters
452
local
extensibles
=
utilities
.
storage
.
allocate
(
)
453
fonts
.
hashes
.
extensibles
=
extensibles
454 455
local
chardata
=
characters
.
data
456
local
extensibles
=
mathematics
.
extensibles
457 458
-- we use numbers at the tex end (otherwise we could stick to chars)
459 460
local
e_left
=
extensibles
.
left
461
local
e_right
=
extensibles
.
right
462
local
e_horizontal
=
extensibles
.
horizontal
463
local
e_mixed
=
extensibles
.
mixed
464
local
e_unknown
=
extensibles
.
unknown
465 466
local
unknown
=
{
e_unknown
,
false
,
false
}
467 468
local
function
extensiblecode
(
font
,
unicode
)
469
local
characters
=
fontcharacters
[
font
]
470
local
character
=
characters
[
unicode
]
471
if
not
character
then
472
return
unknown
473
end
474
local
first
=
character
.
next
475
local
code
=
unicode
476
local
next
=
first
477
while
next
do
478
code
=
next
479
character
=
characters
[
next
]
480
next
=
character
.
next
481
end
482
local
char
=
chardata
[
unicode
]
483
if
not
char
then
484
return
unknown
485
end
486
if
character
.
horiz_variants
then
487
if
character
.
vert_variants
then
488
return
{
e_mixed
,
code
,
character
}
489
else
490
local
m
=
char
.
mathextensible
491
local
e
=
m
and
extensibles
[
m
]
492
return
e
and
{
e
,
code
,
character
}
or
unknown
493
end
494
elseif
character
.
vert_variants
then
495
local
m
=
char
.
mathextensible
496
local
e
=
m
and
extensibles
[
m
]
497
return
e
and
{
e
,
code
,
character
}
or
unknown
498
elseif
first
then
499
-- assume accent (they seldom stretch .. sizes)
500
local
m
=
char
.
mathextensible
or
char
.
mathstretch
501
local
e
=
m
and
extensibles
[
m
]
502
return
e
and
{
e
,
code
,
character
}
or
unknown
503
else
504
return
unknown
505
end
506
end
507 508
setmetatableindex
(
extensibles
,
function
(
extensibles
,
font
)
509
local
codes
=
{
}
510
setmetatableindex
(
codes
,
function
(
codes
,
unicode
)
511
local
status
=
extensiblecode
(
font
,
unicode
)
512
codes
[
unicode
]
=
status
513
return
status
514
end
)
515
extensibles
[
font
]
=
codes
516
return
codes
517
end
)
518 519
local
function
extensiblecode
(
family
,
unicode
)
520
return
extensibles
[
getfontoffamily
(
family
or
0
)
]
[
unicode
]
[
1
]
521
end
522 523
-- left : [head] ...
524
-- right : ... [head]
525
-- horizontal : [head] ... [head]
526
--
527
-- abs(right["start"] - right["end"]) | right.advance | characters[right.glyph].width
528 529
local
function
horizontalcode
(
family
,
unicode
)
530
local
font
=
getfontoffamily
(
family
or
0
)
531
local
data
=
extensibles
[
font
]
[
unicode
]
532
local
kind
=
data
[
1
]
533
local
loffset
=
0
534
local
roffset
=
0
535
if
kind
=
=
e_left
then
536
local
charlist
=
data
[
3
]
.
horiz_variants
537
if
charlist
then
538
local
left
=
charlist
[
1
]
539
loffset
=
abs
(
(
left
[
"
start
"
]
or
0
)
-
(
left
[
"
end
"
]
or
0
)
)
540
end
541
elseif
kind
=
=
e_right
then
542
local
charlist
=
data
[
3
]
.
horiz_variants
543
if
charlist
then
544
local
right
=
charlist
[
#
charlist
]
545
roffset
=
abs
(
(
right
[
"
start
"
]
or
0
)
-
(
right
[
"
end
"
]
or
0
)
)
546
end
547
elseif
kind
=
=
e_horizontal
then
548
local
charlist
=
data
[
3
]
.
horiz_variants
549
if
charlist
then
550
local
left
=
charlist
[
1
]
551
local
right
=
charlist
[
#
charlist
]
552
loffset
=
abs
(
(
left
[
"
start
"
]
or
0
)
-
(
left
[
"
end
"
]
or
0
)
)
553
roffset
=
abs
(
(
right
[
"
start
"
]
or
0
)
-
(
right
[
"
end
"
]
or
0
)
)
554
end
555
end
556
return
kind
,
loffset
,
roffset
557
end
558 559
mathematics
.
extensiblecode
=
extensiblecode
560
mathematics
.
horizontalcode
=
horizontalcode
561 562
interfaces
.
implement
{
563
name
=
"
extensiblecode
"
,
564
arguments
=
{
"
integer
"
,
"
integer
"
}
,
565
actions
=
{
extensiblecode
,
context
}
566
}
567 568
interfaces
.
implement
{
569
name
=
"
horizontalcode
"
,
570
arguments
=
{
"
integer
"
,
"
integer
"
}
,
571
actions
=
function
(
family
,
unicode
)
572
local
kind
,
loffset
,
roffset
=
horizontalcode
(
family
,
unicode
)
573
texsetdimen
(
"
scratchleftoffset
"
,
loffset
)
574
texsetdimen
(
"
scratchrightoffset
"
,
roffset
)
575
context
(
kind
)
576
end
577
}
578 579
-- experiment
580 581
-- check: when true, only set when present in font
582
-- force: when false, then not set when already set
583 584
-- todo: tounicode
585 586
-- function mathematics.injectfallbacks(target,original)
587
-- local properties = original.properties
588
-- if properties and properties.hasmath then
589
-- local specification = target.specification
590
-- if specification then
591
-- local fallbacks = specification.fallbacks
592
-- if fallbacks then
593
-- local definitions = fonts.collections.definitions[fallbacks]
594
-- if definitions then
595
-- if trace_collecting then
596
-- report_math("adding fallback characters to font %a",specification.hash)
597
-- end
598
-- local definedfont = fonts.definers.internal
599
-- local copiedglyph = fonts.handlers.vf.math.copy_glyph
600
-- local fonts = target.fonts
601
-- local size = specification.size -- target.size
602
-- local characters = target.characters
603
-- if not fonts then
604
-- fonts = { }
605
-- target.fonts = fonts
606
-- target.type = "virtual"
607
-- target.properties.virtualized = true
608
-- end
609
-- if #fonts == 0 then
610
-- fonts[1] = { id = 0, size = size } -- sel, will be resolved later
611
-- end
612
-- local done = { }
613
-- for i=1,#definitions do
614
-- local definition = definitions[i]
615
-- local name = definition.font
616
-- local start = definition.start
617
-- local stop = definition.stop
618
-- local gaps = definition.gaps
619
-- local check = definition.check
620
-- local force = definition.force
621
-- local rscale = definition.rscale or 1
622
-- local offset = definition.offset or start
623
-- local id = definedfont { name = name, size = size * rscale }
624
-- local index = #fonts + 1
625
-- fonts[index] = { id = id, size = size }
626
-- local chars = fontchars[id]
627
-- local function remap(unic,unicode,gap)
628
-- -- local unic = unicode + offset - start
629
-- if check and not chars[unicode] then
630
-- -- not in font
631
-- elseif force or (not done[unic] and not characters[unic]) then
632
-- if trace_collecting then
633
-- report_math("remapping math character, vector %a, font %a, character %C%s%s",
634
-- fallbacks,name,unic,check and ", checked",gap and ", gap plugged")
635
-- end
636
-- characters[unic] = copiedglyph(target,characters,chars,unicode,index)
637
-- done[unic] = true
638
-- end
639
-- end
640
-- for unicode = start, stop do
641
-- local unic = unicode + offset - start
642
-- remap(unic,unicode,false)
643
-- end
644
-- if gaps then
645
-- for unic, unicode in next, gaps do
646
-- remap(unic,unicode,true)
647
-- end
648
-- end
649
-- end
650
-- end
651
-- end
652
-- end
653
-- end
654
-- end
655
--
656
-- sequencers.appendaction("aftercopyingcharacters", "system","mathematics.finishfallbacks")
657 658
local
stack
=
{
}
659 660
function
mathematics
.
registerfallbackid
(
n
,
id
,
name
)
661
if
trace_collecting
then
662
report_math
(
"
resolved fallback font %i, name %a, id %a, used %a
"
,
663
n
,
name
,
id
,
fontproperties
[
id
]
.
fontname
)
664
end
665
stack
[
#
stack
]
[
n
]
=
id
666
end
667 668
interfaces
.
implement
{
-- will be shared with text
669
name
=
"
registerfontfallbackid
"
,
670
arguments
=
{
"
integer
"
,
"
integer
"
,
"
string
"
}
,
671
actions
=
mathematics
.
registerfallbackid
,
672
}
673 674
function
mathematics
.
resolvefallbacks
(
target
,
specification
,
fallbacks
)
675
local
definitions
=
fonts
.
collections
.
definitions
[
fallbacks
]
676
if
definitions
then
677
local
size
=
specification
.
size
-- target.size
678
local
list
=
{
}
679
insert
(
stack
,
list
)
680
context
.
pushcatcodes
(
"
prt
"
)
-- context.unprotect()
681
for
i
=
1
,
#
definitions
do
682
local
definition
=
definitions
[
i
]
683
local
name
=
definition
.
font
684
local
features
=
definition
.
features
or
"
"
685
local
size
=
size
*
(
definition
.
rscale
or
1
)
686
context
.
font_fallbacks_register_math
(
i
,
name
,
features
,
size
)
687
if
trace_collecting
then
688
report_math
(
"
registering fallback font %i, name %a, size %a, features %a
"
,
i
,
name
,
size
,
features
)
689
end
690
end
691
context
.
popcatcodes
(
)
692
end
693
end
694 695
function
mathematics
.
finishfallbacks
(
target
,
specification
,
fallbacks
)
696
local
list
=
remove
(
stack
)
697
if
list
and
#
list
>
0
then
698
local
definitions
=
fonts
.
collections
.
definitions
[
fallbacks
]
699
if
definitions
and
#
definitions
>
0
then
700
if
trace_collecting
then
701
report_math
(
"
adding fallback characters to font %a
"
,
specification
.
hash
)
702
end
703
local
definedfont
=
fonts
.
definers
.
internal
704
local
copiedglyph
=
fonts
.
handlers
.
vf
.
math
.
copy_glyph
705
local
fonts
=
target
.
fonts
706
local
size
=
specification
.
size
-- target.size
707
local
characters
=
target
.
characters
708
if
not
fonts
then
709
fonts
=
{
}
710
target
.
fonts
=
fonts
711
end
712
target
.
type
=
"
virtual
"
713
target
.
properties
.
virtualized
=
true
714
if
#
fonts
=
=
0
then
715
fonts
[
1
]
=
{
id
=
0
,
size
=
size
}
-- self, will be resolved later
716
end
717
local
done
=
{
}
718
for
i
=
1
,
#
definitions
do
719
local
definition
=
definitions
[
i
]
720
local
name
=
definition
.
font
721
local
start
=
definition
.
start
722
local
stop
=
definition
.
stop
723
local
gaps
=
definition
.
gaps
724
local
check
=
definition
.
check
725
local
force
=
definition
.
force
726
local
rscale
=
definition
.
rscale
or
1
727
local
offset
=
definition
.
offset
or
start
728
local
id
=
list
[
i
]
729
if
id
then
730
local
index
=
#
fonts
+
1
731
fonts
[
index
]
=
{
id
=
id
,
size
=
size
}
732
local
chars
=
fontchars
[
id
]
733
local
function
remap
(
unic
,
unicode
,
gap
)
734
if
check
and
not
chars
[
unicode
]
then
735
return
736
end
737
if
force
or
(
not
done
[
unic
]
and
not
characters
[
unic
]
)
then
738
if
trace_collecting
then
739
report_math
(
"
replacing math character %C by %C using vector %a and font id %a for %a%s%s
"
,
740
unic
,
unicode
,
fallbacks
,
id
,
fontproperties
[
id
]
.
fontname
,
check
and
"
, checked
"
,
gap
and
"
, gap plugged
"
)
741
end
742
characters
[
unic
]
=
copiedglyph
(
target
,
characters
,
chars
,
unicode
,
index
)
743
done
[
unic
]
=
true
744
end
745
end
746
local
step
=
offset
-
start
747
for
unicode
=
start
,
stop
do
748
remap
(
unicode
+
step
,
unicode
,
false
)
749
end
750
if
gaps
then
751
for
unic
,
unicode
in
next
,
gaps
do
752
remap
(
unic
,
unicode
,
true
)
753
remap
(
unicode
,
unicode
,
true
)
754
end
755
end
756
end
757
end
758
elseif
trace_collecting
then
759
report_math
(
"
no fallback characters added to font %a
"
,
specification
.
hash
)
760
end
761
end
762
end
763