font-imp-effects.lua /size: 12 Kb    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
font-imp-effects
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to font-ini.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
-- todo: pickup from goodies: if type(effect) then ...
10 11
local
next
,
type
,
tonumber
=
next
,
type
,
tonumber
12
local
is_boolean
=
string
.
is_boolean
13 14
local
fonts
=
fonts
15 16
local
handlers
=
fonts
.
handlers
17
local
registerotffeature
=
handlers
.
otf
.
features
.
register
18
local
registerafmfeature
=
handlers
.
afm
.
features
.
register
19 20
local
settings_to_hash
=
utilities
.
parsers
.
settings_to_hash_colon_too
21 22
local
helpers
=
fonts
.
helpers
23
local
prependcommands
=
helpers
.
prependcommands
24
local
charcommand
=
helpers
.
commands
.
char
25
local
leftcommand
=
helpers
.
commands
.
left
26
local
rightcommand
=
helpers
.
commands
.
right
27
local
upcommand
=
helpers
.
commands
.
up
28
local
downcommand
=
helpers
.
commands
.
down
29
local
dummycommand
=
helpers
.
commands
.
dummy
30 31
----- constructors = fonts.constructors
32
----- getmathparameter = constructors.getmathparameter
33
----- setmathparameter = constructors.setmathparameter
34 35
local
report_effect
=
logs
.
reporter
(
"
fonts
"
,
"
effect
"
)
36
local
report_slant
=
logs
.
reporter
(
"
fonts
"
,
"
slant
"
)
37
local
report_extend
=
logs
.
reporter
(
"
fonts
"
,
"
extend
"
)
38
local
report_squeeze
=
logs
.
reporter
(
"
fonts
"
,
"
squeeze
"
)
39 40
local
trace
=
false
41 42
trackers
.
register
(
"
fonts.effect
"
,
function
(
v
)
trace
=
v
end
)
43
trackers
.
register
(
"
fonts.slant
"
,
function
(
v
)
trace
=
v
end
)
44
trackers
.
register
(
"
fonts.extend
"
,
function
(
v
)
trace
=
v
end
)
45
trackers
.
register
(
"
fonts.squeeze
"
,
function
(
v
)
trace
=
v
end
)
46 47
local
function
initializeslant
(
tfmdata
,
value
)
48
value
=
tonumber
(
value
)
49
if
not
value
then
50
value
=
0
51
elseif
value
>
1
then
52
value
=
1
53
elseif
value
<
-1
then
54
value
=
-1
55
end
56
if
trace
then
57
report_slant
(
"
applying %0.3f
"
,
value
)
58
end
59
tfmdata
.
parameters
.
slantfactor
=
value
60
end
61 62
local
specification
=
{
63
name
=
"
slant
"
,
64
description
=
"
slant glyphs
"
,
65
initializers
=
{
66
base
=
initializeslant
,
67
node
=
initializeslant
,
68
}
69
}
70 71
registerotffeature
(
specification
)
72
registerafmfeature
(
specification
)
73 74
local
function
initializeextend
(
tfmdata
,
value
)
75
value
=
tonumber
(
value
)
76
if
not
value
then
77
value
=
0
78
elseif
value
>
10
then
79
value
=
10
80
elseif
value
<
-10
then
81
value
=
-10
82
end
83
if
trace
then
84
report_extend
(
"
applying %0.3f
"
,
value
)
85
end
86
tfmdata
.
parameters
.
extendfactor
=
value
87
end
88 89
local
specification
=
{
90
name
=
"
extend
"
,
91
description
=
"
scale glyphs horizontally
"
,
92
initializers
=
{
93
base
=
initializeextend
,
94
node
=
initializeextend
,
95
}
96
}
97 98
registerotffeature
(
specification
)
99
registerafmfeature
(
specification
)
100 101
local
function
initializesqueeze
(
tfmdata
,
value
)
102
value
=
tonumber
(
value
)
103
if
not
value
then
104
value
=
0
105
elseif
value
>
10
then
106
value
=
10
107
elseif
value
<
-10
then
108
value
=
-10
109
end
110
if
trace
then
111
report_squeeze
(
"
applying %0.3f
"
,
value
)
112
end
113
tfmdata
.
parameters
.
squeezefactor
=
value
114
end
115 116
local
specification
=
{
117
name
=
"
squeeze
"
,
118
description
=
"
scale glyphs vertically
"
,
119
initializers
=
{
120
base
=
initializesqueeze
,
121
node
=
initializesqueeze
,
122
}
123
}
124 125
registerotffeature
(
specification
)
126
registerafmfeature
(
specification
)
127 128
local
effects
=
{
129
inner
=
0
,
130
normal
=
0
,
131
outer
=
1
,
132
outline
=
1
,
133
both
=
2
,
134
hidden
=
3
,
135
}
136 137
local
function
initializeeffect
(
tfmdata
,
value
)
138
local
spec
139
if
type
(
value
)
=
=
"
number
"
then
140
spec
=
{
width
=
value
}
141
else
142
spec
=
settings_to_hash
(
value
)
143
end
144
local
effect
=
spec
.
effect
or
"
both
"
145
local
width
=
tonumber
(
spec
.
width
)
or
0
146
local
mode
=
effects
[
effect
]
147
if
not
mode
then
148
report_effect
(
"
invalid effect %a
"
,
effect
)
149
elseif
width
=
=
0
and
mode
=
=
0
then
150
report_effect
(
"
invalid width %a for effect %a
"
,
width
,
effect
)
151
else
152
local
parameters
=
tfmdata
.
parameters
153
local
properties
=
tfmdata
.
properties
154
parameters
.
mode
=
mode
155
parameters
.
width
=
width
*
1000
156
if
is_boolean
(
spec
.
auto
)
=
=
true
then
157
local
squeeze
=
1
-
width
/
20
158
local
average
=
(
1
-
squeeze
)
*
width
*
100
159
spec
.
squeeze
=
squeeze
160
spec
.
extend
=
1
+
width
/
2
161
spec
.
wdelta
=
average
162
spec
.
hdelta
=
average
/
2
163
spec
.
ddelta
=
average
/
2
164
spec
.
vshift
=
average
/
2
165
end
166
local
factor
=
tonumber
(
spec
.
factor
)
or
0
167
local
hfactor
=
tonumber
(
spec
.
hfactor
)
or
factor
168
local
vfactor
=
tonumber
(
spec
.
vfactor
)
or
factor
169
local
delta
=
tonumber
(
spec
.
delta
)
or
1
170
local
wdelta
=
tonumber
(
spec
.
wdelta
)
or
delta
171
local
hdelta
=
tonumber
(
spec
.
hdelta
)
or
delta
172
local
ddelta
=
tonumber
(
spec
.
ddelta
)
or
hdelta
173
local
vshift
=
tonumber
(
spec
.
vshift
)
or
0
174
local
slant
=
spec
.
slant
175
local
extend
=
spec
.
extend
176
local
squeeze
=
spec
.
squeeze
177
if
slant
then
178
initializeslant
(
tfmdata
,
slant
)
179
end
180
if
extend
then
181
initializeextend
(
tfmdata
,
extend
)
182
end
183
if
squeeze
then
184
initializesqueeze
(
tfmdata
,
squeeze
)
185
end
186
properties
.
effect
=
{
187
effect
=
effect
,
188
width
=
width
,
189
factor
=
factor
,
190
hfactor
=
hfactor
,
191
vfactor
=
vfactor
,
192
wdelta
=
wdelta
,
193
hdelta
=
hdelta
,
194
ddelta
=
ddelta
,
195
vshift
=
vshift
,
196
slant
=
tfmdata
.
parameters
.
slantfactor
,
197
extend
=
tfmdata
.
parameters
.
extendfactor
,
198
squeeze
=
tfmdata
.
parameters
.
squeezefactor
,
199
}
200
end
201
end
202 203
local
rules
=
{
204
"
RadicalRuleThickness
"
,
205
"
OverbarRuleThickness
"
,
206
"
FractionRuleThickness
"
,
207
"
UnderbarRuleThickness
"
,
208
}
209 210
-- radicals are not yet ok
211 212
local
function
setmathparameters
(
tfmdata
,
characters
,
mathparameters
,
dx
,
dy
,
squeeze
,
multiplier
)
213
-- hm, this was "if delta ~= 0 then" but delta was gone
214
if
dy
~
=
0
then
215
for
i
=
1
,
#
rules
do
216
local
name
=
rules
[
i
]
217
local
value
=
mathparameters
[
name
]
218
if
value
then
219
mathparameters
[
name
]
=
(
squeeze
or
1
)
*
(
value
+
dy
)
220
end
221
end
222
end
223
end
224 225
local
function
setmathcharacters
(
tfmdata
,
characters
,
mathparameters
,
dx
,
dy
,
squeeze
,
wdelta
,
hdelta
,
ddelta
)
226 227
-- still not the perfect rule
228 229
local
function
wdpatch
(
char
)
230
if
wsnap
~
=
0
then
231
char
.
width
=
char
.
width
+
wdelta
/
2
232
end
233
end
234 235
local
function
htpatch
(
char
)
236
if
hsnap
~
=
0
then
237
local
height
=
char
.
height
238
if
height
then
239
char
.
height
=
char
.
height
+
2
*
dy
240
end
241
end
242
end
243 244
local
character
=
characters
[
0x221A
]
245 246
if
character
and
character
.
next
then
247
local
char
=
character
248
local
next
=
character
.
next
249
wdpatch
(
char
)
250
htpatch
(
char
)
251
while
next
do
252
char
=
characters
[
next
]
253
wdpatch
(
char
)
254
htpatch
(
char
)
255
next
=
char
.
next
256
end
257
if
char
then
258
local
v
=
char
.
vert_variants
259
if
v
then
260
local
top
=
v
[
#
v
]
261
if
top
then
262
local
char
=
characters
[
top
.
glyph
]
263
htpatch
(
char
)
264
end
265
end
266
end
267
end
268 269
end
270 271
-- local show_effect = { "lua", function(f,c)
272
-- report_effect("font id %i, char %C",f,c)
273
-- inspect(fonts.hashes.characters[f][c])
274
-- end }
275 276
local
function
manipulateeffect
(
tfmdata
)
277
local
effect
=
tfmdata
.
properties
.
effect
278
if
effect
then
279
local
characters
=
tfmdata
.
characters
280
local
parameters
=
tfmdata
.
parameters
281
local
mathparameters
=
tfmdata
.
mathparameters
282
local
multiplier
=
effect
.
width
*
100
283
local
factor
=
parameters
.
factor
284
local
hfactor
=
parameters
.
hfactor
285
local
vfactor
=
parameters
.
vfactor
286
local
wdelta
=
effect
.
wdelta
*
hfactor
*
multiplier
287
local
hdelta
=
effect
.
hdelta
*
vfactor
*
multiplier
288
local
ddelta
=
effect
.
ddelta
*
vfactor
*
multiplier
289
local
vshift
=
effect
.
vshift
*
vfactor
*
multiplier
290
local
squeeze
=
effect
.
squeeze
291
local
hshift
=
wdelta
/
2
292
local
dx
=
multiplier
*
vfactor
293
local
dy
=
vshift
294
local
factor
=
(
1
+
effect
.
factor
)
*
factor
295
local
hfactor
=
(
1
+
effect
.
hfactor
)
*
hfactor
296
local
vfactor
=
(
1
+
effect
.
vfactor
)
*
vfactor
297
vshift
=
vshift
~
=
0
and
upcommand
[
vshift
]
or
false
298
hshift
=
rightcommand
[
hshift
]
299
for
unicode
,
character
in
next
,
characters
do
300
local
oldwidth
=
character
.
width
301
local
oldheight
=
character
.
height
302
local
olddepth
=
character
.
depth
303
if
oldwidth
and
oldwidth
>
0
then
304
character
.
width
=
oldwidth
+
wdelta
305
local
commands
=
character
.
commands
306
if
vshift
then
307
if
commands
then
308
prependcommands
(
commands
,
309
-- show_effect,
310
hshift
,
311
vshift
312
)
313
else
314
character
.
commands
=
{
315
-- show_effect,
316
hshift
,
317
vshift
,
318
charcommand
[
unicode
]
319
}
320
end
321
else
322
if
commands
then
323
prependcommands
(
commands
,
324
-- show_effect,
325
hshift
326
)
327
else
328
character
.
commands
=
{
329
-- show_effect,
330
hshift
,
331
charcommand
[
unicode
]
332
}
333
end
334
end
335
end
336
if
oldheight
and
oldheight
>
0
then
337
character
.
height
=
oldheight
+
hdelta
338
end
339
if
olddepth
and
olddepth
>
0
then
340
character
.
depth
=
olddepth
+
ddelta
341
end
342
end
343
if
mathparameters
then
344
setmathparameters
(
tfmdata
,
characters
,
mathparameters
,
dx
,
dy
,
squeeze
,
multiplier
)
345
setmathcharacters
(
tfmdata
,
characters
,
mathparameters
,
dx
,
dy
,
squeeze
,
wdelta
,
hdelta
,
ddelta
)
346
end
347
parameters
.
factor
=
factor
348
parameters
.
hfactor
=
hfactor
349
parameters
.
vfactor
=
vfactor
350
if
trace
then
351
report_effect
(
"
applying
"
)
352
report_effect
(
"
effect : %s
"
,
effect
.
effect
)
353
report_effect
(
"
width : %s => %s
"
,
effect
.
width
,
multiplier
)
354
report_effect
(
"
factor : %s => %s
"
,
effect
.
factor
,
factor
)
355
report_effect
(
"
hfactor : %s => %s
"
,
effect
.
hfactor
,
hfactor
)
356
report_effect
(
"
vfactor : %s => %s
"
,
effect
.
vfactor
,
vfactor
)
357
report_effect
(
"
wdelta : %s => %s
"
,
effect
.
wdelta
,
wdelta
)
358
report_effect
(
"
hdelta : %s => %s
"
,
effect
.
hdelta
,
hdelta
)
359
report_effect
(
"
ddelta : %s => %s
"
,
effect
.
ddelta
,
ddelta
)
360
end
361
end
362
end
363 364
local
specification
=
{
365
name
=
"
effect
"
,
366
description
=
"
apply effects to glyphs
"
,
367
initializers
=
{
368
base
=
initializeeffect
,
369
node
=
initializeeffect
,
370
}
,
371
manipulators
=
{
372
base
=
manipulateeffect
,
373
node
=
manipulateeffect
,
374
}
,
375
}
376 377
registerotffeature
(
specification
)
378
registerafmfeature
(
specification
)
379 380
local
function
initializeoutline
(
tfmdata
,
value
)
381
value
=
tonumber
(
value
)
382
if
not
value
then
383
value
=
0
384
else
385
value
=
tonumber
(
value
)
or
0
386
end
387
local
parameters
=
tfmdata
.
parameters
388
local
properties
=
tfmdata
.
properties
389
parameters
.
mode
=
effects
.
outline
390
parameters
.
width
=
value
*
1000
391
properties
.
effect
=
{
392
effect
=
effect
,
393
width
=
width
,
394
}
395
end
396 397
local
specification
=
{
398
name
=
"
outline
"
,
399
description
=
"
outline glyphs
"
,
400
initializers
=
{
401
base
=
initializeoutline
,
402
node
=
initializeoutline
,
403
}
404
}
405 406
registerotffeature
(
specification
)
407
registerafmfeature
(
specification
)
408