lpdf-mis.lua /size: 21 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
lpdf-mis
'
]
=
{
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
-- Although we moved most pdf handling to the lua end, we didn't change
10
-- the overall approach. For instance we share all resources i.e. we
11
-- don't make subsets for each xform or page. The current approach is
12
-- quite efficient. A big difference between MkII and MkIV is that we
13
-- now use forward references. In this respect the MkII code shows that
14
-- it evolved over a long period, when backends didn't provide forward
15
-- referencing and references had to be tracked in multiple passes. Of
16
-- course there are a couple of more changes.
17 18
local
next
,
tostring
,
type
=
next
,
tostring
,
type
19
local
format
,
gsub
,
formatters
=
string
.
format
,
string
.
gsub
,
string
.
formatters
20
local
concat
,
flattened
=
table
.
concat
,
table
.
flattened
21
local
settings_to_array
=
utilities
.
parsers
.
settings_to_array
22 23
local
backends
,
lpdf
,
nodes
=
backends
,
lpdf
,
nodes
24 25
local
nodeinjections
=
backends
.
pdf
.
nodeinjections
26
local
codeinjections
=
backends
.
pdf
.
codeinjections
27
local
registrations
=
backends
.
pdf
.
registrations
28 29
local
nuts
=
nodes
.
nuts
30
local
copy_node
=
nuts
.
copy
31 32
local
nodepool
=
nuts
.
pool
33
local
pageliteral
=
nodepool
.
pageliteral
34
local
register
=
nodepool
.
register
35 36
local
pdfdictionary
=
lpdf
.
dictionary
37
local
pdfarray
=
lpdf
.
array
38
local
pdfconstant
=
lpdf
.
constant
39
local
pdfreference
=
lpdf
.
reference
40
local
pdfunicode
=
lpdf
.
unicode
41
local
pdfverbose
=
lpdf
.
verbose
42
local
pdfstring
=
lpdf
.
string
43
local
pdfflushobject
=
lpdf
.
flushobject
44
local
pdfflushstreamobject
=
lpdf
.
flushstreamobject
45
local
pdfaction
=
lpdf
.
action
46
local
pdfminorversion
=
lpdf
.
minorversion
47 48
local
formattedtimestamp
=
lpdf
.
pdftimestamp
49
local
adddocumentextgstate
=
lpdf
.
adddocumentextgstate
50
local
addtocatalog
=
lpdf
.
addtocatalog
51
local
addtoinfo
=
lpdf
.
addtoinfo
52
local
addtopageattributes
=
lpdf
.
addtopageattributes
53
local
addtonames
=
lpdf
.
addtonames
54 55
local
pdfgetmetadata
=
lpdf
.
getmetadata
56 57
local
texset
=
tex
.
set
58 59
local
variables
=
interfaces
.
variables
60 61
local
v_stop
=
variables
.
stop
62
local
v_none
=
variables
.
none
63
local
v_max
=
variables
.
max
64
local
v_bookmark
=
variables
.
bookmark
65
local
v_fit
=
variables
.
fit
66
local
v_doublesided
=
variables
.
doublesided
67
local
v_singlesided
=
variables
.
singlesided
68
local
v_default
=
variables
.
default
69
local
v_auto
=
variables
.
auto
70
local
v_fixed
=
variables
.
fixed
71
local
v_landscape
=
variables
.
landscape
72
local
v_portrait
=
variables
.
portrait
73
local
v_page
=
variables
.
page
74
local
v_paper
=
variables
.
paper
75
local
v_attachment
=
variables
.
attachment
76
local
v_layer
=
variables
.
layer
77
local
v_lefttoright
=
variables
.
lefttoright
78
local
v_righttoleft
=
variables
.
righttoleft
79
local
v_title
=
variables
.
title
80
local
v_nomenubar
=
variables
.
nomenubar
81 82
local
positive
=
register
(
pageliteral
(
"
/GSpositive gs
"
)
)
83
local
negative
=
register
(
pageliteral
(
"
/GSnegative gs
"
)
)
84
local
overprint
=
register
(
pageliteral
(
"
/GSoverprint gs
"
)
)
85
local
knockout
=
register
(
pageliteral
(
"
/GSknockout gs
"
)
)
86 87
local
omitextraboxes
=
false
88 89
directives
.
register
(
"
backend.omitextraboxes
"
,
function
(
v
)
omitextraboxes
=
v
end
)
90 91
local
function
initializenegative
(
)
92
local
a
=
pdfarray
{
0
,
1
}
93
local
g
=
pdfconstant
(
"
ExtGState
"
)
94
local
d
=
pdfdictionary
{
95
FunctionType
=
4
,
96
Range
=
a
,
97
Domain
=
a
,
98
}
99
local
negative
=
pdfdictionary
{
Type
=
g
,
TR
=
pdfreference
(
pdfflushstreamobject
(
"
{ 1 exch sub }
"
,
d
)
)
}
-- can be shared
100
local
positive
=
pdfdictionary
{
Type
=
g
,
TR
=
pdfconstant
(
"
Identity
"
)
}
101
adddocumentextgstate
(
"
GSnegative
"
,
pdfreference
(
pdfflushobject
(
negative
)
)
)
102
adddocumentextgstate
(
"
GSpositive
"
,
pdfreference
(
pdfflushobject
(
positive
)
)
)
103
initializenegative
=
nil
104
end
105 106
local
function
initializeoverprint
(
)
107
local
g
=
pdfconstant
(
"
ExtGState
"
)
108
local
knockout
=
pdfdictionary
{
Type
=
g
,
OP
=
false
,
OPM
=
0
}
109
local
overprint
=
pdfdictionary
{
Type
=
g
,
OP
=
true
,
OPM
=
1
}
110
adddocumentextgstate
(
"
GSknockout
"
,
pdfreference
(
pdfflushobject
(
knockout
)
)
)
111
adddocumentextgstate
(
"
GSoverprint
"
,
pdfreference
(
pdfflushobject
(
overprint
)
)
)
112
initializeoverprint
=
nil
113
end
114 115
function
nodeinjections
.
overprint
(
)
116
if
initializeoverprint
then
initializeoverprint
(
)
end
117
return
copy_node
(
overprint
)
118
end
119
function
nodeinjections
.
knockout
(
)
120
if
initializeoverprint
then
initializeoverprint
(
)
end
121
return
copy_node
(
knockout
)
122
end
123 124
function
nodeinjections
.
positive
(
)
125
if
initializenegative
then
initializenegative
(
)
end
126
return
copy_node
(
positive
)
127
end
128
function
nodeinjections
.
negative
(
)
129
if
initializenegative
then
initializenegative
(
)
end
130
return
copy_node
(
negative
)
131
end
132 133
-- function codeinjections.addtransparencygroup()
134
-- -- png: /CS /DeviceRGB /I true
135
-- local d = pdfdictionary {
136
-- S = pdfconstant("Transparency"),
137
-- I = true,
138
-- K = true,
139
-- }
140
-- lpdf.registerpagefinalizer(function() addtopageattributes("Group",d) end) -- hm
141
-- end
142 143
-- actions (todo: store and update when changed)
144 145
local
openpage
,
closepage
,
opendocument
,
closedocument
146 147
function
codeinjections
.
registerdocumentopenaction
(
open
)
148
opendocument
=
open
149
end
150 151
function
codeinjections
.
registerdocumentcloseaction
(
close
)
152
closedocument
=
close
153
end
154 155
function
codeinjections
.
registerpageopenaction
(
open
)
156
openpage
=
open
157
end
158 159
function
codeinjections
.
registerpagecloseaction
(
close
)
160
closepage
=
close
161
end
162 163
local
function
flushdocumentactions
(
)
164
if
opendocument
then
165
addtocatalog
(
"
OpenAction
"
,
pdfaction
(
opendocument
)
)
166
end
167
if
closedocument
then
168
addtocatalog
(
"
CloseAction
"
,
pdfaction
(
closedocument
)
)
169
end
170
end
171 172
local
function
flushpageactions
(
)
173
if
openpage
or
closepage
then
174
local
d
=
pdfdictionary
(
)
175
if
openpage
then
176
d
.
O
=
pdfaction
(
openpage
)
177
end
178
if
closepage
then
179
d
.
C
=
pdfaction
(
closepage
)
180
end
181
addtopageattributes
(
"
AA
"
,
d
)
182
end
183
end
184 185
lpdf
.
registerpagefinalizer
(
flushpageactions
,
"
page actions
"
)
186
lpdf
.
registerdocumentfinalizer
(
flushdocumentactions
,
"
document actions
"
)
187 188
--- info : this can change and move elsewhere
189 190
local
identity
=
{
}
191 192
function
codeinjections
.
setupidentity
(
specification
)
193
for
k
,
v
in
next
,
specification
do
194
if
v
~
=
"
"
then
195
identity
[
k
]
=
v
196
end
197
end
198
end
199 200
function
codeinjections
.
getidentityvariable
(
name
)
201
return
identity
[
name
]
202
end
203 204
local
done
=
false
-- using "setupidentity = function() end" fails as the meaning is frozen in register
205 206
local
function
setupidentity
(
)
207
if
not
done
then
208
local
metadata
=
pdfgetmetadata
(
)
209
local
creator
=
metadata
.
creator
210
local
version
=
metadata
.
contextversion
211
local
time
=
metadata
.
time
212
local
jobname
=
environment
.
jobname
or
tex
.
jobname
or
"
unknown
"
213
--
214
local
title
=
identity
.
title
215
if
not
title
or
title
=
=
"
"
then
216
title
=
tex
.
jobname
217
end
218
addtoinfo
(
"
Title
"
,
pdfunicode
(
title
)
,
title
)
219
local
subtitle
=
identity
.
subtitle
or
"
"
220
if
subtitle
~
=
"
"
then
221
addtoinfo
(
"
Subject
"
,
pdfunicode
(
subtitle
)
,
subtitle
)
222
end
223
local
author
=
identity
.
author
or
"
"
224
if
author
~
=
"
"
then
225
addtoinfo
(
"
Author
"
,
pdfunicode
(
author
)
,
author
)
-- '/Author' in /Info, 'Creator' in XMP
226
end
227
addtoinfo
(
"
Creator
"
,
pdfunicode
(
creator
)
,
creator
)
228
addtoinfo
(
"
CreationDate
"
,
pdfstring
(
formattedtimestamp
(
time
)
)
)
229
local
date
=
identity
.
date
or
"
"
230
local
pdfdate
=
date
and
formattedtimestamp
(
date
)
231
if
pdfdate
then
232
addtoinfo
(
"
ModDate
"
,
pdfstring
(
pdfdate
)
,
date
)
233
else
234
-- users should enter the date in 2010-01-19T23:27:50+01:00 format
235
-- and if not provided that way we use the creation time instead
236
addtoinfo
(
"
ModDate
"
,
pdfstring
(
formattedtimestamp
(
time
)
)
,
time
)
237
end
238
local
keywords
=
identity
.
keywords
or
"
"
239
if
keywords
~
=
"
"
then
240
keywords
=
concat
(
settings_to_array
(
keywords
)
,
"
"
)
241
addtoinfo
(
"
Keywords
"
,
pdfunicode
(
keywords
)
,
keywords
)
242
end
243
local
id
=
lpdf
.
id
(
)
244
addtoinfo
(
"
ID
"
,
pdfstring
(
id
)
,
id
)
-- needed for pdf/x
245
--
246
addtoinfo
(
"
ConTeXt.Version
"
,
version
)
247
--
248
local
lmtx
=
codeinjections
.
lmtxmode
(
)
249
if
lmtx
then
250
addtoinfo
(
"
ConTeXt.LMTX
"
,
formatters
[
"
%0.2f
"
]
(
lmtx
)
)
251
end
252
--
253
addtoinfo
(
"
ConTeXt.Time
"
,
os
.
date
(
"
%Y-%m-%d %H:%M
"
)
)
254
addtoinfo
(
"
ConTeXt.Jobname
"
,
jobname
)
255
addtoinfo
(
"
ConTeXt.Url
"
,
"
www.pragma-ade.com
"
)
256
addtoinfo
(
"
ConTeXt.Support
"
,
"
contextgarden.net
"
)
257
addtoinfo
(
"
TeX.Support
"
,
"
tug.org
"
)
258
--
259
done
=
true
260
else
261
-- no need for a message
262
end
263
end
264 265
lpdf
.
registerpagefinalizer
(
setupidentity
,
"
identity
"
)
266 267
-- or when we want to be able to set things after pag e1:
268
--
269
-- lpdf.registerdocumentfinalizer(setupidentity,1,"identity")
270 271
local
function
flushjavascripts
(
)
272
local
t
=
interactions
.
javascripts
.
flushpreambles
(
)
273
if
#
t
>
0
then
274
local
a
=
pdfarray
(
)
275
local
pdf_javascript
=
pdfconstant
(
"
JavaScript
"
)
276
for
i
=
1
,
#
t
do
277
local
ti
=
t
[
i
]
278
local
name
=
ti
[
1
]
279
local
script
=
ti
[
2
]
280
local
j
=
pdfdictionary
{
281
S
=
pdf_javascript
,
282
JS
=
pdfreference
(
pdfflushstreamobject
(
script
)
)
,
283
}
284
a
[
#
a
+
1
]
=
pdfstring
(
name
)
285
a
[
#
a
+
1
]
=
pdfreference
(
pdfflushobject
(
j
)
)
286
end
287
addtonames
(
"
JavaScript
"
,
pdfreference
(
pdfflushobject
(
pdfdictionary
{
Names
=
a
}
)
)
)
288
end
289
end
290 291
lpdf
.
registerdocumentfinalizer
(
flushjavascripts
,
"
javascripts
"
)
292 293
-- -- --
294 295
local
plusspecs
=
{
296
[
v_max
]
=
{
297
mode
=
"
FullScreen
"
,
298
}
,
299
[
v_bookmark
]
=
{
300
mode
=
"
UseOutlines
"
,
301
}
,
302
[
v_attachment
]
=
{
303
mode
=
"
UseAttachments
"
,
304
}
,
305
[
v_layer
]
=
{
306
mode
=
"
UseOC
"
,
307
}
,
308
[
v_fit
]
=
{
309
fit
=
true
,
310
}
,
311
[
v_doublesided
]
=
{
312
layout
=
"
TwoColumnRight
"
,
313
}
,
314
[
v_fixed
]
=
{
315
fixed
=
true
,
316
}
,
317
[
v_landscape
]
=
{
318
duplex
=
"
DuplexFlipShortEdge
"
,
319
}
,
320
[
v_portrait
]
=
{
321
duplex
=
"
DuplexFlipLongEdge
"
,
322
}
,
323
[
v_page
]
=
{
324
duplex
=
"
Simplex
"
,
325
}
,
326
[
v_paper
]
=
{
327
paper
=
true
,
328
}
,
329
[
v_title
]
=
{
330
title
=
true
,
331
}
,
332
[
v_lefttoright
]
=
{
333
direction
=
"
L2R
"
,
334
}
,
335
[
v_righttoleft
]
=
{
336
direction
=
"
R2L
"
,
337
}
,
338
[
v_nomenubar
]
=
{
339
nomenubar
=
true
,
340
}
,
341
}
342 343
local
pagespecs
=
{
344
--
345
[
v_max
]
=
plusspecs
[
v_max
]
,
346
[
v_bookmark
]
=
plusspecs
[
v_bookmark
]
,
347
[
v_attachment
]
=
plusspecs
[
v_attachment
]
,
348
[
v_layer
]
=
plusspecs
[
v_layer
]
,
349
[
v_lefttoright
]
=
plusspecs
[
v_lefttoright
]
,
350
[
v_righttoleft
]
=
plusspecs
[
v_righttoleft
]
,
351
[
v_title
]
=
plusspecs
[
v_title
]
,
352
--
353
[
v_none
]
=
{
354
}
,
355
[
v_fit
]
=
{
356
mode
=
"
UseNone
"
,
357
fit
=
true
,
358
}
,
359
[
v_doublesided
]
=
{
360
mode
=
"
UseNone
"
,
361
layout
=
"
TwoColumnRight
"
,
362
fit
=
true
,
363
}
,
364
[
v_singlesided
]
=
{
365
mode
=
"
UseNone
"
366
}
,
367
[
v_default
]
=
{
368
mode
=
"
UseNone
"
,
369
layout
=
"
auto
"
,
370
}
,
371
[
v_auto
]
=
{
372
mode
=
"
UseNone
"
,
373
layout
=
"
auto
"
,
374
}
,
375
[
v_fixed
]
=
{
376
mode
=
"
UseNone
"
,
377
layout
=
"
auto
"
,
378
fixed
=
true
,
-- noscale
379
}
,
380
[
v_landscape
]
=
{
381
mode
=
"
UseNone
"
,
382
layout
=
"
auto
"
,
383
fixed
=
true
,
384
duplex
=
"
DuplexFlipShortEdge
"
,
385
}
,
386
[
v_portrait
]
=
{
387
mode
=
"
UseNone
"
,
388
layout
=
"
auto
"
,
389
fixed
=
true
,
390
duplex
=
"
DuplexFlipLongEdge
"
,
391
}
,
392
[
v_page
]
=
{
393
mode
=
"
UseNone
"
,
394
layout
=
"
auto
"
,
395
fixed
=
true
,
396
duplex
=
"
Simplex
"
,
397
}
,
398
[
v_paper
]
=
{
399
mode
=
"
UseNone
"
,
400
layout
=
"
auto
"
,
401
fixed
=
true
,
402
duplex
=
"
Simplex
"
,
403
paper
=
true
,
404
}
,
405
[
v_nomenubar
]
=
{
406
mode
=
"
UseNone
"
,
407
layout
=
"
auto
"
,
408
nomenubar
=
true
,
409
}
,
410
}
411 412
local
pagespec
,
topoffset
,
leftoffset
,
height
,
width
,
doublesided
=
"
default
"
,
0
,
0
,
0
,
0
,
false
413
local
cropoffset
,
bleedoffset
,
trimoffset
,
artoffset
=
0
,
0
,
0
,
0
414
local
marked
=
false
415
local
copies
=
false
416 417
local
getpagedimensions
getpagedimensions
=
function
(
)
418
getpagedimensions
=
backends
.
codeinjections
.
getpagedimensions
419
return
getpagedimensions
(
)
420
end
421 422
function
codeinjections
.
setupcanvas
(
specification
)
423
local
paperheight
=
specification
.
paperheight
424
local
paperwidth
=
specification
.
paperwidth
425
local
paperdouble
=
specification
.
doublesided
426
--
427
paperwidth
,
paperheight
=
codeinjections
.
setpagedimensions
(
paperwidth
,
paperheight
)
428
--
429
pagespec
=
specification
.
mode
or
pagespec
430
topoffset
=
specification
.
topoffset
or
0
431
leftoffset
=
specification
.
leftoffset
or
0
432
height
=
specification
.
height
or
paperheight
433
width
=
specification
.
width
or
paperwidth
434
marked
=
specification
.
print
435
--
436
copies
=
specification
.
copies
437
if
copies
and
copies
<
2
then
438
copies
=
false
439
end
440
--
441
cropoffset
=
specification
.
cropoffset
or
0
442
trimoffset
=
cropoffset
-
(
specification
.
trimoffset
or
0
)
443
bleedoffset
=
trimoffset
-
(
specification
.
bleedoffset
or
0
)
444
artoffset
=
bleedoffset
-
(
specification
.
artoffset
or
0
)
445
--
446
if
paperdouble
~
=
nil
then
447
doublesided
=
paperdouble
448
end
449
end
450 451
local
function
documentspecification
(
)
452
if
not
pagespec
or
pagespec
=
=
"
"
then
453
pagespec
=
v_default
454
end
455
local
settings
=
settings_to_array
(
pagespec
)
456
-- so the first one detemines the defaults
457
local
first
=
settings
[
1
]
458
local
defaults
=
pagespecs
[
first
]
459
local
spec
=
defaults
or
pagespecs
[
v_default
]
460
-- successive keys can modify this
461
if
spec
.
layout
=
=
"
auto
"
then
462
if
doublesided
then
463
local
s
=
pagespecs
[
v_doublesided
]
-- to be checked voor interfaces
464
for
k
,
v
in
next
,
s
do
465
spec
[
k
]
=
v
466
end
467
else
468
spec
.
layout
=
false
469
end
470
end
471
-- we start at 2 when we have a valid first default set
472
for
i
=
defaults
and
2
or
1
,
#
settings
do
473
local
s
=
plusspecs
[
settings
[
i
]
]
474
if
s
then
475
for
k
,
v
in
next
,
s
do
476
spec
[
k
]
=
v
477
end
478
end
479
end
480
-- maybe interfaces.variables
481
local
layout
=
spec
.
layout
482
local
mode
=
spec
.
mode
483
local
fit
=
spec
.
fit
484
local
fixed
=
spec
.
fixed
485
local
duplex
=
spec
.
duplex
486
local
paper
=
spec
.
paper
487
local
title
=
spec
.
title
488
local
direction
=
spec
.
direction
489
local
nomenubar
=
spec
.
nomenubar
490
if
layout
then
491
addtocatalog
(
"
PageLayout
"
,
pdfconstant
(
layout
)
)
492
end
493
if
mode
then
494
addtocatalog
(
"
PageMode
"
,
pdfconstant
(
mode
)
)
495
end
496
local
prints
=
nil
497
if
marked
then
498
local
pages
=
structures
.
pages
499
local
marked
=
pages
.
allmarked
(
marked
)
500
local
nofmarked
=
marked
and
#
marked
or
0
501
if
nofmarked
>
0
then
502
-- the spec is wrong in saying that numbering starts at 1 which of course makes
503
-- sense as most real documents start with page 0 .. sigh
504
for
i
=
1
,
#
marked
do
marked
[
i
]
=
marked
[
i
]
-
1
end
505
prints
=
pdfarray
(
flattened
(
pages
.
toranges
(
marked
)
)
)
506
end
507
end
508
if
fit
or
fixed
or
duplex
or
copies
or
paper
or
prints
or
title
or
direction
or
nomenubar
then
509
addtocatalog
(
"
ViewerPreferences
"
,
pdfdictionary
{
510
FitWindow
=
fit
and
true
or
nil
,
511
PrintScaling
=
fixed
and
pdfconstant
(
"
None
"
)
or
nil
,
512
Duplex
=
duplex
and
pdfconstant
(
duplex
)
or
nil
,
513
NumCopies
=
copies
and
copies
or
nil
,
514
PickTrayByPDFSize
=
paper
and
true
or
nil
,
515
PrintPageRange
=
prints
or
nil
,
516
DisplayDocTitle
=
title
and
true
or
nil
,
517
Direction
=
direction
and
pdfconstant
(
direction
)
or
nil
,
518
HideMenubar
=
nomenubar
and
true
or
nil
,
519
}
)
520
end
521
addtoinfo
(
"
Trapped
"
,
pdfconstant
(
"
False
"
)
)
-- '/Trapped' in /Info, 'Trapped' in XMP
522
addtocatalog
(
"
Version
"
,
pdfconstant
(
format
(
"
1.%s
"
,
pdfminorversion
(
)
)
)
)
523
addtocatalog
(
"
Lang
"
,
pdfstring
(
tokens
.
getters
.
macro
(
"
currentmainlanguage
"
)
)
)
524
end
525 526
-- temp hack: the mediabox is not under our control and has a precision of 5 digits
527 528
local
factor
=
number
.
dimenfactors
.
bp
529
local
f_value
=
formatters
[
"
%.6N
"
]
530 531
local
function
boxvalue
(
n
)
-- we could share them
532
return
pdfverbose
(
f_value
(
factor
*
n
)
)
533
end
534 535
local
function
pagespecification
(
)
536
local
paperwidth
,
paperheight
=
codeinjections
.
getpagedimensions
(
)
537
local
llx
=
leftoffset
538
local
lly
=
paperheight
+
topoffset
-
height
539
local
urx
=
width
-
leftoffset
540
local
ury
=
paperheight
-
topoffset
541
-- boxes can be cached
542
local
function
extrabox
(
WhatBox
,
offset
,
always
)
543
if
offset
~
=
0
or
always
then
544
addtopageattributes
(
WhatBox
,
pdfarray
{
545
boxvalue
(
llx
+
offset
)
,
546
boxvalue
(
lly
+
offset
)
,
547
boxvalue
(
urx
-
offset
)
,
548
boxvalue
(
ury
-
offset
)
,
549
}
)
550
end
551
end
552
if
omitextraboxes
then
553
-- only useful for testing / comparing
554
else
555
extrabox
(
"
CropBox
"
,
cropoffset
,
true
)
-- mandate for rendering
556
extrabox
(
"
TrimBox
"
,
trimoffset
,
true
)
-- mandate for pdf/x
557
extrabox
(
"
BleedBox
"
,
bleedoffset
)
-- optional
558
-- extrabox("ArtBox",artoffset) -- optional .. unclear what this is meant to do
559
end
560
end
561 562
lpdf
.
registerpagefinalizer
(
pagespecification
,
"
page specification
"
)
563
lpdf
.
registerdocumentfinalizer
(
documentspecification
,
"
document specification
"
)
564 565
-- Page Label support ...
566
--
567
-- In principle we can also support /P (prefix) as we can just use the verbose form
568
-- and we can then forget about the /St (start) as we don't care about those few
569
-- extra bytes due to lack of collapsing. Anyhow, for that we need a stupid prefix
570
-- variant and that's not on the agenda now.
571 572
local
map
=
{
573
numbers
=
"
D
"
,
574
Romannumerals
=
"
R
"
,
575
romannumerals
=
"
r
"
,
576
Characters
=
"
A
"
,
577
characters
=
"
a
"
,
578
}
579 580
-- local function featurecreep()
581
-- local pages, lastconversion, list = structures.pages.tobesaved, nil, pdfarray()
582
-- local getstructureset = structures.sets.get
583
-- for i=1,#pages do
584
-- local p = pages[i]
585
-- if not p then
586
-- return -- fatal error
587
-- else
588
-- local numberdata = p.numberdata
589
-- if numberdata then
590
-- local conversionset = numberdata.conversionset
591
-- if conversionset then
592
-- local conversion = getstructureset("structure:conversions",p.block,conversionset,1,"numbers")
593
-- if conversion ~= lastconversion then
594
-- lastconversion = conversion
595
-- list[#list+1] = i - 1 -- pdf starts numbering at 0
596
-- list[#list+1] = pdfdictionary { S = pdfconstant(map[conversion] or map.numbers) }
597
-- end
598
-- end
599
-- end
600
-- if not lastconversion then
601
-- lastconversion = "numbers"
602
-- list[#list+1] = i - 1 -- pdf starts numbering at 0
603
-- list[#list+1] = pdfdictionary { S = pdfconstant(map.numbers) }
604
-- end
605
-- end
606
-- end
607
-- addtocatalog("PageLabels", pdfdictionary { Nums = list })
608
-- end
609 610
local
function
featurecreep
(
)
611
local
pages
=
structures
.
pages
.
tobesaved
612
local
list
=
pdfarray
(
)
613
local
getset
=
structures
.
sets
.
get
614
local
stopped
=
false
615
local
oldlabel
=
nil
616
local
olconversion
=
nil
617
for
i
=
1
,
#
pages
do
618
local
p
=
pages
[
i
]
619
if
not
p
then
620
return
-- fatal error
621
end
622
local
label
=
p
.
viewerprefix
or
"
"
623
if
p
.
status
=
=
v_stop
then
624
if
not
stopped
then
625
list
[
#
list
+
1
]
=
i
-
1
-- pdf starts numbering at 0
626
list
[
#
list
+
1
]
=
pdfdictionary
{
627
P
=
pdfunicode
(
label
)
,
628
}
629
stopped
=
true
630
end
631
oldlabel
=
nil
632
oldconversion
=
nil
633
stopped
=
false
634
else
635
local
numberdata
=
p
.
numberdata
636
local
conversion
=
nil
637
local
number
=
p
.
number
638
if
numberdata
then
639
local
conversionset
=
numberdata
.
conversionset
640
if
conversionset
then
641
conversion
=
getset
(
"
structure:conversions
"
,
p
.
block
,
conversionset
,
1
,
"
numbers
"
)
642
end
643
end
644
conversion
=
conversion
and
map
[
conversion
]
or
map
.
numbers
645
if
number
=
=
1
or
oldlabel
~
=
label
or
oldconversion
~
=
conversion
then
646
list
[
#
list
+
1
]
=
i
-
1
-- pdf starts numbering at 0
647
list
[
#
list
+
1
]
=
pdfdictionary
{
648
S
=
pdfconstant
(
conversion
)
,
649
St
=
number
,
650
P
=
label
~
=
"
"
and
pdfunicode
(
label
)
or
nil
,
651
}
652
end
653
oldlabel
=
label
654
oldconversion
=
conversion
655
stopped
=
false
656
end
657
end
658
addtocatalog
(
"
PageLabels
"
,
pdfdictionary
{
Nums
=
list
}
)
659
end
660 661
lpdf
.
registerdocumentfinalizer
(
featurecreep
,
"
featurecreep
"
)
662