back-shp.lua /size: 52 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
back-shp
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to lpdf-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
local
type
,
next
=
type
,
next
10
local
round
=
math
.
round
11 12
local
setmetatableindex
=
table
.
setmetatableindex
13
local
formatters
=
string
.
formatters
14
local
concat
=
table
.
concat
15
local
keys
=
table
.
keys
16
local
sortedhash
=
table
.
sortedhash
17
local
splitstring
=
string
.
split
18
local
idiv
=
number
.
idiv
19
local
extract
=
bit32
.
extract
20
local
nuts
=
nodes
.
nuts
21 22
local
tonut
=
nodes
.
tonut
23
local
tonode
=
nodes
.
tonode
24 25
local
getdirection
=
nuts
.
getdirection
26
local
getlist
=
nuts
.
getlist
27
local
getoffsets
=
nuts
.
getoffsets
28
local
getorientation
=
nuts
.
getorientation
29
local
getfield
=
nuts
.
getfield
30
local
getwhd
=
nuts
.
getwhd
31
local
getkern
=
nuts
.
getkern
32
local
getheight
=
nuts
.
getheight
33
local
getdepth
=
nuts
.
getdepth
34
local
getwidth
=
nuts
.
getwidth
35
local
getnext
=
nuts
.
getnext
36
local
getsubtype
=
nuts
.
getsubtype
37
local
getid
=
nuts
.
getid
38
local
getleader
=
nuts
.
getleader
39
local
getglue
=
nuts
.
getglue
40
local
getshift
=
nuts
.
getshift
41
local
getdata
=
nuts
.
getdata
42
local
getboxglue
=
nuts
.
getboxglue
43
local
getexpansion
=
nuts
.
getexpansion
44 45
local
setdirection
=
nuts
.
setdirection
46
local
setfield
=
nuts
.
setfield
47
local
setlink
=
nuts
.
setlink
48 49
local
isglyph
=
nuts
.
isglyph
50
local
findtail
=
nuts
.
tail
51
local
nextdir
=
nuts
.
traversers
.
dir
52
local
nextnode
=
nuts
.
traversers
.
node
53 54
local
rangedimensions
=
nuts
.
rangedimensions
55
local
effectiveglue
=
nuts
.
effective_glue
56 57
local
nodecodes
=
nodes
.
nodecodes
58
local
whatsitcodes
=
nodes
.
whatsitcodes
59
local
leadercodes
=
nodes
.
leadercodes
60
local
subtypes
=
nodes
.
subtypes
61 62
local
dircodes
=
nodes
.
dircodes
63
local
normaldir_code
=
dircodes
.
normal
64 65
local
dirvalues
=
nodes
.
dirvalues
66
local
lefttoright_code
=
dirvalues
.
lefttoright
67
local
righttoleft_code
=
dirvalues
.
righttoleft
68 69
local
glyph_code
=
nodecodes
.
glyph
70
local
kern_code
=
nodecodes
.
kern
71
local
glue_code
=
nodecodes
.
glue
72
local
hlist_code
=
nodecodes
.
hlist
73
local
vlist_code
=
nodecodes
.
vlist
74
local
dir_code
=
nodecodes
.
dir
75
local
disc_code
=
nodecodes
.
disc
76
local
math_code
=
nodecodes
.
math
77
local
rule_code
=
nodecodes
.
rule
78
local
marginkern_code
=
nodecodes
.
marginkern
79
local
whatsit_code
=
nodecodes
.
whatsit
80 81
local
leader_code
=
leadercodes
.
leader
82
local
cleader_code
=
leadercodes
.
cleader
83
local
xleader_code
=
leadercodes
.
xleader
84
local
gleader_code
=
leadercodes
.
gleader
85 86
local
saveposwhatsit_code
=
whatsitcodes
.
savepos
87
local
userdefinedwhatsit_code
=
whatsitcodes
.
userdefined
88
local
openwhatsit_code
=
whatsitcodes
.
open
89
local
writewhatsit_code
=
whatsitcodes
.
write
90
local
closewhatsit_code
=
whatsitcodes
.
close
91
local
lateluawhatsit_code
=
whatsitcodes
.
latelua
92
local
literalwhatsit_code
=
whatsitcodes
.
literal
93
local
setmatrixwhatsit_code
=
whatsitcodes
.
setmatrix
94
local
savewhatsit_code
=
whatsitcodes
.
save
95
local
restorewhatsit_code
=
whatsitcodes
.
restore
96 97
local
texget
=
tex
.
get
98 99
local
fontdata
=
fonts
.
hashes
.
identifiers
100
local
characters
=
fonts
.
hashes
.
characters
101
local
parameters
=
fonts
.
hashes
.
parameters
102 103
local
trace_missing
=
false
104 105
local
report
=
logs
.
reporter
(
"
drivers
"
)
106
local
report_missing
=
logs
.
reporter
(
"
drivers
"
,
"
missing
"
)
107
----- report_detail = logs.reporter("drivers","detail")
108 109
local
getpagedimensions
getpagedimensions
=
function
(
)
110
getpagedimensions
=
backends
.
codeinjections
.
getpagedimensions
111
return
getpagedimensions
(
)
112
end
113 114
local
instances
=
{
}
115 116
drivers
=
{
117
instances
=
instances
,
118
lmtxversion
=
0
.
10
,
119
}
120 121
local
defaulthandlers
=
{
122
-- housekeeping
123
prepare
=
function
(
)
end
,
124
initialize
=
function
(
)
end
,
125
finalize
=
function
(
)
end
,
126
updatefontstate
=
function
(
)
end
,
127
wrapup
=
function
(
)
end
,
128
-- handlers
129
pushorientation
=
function
(
)
if
trace_missing
then
report
(
"
pushorientation
"
)
end
end
,
130
poporientation
=
function
(
)
if
trace_missing
then
report
(
"
poporientation
"
)
end
end
,
131
flushcharacter
=
function
(
)
if
trace_missing
then
report
(
"
flushcharacter
"
)
end
end
,
132
flushrule
=
function
(
)
if
trace_missing
then
report
(
"
flushrule
"
)
end
end
,
133
flushlatelua
=
function
(
)
if
trace_missing
then
report
(
"
flushlatelua
"
)
end
end
,
134
flushpdfliteral
=
function
(
)
if
trace_missing
then
report
(
"
flushpdfliteral
"
)
end
end
,
135
flushpdfsetmatrix
=
function
(
)
if
trace_missing
then
report
(
"
flushpdfsetmatrix
"
)
end
end
,
136
flushpdfsave
=
function
(
)
if
trace_missing
then
report
(
"
flushpdfsave
"
)
end
end
,
137
flushpdfrestore
=
function
(
)
if
trace_missing
then
report
(
"
flushpdfrestore
"
)
end
end
,
138
flushspecial
=
function
(
)
if
trace_missing
then
report
(
"
flushspecial
"
)
end
end
,
139
flushpdfimage
=
function
(
)
if
trace_missing
then
report
(
"
flushpdfimage
"
)
end
end
,
140
}
141 142
function
drivers
.
install
(
specification
)
143
local
name
=
specification
.
name
144
if
not
name
then
145
report
(
"
missing driver name
"
)
146
return
147
end
148
local
actions
=
specification
.
actions
149
if
not
actions
then
150
report
(
"
no actions for driver %a
"
,
name
)
151
return
152
end
153
local
flushers
=
specification
.
flushers
154
if
not
flushers
then
155
report
(
"
no flushers for driver %a
"
,
name
)
156
return
157
end
158
setmetatableindex
(
flushers
,
defaulthandlers
)
159
instances
[
name
]
=
specification
160
end
161 162
function
drivers
.
prepare
(
name
)
163
local
driver
=
instances
[
name
]
164
if
not
driver
then
165
return
166
end
167
local
prepare
=
driver
.
actions
.
prepare
168
if
prepare
then
169
prepare
(
)
170
end
171
end
172 173
function
drivers
.
wrapup
(
name
)
174
local
driver
=
instances
[
name
]
175
if
not
driver
then
176
return
177
end
178
local
wrapup
=
driver
.
actions
.
wrapup
179
if
wrapup
then
180
wrapup
(
)
181
end
182
end
183 184
---------------------------------------------------------------------------------------
185 186
local
synctex
=
false
187 188
local
lastfont
=
nil
189
local
fontcharacters
=
nil
190 191
local
magicconstants
=
tex
.
magicconstants
192
local
trueinch
=
magicconstants
.
trueinch
193
local
maxdimen
=
magicconstants
.
maxdimen
194
local
running
=
magicconstants
.
running
195 196
local
pos_h
=
0
197
local
pos_v
=
0
198
local
pos_r
=
lefttoright_code
199
local
shippingmode
=
"
none
"
200 201
local
abs_max_v
=
0
202
local
abs_max_h
=
0
203 204
local
shipbox_h
=
0
205
local
shipbox_v
=
0
206
local
page_size_h
=
0
207
local
page_size_v
=
0
208
----- page_h_origin = 0 -- trueinch
209
----- page_v_origin = 0 -- trueinch
210 211
local
initialize
212
local
finalize
213
local
updatefontstate
214
local
pushorientation
215
local
poporientation
216
local
flushcharacter
217
local
flushrule
218
local
flushpdfliteral
219
local
flushpdfsetmatrix
220
local
flushpdfsave
221
local
flushpdfrestore
222
local
flushlatelua
223
local
flushspecial
224
local
flushpdfimage
225 226
-- make local
227 228
function
drivers
.
getpos
(
)
return
round
(
pos_h
)
,
round
(
pos_v
)
end
229
function
drivers
.
gethpos
(
)
return
round
(
pos_h
)
end
230
function
drivers
.
getvpos
(
)
return
round
(
pos_v
)
end
231 232
local
function
synch_pos_with_cur
(
ref_h
,
ref_v
,
h
,
v
)
233
if
pos_r
=
=
righttoleft_code
then
234
pos_h
=
ref_h
-
h
235
else
236
pos_h
=
ref_h
+
h
237
end
238
pos_v
=
ref_v
-
v
239
end
240 241
-- characters
242 243
local
flush_character
244 245
local
stack
=
setmetatableindex
(
"
table
"
)
246
local
level
=
0
247
local
nesting
=
0
248
local
main
=
0
249 250
-- todo: cache streams
251 252
local
function
flush_vf_packet
(
pos_h
,
pos_v
,
pos_r
,
font
,
char
,
data
,
factor
,
vfcommands
)
253 254
if
nesting
>
100
then
255
return
256
elseif
nesting
=
=
0
then
257
main
=
font
258
end
259 260
nesting
=
nesting
+
1
261 262
local
saved_h
=
pos_h
263
local
saved_v
=
pos_v
264
local
saved_r
=
pos_r
265
pos_r
=
lefttoright_code
266 267
local
data
=
fontdata
[
font
]
268
local
fnt
=
font
269
local
fonts
=
data
.
fonts
270
local
siz
=
(
data
.
parameters
.
factor
or
1
)
/
65536
271 272
local
function
flushchar
(
font
,
char
,
fnt
,
chr
,
f
,
e
)
273
if
fnt
then
274
local
nest
=
char
~
=
chr
or
font
~
=
fnt
275
if
fnt
=
=
0
then
276
fnt
=
main
277
end
278
return
flush_character
(
false
,
fnt
,
chr
,
factor
,
nest
,
pos_h
,
pos_v
,
pos_r
,
f
,
e
)
279
else
280
return
0
281
end
282
end
283 284
-- we assume resolved fonts: id mandate but maybe also size
285 286
for
i
=
1
,
#
vfcommands
do
287
local
packet
=
vfcommands
[
i
]
288
local
command
=
packet
[
1
]
289
if
command
=
=
"
char
"
then
290
local
chr
,
f
,
e
=
packet
[
2
]
,
packet
[
3
]
,
packet
[
4
]
291
pos_h
=
pos_h
+
flushchar
(
font
,
char
,
fnt
,
chr
,
f
,
e
)
292
elseif
command
=
=
"
slot
"
then
293
local
index
,
chr
,
f
,
e
=
packet
[
2
]
,
packet
[
3
]
,
packet
[
4
]
,
packet
[
5
]
294
if
index
=
=
0
then
295
pos_h
=
pos_h
+
flushchar
(
font
,
char
,
font
,
chr
,
f
,
e
)
296
else
297
local
okay
=
fonts
and
fonts
[
index
]
298
if
okay
then
299
local
fnt
=
okay
.
id
300
if
fnt
then
301
pos_h
=
pos_h
+
flushchar
(
font
,
char
,
fnt
,
chr
,
f
,
e
)
302
end
303
end
304
end
305
elseif
command
=
=
"
right
"
then
306
local
h
=
packet
[
2
]
-- * siz
307
if
factor
~
=
0
and
h
~
=
0
then
308
h
=
h
+
h
*
factor
/
1000
-- expansion
309
end
310
pos_h
=
pos_h
+
h
311
elseif
command
=
=
"
down
"
then
312
local
v
=
packet
[
2
]
-- * siz
313
pos_v
=
pos_v
-
v
314
elseif
command
=
=
"
push
"
then
315
level
=
level
+
1
316
local
s
=
stack
[
level
]
317
s
[
1
]
=
pos_h
318
s
[
2
]
=
pos_v
319
elseif
command
=
=
"
pop
"
then
320
if
level
>
0
then
321
local
s
=
stack
[
level
]
322
pos_h
=
s
[
1
]
323
pos_v
=
s
[
2
]
324
level
=
level
-
1
325
end
326
elseif
command
=
=
"
pdf
"
then
327
flushpdfliteral
(
false
,
pos_h
,
pos_v
,
packet
[
2
]
,
packet
[
3
]
)
328
elseif
command
=
=
"
rule
"
then
329
local
size_v
=
packet
[
2
]
330
local
size_h
=
packet
[
3
]
331
if
factor
~
=
0
and
size_h
>
0
then
332
size_h
=
size_h
+
size_h
*
factor
/
1000
333
end
334
if
size_h
>
0
and
size_v
>
0
then
335
flushsimplerule
(
pos_h
,
pos_v
,
pos_r
,
size_h
,
size_v
)
336
pos_h
=
pos_h
+
size_h
337
end
338
elseif
command
=
=
"
font
"
then
339
local
index
=
packet
[
2
]
340
local
okay
=
fonts
and
fonts
[
index
]
341
if
okay
then
342
fnt
=
okay
.
id
or
fnt
-- or maybe just return
343
end
344
elseif
command
=
=
"
lua
"
then
345
local
code
=
packet
[
2
]
346
if
type
(
code
)
~
=
"
function
"
then
347
code
=
loadstring
(
code
)
348
end
349
if
type
(
code
)
=
=
"
function
"
then
350
code
(
font
,
char
,
pos_h
,
pos_v
)
351
end
352
elseif
command
=
=
"
node
"
then
353
hlist_out
(
packet
[
2
]
)
354
elseif
command
=
=
"
image
"
then
355
-- doesn't work because intercepted by engine so we use a different
356
-- mechanism (for now)
357
local
image
=
packet
[
2
]
358
-- to do
359
elseif
command
=
=
"
pdfmode
"
then
360
-- doesn't happen
361
-- elseif command == "special" then
362
-- -- not supported
363
-- elseif command == "nop" then
364
-- -- nothing to do|
365
-- elseif command == "scale" then
366
-- -- not supported
367
end
368
end
369 370
pos_h
=
saved_h
371
pos_v
=
saved_v
372
pos_r
=
saved_r
373 374
-- synch_pos_with_cur(ref_h, ref_v, pos_h,pos_v)
375
nesting
=
nesting
-
1
376
end
377 378
flush_character
=
function
(
current
,
font
,
char
,
factor
,
vfcommands
,
pos_h
,
pos_v
,
pos_r
,
f
,
e
)
379 380
if
font
~
=
lastfont
then
381
lastfont
=
font
382
fontcharacters
=
characters
[
font
]
383
updatefontstate
(
font
)
384
end
385 386
local
data
=
fontcharacters
[
char
]
387
if
not
data
then
388
-- print("missing font/char",font,char)
389
-- lua_glyph_not_found_callback(font,char)
390
return
0
,
0
,
0
391
end
392
local
width
,
height
,
depth
393
if
current
then
394
width
,
height
,
depth
=
getwhd
(
current
)
395
factor
=
getexpansion
(
current
)
396
if
factor
and
factor
~
=
0
then
397
width
=
(
1
.
0
+
factor
/
1000000
.
0
)
*
width
398
end
399
else
400
width
=
data
.
width
or
0
401
height
=
data
.
height
or
0
402
depth
=
data
.
depth
or
0
403
if
not
factor
then
404
factor
=
0
405
end
406
end
407
if
pos_r
=
=
righttoleft_code
then
408
pos_h
=
pos_h
-
width
409
end
410
if
vfcommands
then
411
vfcommands
=
data
.
commands
412
end
413
if
vfcommands
then
414
flush_vf_packet
(
pos_h
,
pos_v
,
pos_r
,
font
,
char
,
data
,
factor
,
vfcommands
)
-- also f ?
415
else
416
local
orientation
=
data
.
orientation
417
if
orientation
and
(
orientation
=
=
1
or
orientation
=
=
3
)
then
418
local
x
,
y
=
data
.
xoffset
,
data
.
yoffset
419
if
x
then
420
pos_h
=
pos_h
+
x
421
end
422
if
y
then
423
pos_v
=
pos_v
+
y
424
end
425
pushorientation
(
orientation
,
pos_h
,
pos_v
)
426
flushcharacter
(
current
,
pos_h
,
pos_v
,
pos_r
,
font
,
char
,
data
,
factor
,
width
,
f
,
e
)
427
poporientation
(
orientation
,
pos_h
,
pos_v
)
428
else
429
flushcharacter
(
current
,
pos_h
,
pos_v
,
pos_r
,
font
,
char
,
data
,
factor
,
width
,
f
,
e
)
430
end
431
end
432
return
width
,
height
,
depth
433
end
434 435
-- end of characters
436 437
local
function
reset_state
(
)
438
pos_h
=
0
439
pos_v
=
0
440
pos_r
=
lefttoright_code
441
shipbox_h
=
0
442
shipbox_v
=
0
443
shippingmode
=
"
none
"
444
page_size_h
=
0
445
page_size_v
=
0
446
-- page_h_origin = 0 -- trueinch
447
-- page_v_origin = 0 -- trueinch
448
end
449 450
local
function
dirstackentry
(
t
,
k
)
451
local
v
=
{
452
cur_h
=
0
,
453
cur_v
=
0
,
454
ref_h
=
0
,
455
ref_v
=
0
,
456
}
457
t
[
k
]
=
v
458
return
v
459
end
460 461
local
dirstack
=
setmetatableindex
(
dirstackentry
)
462 463
local
function
reset_dir_stack
(
)
464
dirstack
=
setmetatableindex
(
dirstackentry
)
465
end
466 467
local
function
open_write_file
(
n
)
468
-- -- can't yet be done
469
-- local stream = getfield(current,"stream")
470
-- local path = getfield(current,"area")
471
-- local name = getfield(current,"name")
472
-- local suffix = getfield(current,"ext")
473
-- if suffix == "" then
474
-- name = name .. ".tex"
475
-- else
476
-- name = name .. suffix
477
-- end
478
-- if path ~= "" then
479
-- name = file.join(path,name)
480
-- end
481
end
482 483
local
function
close_write_file
(
n
)
484
-- can't yet be done
485
end
486 487
local
function
write_to_file
(
current
)
488
local
stream
=
getfield
(
current
,
"
stream
"
)
489
local
data
=
getdata
(
current
)
490
texio
.
write_nl
(
stream
,
data
)
491
end
492 493
local
function
wrapup_leader
(
current
,
subtype
)
494
if
subtype
=
=
writewhatsit_code
then
495
write_to_file
(
current
)
496
elseif
subtype
=
=
closewhatsit_code
then
497
close_write_file
(
current
)
498
elseif
subtype
=
=
openwhatsit_code
then
499
open_write_file
(
current
)
500
end
501
end
502 503
local
hlist_out
,
vlist_out
do
504 505
-- effective_glue :
506
--
507
-- local cur_g = 0
508
-- local cur_glue = 0.0
509
--
510
-- local width, stretch, shrink, stretch_order, shrink_order = getglue(current)
511
-- if g_sign == 1 then -- stretching
512
-- if stretch_order == g_order then
513
-- -- rule_wd = width - cur_g
514
-- -- cur_glue = cur_glue + stretch
515
-- -- cur_g = g_set * cur_glue
516
-- -- rule_wd = rule_wd + cur_g
517
-- rule_ht = width + g_set * stretch
518
-- else
519
-- rule_wd = width
520
-- end
521
-- else
522
-- if shrink_order == g_order then
523
-- -- rule_wd = width - cur_g
524
-- -- cur_glue = cur_glue - shrink
525
-- -- cur_g = g_set * cur_glue
526
-- -- rule_wd = rule_wd + cur_g
527
-- rule_ht = width - g_set * shrink
528
-- else
529
-- rule_wd = width
530
-- end
531
-- end
532 533
local
function
applyanchor
(
orientation
,
x
,
y
,
width
,
height
,
depth
,
woffset
,
hoffset
,
doffset
,
xoffset
,
yoffset
)
534
local
ot
=
extract
(
orientation
,
0
,
4
)
535
local
ay
=
extract
(
orientation
,
4
,
4
)
536
local
ax
=
extract
(
orientation
,
8
,
4
)
537
local
of
=
extract
(
orientation
,
12
,
4
)
538
if
ot
=
=
4
then
539
ot
,
ay
=
0
,
1
540
elseif
ot
=
=
5
then
541
ot
,
ay
=
0
,
2
542
end
543
if
ot
=
=
0
or
ot
=
=
2
then
544
if
ax
=
=
1
then
x
=
x
-
width
545
elseif
ax
=
=
2
then
x
=
x
+
width
546
elseif
ax
=
=
3
then
x
=
x
-
width
/
2
547
elseif
ax
=
=
4
then
x
=
x
+
width
/
2
548
end
549
if
ot
=
=
2
then
550
doffset
,
hoffset
=
hoffset
,
doffset
551
end
552
if
ay
=
=
1
then
y
=
y
-
doffset
553
elseif
ay
=
=
2
then
y
=
y
+
hoffset
554
elseif
ay
=
=
3
then
y
=
y
+
(
doffset
+
hoffset
)
/
2
-
doffset
555
end
556
elseif
ot
=
=
1
or
ot
=
=
3
then
557
if
ay
=
=
1
then
y
=
y
-
height
558
elseif
ay
=
=
2
then
y
=
y
+
height
559
elseif
ay
=
=
3
then
y
=
y
-
height
/
2
560
end
561
if
ot
=
=
1
then
562
doffset
,
hoffset
=
hoffset
,
doffset
563
end
564
if
ax
=
=
1
then
x
=
x
-
width
565
elseif
ax
=
=
2
then
x
=
x
+
width
566
elseif
ax
=
=
3
then
x
=
x
-
width
/
2
567
elseif
ax
=
=
4
then
x
=
x
+
width
/
2
568
elseif
ax
=
=
5
then
x
=
x
-
hoffset
569
elseif
ax
=
=
6
then
x
=
x
+
doffset
570
end
571
end
572
return
ot
,
x
+
xoffset
,
y
-
yoffset
573
end
574 575
-- rangedir can stick to widths only
576 577
rangedimensions
=
node
.
direct
.
naturalwidth
or
rangedimensions
578 579
local
function
calculate_width_to_enddir
(
this_box
,
begindir
)
-- can be a helper
580
local
dir_nest
=
1
581
local
enddir
=
begindir
582
for
current
,
subtype
in
nextdir
,
getnext
(
begindir
)
do
583
if
subtype
=
=
normaldir_code
then
-- todo
584
dir_nest
=
dir_nest
+
1
585
else
586
dir_nest
=
dir_nest
-
1
587
end
588
if
dir_nest
=
=
0
then
-- does the type matter
589
enddir
=
current
590
local
width
=
rangedimensions
(
this_box
,
begindir
,
enddir
)
591
return
enddir
,
width
592
end
593
end
594
if
enddir
=
=
begindir
then
595
local
width
=
rangedimensions
(
this_box
,
begindir
)
-- ,enddir)
596
return
enddir
,
width
597
end
598
return
enddir
,
0
599
end
600 601
-- check frequencies of nodes
602 603
hlist_out
=
function
(
this_box
,
current
)
604
local
outer_doing_leaders
=
false
605 606
local
ref_h
=
pos_h
607
local
ref_v
=
pos_v
608
local
ref_r
=
pos_r
609
pos_r
=
getdirection
(
this_box
)
610 611
local
boxwidth
,
612
boxheight
,
613
boxdepth
=
getwhd
(
this_box
)
614
local
g_set
,
615
g_order
,
616
g_sign
=
getboxglue
(
this_box
)
617 618
local
cur_h
=
0
619
local
cur_v
=
0
620 621
if
not
current
then
622
current
=
getlist
(
this_box
)
623
end
624 625
-- if synctex then
626
-- synctexhlist(this_box)
627
-- end
628 629
while
current
do
630
local
char
,
id
=
isglyph
(
current
)
631
if
char
then
632
local
x_offset
,
y_offset
=
getoffsets
(
current
)
633
if
x_offset
~
=
0
or
y_offset
~
=
0
then
634
synch_pos_with_cur
(
ref_h
,
ref_v
,
cur_h
+
x_offset
,
cur_v
-
y_offset
)
635
end
636
local
wd
,
ht
,
dp
=
flush_character
(
current
,
id
,
char
,
false
,
true
,
pos_h
,
pos_v
,
pos_r
)
637
cur_h
=
cur_h
+
wd
638
elseif
id
=
=
glue_code
then
639
local
rule_wd
,
rule_ht
,
rule_dp
640
if
g_sign
=
=
0
then
641
rule_wd
=
getwidth
(
current
)
642
else
643
rule_wd
=
effectiveglue
(
current
,
this_box
)
644
end
645
local
leader
=
getleader
(
current
)
646
if
leader
then
647
local
leader_wd
=
0
648
local
boxdir
=
getdirection
(
leader
)
or
lefttoright_code
649
local
width
,
height
,
depth
=
getwhd
(
leader
)
650
if
getid
(
leader
)
=
=
rule_code
then
651
rule_ht
=
height
652
rule_dp
=
depth
653
if
rule_ht
=
=
running
then
654
rule_ht
=
boxheight
655
end
656
if
rule_dp
=
=
running
then
657
rule_dp
=
boxdepth
658
end
659
local
left
,
right
=
getoffsets
(
leader
)
660
if
left
~
=
0
then
661
rule_ht
=
rule_ht
-
left
662
pos_v
=
pos_v
+
left
663
end
664
if
right
~
=
0
then
665
rule_dp
=
rule_dp
-
right
666
end
667
local
total
=
rule_ht
+
rule_dp
668
if
total
>
0
and
rule_wd
>
0
then
669
local
size_h
=
rule_wd
670
local
size_v
=
total
671
if
pos_r
=
=
righttoleft_code
then
672
pos_h
=
pos_h
-
size_h
673
end
674
pos_v
=
pos_v
-
rule_dp
675
flushrule
(
current
,
pos_h
,
pos_v
,
pos_r
,
size_h
,
size_v
)
676
end
677
cur_h
=
cur_h
+
rule_wd
678
else
679
leader_wd
=
width
680
if
leader_wd
>
0
and
rule_wd
>
0
then
681
rule_wd
=
rule_wd
+
10
682
local
edge
=
cur_h
+
rule_wd
683
local
lx
=
0
684
local
subtype
=
getsubtype
(
current
)
685
if
subtype
=
=
gleader_code
then
686
local
save_h
=
cur_h
687
if
pos_r
=
=
righttoleft_code
then
688
cur_h
=
ref_h
-
shipbox_h
-
cur_h
689
cur_h
=
leader_wd
*
(
cur_h
/
leader_wd
)
690
cur_h
=
ref_h
-
shipbox_h
-
cur_h
691
else
692
cur_h
=
cur_h
+
ref_h
-
shipbox_h
693
cur_h
=
leader_wd
*
(
cur_h
/
leader_wd
)
694
cur_h
=
cur_h
-
ref_h
-
shipbox_h
695
end
696
if
cur_h
<
save_h
then
697
cur_h
=
cur_h
+
leader_wd
698
end
699
elseif
subtype
=
=
leader_code
then
-- aleader ?
700
local
save_h
=
cur_h
701
cur_h
=
leader_wd
*
(
cur_h
/
leader_wd
)
702
if
cur_h
<
save_h
then
703
cur_h
=
cur_h
+
leader_wd
704
end
705
else
706
lq
=
rule_wd
/
leader_wd
707
lr
=
rule_wd
%
leader_wd
708
if
subtype
=
=
cleader_code
then
709
cur_h
=
cur_h
+
lr
/
2
710
else
711
lx
=
lr
/
(
lq
+
1
)
712
cur_h
=
cur_h
+
(
lr
-
(
lq
-
1
)
*
lx
)
/
2
713
end
714
end
715
while
cur_h
+
leader_wd
<
=
edge
do
716
local
basepoint_h
=
0
717
local
basepoint_v
=
getshift
(
leader
)
718
if
boxdir
~
=
pos_r
then
719
basepoint_h
=
boxwidth
720
end
721
synch_pos_with_cur
(
ref_h
,
ref_v
,
cur_h
+
basepoint_h
,
basepoint_v
)
722
outer_doing_leaders
=
doing_leaders
723
doing_leaders
=
true
724
if
getid
(
leader
)
=
=
vlist_code
then
725
vlist_out
(
leader
)
726
else
727
hlist_out
(
leader
)
728
end
729
doing_leaders
=
outer_doing_leaders
730
cur_h
=
cur_h
+
leader_wd
+
lx
731
end
732
cur_h
=
edge
-
10
733
else
734
cur_h
=
cur_h
+
rule_wd
735
-- if synctex then
736
-- synch_pos_with_cur(ref_h, ref_v, cur_h, cur_v)
737
-- synctexhorizontalruleorglue(p, this_box)
738
-- end
739
end
740
end
741
else
742
cur_h
=
cur_h
+
rule_wd
743
-- if synctex then
744
-- synch_pos_with_cur(ref_h, ref_v, cur_h, cur_v)
745
-- synctexhorizontalruleorglue(p, this_box)
746
-- end
747
end
748
elseif
id
=
=
hlist_code
or
id
=
=
vlist_code
then
749
-- w h d dir l, s, o = getall(current)
750
local
boxdir
=
getdirection
(
current
)
or
lefttoright_code
751
local
width
,
height
,
depth
=
getwhd
(
current
)
752
local
list
=
getlist
(
current
)
753
if
list
then
754
local
shift
,
orientation
=
getshift
(
current
)
755
if
not
orientation
then
756
local
basepoint_h
=
boxdir
~
=
pos_r
and
width
or
0
757
-- local basepoint_v = shift
758
synch_pos_with_cur
(
ref_h
,
ref_v
,
cur_h
+
basepoint_h
,
shift
)
759
if
id
=
=
vlist_code
then
760
vlist_out
(
current
,
list
)
761
else
762
hlist_out
(
current
,
list
)
763
end
764
elseif
orientation
=
=
0x1000
then
765
local
orientation
,
xoffset
,
yoffset
=
getorientation
(
current
)
766
local
basepoint_h
=
boxdir
~
=
pos_r
and
width
or
0
767
-- local basepoint_v = shift
768
synch_pos_with_cur
(
ref_h
,
ref_v
,
cur_h
+
basepoint_h
+
xoffset
,
shift
-
yoffset
)
769
if
id
=
=
vlist_code
then
770
vlist_out
(
current
,
list
)
771
else
772
hlist_out
(
current
,
list
)
773
end
774
else
775
local
orientation
,
xoffset
,
yoffset
,
woffset
,
hoffset
,
doffset
=
getorientation
(
current
)
776
local
orientation
,
basepoint_h
,
basepoint_v
=
applyanchor
(
orientation
,
0
,
shift
,
width
,
height
,
depth
,
woffset
,
hoffset
,
doffset
,
xoffset
,
yoffset
)
777
if
orientation
=
=
1
then
778
basepoint_h
=
basepoint_h
+
doffset
779
if
boxdir
=
=
pos_r
then
780
basepoint_v
=
basepoint_v
-
height
781
end
782
elseif
orientation
=
=
2
then
783
if
boxdir
=
=
pos_r
then
784
basepoint_h
=
basepoint_h
+
width
785
end
786
elseif
orientation
=
=
3
then
787
basepoint_h
=
basepoint_h
+
hoffset
788
if
boxdir
~
=
pos_r
then
789
basepoint_v
=
basepoint_v
-
height
790
end
791
end
792
synch_pos_with_cur
(
ref_h
,
ref_v
,
cur_h
+
basepoint_h
,
cur_v
+
basepoint_v
)
793
pushorientation
(
orientation
,
pos_h
,
pos_v
,
pos_r
)
794
if
id
=
=
vlist_code
then
795
vlist_out
(
current
,
list
)
796
else
797
hlist_out
(
current
,
list
)
798
end
799
poporientation
(
orientation
,
pos_h
,
pos_v
,
pos_r
)
800
end
801
else
802
-- if synctex then
803
-- if id == vlist_code then
804
-- synctexvoidvlist(p,this_box)
805
-- else
806
-- synctexvoidhlist(p,this_box)
807
-- end
808
-- end
809
end
810
cur_h
=
cur_h
+
width
811
elseif
id
=
=
disc_code
then
812
local
replace
=
getfield
(
current
,
"
replace
"
)
813
if
replace
and
getsubtype
(
current
)
~
=
select_disc
then
814
-- we could flatten .. no gain
815
setlink
(
findtail
(
replace
)
,
getnext
(
current
)
)
816
setlink
(
current
,
replace
)
817
setfield
(
current
,
"
replace
"
)
818
end
819
elseif
id
=
=
kern_code
then
820
-- if synctex then
821
-- synctexkern(p, this_box)
822
-- end
823
local
kern
=
getkern
(
current
)
824
local
factor
=
getexpansion
(
current
)
825
if
factor
and
factor
~
=
0
then
826
cur_h
=
cur_h
+
(
1
.
0
+
factor
/
1000000
.
0
)
*
kern
827
else
828
cur_h
=
cur_h
+
kern
829
end
830
elseif
id
=
=
rule_code
then
831
-- w h d dir l r = getall(current)
832
local
ruledir
=
getdirection
(
current
)
833
local
width
,
height
,
depth
=
getwhd
(
current
)
834
local
left
,
right
=
getoffsets
(
current
)
835
if
not
ruledir
then
836
ruledir
=
pos_r
837
setdirection
(
current
,
ruledir
)
838
end
839
if
height
=
=
running
then
840
height
=
boxheight
841
end
842
if
depth
=
=
running
then
843
depth
=
boxdepth
844
end
845
if
left
~
=
0
then
846
height
=
height
-
left
847
pos_v
=
pos_v
+
left
848
end
849
if
right
~
=
0
then
850
depth
=
depth
-
right
851
end
852
local
total
=
height
+
depth
853
if
total
>
0
and
width
>
0
then
854
local
size_h
=
width
855
local
size_v
=
total
856
if
pos_r
=
=
righttoleft_code
then
857
pos_h
=
pos_h
-
size_h
858
end
859
pos_v
=
pos_v
-
depth
860
flushrule
(
current
,
pos_h
,
pos_v
,
pos_r
,
size_h
,
size_v
)
861
end
862
cur_h
=
cur_h
+
width
863
elseif
id
=
=
math_code
then
864
-- if synctex then
865
-- synctexmath(p, this_box)
866
-- end
867
local
kern
=
getkern
(
current
)
868
if
kern
~
=
0
then
869
cur_h
=
cur_h
+
kern
870
elseif
g_sign
=
=
0
then
871
rule_wd
=
getwidth
(
current
)
872
else
873
rule_wd
=
effectiveglue
(
current
,
this_box
)
874
end
875
elseif
id
=
=
dir_code
then
876
-- we normally have proper begin-end pairs
877
-- a begin without end is (silently) handled
878
-- an end without a begin will be (silently) skipped
879
-- we only need to move forward so a faster calculation
880
local
dir
,
cancel
=
getdirection
(
current
)
881
if
cancel
then
882
local
ds
=
dirstack
[
current
]
883
ref_h
=
ds
.
ref_h
884
ref_v
=
ds
.
ref_v
885
cur_h
=
ds
.
cur_h
886
cur_v
=
ds
.
cur_v
887
pos_r
=
dir
888
else
889
local
enddir
,
width
=
calculate_width_to_enddir
(
this_box
,
current
)
890
local
ds
=
dirstack
[
enddir
]
891
ds
.
cur_h
=
cur_h
+
width
892
if
dir
~
=
pos_r
then
893
cur_h
=
ds
.
cur_h
894
end
895
if
enddir
~
=
current
then
896
local
ds
=
dirstack
[
enddir
]
897
ds
.
cur_v
=
cur_v
898
ds
.
ref_h
=
ref_h
899
ds
.
ref_v
=
ref_v
900
setdirection
(
enddir
,
pos_r
)
901
end
902
synch_pos_with_cur
(
ref_h
,
ref_v
,
cur_h
,
cur_v
)
903
ref_h
=
pos_h
904
ref_v
=
pos_v
905
cur_h
=
0
906
cur_v
=
0
907
pos_r
=
dir
908
end
909
elseif
id
=
=
whatsit_code
then
910
local
subtype
=
getsubtype
(
current
)
911
if
subtype
=
=
literalwhatsit_code
then
912
flushpdfliteral
(
current
,
pos_h
,
pos_v
)
913
elseif
subtype
=
=
lateluawhatsit_code
then
914
flushlatelua
(
current
,
pos_h
,
pos_v
,
cur_h
,
cur_v
)
915
elseif
subtype
=
=
setmatrixwhatsit_code
then
916
flushpdfsetmatrix
(
current
,
pos_h
,
pos_v
)
917
elseif
subtype
=
=
savewhatsit_code
then
918
flushpdfsave
(
current
,
pos_h
,
pos_v
)
919
elseif
subtype
=
=
restorewhatsit_code
then
920
flushpdfrestore
(
current
,
pos_h
,
pos_v
)
921
-- elseif subtype == special_code then
922
-- flushspecial(current,pos_h,pos_v)
923
elseif
subtype
=
=
saveposwhatsit_code
then
924
last_position_x
=
pos_h
-- or pdf_h
925
last_position_y
=
pos_v
-- or pdf_v
926
elseif
subtype
=
=
userdefinedwhatsit_code
then
927
-- nothing
928
elseif
subtype
=
=
openwhatsit_code
or
subtype
=
=
writewhatsit_code
or
subtype
=
=
closewhatsit_code
then
929
if
not
doing_leaders
then
930
wrapup_leader
(
current
,
subtype
)
931
end
932
end
933
elseif
id
=
=
marginkern_code
then
934
cur_h
=
cur_h
+
getkern
(
current
)
935
end
936
current
=
getnext
(
current
)
937
synch_pos_with_cur
(
ref_h
,
ref_v
,
cur_h
,
cur_v
)
-- already done in list so skip
938
end
939
-- if synctex then
940
-- synctextsilh(this_box)
941
-- end
942
pos_h
=
ref_h
943
pos_v
=
ref_v
944
pos_r
=
ref_r
945
end
946 947
vlist_out
=
function
(
this_box
,
current
)
948
local
outer_doing_leaders
=
false
949 950
local
ref_h
=
pos_h
951
local
ref_v
=
pos_v
952
local
ref_r
=
pos_r
953
pos_r
=
getdirection
(
this_box
)
954 955
local
boxwidth
,
956
boxheight
,
957
boxdepth
=
getwhd
(
this_box
)
958
local
g_set
,
959
g_order
,
960
g_sign
=
getboxglue
(
this_box
)
961 962
local
cur_h
=
0
963
local
cur_v
=
-
boxheight
964 965
local
top_edge
=
cur_v
966 967
synch_pos_with_cur
(
ref_h
,
ref_v
,
cur_h
,
cur_v
)
968 969
if
not
current
then
970
current
=
getlist
(
this_box
)
971
end
972 973
-- if synctex then
974
-- synctexvlist(this_box)
975
-- end
976 977
-- while current do
978
-- local id = getid(current)
979
for
current
,
id
,
subtype
in
nextnode
,
current
do
980
if
id
=
=
glue_code
then
981
local
rule_wd
,
rule_ht
,
rule_dp
982
if
g_sign
=
=
0
then
983
rule_ht
=
getwidth
(
current
)
984
else
985
rule_ht
=
effectiveglue
(
current
,
this_box
)
986
end
987
local
leader
=
getleader
(
current
)
988
if
leader
then
989
local
width
,
height
,
depth
=
getwhd
(
leader
)
990
if
getid
(
leader
)
=
=
rule_code
then
991
rule_wd
=
width
992
rule_dp
=
0
993
if
rule_wd
=
=
running
then
994
rule_wd
=
boxwidth
995
end
996
local
left
,
right
=
getoffsets
(
leader
)
997
if
left
~
=
0
then
998
rule_wd
=
rule_wd
-
left
999
cur_h
=
cur_h
+
left
1000
end
1001
if
right
~
=
0
then
1002
rule_wd
=
rule_wd
-
right
1003
end
1004
local
total
=
rule_ht
+
rule_dp
1005
if
total
>
0
and
rule_wd
>
0
then
1006
local
size_h
=
rule_wd
1007
local
size_v
=
total
1008
if
pos_r
=
=
righttoleft_code
then
1009
cur_h
=
cur_h
-
size_h
1010
end
1011
cur_v
=
cur_v
-
size_v
1012
flushrule
(
current
,
pos_h
,
pos_v
-
size_v
,
pos_r
,
size_h
,
size_v
)
1013
end
1014
cur_v
=
cur_v
+
total
1015
else
1016
local
leader_ht
=
height
+
depth
1017
if
leader_ht
>
0
and
rule_ht
>
0
then
1018
rule_ht
=
rule_ht
+
10
1019
local
edge
=
cur_v
+
rule_ht
1020
local
ly
=
0
1021
-- local subtype = getsubtype(current)
1022
if
subtype
=
=
gleader_code
then
1023
save_v
=
cur_v
1024
cur_v
=
ref_v
-
shipbox_v
-
cur_v
1025
cur_v
=
leader_ht
*
(
cur_v
/
leader_ht
)
1026
cur_v
=
ref_v
-
shipbox_v
-
cur_v
1027
if
cur_v
<
save_v
then
1028
cur_v
=
cur_v
+
leader_ht
1029
end
1030
elseif
subtype
=
=
leader_code
then
-- aleader
1031
save_v
=
cur_v
1032
cur_v
=
top_edge
+
leader_ht
*
(
(
cur_v
-
top_edge
)
/
leader_ht
)
1033
if
cur_v
<
save_v
then
1034
cur_v
=
cur_v
+
leader_ht
1035
end
1036
else
1037
lq
=
rule_ht
/
leader_ht
1038
lr
=
rule_ht
%
leader_ht
1039
if
subtype
=
=
cleaders_code
then
1040
cur_v
=
cur_v
+
lr
/
2
1041
else
1042
ly
=
lr
/
(
lq
+
1
)
1043
cur_v
=
cur_v
+
(
lr
-
(
lq
-
1
)
*
ly
)
/
2
1044
end
1045
end
1046
while
cur_v
+
leader_ht
<
=
edge
do
1047
synch_pos_with_cur
(
ref_h
,
ref_v
,
getshift
(
leader
)
,
cur_v
+
height
)
1048
outer_doing_leaders
=
doing_leaders
1049
doing_leaders
=
true
1050
if
getid
(
leader
)
=
=
vlist_code
then
1051
vlist_out
(
leader
)
1052
else
1053
hlist_out
(
leader
)
1054
end
1055
doing_leaders
=
outer_doing_leaders
1056
cur_v
=
cur_v
+
leader_ht
+
ly
1057
end
1058
cur_v
=
edge
-
10
1059
else
1060
cur_v
=
cur_v
+
rule_ht
1061
end
1062
end
1063
else
1064
cur_v
=
cur_v
+
rule_ht
1065
end
1066
elseif
id
=
=
hlist_code
or
id
=
=
vlist_code
then
1067
-- w h d dir l, s, o = getall(current)
1068
local
boxdir
=
getdirection
(
current
)
or
lefttoright_code
1069
local
width
,
height
,
depth
=
getwhd
(
current
)
1070
local
list
=
getlist
(
current
)
1071
if
list
then
1072
local
shift
,
orientation
=
getshift
(
current
)
1073
if
not
orientation
then
1074
-- local basepoint_h = shift
1075
-- local basepoint_v = height
1076
if
boxdir
~
=
pos_r
then
1077
shift
=
shift
+
width
1078
end
1079
synch_pos_with_cur
(
ref_h
,
ref_v
,
shift
,
cur_v
+
height
)
1080
if
id
=
=
vlist_code
then
1081
vlist_out
(
current
,
list
)
1082
else
1083
hlist_out
(
current
,
list
)
1084
end
1085
elseif
orientation
=
=
0x1000
then
1086
local
orientation
,
xoffset
,
yoffset
=
getorientation
(
current
)
1087
-- local basepoint_h = shift
1088
-- local basepoint_v = height
1089
if
boxdir
~
=
pos_r
then
1090
shift
=
shift
+
width
1091
end
1092
synch_pos_with_cur
(
ref_h
,
ref_v
,
shift
+
xoffset
,
cur_v
+
height
-
yoffset
)
1093
if
id
=
=
vlist_code
then
1094
vlist_out
(
current
,
list
)
1095
else
1096
hlist_out
(
current
,
list
)
1097
end
1098
else
1099
local
orientation
,
xoffset
,
yoffset
,
woffset
,
hoffset
,
doffset
=
getorientation
(
current
)
1100
local
orientation
,
basepoint_h
,
basepoint_v
=
applyanchor
(
orientation
,
shift
,
height
,
width
,
height
,
depth
,
woffset
,
hoffset
,
doffset
,
xoffset
,
yoffset
)
1101
if
orientation
=
=
1
then
1102
basepoint_h
=
basepoint_h
+
width
-
height
1103
basepoint_v
=
basepoint_v
-
height
1104
elseif
orientation
=
=
2
then
1105
basepoint_h
=
basepoint_h
+
width
1106
basepoint_v
=
basepoint_v
+
depth
-
height
1107
elseif
orientation
=
=
3
then
-- weird
1108
basepoint_h
=
basepoint_h
+
height
1109
end
1110
synch_pos_with_cur
(
ref_h
,
ref_v
,
basepoint_h
,
cur_v
+
basepoint_v
)
1111
pushorientation
(
orientation
,
pos_h
,
pos_v
,
pos_r
)
1112
if
id
=
=
vlist_code
then
1113
vlist_out
(
current
,
list
)
1114
else
1115
hlist_out
(
current
,
list
)
1116
end
1117
poporientation
(
orientation
,
pos_h
,
pos_v
,
pos_r
)
1118
end
1119
else
1120
-- if synctex then
1121
-- synch_pos_with_cur(ref_h, ref_v, cur_h, cur_v)
1122
-- if id == vlist_code then
1123
-- synctexvoidvlist(current, this_box)
1124
-- else
1125
-- synctexvoidhlist(current, this_box)
1126
-- end
1127
-- end
1128
end
1129
cur_v
=
cur_v
+
height
+
depth
1130
elseif
id
=
=
kern_code
then
1131
cur_v
=
cur_v
+
getkern
(
current
)
1132
elseif
id
=
=
rule_code
then
1133
-- w h d dir l r = getall(current)
1134
local
ruledir
=
getdirection
(
current
)
1135
local
width
,
height
,
depth
=
getwhd
(
current
)
1136
local
left
,
right
=
getoffsets
(
current
)
1137
if
not
ruledir
then
1138
ruledir
=
pos_r
1139
setdirection
(
current
,
ruledir
)
1140
end
1141
if
width
=
=
running
then
1142
width
=
boxwidth
1143
end
1144
if
left
~
=
0
then
1145
width
=
width
-
left
1146
cur_h
=
cur_h
+
left
1147
end
1148
if
right
~
=
0
then
1149
width
=
width
-
right
1150
end
1151
local
total
=
height
+
depth
1152
if
total
>
0
and
width
>
0
then
1153
local
size_h
=
width
1154
local
size_v
=
total
1155
if
pos_r
=
=
righttoleft_code
then
1156
cur_h
=
cur_h
-
size_h
1157
end
1158
flushrule
(
current
,
pos_h
,
pos_v
-
size_v
,
pos_r
,
size_h
,
size_v
)
1159
end
1160
cur_v
=
cur_v
+
total
1161
elseif
id
=
=
whatsit_code
then
1162
-- local subtype = getsubtype(current)
1163
if
subtype
=
=
literalwhatsit_code
then
1164
flushpdfliteral
(
current
,
pos_h
,
pos_v
)
1165
elseif
subtype
=
=
lateluawhatsit_code
then
1166
flushlatelua
(
current
,
pos_h
,
pos_v
,
cur_h
,
cur_v
)
1167
elseif
subtype
=
=
setmatrixwhatsit_code
then
1168
flushpdfsetmatrix
(
current
,
pos_h
,
pos_v
)
1169
elseif
subtype
=
=
savewhatsit_code
then
1170
flushpdfsave
(
current
,
pos_h
,
pos_v
)
1171
elseif
subtype
=
=
restorewhatsit_code
then
1172
flushpdfrestore
(
current
,
pos_h
,
pos_v
)
1173
elseif
subtype
=
=
saveposwhatsit_code
then
1174
last_position_x
=
pos_h
-- or pdf_h
1175
last_position_y
=
pos_v
-- or pdf_v
1176
elseif
subtype
=
=
openwhatsit_code
or
subtype
=
=
writewhatsit_code
or
subtype
=
=
closewhatsit_code
then
1177
if
not
doing_leaders
then
1178
wrapup_leader
(
current
,
subtype
)
1179
end
1180
-- elseif subtype == special_code then
1181
-- flushspecial(current,pos_h,pos_v)
1182
end
1183
end
1184
-- current = getnext(current)
1185
synch_pos_with_cur
(
ref_h
,
ref_v
,
cur_h
,
cur_v
)
1186
end
1187
-- if synctex then
1188
-- synctextsilh(this_box)
1189
-- end
1190
pos_h
=
ref_h
1191
pos_v
=
ref_v
1192
pos_r
=
ref_r
1193
end
1194 1195
end
1196 1197
function
drivers
.
convert
(
name
,
box
,
smode
,
objnum
,
specification
)
1198 1199
if
box
then
1200
box
=
tonut
(
box
)
1201
else
1202
report
(
"
error on converter, no box
"
)
1203
return
1204
end
1205 1206
local
driver
=
instances
[
name
]
1207
if
driver
then
1208
-- tracing
1209
else
1210
return
1211
end
1212 1213
local
actions
=
driver
.
actions
1214
local
flushers
=
driver
.
flushers
1215 1216
initialize
=
actions
.
initialize
1217
finalize
=
actions
.
finalize
1218
updatefontstate
=
actions
.
updatefontstate
1219 1220
pushorientation
=
flushers
.
pushorientation
1221
poporientation
=
flushers
.
poporientation
1222 1223
flushcharacter
=
flushers
.
character
1224
flushrule
=
flushers
.
rule
1225
flushsimplerule
=
flushers
.
simplerule
1226
flushlatelua
=
flushers
.
latelua
1227
flushspecial
=
flushers
.
special
1228
flushpdfliteral
=
flushers
.
pdfliteral
1229
flushpdfsetmatrix
=
flushers
.
pdfsetmatrix
1230
flushpdfsave
=
flushers
.
pdfsave
1231
flushpdfrestore
=
flushers
.
pdfrestore
1232
flushpdfimage
=
flushers
.
pdfimage
1233 1234
reset_dir_stack
(
)
1235
reset_state
(
)
1236 1237
shippingmode
=
smode
1238 1239
-- synctex = texget("synctex")
1240 1241
-- if synctex then
1242
-- synctexsheet(1000)
1243
-- end
1244 1245
local
width
,
height
,
depth
=
getwhd
(
box
)
1246 1247
local
total
=
height
+
depth
1248 1249
----- v_offset_par = 0
1250
----- h_offset_par = 0
1251 1252
local
max_v
=
total
-- + v_offset_par
1253
local
max_h
=
width
-- + h_offset_par
1254 1255
if
height
>
maxdimen
or
depth
>
maxdimen
or
width
>
maxdimen
then
1256
goto
DONE
1257
end
1258 1259
if
max_v
>
maxdimen
then
1260
goto
DONE
1261
elseif
max_v
>
abs_max_v
then
1262
abs_max_v
=
max_v
1263
end
1264 1265
if
max_h
>
maxdimen
then
1266
goto
DONE
1267
elseif
max_h
>
abs_max_h
then
1268
abs_max_h
=
max_h
1269
end
1270 1271
if
shippingmode
=
=
"
page
"
then
1272 1273
-- We have zero offsets in ConTeXt.
1274 1275
local
pagewidth
,
pageheight
=
getpagedimensions
(
)
1276
-- local h_offset_par, v_offset_par = texget("hoffset"), texget("voffset")
1277 1278
-- page_h_origin = trueinch
1279
-- page_v_origin = trueinch
1280 1281
pos_r
=
lefttoright_code
1282 1283
if
pagewidth
>
0
then
1284
page_size_h
=
pagewidth
1285
else
1286
page_size_h
=
width
1287
end
1288 1289
if
page_size_h
=
=
0
then
1290
page_size_h
=
width
1291
end
1292 1293
if
pageheight
>
0
then
1294
page_size_v
=
pageheight
1295
else
1296
page_size_v
=
total
1297
end
1298 1299
if
page_size_v
=
=
0
then
1300
page_size_v
=
total
1301
end
1302 1303
local
refpoint_h
=
0
-- + page_h_origin + h_offset_par
1304
local
refpoint_v
=
page_size_v
-- - page_v_origin - v_offset_par
1305 1306
synch_pos_with_cur
(
refpoint_h
,
refpoint_v
,
0
,
height
)
1307 1308
else
1309 1310
-- page_h_origin = 0
1311
-- page_v_origin = 0
1312
page_size_h
=
width
1313
page_size_v
=
total
1314
pos_r
=
getdirection
(
box
)
1315
pos_v
=
depth
1316
pos_h
=
pos_r
=
=
righttoleft_code
and
width
or
0
1317 1318
end
1319 1320
shipbox_ref_h
=
pos_h
1321
shipbox_ref_v
=
pos_v
1322 1323
initialize
{
1324
shippingmode
=
smode
,
-- target
1325
boundingbox
=
{
0
,
0
,
page_size_h
,
page_size_v
}
,
1326
objectnumber
=
objnum
,
1327
}
1328 1329
if
getid
(
box
)
=
=
vlist_code
then
1330
vlist_out
(
box
)
1331
else
1332
hlist_out
(
box
)
1333
end
1334 1335
::
DONE
::
1336 1337
-- if synctex then
1338
-- synctexteehs()
1339
-- end
1340 1341
finalize
(
objnum
,
specification
)
1342
shippingmode
=
"
none
"
1343
end
1344 1345
-- synctex
1346
-- flush node list
1347
-- reset dead cycles
1348 1349
-- This is now a bit messy but will be done better. --
1350 1351
local
initialized
=
false
1352
local
shipouts
=
{
}
1353 1354
local
function
wrapup
(
)
1355
statistics
.
starttiming
(
shipouts
)
1356
drivers
.
wrapup
(
"
pdf
"
)
1357
statistics
.
stoptiming
(
shipouts
)
1358
end
1359 1360
local
function
report
(
)
1361
return
statistics
.
elapsedseconds
(
shipouts
)
1362
end
1363 1364
local
function
shipout
(
boxnumber
)
1365
callbacks
.
functions
.
start_page_number
(
)
1366
statistics
.
starttiming
(
shipouts
)
1367
drivers
.
convert
(
"
pdf
"
,
tex
.
box
[
boxnumber
]
,
"
page
"
)
1368
statistics
.
stoptiming
(
shipouts
)
1369
callbacks
.
functions
.
stop_page_number
(
)
1370
end
1371 1372
-- For the moment this is sort of messy and pdf ... will change
1373 1374
local
function
enableshipout
(
)
1375
if
not
initialized
then
1376
-- install new functions in pdf namespace
1377
updaters
.
apply
(
"
backend.update.pdf
"
)
1378
-- install new functions in lpdf namespace
1379
updaters
.
apply
(
"
backend.update.lpdf
"
)
1380
-- adapt existing shortcuts to lpdf namespace
1381
updaters
.
apply
(
"
backend.update.tex
"
)
1382
-- adapt existing shortcuts to tex namespace
1383
updaters
.
apply
(
"
backend.update
"
)
1384
--
1385
directives
.
enable
(
"
graphics.uselua
"
)
1386
--
1387
if
rawget
(
pdf
,
"
setforcefile
"
)
then
1388
pdf
.
setforcefile
(
false
)
-- default anyway
1389
end
1390
--
1391
local
pdfname
=
tex
.
jobname
.
.
"
.pdf
"
1392
local
tmpname
=
"
l_m_t_x_
"
.
.
pdfname
1393
os
.
remove
(
tmpname
)
1394
if
lfs
.
isfile
(
tmpname
)
then
1395
report
(
"
file %a can't be opened, aborting
"
,
tmpname
)
1396
os
.
exit
(
)
1397
end
1398
lpdf
.
openfile
(
tmpname
)
1399
--
1400
luatex
.
registerstopactions
(
1
,
function
(
)
1401
lpdf
.
finalizedocument
(
)
1402
lpdf
.
closefile
(
)
1403
end
)
1404
--
1405
luatex
.
registerpageactions
(
1
,
function
(
)
1406
lpdf
.
finalizepage
(
true
)
1407
end
)
1408
--
1409
luatex
.
wrapup
(
function
(
)
1410
local
ok
=
true
1411
if
lfs
.
isfile
(
pdfname
)
then
1412
os
.
remove
(
pdfname
)
1413
end
1414
if
lfs
.
isfile
(
pdfname
)
then
1415
ok
=
false
1416
else
1417
os
.
rename
(
tmpname
,
pdfname
)
1418
if
lfs
.
isfile
(
tmpname
)
then
1419
ok
=
false
1420
end
1421
end
1422
if
not
ok
then
1423
print
(
formatters
[
"
\nerror in renaming %a to %a\n
"
]
(
tmpname
,
pdfname
)
)
1424
end
1425
end
)
1426
--
1427
fonts
.
constructors
.
autocleanup
=
false
1428
--
1429
lpdf
.
registerdocumentfinalizer
(
wrapup
,
nil
,
"
wrapping up
"
)
1430
--
1431
statistics
.
register
(
"
pdf generation time (minus font inclusion)
"
,
report
)
1432
--
1433
environment
.
lmtxmode
=
true
1434
--
1435
initialized
=
true
1436
end
1437
end
1438 1439
interfaces
.
implement
{
1440
name
=
"
shipoutpage
"
,
1441
arguments
=
"
integer
"
,
1442
actions
=
shipout
,
1443
}
1444 1445
interfaces
.
implement
{
1446
name
=
"
enableshipout
"
,
1447
actions
=
enableshipout
,
1448
}
1449