mlib-pps.lua /size: 55 Kb    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
mlib-pps
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to mlib-ctx.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
,
7
}
8 9
local
format
,
gmatch
,
match
,
split
,
gsub
=
string
.
format
,
string
.
gmatch
,
string
.
match
,
string
.
split
,
string
.
gsub
10
local
tonumber
,
type
,
unpack
,
next
,
select
=
tonumber
,
type
,
unpack
,
next
,
select
11
local
round
,
sqrt
,
min
,
max
=
math
.
round
,
math
.
sqrt
,
math
.
min
,
math
.
max
12
local
insert
,
remove
,
concat
=
table
.
insert
,
table
.
remove
,
table
.
concat
13
local
Cs
,
Cf
,
C
,
Cg
,
Ct
,
P
,
S
,
V
,
Carg
=
lpeg
.
Cs
,
lpeg
.
Cf
,
lpeg
.
C
,
lpeg
.
Cg
,
lpeg
.
Ct
,
lpeg
.
P
,
lpeg
.
S
,
lpeg
.
V
,
lpeg
.
Carg
14
local
lpegmatch
,
tsplitat
,
tsplitter
=
lpeg
.
match
,
lpeg
.
tsplitat
,
lpeg
.
tsplitter
15
local
formatters
=
string
.
formatters
16
local
exists
,
savedata
=
io
.
exists
,
io
.
savedata
17 18
local
mplib
=
mplib
19
local
metapost
=
metapost
20
local
lpdf
=
lpdf
21
local
context
=
context
22 23
local
implement
=
interfaces
.
implement
24
local
setmacro
=
interfaces
.
setmacro
25 26
local
texsetbox
=
tex
.
setbox
27
local
textakebox
=
tex
.
takebox
-- or: nodes.takebox
28
local
texrunlocal
=
tex
.
runlocal
29
local
copylist
=
nodes
.
copylist
30
local
flushlist
=
nodes
.
flushlist
31
local
setmetatableindex
=
table
.
setmetatableindex
32
local
sortedhash
=
table
.
sortedhash
33 34
local
new_hlist
=
nodes
.
pool
.
hlist
35 36
local
starttiming
=
statistics
.
starttiming
37
local
stoptiming
=
statistics
.
stoptiming
38 39
local
trace_runs
=
false
trackers
.
register
(
"
metapost.runs
"
,
function
(
v
)
trace_runs
=
v
end
)
40
local
trace_textexts
=
false
trackers
.
register
(
"
metapost.textexts
"
,
function
(
v
)
trace_textexts
=
v
end
)
41
local
trace_scripts
=
false
trackers
.
register
(
"
metapost.scripts
"
,
function
(
v
)
trace_scripts
=
v
end
)
42
local
trace_btexetex
=
false
trackers
.
register
(
"
metapost.btexetex
"
,
function
(
v
)
trace_btexetex
=
v
end
)
43 44
local
report_metapost
=
logs
.
reporter
(
"
metapost
"
)
45
local
report_textexts
=
logs
.
reporter
(
"
metapost
"
,
"
textexts
"
)
46
local
report_scripts
=
logs
.
reporter
(
"
metapost
"
,
"
scripts
"
)
47 48
local
colors
=
attributes
.
colors
49
local
defineprocesscolor
=
colors
.
defineprocesscolor
50
local
definespotcolor
=
colors
.
definespotcolor
51
local
definemultitonecolor
=
colors
.
definemultitonecolor
52
local
colorvalue
=
colors
.
value
53 54
local
transparencies
=
attributes
.
transparencies
55
local
registertransparency
=
transparencies
.
register
56
local
transparencyvalue
=
transparencies
.
value
57 58
local
rgbtocmyk
=
colors
.
rgbtocmyk
-- or function() return 0,0,0,1 end
59
local
cmyktorgb
=
colors
.
cmyktorgb
-- or function() return 0,0,0 end
60
local
rgbtogray
=
colors
.
rgbtogray
-- or function() return 0 end
61
local
cmyktogray
=
colors
.
cmyktogray
-- or function() return 0 end
62 63
local
nooutercolor
=
"
0 g 0 G
"
64
local
nooutertransparency
=
"
/Tr0 gs
"
-- only when set
65
local
outercolormode
=
0
66
local
outercolormodel
=
1
67
local
outercolor
=
nooutercolor
68
local
outertransparency
=
nooutertransparency
69
local
innercolor
=
nooutercolor
70
local
innertransparency
=
nooutertransparency
71 72
local
pdfcolor
=
lpdf
.
color
73
local
pdftransparency
=
lpdf
.
transparency
74 75
function
metapost
.
setoutercolor
(
mode
,
colormodel
,
colorattribute
,
transparencyattribute
)
76
-- has always to be called before conversion
77
-- todo: transparency (not in the mood now)
78
outercolormode
=
mode
79
outercolormodel
=
colormodel
80
if
mode
=
=
1
or
mode
=
=
3
then
81
-- inherit from outer (registered color)
82
outercolor
=
pdfcolor
(
colormodel
,
colorattribute
)
or
nooutercolor
83
outertransparency
=
pdftransparency
(
transparencyattribute
)
or
nooutertransparency
84
elseif
mode
=
=
2
then
85
-- stand alone (see m-punk.tex)
86
outercolor
=
"
"
87
outertransparency
=
"
"
88
else
-- 0
89
outercolor
=
nooutercolor
90
outertransparency
=
nooutertransparency
91
end
92
innercolor
=
outercolor
93
innertransparency
=
outertransparency
-- not yet used
94
end
95 96
-- todo: get this from the lpdf module
97 98
local
f_f
=
formatters
[
"
%.6N
"
]
99
local
f_f3
=
formatters
[
"
%.3N
"
]
100
local
f_gray
=
formatters
[
"
%.3N g %.3N G
"
]
101
local
f_rgb
=
formatters
[
"
%.3N %.3N %.3N rg %.3N %.3N %.3N RG
"
]
102
local
f_cmyk
=
formatters
[
"
%.3N %.3N %.3N %.3N k %.3N %.3N %.3N %.3N K
"
]
103
local
f_cm_b
=
formatters
[
"
q %.6N %.6N %.6N %.6N %.6N %.6N cm
"
]
104
local
f_scn
=
formatters
[
"
%.3N
"
]
105 106
local
f_shade
=
formatters
[
"
MpSh%s
"
]
107
local
f_spot
=
formatters
[
"
/%s cs /%s CS %s SCN %s scn
"
]
108
local
s_cm_e
=
"
Q
"
109 110
local
function
checked_color_pair
(
color
,
...
)
111
if
not
color
then
112
return
innercolor
,
outercolor
113
end
114
if
outercolormode
=
=
3
then
115
innercolor
=
color
(
...
)
116
return
innercolor
,
innercolor
117
else
118
return
color
(
...
)
,
outercolor
119
end
120
end
121 122
function
metapost
.
colorinitializer
(
)
123
innercolor
=
outercolor
124
innertransparency
=
outertransparency
125
return
outercolor
,
outertransparency
126
end
127 128
--~
129 130
local
specificationsplitter
=
tsplitat
(
"
"
)
131
local
colorsplitter
=
tsplitter
(
"
:
"
,
tonumber
)
-- no need for :
132
local
domainsplitter
=
tsplitter
(
"
"
,
tonumber
)
133
local
centersplitter
=
domainsplitter
134
local
coordinatesplitter
=
domainsplitter
135 136
-- thanks to taco's reading of the postscript manual:
137
--
138
-- x' = sx * x + ry * y + tx
139
-- y' = rx * x + sy * y + ty
140 141
local
nofshades
=
0
-- todo: hash resources, start at 1000 in order not to clash with older
142 143
local
function
normalize
(
ca
,
cb
)
144
if
#
cb
=
=
1
then
145
if
#
ca
=
=
4
then
146
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
,
cb
[
4
]
=
0
,
0
,
0
,
1
-
cb
[
1
]
147
else
148
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
=
cb
[
1
]
,
cb
[
1
]
,
cb
[
1
]
149
end
150
elseif
#
cb
=
=
3
then
151
if
#
ca
=
=
4
then
152
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
,
cb
[
4
]
=
rgbtocmyk
(
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
)
153
else
154
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
=
cmyktorgb
(
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
,
cb
[
4
]
)
155
end
156
end
157
end
158 159 160
local
commasplitter
=
tsplitat
(
"
,
"
)
161 162
local
function
checkandconvertspot
(
n_a
,
f_a
,
c_a
,
v_a
,
n_b
,
f_b
,
c_b
,
v_b
)
163
-- must be the same but we don't check
164
local
name
=
f_shade
(
nofshades
)
165
local
ca
=
lpegmatch
(
commasplitter
,
v_a
)
166
local
cb
=
lpegmatch
(
commasplitter
,
v_b
)
167
if
#
ca
=
=
0
or
#
cb
=
=
0
then
168
return
{
0
}
,
{
1
}
,
"
DeviceGray
"
,
name
169
else
170
for
i
=
1
,
#
ca
do
ca
[
i
]
=
tonumber
(
ca
[
i
]
)
or
0
end
171
for
i
=
1
,
#
cb
do
cb
[
i
]
=
tonumber
(
cb
[
i
]
)
or
1
end
172
--~ spotcolorconverter(n_a,f_a,c_a,v_a) -- not really needed
173
return
ca
,
cb
,
n_a
or
n_b
,
name
174
end
175
end
176 177
local
function
checkandconvert
(
ca
,
cb
,
model
)
178
local
name
=
f_shade
(
nofshades
)
179
if
not
ca
or
not
cb
or
type
(
ca
)
=
=
"
string
"
then
180
return
{
0
}
,
{
1
}
,
"
DeviceGray
"
,
name
181
else
182
if
#
ca
>
#
cb
then
183
normalize
(
ca
,
cb
)
184
elseif
#
ca
<
#
cb
then
185
normalize
(
cb
,
ca
)
186
end
187
if
not
model
then
188
model
=
colors
.
currentnamedmodel
(
)
189
end
190
if
model
=
=
"
all
"
then
191
model
=
(
#
ca
=
=
4
and
"
cmyk
"
)
or
(
#
ca
=
=
3
and
"
rgb
"
)
or
"
gray
"
192
end
193
if
model
=
=
"
rgb
"
then
194
if
#
ca
=
=
4
then
195
ca
=
{
cmyktorgb
(
ca
[
1
]
,
ca
[
2
]
,
ca
[
3
]
,
ca
[
4
]
)
}
196
cb
=
{
cmyktorgb
(
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
,
cb
[
4
]
)
}
197
elseif
#
ca
=
=
1
then
198
local
a
=
1
-
ca
[
1
]
199
local
b
=
1
-
cb
[
1
]
200
ca
=
{
a
,
a
,
a
}
201
cb
=
{
b
,
b
,
b
}
202
end
203
return
ca
,
cb
,
"
DeviceRGB
"
,
name
,
model
204
elseif
model
=
=
"
cmyk
"
then
205
if
#
ca
=
=
3
then
206
ca
=
{
rgbtocmyk
(
ca
[
1
]
,
ca
[
2
]
,
ca
[
3
]
)
}
207
cb
=
{
rgbtocmyk
(
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
)
}
208
elseif
#
ca
=
=
1
then
209
ca
=
{
0
,
0
,
0
,
ca
[
1
]
}
210
cb
=
{
0
,
0
,
0
,
ca
[
1
]
}
211
end
212
return
ca
,
cb
,
"
DeviceCMYK
"
,
name
,
model
213
else
214
if
#
ca
=
=
4
then
215
ca
=
{
cmyktogray
(
ca
[
1
]
,
ca
[
2
]
,
ca
[
3
]
,
ca
[
4
]
)
}
216
cb
=
{
cmyktogray
(
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
,
cb
[
4
]
)
}
217
elseif
#
ca
=
=
3
then
218
ca
=
{
rgbtogray
(
ca
[
1
]
,
ca
[
2
]
,
ca
[
3
]
)
}
219
cb
=
{
rgbtogray
(
cb
[
1
]
,
cb
[
2
]
,
cb
[
3
]
)
}
220
end
221
-- backend specific (will be renamed)
222
return
ca
,
cb
,
"
DeviceGray
"
,
name
,
model
223
end
224
end
225
end
226 227
-- We keep textexts in a shared list (as it's easier that way and we also had that in
228
-- the beginning). Each graphic gets its own (1 based) subtable so that we can also
229
-- handle multiple conversions in one go which is needed when we process mp files
230
-- directly.
231 232
local
stack
=
{
}
-- quick hack, we will pass topofstack around
233
local
top
=
nil
234
local
nofruns
=
0
-- askedfig: "all", "first", number
235 236
local
function
preset
(
t
,
k
)
237
-- references to textexts by mp index
238
local
v
=
{
239
textrial
=
0
,
240
texfinal
=
0
,
241
texslots
=
{
}
,
242
texorder
=
{
}
,
243
texhash
=
{
}
,
244
}
245
t
[
k
]
=
v
246
return
v
247
end
248 249
local
function
startjob
(
plugmode
,
kind
,
mpx
)
250
insert
(
stack
,
top
)
251
top
=
{
252
textexts
=
{
}
,
-- all boxes, optionally with a different color
253
texstrings
=
{
}
,
254
texregimes
=
{
}
,
255
mapstrings
=
{
}
,
256
mapindices
=
{
}
,
257
mapmoves
=
{
}
,
258
texlast
=
0
,
259
texdata
=
setmetatableindex
(
{
}
,
preset
)
,
-- references to textexts in order or usage
260
plugmode
=
plugmode
,
-- some day we can then skip all pre/postscripts
261
extradata
=
mpx
and
metapost
.
getextradata
(
mpx
)
,
262
}
263
if
trace_runs
then
264
report_metapost
(
"
starting %s run at level %i in %s mode
"
,
265
kind
,
#
stack
+
1
,
plugmode
and
"
plug
"
or
"
normal
"
)
266
end
267
return
top
268
end
269 270
local
function
stopjob
(
)
271
if
top
then
272
for
slot
,
content
in
next
,
top
.
textexts
do
273
if
content
then
274
flushlist
(
content
)
275
if
trace_textexts
then
276
report_textexts
(
"
freeing text %s
"
,
slot
)
277
end
278
end
279
end
280
if
trace_runs
then
281
report_metapost
(
"
stopping run at level %i
"
,
#
stack
+
1
)
282
end
283
top
=
remove
(
stack
)
284
return
top
285
end
286
end
287 288
function
metapost
.
getjobdata
(
)
289
return
top
290
end
291 292
-- end of new
293 294
local
settext
=
function
(
box
,
slot
,
str
)
295
if
top
then
296
-- if trace_textexts then
297
-- report_textexts("getting text %s from box %s",slot,box)
298
-- end
299
top
.
textexts
[
slot
]
=
textakebox
(
box
)
300
end
301
end
302 303
local
gettext
=
function
(
box
,
slot
)
304
if
top
then
305
texsetbox
(
box
,
top
.
textexts
[
slot
]
)
306
top
.
textexts
[
slot
]
=
false
307
-- if trace_textexts then
308
-- report_textexts("putting text %s in box %s",slot,box)
309
-- end
310
end
311
end
312 313
metapost
.
settext
=
settext
314
metapost
.
gettext
=
gettext
315 316
implement
{
name
=
"
mpsettext
"
,
actions
=
settext
,
arguments
=
{
"
integer
"
,
"
integer
"
}
}
-- box slot
317
implement
{
name
=
"
mpgettext
"
,
actions
=
gettext
,
arguments
=
{
"
integer
"
,
"
integer
"
}
}
-- box slot
318 319
-- rather generic pdf, so use this elsewhere too it no longer pays
320
-- off to distinguish between outline and fill (we now have both
321
-- too, e.g. in arrows)
322 323
metapost
.
reducetogray
=
true
324 325
local
models
=
{
}
326 327
function
models
.
all
(
cr
)
328
local
n
=
#
cr
329
if
n
=
=
0
then
330
return
checked_color_pair
(
)
331
elseif
metapost
.
reducetogray
then
332
if
n
=
=
1
then
333
local
s
=
cr
[
1
]
334
return
checked_color_pair
(
f_gray
,
s
,
s
)
335
elseif
n
=
=
3
then
336
local
r
=
cr
[
1
]
337
local
g
=
cr
[
2
]
338
local
b
=
cr
[
3
]
339
if
r
=
=
g
and
g
=
=
b
then
340
return
checked_color_pair
(
f_gray
,
r
,
r
)
341
else
342
return
checked_color_pair
(
f_rgb
,
r
,
g
,
b
,
r
,
g
,
b
)
343
end
344
else
345
local
c
=
cr
[
1
]
346
local
m
=
cr
[
2
]
347
local
y
=
cr
[
3
]
348
local
k
=
cr
[
4
]
349
if
c
=
=
m
and
m
=
=
y
and
y
=
=
0
then
350
k
=
1
-
k
351
return
checked_color_pair
(
f_gray
,
k
,
k
)
352
else
353
return
checked_color_pair
(
f_cmyk
,
c
,
m
,
y
,
k
,
c
,
m
,
y
,
k
)
354
end
355
end
356
elseif
n
=
=
1
then
357
local
s
=
cr
[
1
]
358
return
checked_color_pair
(
f_gray
,
s
,
s
)
359
elseif
n
=
=
3
then
360
local
r
=
cr
[
1
]
361
local
g
=
cr
[
2
]
362
local
b
=
cr
[
3
]
363
return
checked_color_pair
(
f_rgb
,
r
,
g
,
b
,
r
,
g
,
b
)
364
else
365
local
c
=
cr
[
1
]
366
local
m
=
cr
[
2
]
367
local
y
=
cr
[
3
]
368
local
k
=
cr
[
4
]
369
return
checked_color_pair
(
f_cmyk
,
c
,
m
,
y
,
k
,
c
,
m
,
y
,
k
)
370
end
371
end
372 373
function
models
.
rgb
(
cr
)
374
local
n
=
#
cr
375
if
n
=
=
0
then
376
return
checked_color_pair
(
)
377
elseif
metapost
.
reducetogray
then
378
if
n
=
=
1
then
379
local
s
=
cr
[
1
]
380
return
checked_color_pair
(
f_gray
,
s
,
s
)
381
elseif
n
=
=
3
then
382
local
r
=
cr
[
1
]
383
local
g
=
cr
[
2
]
384
local
b
=
cr
[
3
]
385
if
r
=
=
g
and
g
=
=
b
then
386
return
checked_color_pair
(
f_gray
,
r
,
r
)
387
else
388
return
checked_color_pair
(
f_rgb
,
r
,
g
,
b
,
r
,
g
,
b
)
389
end
390
else
391
local
c
=
cr
[
1
]
392
local
m
=
cr
[
2
]
393
local
y
=
cr
[
3
]
394
local
k
=
cr
[
4
]
395
if
c
=
=
m
and
m
=
=
y
and
y
=
=
0
then
396
k
=
1
-
k
397
return
checked_color_pair
(
f_gray
,
k
,
k
)
398
else
399
local
r
,
g
,
b
=
cmyktorgb
(
c
,
m
,
y
,
k
)
400
return
checked_color_pair
(
f_rgb
,
r
,
g
,
b
,
r
,
g
,
b
)
401
end
402
end
403
elseif
n
=
=
1
then
404
local
s
=
cr
[
1
]
405
return
checked_color_pair
(
f_gray
,
s
,
s
)
406
else
407
local
r
=
cr
[
1
]
408
local
g
=
cr
[
2
]
409
local
b
=
cr
[
3
]
410
local
r
,
g
,
b
411
if
n
=
=
3
then
412
r
,
g
,
b
=
cmyktorgb
(
r
,
g
,
b
,
cr
[
4
]
)
413
end
414
return
checked_color_pair
(
f_rgb
,
r
,
g
,
b
,
r
,
g
,
b
)
415
end
416
end
417 418
function
models
.
cmyk
(
cr
)
419
local
n
=
#
cr
420
if
n
=
=
0
then
421
return
checked_color_pair
(
)
422
elseif
metapost
.
reducetogray
then
423
if
n
=
=
1
then
424
local
s
=
cr
[
1
]
425
return
checked_color_pair
(
f_gray
,
s
,
s
)
426
elseif
n
=
=
3
then
427
local
r
=
cr
[
1
]
428
local
g
=
cr
[
2
]
429
local
b
=
cr
[
3
]
430
if
r
=
=
g
and
g
=
=
b
then
431
return
checked_color_pair
(
f_gray
,
r
,
r
)
432
else
433
local
c
,
m
,
y
,
k
=
rgbtocmyk
(
r
,
g
,
b
)
434
return
checked_color_pair
(
f_cmyk
,
c
,
m
,
y
,
k
,
c
,
m
,
y
,
k
)
435
end
436
else
437
local
c
=
cr
[
1
]
438
local
m
=
cr
[
2
]
439
local
y
=
cr
[
3
]
440
local
k
=
cr
[
4
]
441
if
c
=
=
m
and
m
=
=
y
and
y
=
=
0
then
442
k
=
1
-
k
443
return
checked_color_pair
(
f_gray
,
k
,
k
)
444
else
445
return
checked_color_pair
(
f_cmyk
,
c
,
m
,
y
,
k
,
c
,
m
,
y
,
k
)
446
end
447
end
448
elseif
n
=
=
1
then
449
local
s
=
cr
[
1
]
450
return
checked_color_pair
(
f_gray
,
s
,
s
)
451
else
452
local
c
=
cr
[
1
]
453
local
m
=
cr
[
2
]
454
local
y
=
cr
[
3
]
455
local
k
=
cr
[
4
]
456
if
n
=
=
3
then
457
if
c
=
=
m
and
m
=
=
y
then
458
k
,
c
,
m
,
y
=
1
-
c
,
0
,
0
,
0
459
else
460
c
,
m
,
y
,
k
=
rgbtocmyk
(
c
,
m
,
y
)
461
end
462
end
463
return
checked_color_pair
(
f_cmyk
,
c
,
m
,
y
,
k
,
c
,
m
,
y
,
k
)
464
end
465
end
466 467
function
models
.
gray
(
cr
)
468
local
n
=
#
cr
469
local
s
=
0
470
if
n
=
=
0
then
471
return
checked_color_pair
(
)
472
elseif
n
=
=
4
then
473
s
=
cmyktogray
(
cr
[
1
]
,
cr
[
2
]
,
cr
[
3
]
,
cr
[
4
]
)
474
elseif
n
=
=
3
then
475
s
=
rgbtogray
(
cr
[
1
]
,
cr
[
2
]
,
cr
[
3
]
)
476
else
477
s
=
cr
[
1
]
478
end
479
return
checked_color_pair
(
f_gray
,
s
,
s
)
480
end
481 482
models
[
1
]
=
models
.
all
483
models
[
2
]
=
models
.
gray
484
models
[
3
]
=
models
.
rgb
485
models
[
4
]
=
models
.
cmyk
486 487
setmetatableindex
(
models
,
function
(
t
,
k
)
488
local
v
=
models
.
gray
489
t
[
k
]
=
v
490
return
v
491
end
)
492 493
local
function
colorconverter
(
cs
)
494
return
models
[
outercolormodel
]
(
cs
)
495
end
496 497
local
factor
=
65536
*
(
7227
/
7200
)
498 499
implement
{
500
name
=
"
mpsetsxsy
"
,
501
arguments
=
{
"
dimen
"
,
"
dimen
"
,
"
dimen
"
}
,
502
actions
=
function
(
wd
,
ht
,
dp
)
503
local
hd
=
ht
+
dp
504
setmacro
(
"
mlib_sx
"
,
wd
~
=
0
and
factor
/
wd
or
0
)
505
setmacro
(
"
mlib_sy
"
,
hd
~
=
0
and
factor
/
hd
or
0
)
506
end
507
}
508 509
local
function
sxsy
(
wd
,
ht
,
dp
)
-- helper for text
510
local
hd
=
ht
+
dp
511
return
(
wd
~
=
0
and
factor
/
wd
)
or
0
,
(
hd
~
=
0
and
factor
/
hd
)
or
0
512
end
513 514
metapost
.
sxsy
=
sxsy
515 516
-- for stock mp we need to declare the booleans first
517 518
local
do_begin_fig
=
"
; beginfig(1) ;
"
519
local
do_end_fig
=
"
; endfig ;
"
520
local
do_safeguard
=
"
;
"
521 522
function
metapost
.
preparetextextsdata
(
)
523
local
textexts
=
top
.
textexts
524
local
collected
=
{
}
525
for
k
,
data
in
sortedhash
(
top
.
texdata
)
do
-- sort is nicer in trace
526
local
texorder
=
data
.
texorder
527
for
n
=
1
,
#
texorder
do
528
local
box
=
textexts
[
texorder
[
n
]
]
529
if
box
then
530
collected
[
n
]
=
box
531
else
532
break
533
end
534
end
535
end
536
mp
.
mf_tt_initialize
(
collected
)
537
end
538 539
local
runmetapost
=
metapost
.
run
540 541
local
function
checkaskedfig
(
askedfig
)
-- return askedfig, wrappit
542
if
not
askedfig
then
543
return
"
direct
"
,
true
544
elseif
askedfig
=
=
"
all
"
then
545
return
"
all
"
,
false
546
elseif
askedfig
=
=
"
direct
"
then
547
return
"
all
"
,
true
548
else
549
askedfig
=
tonumber
(
askedfig
)
550
if
askedfig
then
551
return
askedfig
,
false
552
else
553
return
"
direct
"
,
true
554
end
555
end
556
end
557 558
local
function
extrapass
(
)
559
if
trace_runs
then
560
report_metapost
(
"
second run of job %s, asked figure %a
"
,
top
.
nofruns
,
top
.
askedfig
)
561
end
562
metapost
.
preparetextextsdata
(
)
563
runmetapost
{
564
mpx
=
top
.
mpx
,
565
askedfig
=
top
.
askedfig
,
566
incontext
=
true
,
567
data
=
{
568
top
.
wrappit
and
do_begin_fig
or
"
"
,
569
no_trial_run
,
570
top
.
initializations
,
571
do_safeguard
,
572
top
.
data
,
573
top
.
wrappit
and
do_end_fig
or
"
"
,
574
}
,
575
}
576
end
577 578
-- This one is called from the \TEX\ end so the specification is different
579
-- from the specification to metapost,run cum suis! The definitions and
580
-- extension used to be handled here but are now delegated to the format
581
-- initializers because we need to accumulate them for nested instances (a
582
-- side effect of going single pass).
583 584
function
metapost
.
graphic_base_pass
(
specification
)
585
local
mpx
=
specification
.
mpx
-- mandate
586
local
top
=
startjob
(
true
,
"
base
"
,
mpx
)
587
local
data
=
specification
.
data
or
"
"
588
local
inclusions
=
specification
.
inclusions
or
"
"
589
local
initializations
=
specification
.
initializations
or
"
"
590
local
askedfig
,
591
wrappit
=
checkaskedfig
(
specification
.
figure
)
592
nofruns
=
nofruns
+
1
593
top
.
askedfig
=
askedfig
594
top
.
wrappit
=
wrappit
595
top
.
nofruns
=
nofruns
596
metapost
.
namespace
=
specification
.
namespace
or
"
"
597
top
.
mpx
=
mpx
598
top
.
data
=
data
599
top
.
initializations
=
initializations
600
if
trace_runs
then
601
report_metapost
(
"
running job %s, asked figure %a
"
,
nofruns
,
askedfig
)
602
end
603
runmetapost
{
604
mpx
=
mpx
,
605
askedfig
=
askedfig
,
606
incontext
=
true
,
607
data
=
{
608
inclusions
,
609
wrappit
and
do_begin_fig
or
"
"
,
610
initializations
,
611
do_safeguard
,
612
data
,
613
wrappit
and
do_end_fig
or
"
"
,
614
}
,
615
}
616
context
(
stopjob
)
617
end
618 619
local
function
oldschool
(
mpx
,
data
,
trial_run
,
flusher
,
was_multi_pass
,
is_extra_pass
,
askedfig
,
incontext
)
620
metapost
.
process
{
621
mpx
=
mpx
,
622
flusher
=
flusher
,
623
askedfig
=
askedfig
,
624
useplugins
=
incontext
,
625
incontext
=
incontext
,
626
data
=
data
,
627
}
628
end
629 630
function
metapost
.
process
(
specification
,
...
)
631
if
type
(
specification
)
~
=
"
table
"
then
632
oldschool
(
specification
,
...
)
633
else
634
startjob
(
specification
.
incontext
or
specification
.
useplugins
,
"
process
"
,
false
)
635
runmetapost
(
specification
)
636
stopjob
(
)
637
end
638
end
639 640
-- -- the new plugin handler -- --
641 642
local
sequencers
=
utilities
.
sequencers
643
local
appendgroup
=
sequencers
.
appendgroup
644
local
appendaction
=
sequencers
.
appendaction
645 646
local
resetteractions
=
sequencers
.
new
{
arguments
=
"
t
"
}
647
local
processoractions
=
sequencers
.
new
{
arguments
=
"
object,prescript,before,after
"
}
648 649
appendgroup
(
resetteractions
,
"
system
"
)
650
appendgroup
(
processoractions
,
"
system
"
)
651 652
-- later entries come first
653 654
local
scriptsplitter
=
Ct
(
Ct
(
655
C
(
(
1
-
S
(
"
=
"
)
)
^
1
)
*
S
(
"
=
"
)
^
1
*
C
(
(
1
-
S
(
"
\n\r
"
)
)
^
0
)
*
S
(
"
\n\r
"
)
^
0
656
)
^
0
)
657 658
local
function
splitprescript
(
script
)
659
local
hash
=
lpegmatch
(
scriptsplitter
,
script
)
660
for
i
=
#
hash
,
1
,
-1
do
661
local
h
=
hash
[
i
]
662
if
h
=
=
"
reset
"
then
663
for
k
,
v
in
next
,
hash
do
664
if
type
(
k
)
~
=
"
number
"
then
665
hash
[
k
]
=
nil
666
end
667
end
668
else
669
hash
[
h
[
1
]
]
=
h
[
2
]
670
end
671
end
672
if
trace_scripts
then
673
report_scripts
(
table
.
serialize
(
hash
,
"
prescript
"
)
)
674
end
675
return
hash
676
end
677 678
metapost
.
splitprescript
=
splitprescript
679 680
-- -- not used:
681
--
682
-- local function splitpostscript(script)
683
-- local hash = lpegmatch(scriptsplitter,script)
684
-- for i=1,#hash do
685
-- local h = hash[i]
686
-- hash[h[1]] = h[2]
687
-- end
688
-- if trace_scripts then
689
-- report_scripts(table.serialize(hash,"postscript"))
690
-- end
691
-- return hash
692
-- end
693 694
function
metapost
.
pluginactions
(
what
,
t
,
flushfigure
)
-- before/after object, depending on what
695
if
top
and
top
.
plugmode
then
-- hm, what about other features
696
for
i
=
1
,
#
what
do
697
local
wi
=
what
[
i
]
698
if
type
(
wi
)
=
=
"
function
"
then
699
-- assume injection
700
flushfigure
(
t
)
-- to be checked: too many 0 g 0 G
701
t
=
{
}
702
wi
(
)
703
else
704
t
[
#
t
+
1
]
=
wi
705
end
706
end
707
return
t
708
end
709
end
710 711
function
metapost
.
resetplugins
(
t
)
-- intialize plugins, before figure
712
if
top
and
top
.
plugmode
then
713
outercolormodel
=
colors
.
currentmodel
(
)
-- currently overloads the one set at the tex end
714
resetteractions
.
runner
(
t
)
715
end
716
end
717 718
function
metapost
.
processplugins
(
object
)
-- each object (second pass)
719
if
top
and
top
.
plugmode
then
720
local
prescript
=
object
.
prescript
-- specifications
721
if
prescript
and
#
prescript
>
0
then
722
local
before
=
{
}
723
local
after
=
{
}
724
processoractions
.
runner
(
object
,
splitprescript
(
prescript
)
or
{
}
,
before
,
after
)
725
return
#
before
>
0
and
before
,
#
after
>
0
and
after
726
else
727
local
c
=
object
.
color
728
if
c
and
#
c
>
0
then
729
local
b
,
a
=
colorconverter
(
c
)
730
return
{
b
}
,
{
a
}
731
end
732
end
733
end
734
end
735 736
-- helpers
737 738
local
basepoints
=
number
.
dimenfactors
[
"
bp
"
]
739 740
local
function
cm
(
object
)
741
local
op
=
object
.
path
742
if
op
then
743
local
first
=
op
[
1
]
744
local
second
=
op
[
2
]
745
local
fourth
=
op
[
4
]
746
if
fourth
then
747
local
tx
=
first
.
x_coord
748
local
ty
=
first
.
y_coord
749
local
sx
=
second
.
x_coord
-
tx
750
local
sy
=
fourth
.
y_coord
-
ty
751
local
rx
=
second
.
y_coord
-
ty
752
local
ry
=
fourth
.
x_coord
-
tx
753
if
sx
=
=
0
then
sx
=
0
.
00001
end
754
if
sy
=
=
0
then
sy
=
0
.
00001
end
755
return
sx
,
rx
,
ry
,
sy
,
tx
,
ty
756
end
757
end
758
return
1
,
0
,
0
,
1
,
0
,
0
-- weird case
759
end
760 761
metapost
.
cm
=
cm
762 763
-- color
764 765
local
function
cl_reset
(
t
)
766
t
[
#
t
+
1
]
=
metapost
.
colorinitializer
(
)
-- only color
767
end
768 769
-- text
770 771
local
tx_reset
,
tx_process
do
772 773
local
eol
=
S
(
"
\n\r
"
)
^
1
774
local
cleaner
=
Cs
(
(
P
(
"
@@
"
)
/
"
@
"
+
P
(
"
@
"
)
/
"
%%
"
+
P
(
1
)
)
^
0
)
775
local
splitter
=
Ct
(
776
(
(
777
P
(
"
s:
"
)
*
C
(
(
1
-
eol
)
^
1
)
778
+
P
(
"
n:
"
)
*
(
(
1
-
eol
)
^
1
/
tonumber
)
779
+
P
(
"
b:
"
)
*
(
(
1
-
eol
)
^
1
/
toboolean
)
780
)
*
eol
^
0
)
^
0
)
781 782
local
function
applyformat
(
s
)
783
local
t
=
lpegmatch
(
splitter
,
s
)
784
if
#
t
=
=
1
then
785
return
s
786
else
787
local
f
=
lpegmatch
(
cleaner
,
t
[
1
]
)
788
return
formatters
[
f
]
(
unpack
(
t
,
2
)
)
789
end
790
end
791 792
local
fmt
=
formatters
[
"
%s %s %s % t
"
]
793
----- pat = tsplitat(":")
794
local
pat
=
lpeg
.
tsplitter
(
"
:
"
,
tonumber
)
-- so that %F can do its work
795 796
local
f_gray_yes
=
formatters
[
"
s=%.3N,a=%i,t=%.3N
"
]
797
local
f_gray_nop
=
formatters
[
"
s=%.3N
"
]
798
local
f_rgb_yes
=
formatters
[
"
r=%.3N,g=%.3N,b=%.3N,a=%.3N,t=%.3N
"
]
799
local
f_rgb_nop
=
formatters
[
"
r=%.3N,g=%.3N,b=%.3N
"
]
800
local
f_cmyk_yes
=
formatters
[
"
c=%.3N,m=%.3N,y=%.3N,k=%.3N,a=%.3N,t=%.3N
"
]
801
local
f_cmyk_nop
=
formatters
[
"
c=%.3N,m=%.3N,y=%.3N,k=%.3N
"
]
802 803
local
ctx_MPLIBsetNtext
=
context
.
MPLIBsetNtextX
804
local
ctx_MPLIBsetCtext
=
context
.
MPLIBsetCtextX
805
local
ctx_MPLIBsettext
=
context
.
MPLIBsettextX
806 807
local
bp
=
number
.
dimenfactors
.
bp
808 809
local
mp_index
=
0
810
local
mp_target
=
0
811
local
mp_c
=
nil
812
local
mp_a
=
nil
813
local
mp_t
=
nil
814 815
local
function
processtext
(
)
816
local
mp_text
=
top
.
texstrings
[
mp_index
]
817
local
mp_regime
=
top
.
texregimes
[
mp_index
]
818
if
mp_regime
and
tonumber
(
mp_regime
)
>
=
0
then
819
mp_text
=
function
(
)
820
context
.
sprint
(
mp_regime
,
top
.
texstrings
[
mp_index
]
or
"
"
)
821
end
822
end
823
if
not
mp_text
then
824
report_textexts
(
"
missing text for index %a
"
,
mp_index
)
825
elseif
not
mp_c
then
826
ctx_MPLIBsetNtext
(
mp_target
,
mp_text
)
827
elseif
#
mp_c
=
=
1
then
828
if
mp_a
and
mp_t
then
829
ctx_MPLIBsetCtext
(
mp_target
,
f_gray_yes
(
mp_c
[
1
]
,
mp_a
,
mp_t
)
,
mp_text
)
830
else
831
ctx_MPLIBsetCtext
(
mp_target
,
f_gray_nop
(
mp_c
[
1
]
)
,
mp_text
)
832
end
833
elseif
#
mp_c
=
=
3
then
834
if
mp_a
and
mp_t
then
835
ctx_MPLIBsetCtext
(
mp_target
,
f_rgb_yes
(
mp_c
[
1
]
,
mp_c
[
2
]
,
mp_c
[
3
]
,
mp_a
,
mp_t
)
,
mp_text
)
836
else
837
ctx_MPLIBsetCtext
(
mp_target
,
f_rgb_nop
(
mp_c
[
1
]
,
mp_c
[
2
]
,
mp_c
[
3
]
)
,
mp_text
)
838
end
839
elseif
#
mp_c
=
=
4
then
840
if
mp_a
and
mp_t
then
841
ctx_MPLIBsetCtext
(
mp_target
,
f_cmyk_yes
(
mp_c
[
1
]
,
mp_c
[
2
]
,
mp_c
[
3
]
,
mp_c
[
4
]
,
mp_a
,
mp_t
)
,
mp_text
)
842
else
843
ctx_MPLIBsetCtext
(
mp_target
,
f_cmyk_nop
(
mp_c
[
1
]
,
mp_c
[
2
]
,
mp_c
[
3
]
,
mp_c
[
4
]
)
,
mp_text
)
844
end
845
else
846
-- can't happen
847
ctx_MPLIBsetNtext
(
mp_target
,
mp_text
)
848
end
849
end
850 851
local
madetext
=
nil
852 853
function
mp
.
mf_some_text
(
index
,
str
,
regime
)
854
mp_target
=
index
855
mp_index
=
index
856
mp_c
=
nil
857
mp_a
=
nil
858
mp_t
=
nil
859
top
.
texstrings
[
mp_index
]
=
str
860
top
.
texregimes
[
mp_index
]
=
regime
or
-1
861
texrunlocal
(
"
mptexttoks
"
)
862
local
box
=
textakebox
(
"
mptextbox
"
)
863
top
.
textexts
[
mp_target
]
=
box
864
mp
.
triplet
(
bp
*
box
.
width
,
bp
*
box
.
height
,
bp
*
box
.
depth
)
865
madetext
=
nil
866
end
867 868
function
mp
.
mf_made_text
(
index
)
869
mp
.
mf_some_text
(
index
,
madetext
,
catcodes
.
numbers
.
ctxcatcodes
)
-- btex/etex ..
870
end
871 872
-- a label can be anything, also something mp doesn't like in strings
873
-- so we return an index instead
874 875
function
metapost
.
processing
(
)
876
return
top
and
true
or
false
877
end
878 879
function
metapost
.
remaptext
(
replacement
)
880
if
top
then
881
local
mapstrings
=
top
.
mapstrings
882
local
mapindices
=
top
.
mapindices
883
local
label
=
replacement
.
label
884
local
index
=
0
885
if
label
then
886
local
found
=
mapstrings
[
label
]
887
if
found
then
888
setmetatableindex
(
found
,
replacement
)
889
index
=
found
.
index
890
else
891
index
=
#
mapindices
+
1
892
replacement
.
index
=
index
893
mapindices
[
index
]
=
replacement
894
mapstrings
[
label
]
=
replacement
895
end
896
end
897
return
index
898
else
899
return
0
900
end
901
end
902 903
function
metapost
.
remappedtext
(
what
)
904
return
top
and
(
top
.
mapstrings
[
what
]
or
top
.
mapindices
[
tonumber
(
what
)
]
)
905
end
906 907
function
mp
.
mf_map_move
(
index
)
908
mp
.
triplet
(
top
.
mapmoves
[
index
]
)
909
end
910 911
function
mp
.
mf_map_text
(
index
,
str
,
regime
)
912
local
map
=
top
.
mapindices
[
tonumber
(
str
)
]
913
if
type
(
map
)
=
=
"
table
"
then
914
local
text
=
map
.
text
915
local
overload
=
map
.
overload
916
local
offset
=
0
917
local
width
=
0
918
local
where
=
nil
919
--
920
mp_index
=
index
921
-- the image text
922
if
overload
then
923
top
.
texstrings
[
mp_index
]
=
map
.
template
or
map
.
label
or
"
error
"
924
top
.
texregimes
[
mp_index
]
=
regime
or
-1
925
texrunlocal
(
"
mptexttoks
"
)
926
local
box
=
textakebox
(
"
mptextbox
"
)
or
new_hlist
(
)
927
width
=
bp
*
box
.
width
928
where
=
overload
.
where
929
end
930
-- the real text
931
top
.
texstrings
[
mp_index
]
=
overload
and
overload
.
text
or
text
or
"
error
"
932
top
.
texregimes
[
mp_index
]
=
regime
or
-1
933
texrunlocal
(
"
mptexttoks
"
)
934
local
box
=
textakebox
(
"
mptextbox
"
)
or
new_hlist
(
)
935
local
twd
=
bp
*
box
.
width
936
local
tht
=
bp
*
box
.
height
937
local
tdp
=
bp
*
box
.
depth
938
-- the check
939
if
where
then
940
local
scale
=
1
-- / (map.scale or 1)
941
if
where
=
=
"
l
"
or
where
=
=
"
left
"
then
942
offset
=
scale
*
(
twd
-
width
)
943
elseif
where
=
=
"
m
"
or
where
=
=
"
middle
"
then
944
offset
=
scale
*
(
twd
-
width
)
/
2
945
end
946
end
947
-- the result
948
top
.
textexts
[
mp_index
]
=
box
949
top
.
mapmoves
[
mp_index
]
=
{
offset
,
map
.
dx
or
0
,
map
.
dy
or
0
}
950
--
951
mp
.
triplet
(
twd
,
tht
,
tdp
)
952
madetext
=
nil
953
return
954
else
955
map
=
type
(
map
)
=
=
"
string
"
and
map
or
str
956
return
mp
.
mf_some_text
(
index
,
context
.
escape
(
map
)
or
map
)
957
end
958
end
959 960
-- This is a bit messy. In regular metapost it's a kind of immediate replacement
961
-- so embedded btex ... etex is not really working as one would expect. We now have
962
-- a mix: it's immediate when we are at the outer level (rawmadetext) and indirect
963
-- (with the danger of stuff that doesn't work well in strings) when we are for
964
-- instance in a macro definition (rawtextext (pass back string)) ... of course one
965
-- should use textext so this is just a catch. When not in lmtx it's never immediate.
966 967
local
reported
=
false
968
local
alwayswrap
=
false
-- CONTEXTLMTXMODE <= 1 -- was always nil due to typo
969 970
function
metapost
.
maketext
(
s
,
mode
)
971
if
not
reported
then
972
reported
=
true
973
report_metapost
(
"
use 'textext(.....)' instead of 'btex ..... etex'
"
)
974
end
975
if
mode
and
mode
=
=
1
then
976
if
trace_btexetex
then
977
report_metapost
(
"
ignoring verbatimtex: [[%s]]
"
,
s
)
978
end
979
elseif
alwayswrap
then
980
if
trace_btexetex
then
981
report_metapost
(
"
rewrapping btex ... etex [[%s]]
"
,
s
)
982
end
983
return
'
rawtextext("
'
.
.
gsub
(
s
,
'
"
'
,
'
"&ditto&"
'
)
.
.
'
")
'
-- nullpicture
984
elseif
metapost
.
currentmpxstatus
(
)
~
=
0
then
985
if
trace_btexetex
then
986
report_metapost
(
"
rewrapping btex ... etex at the outer level [[%s]]
"
,
s
)
987
end
988
return
'
rawtextext("
'
.
.
gsub
(
s
,
'
"
'
,
'
"&ditto&"
'
)
.
.
'
")
'
-- nullpicture
989
else
990
if
trace_btexetex
then
991
report_metapost
(
"
handling btex ... etex: [[%s]]
"
,
s
)
992
end
993
-- madetext = utilities.strings.collapse(s)
994
madetext
=
s
995
return
"
rawmadetext
"
-- is assuming immediate processing
996
end
997
end
998 999
function
mp
.
mf_formatted_text
(
index
,
fmt
,
...
)
1000
local
t
=
{
}
1001
for
i
=
1
,
select
(
"
#
"
,
...
)
do
1002
local
ti
=
select
(
i
,
...
)
1003
if
type
(
ti
)
~
=
"
table
"
then
1004
t
[
#
t
+
1
]
=
ti
1005
end
1006
end
1007
local
f
=
lpegmatch
(
cleaner
,
fmt
)
1008
local
s
=
formatters
[
f
]
(
unpack
(
t
)
)
or
"
"
1009
mp
.
mf_some_text
(
index
,
s
)
1010
end
1011 1012
interfaces
.
implement
{
1013
name
=
"
mptexttoks
"
,
1014
actions
=
processtext
,
1015
}
1016 1017
tx_reset
=
function
(
)
1018
if
top
then
1019
top
.
texhash
=
{
}
1020
top
.
texlast
=
0
1021
end
1022
end
1023 1024
tx_process
=
function
(
object
,
prescript
,
before
,
after
)
1025
local
data
=
top
.
texdata
[
metapost
.
properties
.
number
]
-- the current figure number, messy
1026
local
index
=
tonumber
(
prescript
.
tx_index
)
1027
if
index
then
1028
if
trace_textexts
then
1029
report_textexts
(
"
using index %a
"
,
index
)
1030
end
1031
--
1032
mp_c
=
object
.
color
1033
if
#
mp_c
=
=
0
then
1034
local
txc
=
prescript
.
tx_color
1035
if
txc
then
1036
mp_c
=
lpegmatch
(
pat
,
txc
)
1037
end
1038
end
1039
mp_a
=
tonumber
(
prescript
.
tr_alternative
)
1040
mp_t
=
tonumber
(
prescript
.
tr_transparency
)
1041
--
1042
mp_index
=
index
1043
mp_target
=
top
.
texlast
-
1
1044
top
.
texlast
=
mp_target
1045
--
1046
local
mp_text
=
top
.
texstrings
[
mp_index
]
1047
local
mp_hash
=
prescript
.
tx_cache
1048
local
box
1049
if
mp_hash
=
=
"
no
"
then
1050
texrunlocal
(
"
mptexttoks
"
)
1051
box
=
textakebox
(
"
mptextbox
"
)
1052
else
1053
local
cache
=
data
.
texhash
1054
if
mp_hash
then
1055
mp_hash
=
tonumber
(
mp_hash
)
1056
end
1057
if
mp_hash
then
1058
local
extradata
=
top
.
extradata
1059
if
extradata
then
1060
cache
=
extradata
.
globalcache
1061
if
not
cache
then
1062
cache
=
{
}
1063
extradata
.
globalcache
=
cache
1064
end
1065
if
trace_runs
then
1066
if
cache
[
mp_hash
]
then
1067
report_textexts
(
"
reusing global entry %i
"
,
mp_hash
)
1068
else
1069
report_textexts
(
"
storing global entry %i
"
,
mp_hash
)
1070
end
1071
end
1072
else
1073
mp_hash
=
nil
1074
end
1075
end
1076
if
not
mp_hash
then
1077
mp_hash
=
fmt
(
mp_text
,
mp_a
or
"
-
"
,
mp_t
or
"
-
"
,
mp_c
or
"
-
"
)
1078
end
1079
box
=
cache
[
mp_hash
]
1080
if
box
then
1081
box
=
copylist
(
box
)
1082
else
1083
texrunlocal
(
"
mptexttoks
"
)
1084
box
=
textakebox
(
"
mptextbox
"
)
1085
cache
[
mp_hash
]
=
box
1086
end
1087
end
1088
top
.
textexts
[
mp_target
]
=
box
1089
--
1090
if
box
then
1091
-- we need to freeze the variables outside the function
1092
local
sx
,
rx
,
ry
,
sy
,
tx
,
ty
=
cm
(
object
)
1093
local
target
=
mp_target
1094
before
[
#
before
+
1
]
=
function
(
)
1095
context
.
MPLIBgettextscaledcm
(
target
,
1096
f_f
(
sx
)
,
-- bah ... %s no longer checks
1097
f_f
(
rx
)
,
-- bah ... %s no longer checks
1098
f_f
(
ry
)
,
-- bah ... %s no longer checks
1099
f_f
(
sy
)
,
-- bah ... %s no longer checks
1100
f_f
(
tx
)
,
-- bah ... %s no longer checks
1101
f_f
(
ty
)
,
-- bah ... %s no longer checks
1102
sxsy
(
box
.
width
,
box
.
height
,
box
.
depth
)
)
1103
end
1104
else
1105
before
[
#
before
+
1
]
=
function
(
)
1106
report_textexts
(
"
unknown %s
"
,
index
)
1107
end
1108
end
1109
if
not
trace_textexts
then
1110
object
.
path
=
false
-- else: keep it
1111
end
1112
object
.
color
=
false
1113
object
.
grouped
=
true
1114
object
.
istext
=
true
1115
end
1116
end
1117 1118
end
1119 1120
-- we could probably redo normal textexts in the next way but as it's rather optimized
1121
-- we keep away from that (at least for now)
1122 1123
local
function
bx_process
(
object
,
prescript
,
before
,
after
)
1124
local
bx_category
=
prescript
.
bx_category
1125
local
bx_name
=
prescript
.
bx_name
1126
if
bx_category
and
bx_name
then
1127
if
trace_textexts
then
1128
report_textexts
(
"
category %a, name %a
"
,
bx_category
,
bx_name
)
1129
end
1130
local
sx
,
rx
,
ry
,
sy
,
tx
,
ty
=
cm
(
object
)
-- needs to be frozen outside the function
1131
local
wd
,
ht
,
dp
=
nodes
.
boxes
.
dimensions
(
bx_category
,
bx_name
)
1132
before
[
#
before
+
1
]
=
function
(
)
1133
context
.
MPLIBgetboxscaledcm
(
bx_category
,
bx_name
,
1134
f_f
(
sx
)
,
-- bah ... %s no longer checks
1135
f_f
(
rx
)
,
-- bah ... %s no longer checks
1136
f_f
(
ry
)
,
-- bah ... %s no longer checks
1137
f_f
(
sy
)
,
-- bah ... %s no longer checks
1138
f_f
(
tx
)
,
-- bah ... %s no longer checks
1139
f_f
(
ty
)
,
-- bah ... %s no longer checks
1140
sxsy
(
wd
,
ht
,
dp
)
)
1141
end
1142
if
not
trace_textexts
then
1143
object
.
path
=
false
-- else: keep it
1144
end
1145
object
.
color
=
false
1146
object
.
grouped
=
true
1147
object
.
istext
=
true
1148
end
1149
end
1150 1151
-- graphics (we use the given index because pictures can be reused)
1152 1153 1154
local
gt_reset
,
gt_process
do
1155 1156
local
graphics
=
{
}
1157 1158 1159
local
mp_index
=
0
1160
local
mp_str
=
"
"
1161 1162
function
mp
.
mf_graphic_text
(
index
,
str
)
1163
if
not
graphics
[
index
]
then
1164
mp_index
=
index
1165
mp_str
=
str
1166
texrunlocal
(
"
mpgraphictexttoks
"
)
1167
end
1168
end
1169 1170
interfaces
.
implement
{
1171
name
=
"
mpgraphictexttoks
"
,
1172
actions
=
function
(
)
1173
context
.
MPLIBgraphictext
(
mp_index
,
mp_str
)
1174
end
,
1175
}
1176 1177
end
1178 1179
-- shades
1180 1181
local
function
sh_process
(
object
,
prescript
,
before
,
after
)
1182
local
sh_type
=
prescript
.
sh_type
1183
if
sh_type
then
1184
nofshades
=
nofshades
+
1
1185
local
domain
=
lpegmatch
(
domainsplitter
,
prescript
.
sh_domain
or
"
0 1
"
)
1186
local
centera
=
lpegmatch
(
centersplitter
,
prescript
.
sh_center_a
or
"
0 0
"
)
1187
local
centerb
=
lpegmatch
(
centersplitter
,
prescript
.
sh_center_b
or
"
0 0
"
)
1188
local
transform
=
toboolean
(
prescript
.
sh_transform
or
"
yes
"
,
true
)
1189
-- compensation for scaling
1190
local
sx
=
1
1191
local
sy
=
1
1192
local
sr
=
1
1193
local
dx
=
0
1194
local
dy
=
0
1195
if
transform
then
1196
local
first
=
lpegmatch
(
coordinatesplitter
,
prescript
.
sh_first
or
"
0 0
"
)
1197
local
setx
=
lpegmatch
(
coordinatesplitter
,
prescript
.
sh_set_x
or
"
0 0
"
)
1198
local
sety
=
lpegmatch
(
coordinatesplitter
,
prescript
.
sh_set_y
or
"
0 0
"
)
1199 1200
local
x
=
setx
[
1
]
-- point that has different x
1201
local
y
=
sety
[
1
]
-- point that has different y
1202 1203
if
x
=
=
0
or
y
=
=
0
then
1204
-- forget about it
1205
else
1206
local
path
=
object
.
path
1207
local
path1x
=
path
[
1
]
.
x_coord
1208
local
path1y
=
path
[
1
]
.
y_coord
1209
local
path2x
=
path
[
x
]
.
x_coord
1210
local
path2y
=
path
[
y
]
.
y_coord
1211 1212
local
dxa
=
path2x
-
path1x
1213
local
dya
=
path2y
-
path1y
1214
local
dxb
=
setx
[
2
]
-
first
[
1
]
1215
local
dyb
=
sety
[
2
]
-
first
[
2
]
1216 1217
if
dxa
=
=
0
or
dya
=
=
0
or
dxb
=
=
0
or
dyb
=
=
0
then
1218
-- forget about it
1219
else
1220
sx
=
dxa
/
dxb
;
if
sx
<
0
then
sx
=
-
sx
end
-- yes or no
1221
sy
=
dya
/
dyb
;
if
sy
<
0
then
sy
=
-
sy
end
-- yes or no
1222 1223
sr
=
sqrt
(
sx
^
2
+
sy
^
2
)
1224 1225
dx
=
path1x
-
sx
*
first
[
1
]
1226
dy
=
path1y
-
sy
*
first
[
2
]
1227
end
1228
end
1229
end
1230 1231
local
steps
=
tonumber
(
prescript
.
sh_step
)
or
1
1232
local
sh_color_a
=
prescript
.
sh_color_a_1
or
prescript
.
sh_color_a
or
"
1
"
1233
local
sh_color_b
=
prescript
.
sh_color_b_1
or
prescript
.
sh_color_b
or
"
1
"
-- sh_color_b_<sh_steps>
1234
local
ca
,
cb
,
colorspace
,
name
,
model
,
separation
,
fractions
1235
if
prescript
.
sh_color
=
=
"
into
"
and
prescript
.
sp_name
then
1236
-- some spotcolor
1237
local
value_a
,
components_a
,
fractions_a
,
name_a
1238
local
value_b
,
components_b
,
fractions_b
,
name_b
1239
for
i
=
1
,
#
prescript
do
1240
-- { "sh_color_a", "1" },
1241
-- { "sh_color", "into" },
1242
-- { "sh_radius_b", "0" },
1243
-- { "sh_radius_a", "141.73225" },
1244
-- { "sh_center_b", "425.19676 141.73225" },
1245
-- { "sh_center_a", "425.19676 0" },
1246
-- { "sh_factor", "1" },
1247
local
tag
=
prescript
[
i
]
[
1
]
1248
if
not
name_a
and
tag
=
=
"
sh_color_a
"
then
1249
value_a
=
prescript
[
i
-5
]
[
2
]
1250
components_a
=
prescript
[
i
-4
]
[
2
]
1251
fractions_a
=
prescript
[
i
-3
]
[
2
]
1252
name_a
=
prescript
[
i
-2
]
[
2
]
1253
elseif
not
name_b
and
tag
=
=
"
sh_color_b
"
then
1254
value_b
=
prescript
[
i
-5
]
[
2
]
1255
components_b
=
prescript
[
i
-4
]
[
2
]
1256
fractions_b
=
prescript
[
i
-3
]
[
2
]
1257
name_b
=
prescript
[
i
-2
]
[
2
]
1258
end
1259
if
name_a
and
name_b
then
1260
break
1261
end
1262
end
1263
ca
,
cb
,
separation
,
name
=
checkandconvertspot
(
1264
name_a
,
fractions_a
,
components_a
,
value_a
,
1265
name_b
,
fractions_b
,
components_b
,
value_b
1266
)
1267
else
1268
local
colora
=
lpegmatch
(
colorsplitter
,
sh_color_a
)
1269
local
colorb
=
lpegmatch
(
colorsplitter
,
sh_color_b
)
1270
ca
,
cb
,
colorspace
,
name
,
model
=
checkandconvert
(
colora
,
colorb
)
1271
-- test:
1272
if
steps
>
1
then
1273
ca
=
{
ca
}
1274
cb
=
{
cb
}
1275
fractions
=
{
tonumber
(
prescript
[
formatters
[
"
sh_fraction_%i
"
]
(
1
)
]
)
or
0
}
1276
for
i
=
2
,
steps
do
1277
local
colora
=
lpegmatch
(
colorsplitter
,
prescript
[
formatters
[
"
sh_color_a_%i
"
]
(
i
)
]
)
1278
local
colorb
=
lpegmatch
(
colorsplitter
,
prescript
[
formatters
[
"
sh_color_b_%i
"
]
(
i
)
]
)
1279
ca
[
i
]
,
cb
[
i
]
=
checkandconvert
(
colora
,
colorb
,
model
)
1280
fractions
[
i
]
=
tonumber
(
prescript
[
formatters
[
"
sh_fraction_%i
"
]
(
i
)
]
)
or
(
i
/
steps
)
1281
end
1282
end
1283
end
1284
if
not
ca
or
not
cb
then
1285
ca
,
cb
,
colorspace
,
name
=
checkandconvert
(
)
1286
steps
=
1
1287
end
1288
if
sh_type
=
=
"
linear
"
then
1289
local
coordinates
=
{
dx
+
sx
*
centera
[
1
]
,
dy
+
sy
*
centera
[
2
]
,
dx
+
sx
*
centerb
[
1
]
,
dy
+
sy
*
centerb
[
2
]
}
1290
lpdf
.
linearshade
(
name
,
domain
,
ca
,
cb
,
1
,
colorspace
,
coordinates
,
separation
,
steps
>
1
and
steps
,
fractions
)
-- backend specific (will be renamed)
1291
elseif
sh_type
=
=
"
circular
"
then
1292
local
factor
=
tonumber
(
prescript
.
sh_factor
)
or
1
1293
local
radiusa
=
factor
*
tonumber
(
prescript
.
sh_radius_a
)
1294
local
radiusb
=
factor
*
tonumber
(
prescript
.
sh_radius_b
)
1295
local
coordinates
=
{
dx
+
sx
*
centera
[
1
]
,
dy
+
sy
*
centera
[
2
]
,
sr
*
radiusa
,
dx
+
sx
*
centerb
[
1
]
,
dy
+
sy
*
centerb
[
2
]
,
sr
*
radiusb
}
1296
lpdf
.
circularshade
(
name
,
domain
,
ca
,
cb
,
1
,
colorspace
,
coordinates
,
separation
,
steps
>
1
and
steps
,
fractions
)
-- backend specific (will be renamed)
1297
else
1298
-- fatal error
1299
end
1300
before
[
#
before
+
1
]
=
"
q /Pattern cs
"
1301
after
[
#
after
+
1
]
=
formatters
[
"
W n /%s sh Q
"
]
(
name
)
1302
-- false, not nil, else mt triggered
1303
object
.
colored
=
false
-- hm, not object.color ?
1304
object
.
type
=
false
1305
object
.
grouped
=
true
1306
end
1307
end
1308 1309
-- bitmaps
1310 1311
local
function
bm_process
(
object
,
prescript
,
before
,
after
)
1312
local
bm_xresolution
=
prescript
.
bm_xresolution
1313
if
bm_xresolution
then
1314
before
[
#
before
+
1
]
=
f_cm_b
(
cm
(
object
)
)
1315
before
[
#
before
+
1
]
=
function
(
)
1316
figures
.
bitmapimage
{
1317
xresolution
=
tonumber
(
bm_xresolution
)
,
1318
yresolution
=
tonumber
(
prescript
.
bm_yresolution
)
,
1319
width
=
1
/
basepoints
,
1320
height
=
1
/
basepoints
,
1321
data
=
object
.
postscript
1322
}
1323
end
1324
before
[
#
before
+
1
]
=
s_cm_e
1325
object
.
path
=
false
1326
object
.
color
=
false
1327
object
.
grouped
=
true
1328
end
1329
end
1330 1331
-- positions
1332 1333
local
function
ps_process
(
object
,
prescript
,
before
,
after
)
1334
local
ps_label
=
prescript
.
ps_label
1335
if
ps_label
then
1336
local
op
=
object
.
path
1337
local
first
=
op
[
1
]
1338
local
third
=
op
[
3
]
1339
local
x
=
first
.
x_coord
1340
local
y
=
first
.
y_coord
1341
local
w
=
third
.
x_coord
-
x
1342
local
h
=
third
.
y_coord
-
y
1343
local
properties
=
metapost
.
properties
1344
x
=
x
-
properties
.
llx
1345
y
=
properties
.
ury
-
y
1346
before
[
#
before
+
1
]
=
function
(
)
1347
context
.
MPLIBpositionwhd
(
ps_label
,
x
,
y
,
w
,
h
)
1348
end
1349
object
.
path
=
false
1350
end
1351
end
1352 1353
-- figures
1354 1355
-- local sx, rx, ry, sy, tx, ty = cm(object)
1356
-- sxsy(box.width,box.height,box.depth))
1357 1358
function
mp
.
mf_external_figure
(
filename
)
1359
local
f
=
figures
.
getinfo
(
filename
)
1360
local
w
=
0
1361
local
h
=
0
1362
if
f
then
1363
local
u
=
f
.
used
1364
if
u
and
u
.
fullname
then
1365
w
=
u
.
width
or
0
1366
h
=
u
.
height
or
0
1367
end
1368
else
1369
report_metapost
(
"
external figure %a not found
"
,
filename
)
1370
end
1371
mp
.
triplet
(
w
/
65536
,
h
/
65536
,
0
)
1372
end
1373 1374
local
function
fg_process
(
object
,
prescript
,
before
,
after
)
1375
local
fg_name
=
prescript
.
fg_name
1376
if
fg_name
then
1377
before
[
#
before
+
1
]
=
f_cm_b
(
cm
(
object
)
)
-- beware: does not use the cm stack
1378
before
[
#
before
+
1
]
=
function
(
)
1379
context
.
MPLIBfigure
(
fg_name
,
prescript
.
fg_mask
or
"
"
)
1380
end
1381
before
[
#
before
+
1
]
=
s_cm_e
1382
object
.
path
=
false
1383
object
.
grouped
=
true
1384
end
1385
end
1386 1387
-- color and transparency
1388 1389
local
value
=
Cs
(
(
1390
(
Carg
(
1
)
*
C
(
(
1
-
P
(
"
,
"
)
)
^
1
)
)
/
function
(
a
,
b
)
return
f_f3
(
a
*
tonumber
(
b
)
)
end
1391
+
P
(
"
,
"
)
)
^
1
1392
)
1393 1394
-- should be codeinjections
1395 1396
local
t_list
=
attributes
.
list
[
attributes
.
private
(
'
transparency
'
)
]
1397
local
c_list
=
attributes
.
list
[
attributes
.
private
(
'
color
'
)
]
1398 1399
local
remappers
=
{
1400
[
1
]
=
formatters
[
"
s=%s
"
]
,
1401
[
3
]
=
formatters
[
"
r=%s,g=%s,b=%s
"
]
,
1402
[
4
]
=
formatters
[
"
c=%s,m=%s,y=%s,k=%s
"
]
,
1403
}
1404 1405
local
processlast
=
0
1406
local
processhash
=
setmetatableindex
(
function
(
t
,
k
)
1407
processlast
=
processlast
+
1
1408
local
v
=
formatters
[
"
mp_%s
"
]
(
processlast
)
1409
defineprocesscolor
(
v
,
k
,
true
,
true
)
1410
t
[
k
]
=
v
1411
return
v
1412
end
)
1413 1414
local
function
checked_transparency
(
alternative
,
transparency
,
before
,
after
)
1415
alternative
=
tonumber
(
alternative
)
or
1
1416
transparency
=
tonumber
(
transparency
)
or
0
1417
before
[
#
before
+
1
]
=
formatters
[
"
/Tr%s gs
"
]
(
registertransparency
(
nil
,
alternative
,
transparency
,
true
)
)
1418
after
[
#
after
+
1
]
=
"
/Tr0 gs
"
-- outertransparency
1419
end
1420 1421
local
function
tr_process
(
object
,
prescript
,
before
,
after
)
1422
-- before can be shortcut to t
1423
local
tr_alternative
=
prescript
.
tr_alternative
1424
if
tr_alternative
then
1425
checked_transparency
(
tr_alternative
,
prescript
.
tr_transparency
,
before
,
after
)
1426
end
1427
local
cs
=
object
.
color
1428
if
cs
and
#
cs
>
0
then
1429
local
c_b
,
c_a
1430
local
sp_type
=
prescript
.
sp_type
1431
if
not
sp_type
then
1432
c_b
,
c_a
=
colorconverter
(
cs
)
1433
else
1434
local
sp_name
=
prescript
.
sp_name
or
"
black
"
1435
if
sp_type
=
=
"
spot
"
then
1436
local
sp_value
=
prescript
.
sp_value
or
"
1
"
1437
local
components
=
split
(
sp_value
,
"
:
"
)
1438
local
specification
=
remappers
[
#
components
]
1439
if
specification
then
1440
specification
=
specification
(
unpack
(
components
)
)
1441
else
1442
specification
=
"
s=0
"
1443
end
1444
local
sp_spec
=
processhash
[
specification
]
1445
definespotcolor
(
sp_name
,
sp_spec
,
"
p=1
"
,
true
)
1446
sp_type
=
"
named
"
1447
elseif
sp_type
=
=
"
multitone
"
then
-- (fractions of a multitone) don't work well in mupdf
1448
local
sp_value
=
prescript
.
sp_value
or
"
1
"
1449
local
sp_specs
=
{
}
1450
local
sp_list
=
split
(
sp_value
,
"
"
)
1451
for
i
=
1
,
#
sp_list
do
1452
local
sp_value
=
sp_list
[
i
]
1453
local
components
=
split
(
sp_value
,
"
:
"
)
1454
local
specification
=
remappers
[
#
components
]
1455
if
specification
then
1456
specification
=
specification
(
unpack
(
components
)
)
1457
else
1458
specification
=
"
s=0
"
1459
end
1460
local
sp_spec
=
processhash
[
specification
]
1461
sp_specs
[
i
]
=
formatters
[
"
%s=1
"
]
(
sp_spec
)
1462
end
1463
sp_specs
=
concat
(
sp_specs
,
"
,
"
)
1464
definemultitonecolor
(
sp_name
,
sp_specs
,
"
"
,
"
"
)
1465
sp_type
=
"
named
"
1466
elseif
sp_type
=
=
"
named
"
then
1467
cs
=
{
1
}
-- factor 1
1468
end
1469
if
sp_type
=
=
"
named
"
then
1470
-- we might move this to another namespace .. also, named can be a spotcolor
1471
-- so we need to check for that too ... also we need to resolve indirect
1472
-- colors so we might need the second pass for this (draw dots with \MPcolor)
1473
if
not
tr_alternative
then
1474
-- todo: sp_name is not yet registered at this time
1475
local
t
=
t_list
[
sp_name
]
-- string or attribute
1476
local
v
=
t
and
transparencyvalue
(
t
)
1477
if
v
then
1478
checked_transparency
(
v
[
1
]
,
v
[
2
]
,
before
,
after
)
1479
end
1480
end
1481
local
c
=
c_list
[
sp_name
]
-- string or attribute
1482
local
v
=
c
and
colorvalue
(
c
)
1483
if
v
then
1484
-- all=1 gray=2 rgb=3 cmyk=4
1485
local
colorspace
=
v
[
1
]
1486
local
factor
=
cs
[
1
]
1487
if
colorspace
=
=
2
then
1488
local
s
=
factor
*
v
[
2
]
1489
c_b
,
c_a
=
checked_color_pair
(
f_gray
,
s
,
s
)
1490
elseif
colorspace
=
=
3
then
1491
local
r
=
factor
*
v
[
3
]
1492
local
g
=
factor
*
v
[
4
]
1493
local
b
=
factor
*
v
[
5
]
1494
c_b
,
c_a
=
checked_color_pair
(
f_rgb
,
r
,
g
,
b
,
r
,
g
,
b
)
1495
elseif
colorspace
=
=
4
or
colorspace
=
=
1
then
1496
local
c
=
factor
*
v
[
6
]
1497
local
m
=
factor
*
v
[
7
]
1498
local
y
=
factor
*
v
[
8
]
1499
local
k
=
factor
*
v
[
9
]
1500
c_b
,
c_a
=
checked_color_pair
(
f_cmyk
,
c
,
m
,
y
,
k
,
c
,
m
,
y
,
k
)
1501
elseif
colorspace
=
=
5
then
1502
-- not all viewers show the fractions ok
1503
local
name
=
v
[
10
]
1504
local
value
=
split
(
v
[
13
]
,
"
,
"
)
1505
if
factor
~
=
1
then
1506
for
i
=
1
,
#
value
do
1507
value
[
i
]
=
f_scn
(
factor
*
(
tonumber
(
value
[
i
]
)
or
1
)
)
1508
end
1509
end
1510
value
=
concat
(
value
,
"
"
)
1511
c_b
,
c_a
=
checked_color_pair
(
f_spot
,
name
,
name
,
value
,
value
)
1512
else
1513
local
s
=
factor
*
v
[
2
]
1514
c_b
,
c_a
=
checked_color_pair
(
f_gray
,
s
,
s
)
1515
end
1516
end
1517
end
1518
end
1519
if
c_a
and
c_b
then
1520
before
[
#
before
+
1
]
=
c_b
1521
after
[
#
after
+
1
]
=
c_a
1522
end
1523
end
1524
end
1525 1526
-- layers (nasty: we need to keep the 'grouping' right
1527 1528
local
function
la_process
(
object
,
prescript
,
before
,
after
)
1529
local
la_name
=
prescript
.
la_name
1530
if
la_name
then
1531
before
[
#
before
+
1
]
=
backends
.
codeinjections
.
startlayer
(
la_name
)
1532
insert
(
after
,
1
,
backends
.
codeinjections
.
stoplayer
(
)
)
1533
end
1534
end
1535 1536
-- groups
1537 1538
local
function
gr_process
(
object
,
prescript
,
before
,
after
)
1539
local
gr_state
=
prescript
.
gr_state
1540
if
not
gr_state
then
1541
return
1542
elseif
gr_state
=
=
"
start
"
then
1543
local
gr_type
=
utilities
.
parsers
.
settings_to_set
(
prescript
.
gr_type
)
1544
local
path
=
object
.
path
1545
local
p1
=
path
[
1
]
1546
local
p2
=
path
[
2
]
1547
local
p3
=
path
[
3
]
1548
local
p4
=
path
[
4
]
1549
local
llx
=
min
(
p1
.
x_coord
,
p2
.
x_coord
,
p3
.
x_coord
,
p4
.
x_coord
)
1550
local
lly
=
min
(
p1
.
y_coord
,
p2
.
y_coord
,
p3
.
y_coord
,
p4
.
y_coord
)
1551
local
urx
=
max
(
p1
.
x_coord
,
p2
.
x_coord
,
p3
.
x_coord
,
p4
.
x_coord
)
1552
local
ury
=
max
(
p1
.
y_coord
,
p2
.
y_coord
,
p3
.
y_coord
,
p4
.
y_coord
)
1553
before
[
#
before
+
1
]
=
function
(
)
1554
context
.
MPLIBstartgroup
(
1555
gr_type
.
isolated
and
1
or
0
,
1556
gr_type
.
knockout
and
1
or
0
,
1557
llx
,
lly
,
urx
,
ury
1558
)
1559
end
1560
elseif
gr_state
=
=
"
stop
"
then
1561
after
[
#
after
+
1
]
=
function
(
)
1562
context
.
MPLIBstopgroup
(
)
1563
end
1564
end
1565
object
.
path
=
false
1566
object
.
color
=
false
1567
object
.
grouped
=
true
1568
end
1569 1570
-- outlines
1571 1572
local
ot_reset
,
ot_process
do
1573 1574
local
outlinetexts
=
{
}
-- also in top data
1575 1576
ot_reset
=
function
(
)
1577
outlinetexts
=
{
}
1578
end
1579 1580
local
mp_index
=
0
1581
local
mp_kind
=
"
"
1582
local
mp_str
=
"
"
1583 1584
function
mp
.
mf_outline_text
(
index
,
str
,
kind
)
1585
if
not
outlinetexts
[
index
]
then
1586
mp_index
=
index
1587
mp_kind
=
kind
1588
mp_str
=
str
1589
texrunlocal
(
"
mpoutlinetoks
"
)
1590
end
1591
end
1592 1593
interfaces
.
implement
{
1594
name
=
"
mpoutlinetoks
"
,
1595
actions
=
function
(
)
1596
context
.
MPLIBoutlinetext
(
mp_index
,
mp_kind
,
mp_str
)
1597
end
,
1598
}
1599 1600
implement
{
1601
name
=
"
MPLIBconvertoutlinetext
"
,
1602
arguments
=
{
"
integer
"
,
"
string
"
,
"
integer
"
}
,
1603
actions
=
function
(
index
,
kind
,
box
)
1604
local
boxtomp
=
fonts
.
metapost
.
boxtomp
1605
if
boxtomp
then
1606
outlinetexts
[
index
]
=
boxtomp
(
box
,
kind
)
1607
else
1608
outlinetexts
[
index
]
=
"
"
1609
end
1610
end
1611
}
1612 1613
function
mp
.
mf_get_outline_text
(
index
)
-- maybe we need a more private namespace
1614
mp
.
print
(
outlinetexts
[
index
]
or
"
draw origin;
"
)
1615
end
1616 1617
end
1618 1619
-- mf_object=<string>
1620 1621
local
p1
=
P
(
"
mf_object=
"
)
1622
local
p2
=
lpeg
.
patterns
.
eol
*
p1
1623
local
pattern
=
(
1
-
p2
)
^
0
*
p2
+
p1
1624 1625
function
metapost
.
isobject
(
str
)
1626
return
pattern
and
str
~
=
"
"
and
lpegmatch
(
p
,
str
)
and
true
or
false
1627
end
1628 1629
local
function
installplugin
(
specification
)
1630
local
reset
=
specification
.
reset
1631
local
process
=
specification
.
process
1632
local
object
=
specification
.
object
1633
if
reset
then
1634
appendaction
(
resetteractions
,
"
system
"
,
reset
)
1635
end
1636
if
process
then
1637
appendaction
(
processoractions
,
"
system
"
,
process
)
1638
end
1639
end
1640 1641
metapost
.
installplugin
=
installplugin
1642 1643
-- definitions
1644 1645
installplugin
{
name
=
"
outline
"
,
reset
=
ot_reset
,
process
=
ot_process
}
1646
installplugin
{
name
=
"
color
"
,
reset
=
cl_reset
,
process
=
cl_process
}
1647
installplugin
{
name
=
"
text
"
,
reset
=
tx_reset
,
process
=
tx_process
}
1648
installplugin
{
name
=
"
group
"
,
reset
=
gr_reset
,
process
=
gr_process
}
1649
installplugin
{
name
=
"
graphictext
"
,
reset
=
gt_reset
,
process
=
gt_process
}
1650
installplugin
{
name
=
"
shade
"
,
reset
=
sh_reset
,
process
=
sh_process
}
1651
installplugin
{
name
=
"
bitmap
"
,
reset
=
bm_reset
,
process
=
bm_process
}
1652
installplugin
{
name
=
"
box
"
,
reset
=
bx_reset
,
process
=
bx_process
}
1653
installplugin
{
name
=
"
position
"
,
reset
=
ps_reset
,
process
=
ps_process
}
1654
installplugin
{
name
=
"
figure
"
,
reset
=
fg_reset
,
process
=
fg_process
}
1655
installplugin
{
name
=
"
layer
"
,
reset
=
la_reset
,
process
=
la_process
}
1656
installplugin
{
name
=
"
transparency
"
,
reset
=
tr_reset
,
process
=
tr_process
}
1657