lpdf-ini.lua /size: 53 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
lpdf-ini
'
]
=
{
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
-- beware of "too many locals" here
10 11
local
setmetatable
,
getmetatable
,
type
,
next
,
tostring
,
tonumber
,
rawset
=
setmetatable
,
getmetatable
,
type
,
next
,
tostring
,
tonumber
,
rawset
12
local
char
,
byte
,
format
,
gsub
,
concat
,
match
,
sub
,
gmatch
=
string
.
char
,
string
.
byte
,
string
.
format
,
string
.
gsub
,
table
.
concat
,
string
.
match
,
string
.
sub
,
string
.
gmatch
13
local
utfchar
,
utfbyte
,
utfvalues
=
utf
.
char
,
utf
.
byte
,
utf
.
values
14
local
sind
,
cosd
,
max
,
min
=
math
.
sind
,
math
.
cosd
,
math
.
max
,
math
.
min
15
local
sort
,
sortedhash
=
table
.
sort
,
table
.
sortedhash
16
local
P
,
C
,
R
,
S
,
Cc
,
Cs
,
V
=
lpeg
.
P
,
lpeg
.
C
,
lpeg
.
R
,
lpeg
.
S
,
lpeg
.
Cc
,
lpeg
.
Cs
,
lpeg
.
V
17
local
lpegmatch
,
lpegpatterns
=
lpeg
.
match
,
lpeg
.
patterns
18
local
formatters
=
string
.
formatters
19
local
isboolean
=
string
.
is_boolean
20
local
rshift
=
bit32
.
rshift
21
local
osdate
,
ostime
=
os
.
date
,
os
.
time
22 23
local
report_objects
=
logs
.
reporter
(
"
backend
"
,
"
objects
"
)
24
local
report_finalizing
=
logs
.
reporter
(
"
backend
"
,
"
finalizing
"
)
25
local
report_blocked
=
logs
.
reporter
(
"
backend
"
,
"
blocked
"
)
26 27
local
implement
=
interfaces
.
implement
28 29
local
context
=
context
30 31
-- In ConTeXt MkIV we use utf8 exclusively so all strings get mapped onto a hex
32
-- encoded utf16 string type between <>. We could probably save some bytes by using
33
-- strings between () but then we end up with escaped ()\ too.
34 35
pdf
=
type
(
pdf
)
=
=
"
table
"
and
pdf
or
{
}
36
local
factor
=
number
.
dimenfactors
.
bp
37 38
local
codeinjections
=
{
}
39
local
nodeinjections
=
{
}
40 41
local
backends
=
backends
42 43
local
pdfbackend
=
{
44
comment
=
"
backend for directly generating pdf output
"
,
45
nodeinjections
=
nodeinjections
,
46
codeinjections
=
codeinjections
,
47
registrations
=
{
}
,
48
tables
=
{
}
,
49
}
50 51
backends
.
pdf
=
pdfbackend
52 53
lpdf
=
lpdf
or
{
}
54
local
lpdf
=
lpdf
55
lpdf
.
flags
=
lpdf
.
flags
or
{
}
-- will be filled later
56 57
local
trace_finalizers
=
false
trackers
.
register
(
"
backend.finalizers
"
,
function
(
v
)
trace_finalizers
=
v
end
)
58
local
trace_resources
=
false
trackers
.
register
(
"
backend.resources
"
,
function
(
v
)
trace_resources
=
v
end
)
59
local
trace_objects
=
false
trackers
.
register
(
"
backend.objects
"
,
function
(
v
)
trace_objects
=
v
end
)
60
local
trace_details
=
false
trackers
.
register
(
"
backend.details
"
,
function
(
v
)
trace_details
=
v
end
)
61 62
do
63 64
local
pdfsetmajorversion
,
pdfsetminorversion
,
pdfgetmajorversion
,
pdfgetminorversion
65
local
pdfsetcompresslevel
,
pdfsetobjectcompresslevel
,
pdfgetcompresslevel
,
pdfgetobjectcompresslevel
66
local
pdfsetsuppressoptionalinfo
,
pdfsetomitcidset
,
pdfsetomitcharset
67 68
updaters
.
register
(
"
backend.update.lpdf
"
,
function
(
)
69
pdfsetmajorversion
=
pdf
.
setmajorversion
70
pdfsetminorversion
=
pdf
.
setminorversion
71
pdfgetmajorversion
=
pdf
.
getmajorversion
72
pdfgetminorversion
=
pdf
.
getminorversion
73 74
pdfsetcompresslevel
=
pdf
.
setcompresslevel
75
pdfsetobjectcompresslevel
=
pdf
.
setobjcompresslevel
76
pdfgetcompresslevel
=
pdf
.
getcompresslevel
77
pdfgetobjectcompresslevel
=
pdf
.
getobjcompresslevel
78 79
pdfsetsuppressoptionalinfo
=
pdf
.
setsuppressoptionalinfo
80
pdfsetomitcidset
=
pdf
.
setomitcidset
81
pdfsetomitcharset
=
pdf
.
setomitcharset
82
end
)
83 84
function
lpdf
.
setversion
(
major
,
minor
)
85
pdfsetmajorversion
(
major
or
1
)
86
pdfsetminorversion
(
minor
or
7
)
87
end
88 89
function
lpdf
.
getversion
(
major
,
minor
)
90
return
pdfgetmajorversion
(
)
,
pdfgetminorversion
(
)
91
end
92 93
function
lpdf
.
majorversion
(
)
return
pdfgetmajorversion
(
)
end
94
function
lpdf
.
minorversion
(
)
return
pdfgetminorversion
(
)
end
95 96
local
frozen
=
false
97
local
clevel
=
3
98
local
olevel
=
1
99 100
function
lpdf
.
setcompression
(
level
,
objectlevel
,
freeze
)
101
if
not
frozen
then
102
if
pdfsetcompresslevel
then
103
pdfsetcompresslevel
(
level
or
3
)
104
pdfsetobjectcompresslevel
(
objectlevel
or
level
or
3
)
105
else
106
clevel
=
level
107
olevel
=
objectlevel
108
end
109
frozen
=
freeze
110
end
111
end
112 113
function
lpdf
.
getcompression
(
)
114
if
pdfgetcompresslevel
then
115
return
pdfgetcompresslevel
(
)
,
pdfgetobjectcompresslevel
(
)
116
else
117
return
clevel
,
olevel
118
end
119
end
120 121
function
lpdf
.
compresslevel
(
)
122
if
pdfgetcompresslevel
then
123
return
pdfgetcompresslevel
(
)
124
else
125
return
clevel
126
end
127
end
128 129
function
lpdf
.
objectcompresslevel
(
)
130
if
pdfgetobjectcompresslevel
then
131
return
pdfgetobjectcompresslevel
(
)
132
else
133
return
olevel
134
end
135
end
136 137
function
lpdf
.
setsuppressoptionalinfo
(
n
)
138
if
pdfsetsuppressoptionalinfo
then
139
pdfsetsuppressoptionalinfo
(
n
)
-- todo
140
end
141
end
142 143
function
lpdf
.
setomitcidset
(
v
)
144
return
pdfsetomitcidset
(
v
)
145
end
146 147
function
lpdf
.
setomitcharset
(
v
)
148
return
pdfsetomitcharset
(
v
)
149
end
150 151
end
152 153
do
154 155
local
pdfgetxformname
,
pdfincludeimage
156 157
updaters
.
register
(
"
backend.update.lpdf
"
,
function
(
)
158
pdfgetxformname
=
pdf
.
getxformname
159
pdfincludeimage
=
pdf
.
includeimage
160
end
)
161 162
function
lpdf
.
getxformname
(
id
)
return
pdfgetxformname
(
id
)
end
163
function
lpdf
.
includeimage
(
id
)
return
pdfincludeimage
(
id
)
end
164 165
end
166 167
local
pdfsetpageresources
,
pdfsetpageattributes
,
pdfsetpagesattributes
168
local
pdfreserveobject
,
pdfimmediateobject
,
pdfdeferredobject
,
pdfreferenceobject
169
local
pdfgetpagereference
170 171
updaters
.
register
(
"
backend.update.lpdf
"
,
function
(
)
172
pdfreserveobject
=
pdf
.
reserveobj
173
pdfimmediateobject
=
pdf
.
immediateobj
174
pdfdeferredobject
=
pdf
.
obj
175
pdfreferenceobject
=
pdf
.
refobj
176 177
pdfgetpagereference
=
pdf
.
getpageref
178 179
pdfsetpageresources
=
pdf
.
setpageresources
180
pdfsetpageattributes
=
pdf
.
setpageattributes
181
pdfsetpagesattributes
=
pdf
.
setpagesattributes
182
end
)
183 184
local
jobpositions
=
job
.
positions
185
local
getpos
=
jobpositions
.
getpos
186
local
getrpos
=
jobpositions
.
getrpos
187 188
jobpositions
.
registerhandlers
{
189
getpos
=
pdf
.
getpos
,
190
-- getrpos = pdf.getrpos,
191
gethpos
=
pdf
.
gethpos
,
192
getvpos
=
pdf
.
getvpos
,
193
}
194 195
do
196 197
local
pdfgetmatrix
,
pdfhasmatrix
,
pdfprint
198 199
updaters
.
register
(
"
backend.update.lpdf
"
,
function
(
)
200
pdfgetmatrix
=
pdf
.
getmatrix
201
pdfhasmatrix
=
pdf
.
hasmatrix
202
pdfprint
=
pdf
.
print
203
end
)
204 205
function
lpdf
.
print
(
...
)
206
return
pdfprint
(
...
)
207
end
208 209
-- local function transform(llx,lly,urx,ury,rx,sx,sy,ry)
210
-- local x1 = llx * rx + lly * sy
211
-- local y1 = llx * sx + lly * ry
212
-- local x2 = llx * rx + ury * sy
213
-- local y2 = llx * sx + ury * ry
214
-- local x3 = urx * rx + lly * sy
215
-- local y3 = urx * sx + lly * ry
216
-- local x4 = urx * rx + ury * sy
217
-- local y4 = urx * sx + ury * ry
218
-- llx = min(x1,x2,x3,x4);
219
-- lly = min(y1,y2,y3,y4);
220
-- urx = max(x1,x2,x3,x4);
221
-- ury = max(y1,y2,y3,y4);
222
-- return llx, lly, urx, ury
223
-- end
224
--
225
-- function lpdf.transform(llx,lly,urx,ury) -- not yet used so unchecked
226
-- if pdfhasmatrix() then
227
-- local sx, rx, ry, sy = pdfgetmatrix()
228
-- local w, h = urx - llx, ury - lly
229
-- return llx, lly, llx + sy*w - ry*h, lly + sx*h - rx*w
230
-- -- return transform(llx,lly,urx,ury,sx,rx,ry,sy)
231
-- else
232
-- return llx, lly, urx, ury
233
-- end
234
-- end
235 236
-- funny values for tx and ty
237 238
function
lpdf
.
rectangle
(
width
,
height
,
depth
,
offset
)
239
local
tx
,
ty
=
getpos
(
)
-- pdfgetpos, maybe some day use dir here
240
if
offset
then
241
tx
=
tx
-
offset
242
ty
=
ty
+
offset
243
width
=
width
+
2
*
offset
244
height
=
height
+
offset
245
depth
=
depth
+
offset
246
end
247
if
pdfhasmatrix
(
)
then
248
local
rx
,
sx
,
sy
,
ry
=
pdfgetmatrix
(
)
249
return
250
factor
*
tx
,
251
factor
*
(
ty
-
ry
*
depth
+
sx
*
width
)
,
252
factor
*
(
tx
+
rx
*
width
-
sy
*
height
)
,
253
factor
*
(
ty
+
ry
*
height
-
sx
*
width
)
254
else
255
return
256
factor
*
tx
,
257
factor
*
(
ty
-
depth
)
,
258
factor
*
(
tx
+
width
)
,
259
factor
*
(
ty
+
height
)
260
end
261
end
262 263
end
264 265
-- we could use a hash of predefined unicodes
266 267
-- local function tosixteen(str) -- an lpeg might be faster (no table)
268
-- if not str or str == "" then
269
-- return "<feff>" -- not () as we want an indication that it's unicode
270
-- else
271
-- local r, n = { "<feff" }, 1
272
-- for b in utfvalues(str) do
273
-- n = n + 1
274
-- if b < 0x10000 then
275
-- r[n] = format("%04x",b)
276
-- else
277
-- r[n] = format("%04x%04x",rshift(b,10),b%1024+0xDC00)
278
-- end
279
-- end
280
-- n = n + 1
281
-- r[n] = ">"
282
-- return concat(r)
283
-- end
284
-- end
285 286
local
tosixteen
,
fromsixteen
,
topdfdoc
,
frompdfdoc
,
toeight
,
fromeight
287 288
do
289 290
local
escaped
=
Cs
(
Cc
(
"
(
"
)
*
(
S
(
"
\\()\n\r\t\b\f
"
)
/
"
\\%0
"
+
P
(
1
)
)
^
0
*
Cc
(
"
)
"
)
)
291 292
local
cache
=
table
.
setmetatableindex
(
function
(
t
,
k
)
-- can be made weak
293
local
v
=
utfbyte
(
k
)
294
if
v
<
0x10000
then
295
v
=
format
(
"
%04x
"
,
v
)
296
else
297
v
=
format
(
"
%04x%04x
"
,
rshift
(
v
,
10
)
,
v
%
1024
+
0xDC00
)
298
end
299
t
[
k
]
=
v
300
return
v
301
end
)
302 303
local
unified
=
Cs
(
Cc
(
"
<feff
"
)
*
(
lpeg
.
patterns
.
utf8character
/
cache
)
^
1
*
Cc
(
"
>
"
)
)
304 305
tosixteen
=
function
(
str
)
-- an lpeg might be faster (no table)
306
if
not
str
or
str
=
=
"
"
then
307
return
"
<feff>
"
-- not () as we want an indication that it's unicode
308
else
309
return
lpegmatch
(
unified
,
str
)
310
end
311
end
312 313
local
more
=
0
314 315
local
pattern
=
C
(
4
)
/
function
(
s
)
-- needs checking !
316
local
now
=
tonumber
(
s
,
16
)
317
if
more
>
0
then
318
now
=
(
more
-0xD800
)
*
0x400
+
(
now
-0xDC00
)
+
0x10000
-- the 0x10000 smells wrong
319
more
=
0
320
return
utfchar
(
now
)
321
elseif
now
>
=
0xD800
and
now
<
=
0xDBFF
then
322
more
=
now
323
return
"
"
-- else the c's end up in the stream
324
else
325
return
utfchar
(
now
)
326
end
327
end
328 329
local
pattern
=
P
(
true
)
/
function
(
)
more
=
0
end
*
Cs
(
pattern
^
0
)
330 331
fromsixteen
=
function
(
str
)
332
if
not
str
or
str
=
=
"
"
then
333
return
"
"
334
else
335
return
lpegmatch
(
pattern
,
str
)
336
end
337
end
338 339
local
toregime
=
regimes
.
toregime
340
local
fromregime
=
regimes
.
fromregime
341 342
topdfdoc
=
function
(
str
,
default
)
343
if
not
str
or
str
=
=
"
"
then
344
return
"
"
345
else
346
return
lpegmatch
(
escaped
,
toregime
(
"
pdfdoc
"
,
str
,
default
)
)
-- could be combined if needed
347
end
348
end
349 350
frompdfdoc
=
function
(
str
)
351
if
not
str
or
str
=
=
"
"
then
352
return
"
"
353
else
354
return
fromregime
(
"
pdfdoc
"
,
str
)
355
end
356
end
357 358
if
not
toregime
then
topdfdoc
=
function
(
s
)
return
s
end
end
359
if
not
fromregime
then
frompdfdoc
=
function
(
s
)
return
s
end
end
360 361
toeight
=
function
(
str
)
362
if
not
str
or
str
=
=
"
"
then
363
return
"
()
"
364
else
365
return
lpegmatch
(
escaped
,
str
)
366
end
367
end
368 369
local
b_pattern
=
Cs
(
(
P
(
"
\\
"
)
/
"
"
*
(
370
S
(
"
()
"
)
371
+
S
(
"
nrtbf
"
)
/
{
n
=
"
\n
"
,
r
=
"
\r
"
,
t
=
"
\t
"
,
b
=
"
\b
"
,
f
=
"
\f
"
}
372
+
lpegpatterns
.
octdigit
^
-3
/
function
(
s
)
return
char
(
tonumber
(
s
,
8
)
)
end
)
373
+
P
(
1
)
)
^
0
)
374 375
fromeight
=
function
(
str
)
376
if
not
str
or
str
=
=
"
"
then
377
return
"
"
378
else
379
return
lpegmatch
(
unescape
,
str
)
380
end
381
end
382 383
local
u_pattern
=
lpegpatterns
.
utfbom_16_be
*
lpegpatterns
.
utf16_to_utf8_be
-- official
384
+
lpegpatterns
.
utfbom_16_le
*
lpegpatterns
.
utf16_to_utf8_le
-- we've seen these
385 386
local
h_pattern
=
lpegpatterns
.
hextobytes
387 388
local
zero
=
S
(
"
\n\r\t
"
)
+
P
(
"
\\
"
)
389
local
one
=
C
(
4
)
390
local
two
=
P
(
"
d
"
)
*
R
(
"
89
"
,
"
af
"
)
*
C
(
2
)
*
C
(
4
)
391 392
local
x_pattern
=
P
{
"
start
"
,
393
start
=
V
(
"
wrapped
"
)
+
V
(
"
unwrapped
"
)
+
V
(
"
original
"
)
,
394
original
=
Cs
(
P
(
1
)
^
0
)
,
395
wrapped
=
P
(
"
<
"
)
*
V
(
"
unwrapped
"
)
*
P
(
"
>
"
)
*
P
(
-1
)
,
396
unwrapped
=
P
(
"
feff
"
)
397
*
Cs
(
(
398
zero
/
"
"
399
+
two
/
function
(
a
,
b
)
400
a
=
(
tonumber
(
a
,
16
)
-
0xD800
)
*
1024
401
b
=
(
tonumber
(
b
,
16
)
-
0xDC00
)
402
return
utfchar
(
a
+
b
)
403
end
404
+
one
/
function
(
a
)
405
return
utfchar
(
tonumber
(
a
,
16
)
)
406
end
407
)
^
1
)
*
P
(
-1
)
408
}
409 410
function
lpdf
.
frombytes
(
s
,
hex
)
411
if
not
s
or
s
=
=
"
"
then
412
return
"
"
413
end
414
if
hex
then
415
local
x
=
lpegmatch
(
x_pattern
,
s
)
416
if
x
then
417
return
x
418
end
419
local
h
=
lpegmatch
(
h_pattern
,
s
)
420
if
h
then
421
return
h
422
end
423
else
424
local
u
=
lpegmatch
(
u_pattern
,
s
)
425
if
u
then
426
return
u
427
end
428
end
429
return
lpegmatch
(
b_pattern
,
s
)
430
end
431 432
lpdf
.
tosixteen
=
tosixteen
433
lpdf
.
toeight
=
toeight
434
lpdf
.
topdfdoc
=
topdfdoc
435
lpdf
.
fromsixteen
=
fromsixteen
436
lpdf
.
fromeight
=
fromeight
437
lpdf
.
frompdfdoc
=
frompdfdoc
438 439
end
440 441
local
tostring_a
,
tostring_d
442 443
do
444 445
local
f_key_null
=
formatters
[
"
/%s null
"
]
446
local
f_key_value
=
formatters
[
"
/%s %s
"
]
447
local
f_key_dictionary
=
formatters
[
"
/%s << % t >>
"
]
448
local
f_dictionary
=
formatters
[
"
<< % t >>
"
]
449
local
f_key_array
=
formatters
[
"
/%s [ % t ]
"
]
450
local
f_array
=
formatters
[
"
[ % t ]
"
]
451
local
f_key_number
=
formatters
[
"
/%s %N
"
]
-- always with max 9 digits and integer is possible
452
local
f_tonumber
=
formatters
[
"
%N
"
]
-- always with max 9 digits and integer is possible
453 454
tostring_d
=
function
(
t
,
contentonly
,
key
)
455
if
next
(
t
)
then
456
local
r
=
{
}
457
local
n
=
0
458
local
e
459
for
k
,
v
in
next
,
t
do
460
if
k
=
=
"
__extra__
"
then
461
e
=
v
462
elseif
k
=
=
"
__stream__
"
then
463
-- do nothing (yet)
464
else
465
n
=
n
+
1
466
r
[
n
]
=
k
467
end
468
end
469
if
n
>
1
then
470
sort
(
r
)
471
end
472
for
i
=
1
,
n
do
473
local
k
=
r
[
i
]
474
local
v
=
t
[
k
]
475
local
tv
=
type
(
v
)
476
-- mostly tables
477
if
tv
=
=
"
table
"
then
478
-- local mv = getmetatable(v)
479
-- if mv and mv.__lpdftype then
480
if
v
.
__lpdftype__
then
481
-- if v == t then
482
-- report_objects("ignoring circular reference in dirctionary")
483
-- r[i] = f_key_null(k)
484
-- else
485
r
[
i
]
=
f_key_value
(
k
,
tostring
(
v
)
)
486
-- end
487
elseif
v
[
1
]
then
488
r
[
i
]
=
f_key_value
(
k
,
tostring_a
(
v
)
)
489
else
490
r
[
i
]
=
f_key_value
(
k
,
tostring_d
(
v
)
)
491
end
492
elseif
tv
=
=
"
string
"
then
493
r
[
i
]
=
f_key_value
(
k
,
toeight
(
v
)
)
494
elseif
tv
=
=
"
number
"
then
495
r
[
i
]
=
f_key_number
(
k
,
v
)
496
else
497
r
[
i
]
=
f_key_value
(
k
,
tostring
(
v
)
)
498
end
499
end
500
if
e
then
501
r
[
n
+
1
]
=
e
502
end
503
if
contentonly
then
504
return
concat
(
r
,
"
"
)
505
elseif
key
then
506
return
f_key_dictionary
(
key
,
r
)
507
else
508
return
f_dictionary
(
r
)
509
end
510
elseif
contentonly
then
511
return
"
"
512
else
513
return
"
<< >>
"
514
end
515
end
516 517
tostring_a
=
function
(
t
,
contentonly
,
key
)
518
local
tn
=
#
t
519
if
tn
~
=
0
then
520
local
r
=
{
}
521
for
k
=
1
,
tn
do
522
local
v
=
t
[
k
]
523
local
tv
=
type
(
v
)
524
-- mostly numbers and tables
525
if
tv
=
=
"
number
"
then
526
r
[
k
]
=
f_tonumber
(
v
)
527
elseif
tv
=
=
"
table
"
then
528
-- local mv = getmetatable(v)
529
-- if mv and mv.__lpdftype then
530
if
v
.
__lpdftype__
then
531
-- if v == t then
532
-- report_objects("ignoring circular reference in array")
533
-- r[k] = "null"
534
-- else
535
r
[
k
]
=
tostring
(
v
)
536
-- end
537
elseif
v
[
1
]
then
538
r
[
k
]
=
tostring_a
(
v
)
539
else
540
r
[
k
]
=
tostring_d
(
v
)
541
end
542
elseif
tv
=
=
"
string
"
then
543
r
[
k
]
=
toeight
(
v
)
544
else
545
r
[
k
]
=
tostring
(
v
)
546
end
547
end
548
local
e
=
t
.
__extra__
549
if
e
then
550
r
[
tn
+
1
]
=
e
551
end
552
if
contentonly
then
553
return
concat
(
r
,
"
"
)
554
elseif
key
then
555
return
f_key_array
(
key
,
r
)
556
else
557
return
f_array
(
r
)
558
end
559
elseif
contentonly
then
560
return
"
"
561
else
562
return
"
[ ]
"
563
end
564
end
565 566
end
567 568
local
f_tonumber
=
formatters
[
"
%N
"
]
569 570
local
tostring_x
=
function
(
t
)
return
concat
(
t
,
"
"
)
end
571
local
tostring_s
=
function
(
t
)
return
toeight
(
t
[
1
]
)
end
572
local
tostring_p
=
function
(
t
)
return
topdfdoc
(
t
[
1
]
,
t
[
2
]
)
end
573
local
tostring_u
=
function
(
t
)
return
tosixteen
(
t
[
1
]
)
end
574
----- tostring_n = function(t) return tostring(t[1]) end -- tostring not needed
575
local
tostring_n
=
function
(
t
)
return
f_tonumber
(
t
[
1
]
)
end
-- tostring not needed
576
local
tostring_c
=
function
(
t
)
return
t
[
1
]
end
-- already prefixed (hashed)
577
local
tostring_z
=
function
(
)
return
"
null
"
end
578
local
tostring_t
=
function
(
)
return
"
true
"
end
579
local
tostring_f
=
function
(
)
return
"
false
"
end
580
local
tostring_r
=
function
(
t
)
local
n
=
t
[
1
]
return
n
and
n
>
0
and
(
n
.
.
"
0 R
"
)
or
"
null
"
end
581 582
local
tostring_v
=
function
(
t
)
583
local
s
=
t
[
1
]
584
if
type
(
s
)
=
=
"
table
"
then
585
return
concat
(
s
)
586
else
587
return
s
588
end
589
end
590 591
local
tostring_l
=
function
(
t
)
592
local
s
=
t
[
1
]
593
if
not
s
or
s
=
=
"
"
then
594
return
"
()
"
595
elseif
t
[
2
]
then
596
return
"
<
"
.
.
s
.
.
"
>
"
597
else
598
return
"
(
"
.
.
s
.
.
"
)
"
599
end
600
end
601 602
local
function
value_x
(
t
)
return
t
end
603
local
function
value_s
(
t
)
return
t
[
1
]
end
604
local
function
value_p
(
t
)
return
t
[
1
]
end
605
local
function
value_u
(
t
)
return
t
[
1
]
end
606
local
function
value_n
(
t
)
return
t
[
1
]
end
607
local
function
value_c
(
t
)
return
sub
(
t
[
1
]
,
2
)
end
608
local
function
value_d
(
t
)
return
tostring_d
(
t
,
true
)
end
609
local
function
value_a
(
t
)
return
tostring_a
(
t
,
true
)
end
610
local
function
value_z
(
)
return
nil
end
611
local
function
value_t
(
t
)
return
t
.
value
or
true
end
612
local
function
value_f
(
t
)
return
t
.
value
or
false
end
613
local
function
value_r
(
t
)
return
t
[
1
]
or
0
end
-- null
614
local
function
value_v
(
t
)
return
t
[
1
]
end
615
local
function
value_l
(
t
)
return
t
[
1
]
end
616 617
local
function
add_to_d
(
t
,
v
)
618
local
k
=
type
(
v
)
619
if
k
=
=
"
string
"
then
620
if
t
.
__extra__
then
621
t
.
__extra__
=
t
.
__extra__
.
.
"
"
.
.
v
622
else
623
t
.
__extra__
=
v
624
end
625
elseif
k
=
=
"
table
"
then
626
for
k
,
v
in
next
,
v
do
627
t
[
k
]
=
v
628
end
629
end
630
return
t
631
end
632 633
local
function
add_to_a
(
t
,
v
)
634
local
k
=
type
(
v
)
635
if
k
=
=
"
string
"
then
636
if
t
.
__extra__
then
637
t
.
__extra__
=
t
.
__extra__
.
.
"
"
.
.
v
638
else
639
t
.
__extra__
=
v
640
end
641
elseif
k
=
=
"
table
"
then
642
local
n
=
#
t
643
for
i
=
1
,
#
v
do
644
n
=
n
+
1
645
t
[
n
]
=
v
[
i
]
646
end
647
end
648
return
t
649
end
650 651
local
function
add_x
(
t
,
k
,
v
)
rawset
(
t
,
k
,
tostring
(
v
)
)
end
652 653
-- local mt_x = { __index = { __lpdftype__ = "stream" }, __lpdftype = "stream", __tostring = tostring_x, __call = value_x, __newindex = add_x }
654
-- local mt_d = { __index = { __lpdftype__ = "dictionary" }, __lpdftype = "dictionary", __tostring = tostring_d, __call = value_d, __add = add_to_d }
655
-- local mt_a = { __index = { __lpdftype__ = "array" }, __lpdftype = "array", __tostring = tostring_a, __call = value_a, __add = add_to_a }
656
-- local mt_u = { __index = { __lpdftype__ = "unicode" }, __lpdftype = "unicode", __tostring = tostring_u, __call = value_u }
657
-- local mt_s = { __index = { __lpdftype__ = "string" }, __lpdftype = "string", __tostring = tostring_s, __call = value_s }
658
-- local mt_p = { __index = { __lpdftype__ = "docstring" }, __lpdftype = "docstring", __tostring = tostring_p, __call = value_p }
659
-- local mt_n = { __index = { __lpdftype__ = "number" }, __lpdftype = "number", __tostring = tostring_n, __call = value_n }
660
-- local mt_c = { __index = { __lpdftype__ = "constant" }, __lpdftype = "constant", __tostring = tostring_c, __call = value_c }
661
-- local mt_z = { __index = { __lpdftype__ = "null" }, __lpdftype = "null", __tostring = tostring_z, __call = value_z }
662
-- local mt_t = { __index = { __lpdftype__ = "true" }, __lpdftype = "true", __tostring = tostring_t, __call = value_t }
663
-- local mt_f = { __index = { __lpdftype__ = "false" }, __lpdftype = "false", __tostring = tostring_f, __call = value_f }
664
-- local mt_r = { __index = { __lpdftype__ = "reference" }, __lpdftype = "reference", __tostring = tostring_r, __call = value_r }
665
-- local mt_v = { __index = { __lpdftype__ = "verbose" }, __lpdftype = "verbose", __tostring = tostring_v, __call = value_v }
666
-- local mt_l = { __index = { __lpdftype__ = "literal" }, __lpdftype = "literal", __tostring = tostring_l, __call = value_l }
667 668
local
mt_x
=
{
__index
=
{
__lpdftype__
=
"
stream
"
}
,
__tostring
=
tostring_x
,
__call
=
value_x
,
__newindex
=
add_x
}
669
local
mt_d
=
{
__index
=
{
__lpdftype__
=
"
dictionary
"
}
,
__tostring
=
tostring_d
,
__call
=
value_d
,
__add
=
add_to_d
}
670
local
mt_a
=
{
__index
=
{
__lpdftype__
=
"
array
"
}
,
__tostring
=
tostring_a
,
__call
=
value_a
,
__add
=
add_to_a
}
671
local
mt_u
=
{
__index
=
{
__lpdftype__
=
"
unicode
"
}
,
__tostring
=
tostring_u
,
__call
=
value_u
}
672
local
mt_s
=
{
__index
=
{
__lpdftype__
=
"
string
"
}
,
__tostring
=
tostring_s
,
__call
=
value_s
}
673
local
mt_p
=
{
__index
=
{
__lpdftype__
=
"
docstring
"
}
,
__tostring
=
tostring_p
,
__call
=
value_p
}
674
local
mt_n
=
{
__index
=
{
__lpdftype__
=
"
number
"
}
,
__tostring
=
tostring_n
,
__call
=
value_n
}
675
local
mt_c
=
{
__index
=
{
__lpdftype__
=
"
constant
"
}
,
__tostring
=
tostring_c
,
__call
=
value_c
}
676
local
mt_z
=
{
__index
=
{
__lpdftype__
=
"
null
"
}
,
__tostring
=
tostring_z
,
__call
=
value_z
}
677
local
mt_t
=
{
__index
=
{
__lpdftype__
=
"
true
"
}
,
__tostring
=
tostring_t
,
__call
=
value_t
}
678
local
mt_f
=
{
__index
=
{
__lpdftype__
=
"
false
"
}
,
__tostring
=
tostring_f
,
__call
=
value_f
}
679
local
mt_r
=
{
__index
=
{
__lpdftype__
=
"
reference
"
}
,
__tostring
=
tostring_r
,
__call
=
value_r
}
680
local
mt_v
=
{
__index
=
{
__lpdftype__
=
"
verbose
"
}
,
__tostring
=
tostring_v
,
__call
=
value_v
}
681
local
mt_l
=
{
__index
=
{
__lpdftype__
=
"
literal
"
}
,
__tostring
=
tostring_l
,
__call
=
value_l
}
682 683
local
function
pdfstream
(
t
)
-- we need to add attributes
684
if
t
then
685
local
tt
=
type
(
t
)
686
if
tt
=
=
"
table
"
then
687
for
i
=
1
,
#
t
do
688
t
[
i
]
=
tostring
(
t
[
i
]
)
689
end
690
elseif
tt
=
=
"
string
"
then
691
t
=
{
t
}
692
else
693
t
=
{
tostring
(
t
)
}
694
end
695
end
696
return
setmetatable
(
t
or
{
}
,
mt_x
)
697
end
698 699
local
function
pdfdictionary
(
t
)
700
return
setmetatable
(
t
or
{
}
,
mt_d
)
701
end
702 703
local
function
pdfarray
(
t
)
704
if
type
(
t
)
=
=
"
string
"
then
705
return
setmetatable
(
{
t
}
,
mt_a
)
706
else
707
return
setmetatable
(
t
or
{
}
,
mt_a
)
708
end
709
end
710 711
local
function
pdfstring
(
str
,
default
)
712
return
setmetatable
(
{
str
or
default
or
"
"
}
,
mt_s
)
713
end
714 715
local
function
pdfdocstring
(
str
,
default
,
defaultchar
)
716
return
setmetatable
(
{
str
or
default
or
"
"
,
defaultchar
or
"
"
}
,
mt_p
)
717
end
718 719
local
function
pdfunicode
(
str
,
default
)
720
return
setmetatable
(
{
str
or
default
or
"
"
}
,
mt_u
)
-- could be a string
721
end
722 723
local
function
pdfliteral
(
str
,
hex
)
-- can also produce a hex <> instead of () literal
724
return
setmetatable
(
{
str
,
hex
}
,
mt_l
)
725
end
726 727
local
pdfnumber
,
pdfconstant
728 729
do
730 731
local
cache
=
{
}
-- can be weak
732 733
pdfnumber
=
function
(
n
,
default
)
-- 0-10
734
if
not
n
then
735
n
=
default
736
end
737
local
c
=
cache
[
n
]
738
if
not
c
then
739
c
=
setmetatable
(
{
n
}
,
mt_n
)
740
-- cache[n] = c -- too many numbers
741
end
742
return
c
743
end
744 745
for
i
=
-1
,
9
do
cache
[
i
]
=
pdfnumber
(
i
)
end
746 747
local
replacer
=
S
(
"
\0\t\n\r\f ()[]{}/%%#\\
"
)
/
{
748
[
"
\00
"
]
=
"
#00
"
,
749
[
"
\09
"
]
=
"
#09
"
,
750
[
"
\10
"
]
=
"
#0a
"
,
751
[
"
\12
"
]
=
"
#0c
"
,
752
[
"
\13
"
]
=
"
#0d
"
,
753
[
"
"
]
=
"
#20
"
,
754
[
"
#
"
]
=
"
#23
"
,
755
[
"
%
"
]
=
"
#25
"
,
756
[
"
(
"
]
=
"
#28
"
,
757
[
"
)
"
]
=
"
#29
"
,
758
[
"
/
"
]
=
"
#2f
"
,
759
[
"
[
"
]
=
"
#5b
"
,
760
[
"
\\
"
]
=
"
#5c
"
,
761
[
"
]
"
]
=
"
#5d
"
,
762
[
"
{
"
]
=
"
#7b
"
,
763
[
"
}
"
]
=
"
#7d
"
,
764
}
+
P
(
1
)
765 766
local
escaped
=
Cs
(
Cc
(
"
/
"
)
*
replacer
^
0
)
767 768
local
cache
=
table
.
setmetatableindex
(
function
(
t
,
k
)
769
local
v
=
setmetatable
(
{
lpegmatch
(
escaped
,
k
)
}
,
mt_c
)
770
t
[
k
]
=
v
771
return
v
772
end
)
773 774
pdfconstant
=
function
(
str
,
default
)
775
if
not
str
then
776
str
=
default
or
"
none
"
777
end
778
return
cache
[
str
]
779
end
780 781
local
escaped
=
Cs
(
replacer
^
0
)
782 783
function
lpdf
.
escaped
(
str
)
784
return
lpegmatch
(
escaped
,
str
)
or
str
785
end
786 787
end
788 789
local
pdfnull
,
pdfboolean
,
pdfreference
,
pdfverbose
790 791
do
792 793
local
p_null
=
{
}
setmetatable
(
p_null
,
mt_z
)
794
local
p_true
=
{
}
setmetatable
(
p_true
,
mt_t
)
795
local
p_false
=
{
}
setmetatable
(
p_false
,
mt_f
)
796 797
pdfnull
=
function
(
)
798
return
p_null
799
end
800 801
pdfboolean
=
function
(
b
,
default
)
802
if
type
(
b
)
=
=
"
boolean
"
then
803
return
b
and
p_true
or
p_false
804
else
805
return
default
and
p_true
or
p_false
806
end
807
end
808 809
-- print(pdfboolean(false),pdfboolean(false,false),pdfboolean(false,true))
810
-- print(pdfboolean(true),pdfboolean(true,false),pdfboolean(true,true))
811
-- print(pdfboolean(nil,true),pdfboolean(nil,false))
812 813
local
r_zero
=
setmetatable
(
{
0
}
,
mt_r
)
814 815
pdfreference
=
function
(
r
)
-- maybe make a weak table
816
if
r
and
r
~
=
0
then
817
return
setmetatable
(
{
r
}
,
mt_r
)
818
else
819
return
r_zero
820
end
821
end
822 823
local
v_zero
=
setmetatable
(
{
0
}
,
mt_v
)
824
local
v_empty
=
setmetatable
(
{
"
"
}
,
mt_v
)
825 826
pdfverbose
=
function
(
t
)
-- maybe check for type
827
if
t
=
=
0
then
828
return
v_zero
829
elseif
t
=
=
"
"
then
830
return
v_empty
831
else
832
return
setmetatable
(
{
t
}
,
mt_v
)
833
end
834
end
835 836
end
837 838
lpdf
.
stream
=
pdfstream
-- THIS WILL PROBABLY CHANGE
839
lpdf
.
dictionary
=
pdfdictionary
840
lpdf
.
array
=
pdfarray
841
lpdf
.
docstring
=
pdfdocstring
842
lpdf
.
string
=
pdfstring
843
lpdf
.
unicode
=
pdfunicode
844
lpdf
.
number
=
pdfnumber
845
lpdf
.
constant
=
pdfconstant
846
lpdf
.
null
=
pdfnull
847
lpdf
.
boolean
=
pdfboolean
848
lpdf
.
reference
=
pdfreference
849
lpdf
.
verbose
=
pdfverbose
850
lpdf
.
literal
=
pdfliteral
851 852
local
names
,
cache
=
{
}
,
{
}
853 854
function
lpdf
.
reserveobject
(
name
)
855
local
r
=
pdfreserveobject
(
)
-- we don't support "annot"
856
if
name
then
857
names
[
name
]
=
r
858
if
trace_objects
then
859
report_objects
(
"
reserving number %a under name %a
"
,
r
,
name
)
860
end
861
elseif
trace_objects
then
862
report_objects
(
"
reserving number %a
"
,
r
)
863
end
864
return
r
865
end
866 867
local
nofpages
=
0
868 869
local
texgetcount
=
tex
.
getcount
870 871
function
lpdf
.
pagereference
(
n
,
complete
)
-- true | false | nil | n [true,false]
872
if
nofpages
=
=
0
then
873
nofpages
=
structures
.
pages
.
nofpages
874
if
nofpages
=
=
0
then
875
nofpages
=
1
876
end
877
end
878
if
n
=
=
true
or
not
n
then
879
complete
=
n
880
n
=
texgetcount
(
"
realpageno
"
)
881
end
882
local
r
=
n
>
nofpages
and
pdfgetpagereference
(
nofpages
)
or
pdfgetpagereference
(
n
)
883
return
complete
and
pdfreference
(
r
)
or
r
884
end
885 886
function
lpdf
.
nofpages
(
)
887
return
structures
.
pages
.
nofpages
888
end
889 890
function
lpdf
.
obj
(
...
)
891
pdfdeferredobject
(
...
)
892
end
893 894
function
lpdf
.
immediateobj
(
...
)
895
pdfimmediateobject
(
...
)
896
end
897 898
function
lpdf
.
delayedobject
(
data
,
n
)
899
if
n
then
900
pdfdeferredobject
(
n
,
data
)
901
else
902
n
=
pdfdeferredobject
(
data
)
903
end
904
pdfreferenceobject
(
n
)
905
return
n
906
end
907 908
function
lpdf
.
flushobject
(
name
,
data
)
909
if
data
then
910
local
named
=
names
[
name
]
911
if
named
then
912
if
not
trace_objects
then
913
elseif
trace_details
then
914
report_objects
(
"
flushing data to reserved object with name %a, data: %S
"
,
name
,
data
)
915
else
916
report_objects
(
"
flushing data to reserved object with name %a
"
,
name
)
917
end
918
return
pdfimmediateobject
(
named
,
tostring
(
data
)
)
919
else
920
if
not
trace_objects
then
921
elseif
trace_details
then
922
report_objects
(
"
flushing data to reserved object with number %s, data: %S
"
,
name
,
data
)
923
else
924
report_objects
(
"
flushing data to reserved object with number %s
"
,
name
)
925
end
926
return
pdfimmediateobject
(
name
,
tostring
(
data
)
)
927
end
928
else
929
if
trace_objects
and
trace_details
then
930
report_objects
(
"
flushing data: %S
"
,
name
)
931
end
932
return
pdfimmediateobject
(
tostring
(
name
)
)
933
end
934
end
935 936
function
lpdf
.
flushstreamobject
(
data
,
dict
,
compressed
,
objnum
)
-- default compressed
937
if
trace_objects
then
938
report_objects
(
"
flushing stream object of %s bytes
"
,
#
data
)
939
end
940
local
dtype
=
type
(
dict
)
941
local
kind
=
compressed
=
=
"
raw
"
and
"
raw
"
or
"
stream
"
942
local
nolength
=
nil
943
if
compressed
=
=
"
raw
"
then
944
compressed
=
nil
945
nolength
=
true
946
-- data = string.formatters["<< %s >>stream\n%s\nendstream"](attr,data)
947
end
948
return
pdfdeferredobject
{
949
objnum
=
objnum
,
950
immediate
=
true
,
951
nolength
=
nolength
,
952
compresslevel
=
compressed
=
=
false
and
0
or
nil
,
953
type
=
"
stream
"
,
954
string
=
data
,
955
attr
=
(
dtype
=
=
"
string
"
and
dict
)
or
(
dtype
=
=
"
table
"
and
dict
(
)
)
or
nil
,
956
}
957
end
958 959
function
lpdf
.
flushstreamfileobject
(
filename
,
dict
,
compressed
,
objnum
)
-- default compressed
960
if
trace_objects
then
961
report_objects
(
"
flushing stream file object %a
"
,
filename
)
962
end
963
local
dtype
=
type
(
dict
)
964
return
pdfdeferredobject
{
965
objnum
=
objnum
,
966
immediate
=
true
,
967
compresslevel
=
compressed
=
=
false
and
0
or
nil
,
968
type
=
"
stream
"
,
969
file
=
filename
,
970
attr
=
(
dtype
=
=
"
string
"
and
dict
)
or
(
dtype
=
=
"
table
"
and
dict
(
)
)
or
nil
,
971
}
972
end
973 974
local
shareobjectcache
,
shareobjectreferencecache
=
{
}
,
{
}
975 976
function
lpdf
.
shareobject
(
content
)
977
if
content
=
=
nil
then
978
-- invalid object not created
979
else
980
content
=
tostring
(
content
)
981
local
o
=
shareobjectcache
[
content
]
982
if
not
o
then
983
o
=
pdfimmediateobject
(
content
)
984
shareobjectcache
[
content
]
=
o
985
end
986
return
o
987
end
988
end
989 990
function
lpdf
.
shareobjectreference
(
content
)
991
if
content
=
=
nil
then
992
-- invalid object not created
993
else
994
content
=
tostring
(
content
)
995
local
r
=
shareobjectreferencecache
[
content
]
996
if
not
r
then
997
local
o
=
shareobjectcache
[
content
]
998
if
not
o
then
999
o
=
pdfimmediateobject
(
content
)
1000
shareobjectcache
[
content
]
=
o
1001
end
1002
r
=
pdfreference
(
o
)
1003
shareobjectreferencecache
[
content
]
=
r
1004
end
1005
return
r
1006
end
1007
end
1008 1009
-- three priority levels, default=2
1010 1011
local
pagefinalizers
=
{
{
}
,
{
}
,
{
}
}
1012
local
documentfinalizers
=
{
{
}
,
{
}
,
{
}
}
1013 1014
local
pageresources
,
pageattributes
,
pagesattributes
1015 1016
local
function
resetpageproperties
(
)
1017
pageresources
=
pdfdictionary
(
)
1018
pageattributes
=
pdfdictionary
(
)
1019
pagesattributes
=
pdfdictionary
(
)
1020
end
1021 1022
function
lpdf
.
getpageproperties
(
)
1023
return
{
1024
pageresources
=
pageresources
,
1025
pageattributes
=
pageattributes
,
1026
pagesattributes
=
pagesattributes
,
1027
}
1028
end
1029 1030
resetpageproperties
(
)
1031 1032
local
function
setpageproperties
(
)
1033
pdfsetpageresources
(
pageresources
(
)
)
1034
pdfsetpageattributes
(
pageattributes
(
)
)
1035
pdfsetpagesattributes
(
pagesattributes
(
)
)
1036
end
1037 1038
local
function
addtopageresources
(
k
,
v
)
pageresources
[
k
]
=
v
end
1039
local
function
addtopageattributes
(
k
,
v
)
pageattributes
[
k
]
=
v
end
1040
local
function
addtopagesattributes
(
k
,
v
)
pagesattributes
[
k
]
=
v
end
1041 1042
lpdf
.
addtopageresources
=
addtopageresources
1043
lpdf
.
addtopageattributes
=
addtopageattributes
1044
lpdf
.
addtopagesattributes
=
addtopagesattributes
1045 1046
local
function
set
(
where
,
what
,
f
,
when
,
comment
)
1047
if
type
(
when
)
=
=
"
string
"
then
1048
when
,
comment
=
2
,
when
1049
elseif
not
when
then
1050
when
=
2
1051
end
1052
local
w
=
where
[
when
]
1053
w
[
#
w
+
1
]
=
{
f
,
comment
}
1054
if
trace_finalizers
then
1055
report_finalizing
(
"
%s set: [%s,%s]
"
,
what
,
when
,
#
w
)
1056
end
1057
end
1058 1059
local
function
run
(
where
,
what
)
1060
if
trace_finalizers
then
1061
report_finalizing
(
"
start backend, category %a, n %a
"
,
what
,
#
where
)
1062
end
1063
for
i
=
1
,
#
where
do
1064
local
w
=
where
[
i
]
1065
for
j
=
1
,
#
w
do
1066
local
wj
=
w
[
j
]
1067
if
trace_finalizers
then
1068
report_finalizing
(
"
%s finalizer: [%s,%s] %s
"
,
what
,
i
,
j
,
wj
[
2
]
or
"
"
)
1069
end
1070
wj
[
1
]
(
)
1071
end
1072
end
1073
if
trace_finalizers
then
1074
report_finalizing
(
"
stop finalizing
"
)
1075
end
1076
end
1077 1078
local
function
registerpagefinalizer
(
f
,
when
,
comment
)
1079
set
(
pagefinalizers
,
"
page
"
,
f
,
when
,
comment
)
1080
end
1081 1082
local
function
registerdocumentfinalizer
(
f
,
when
,
comment
)
1083
set
(
documentfinalizers
,
"
document
"
,
f
,
when
,
comment
)
1084
end
1085 1086
lpdf
.
registerpagefinalizer
=
registerpagefinalizer
1087
lpdf
.
registerdocumentfinalizer
=
registerdocumentfinalizer
1088 1089
function
lpdf
.
finalizepage
(
shipout
)
1090
if
shipout
and
not
environment
.
initex
then
1091
-- resetpageproperties() -- maybe better before
1092
run
(
pagefinalizers
,
"
page
"
)
1093
setpageproperties
(
)
1094
resetpageproperties
(
)
-- maybe better before
1095
end
1096
end
1097 1098
function
lpdf
.
finalizedocument
(
)
1099
if
not
environment
.
initex
then
1100
run
(
documentfinalizers
,
"
document
"
)
1101
function
lpdf
.
finalizedocument
(
)
1102
-- report_finalizing("serious error: the document is finalized multiple times")
1103
function
lpdf
.
finalizedocument
(
)
end
1104
end
1105
end
1106
end
1107 1108
callbacks
.
register
(
"
finish_pdfpage
"
,
lpdf
.
finalizepage
)
1109
callbacks
.
register
(
"
finish_pdffile
"
,
lpdf
.
finalizedocument
)
1110 1111
do
1112 1113
local
pdfsetinfo
,
pdfsetcatalog
,
pdfsettrailerid
-- pdfsetnames pdfsettrailer
1114 1115
updaters
.
register
(
"
backend.update.lpdf
"
,
function
(
)
1116
pdfsetinfo
=
pdf
.
setinfo
1117
pdfsetcatalog
=
pdf
.
setcatalog
1118
pdfsettrailerid
=
pdf
.
settrailerid
1119
end
)
1120 1121
function
lpdf
.
settrailerid
(
id
)
1122
pdfsettrailerid
(
id
)
1123
end
1124 1125
-- some minimal tracing, handy for checking the order
1126 1127
local
function
trace_set
(
what
,
key
)
1128
if
trace_resources
then
1129
report_finalizing
(
"
setting key %a in %a
"
,
key
,
what
)
1130
end
1131
end
1132 1133
local
function
trace_flush
(
what
)
1134
if
trace_resources
then
1135
report_finalizing
(
"
flushing %a
"
,
what
)
1136
end
1137
end
1138 1139
lpdf
.
protectresources
=
true
1140 1141
local
catalog
=
pdfdictionary
{
Type
=
pdfconstant
(
"
Catalog
"
)
}
-- nicer, but when we assign we nil the Type
1142
local
info
=
pdfdictionary
{
Type
=
pdfconstant
(
"
Info
"
)
}
-- nicer, but when we assign we nil the Type
1143
----- names = pdfdictionary { Type = pdfconstant("Names") } -- nicer, but when we assign we nil the Type
1144 1145
local
function
checkcatalog
(
)
1146
if
not
environment
.
initex
then
1147
trace_flush
(
"
catalog
"
)
1148
return
true
1149
end
1150
end
1151 1152
local
function
checkinfo
(
)
1153
if
not
environment
.
initex
then
1154
trace_flush
(
"
info
"
)
1155
if
lpdf
.
majorversion
(
)
>
1
then
1156
for
k
,
v
in
next
,
info
do
1157
if
k
=
=
"
CreationDate
"
or
k
=
=
"
ModDate
"
then
1158
-- mandate >= 2.0
1159
else
1160
info
[
k
]
=
nil
1161
end
1162
end
1163
end
1164
return
true
1165
end
1166
end
1167 1168
local
function
flushcatalog
(
)
1169
if
checkcatalog
(
)
then
1170
catalog
.
Type
=
nil
1171
pdfsetcatalog
(
catalog
(
)
)
1172
end
1173
end
1174 1175
local
function
flushinfo
(
)
1176
if
checkinfo
(
)
then
1177
info
.
Type
=
nil
1178
pdfsetinfo
(
info
(
)
)
1179
end
1180
end
1181 1182
function
lpdf
.
getcatalog
(
)
1183
if
checkcatalog
(
)
then
1184
catalog
.
Type
=
pdfconstant
(
"
Catalog
"
)
1185
return
pdfreference
(
pdfimmediateobject
(
tostring
(
catalog
)
)
)
1186
end
1187
end
1188 1189
function
lpdf
.
getinfo
(
)
1190
if
checkinfo
(
)
then
1191
return
pdfreference
(
pdfimmediateobject
(
tostring
(
info
)
)
)
1192
end
1193
end
1194 1195
function
lpdf
.
addtocatalog
(
k
,
v
)
1196
if
not
(
lpdf
.
protectresources
and
catalog
[
k
]
)
then
1197
trace_set
(
"
catalog
"
,
k
)
1198
catalog
[
k
]
=
v
1199
end
1200
end
1201 1202
function
lpdf
.
addtoinfo
(
k
,
v
)
1203
if
not
(
lpdf
.
protectresources
and
info
[
k
]
)
then
1204
trace_set
(
"
info
"
,
k
)
1205
info
[
k
]
=
v
1206
end
1207
end
1208 1209
-- local function lpdf.addtonames(k,v)
1210
-- if not (lpdf.protectresources and names[k]) then
1211
-- trace_set("names",k)
1212
-- names[k] = v
1213
-- end
1214
-- end
1215 1216
local
names
=
pdfdictionary
{
1217
-- Type = pdfconstant("Names")
1218
}
1219 1220
local
function
flushnames
(
)
1221
if
next
(
names
)
and
not
environment
.
initex
then
1222
names
.
Type
=
pdfconstant
(
"
Names
"
)
1223
trace_flush
(
"
names
"
)
1224
lpdf
.
addtocatalog
(
"
Names
"
,
pdfreference
(
pdfimmediateobject
(
tostring
(
names
)
)
)
)
1225
end
1226
end
1227 1228
function
lpdf
.
addtonames
(
k
,
v
)
1229
if
not
(
lpdf
.
protectresources
and
names
[
k
]
)
then
1230
trace_set
(
"
names
"
,
k
)
1231
names
[
k
]
=
v
1232
end
1233
end
1234 1235
local
r_extgstates
,
r_colorspaces
,
r_patterns
,
r_shades
1236
local
d_extgstates
,
d_colorspaces
,
d_patterns
,
d_shades
1237
local
p_extgstates
,
p_colorspaces
,
p_patterns
,
p_shades
1238 1239
local
function
checkextgstates
(
)
if
d_extgstates
then
addtopageresources
(
"
ExtGState
"
,
p_extgstates
)
end
end
1240
local
function
checkcolorspaces
(
)
if
d_colorspaces
then
addtopageresources
(
"
ColorSpace
"
,
p_colorspaces
)
end
end
1241
local
function
checkpatterns
(
)
if
d_patterns
then
addtopageresources
(
"
Pattern
"
,
p_patterns
)
end
end
1242
local
function
checkshades
(
)
if
d_shades
then
addtopageresources
(
"
Shading
"
,
p_shades
)
end
end
1243 1244
local
function
flushextgstates
(
)
if
d_extgstates
then
trace_flush
(
"
extgstates
"
)
pdfimmediateobject
(
r_extgstates
,
tostring
(
d_extgstates
)
)
end
end
1245
local
function
flushcolorspaces
(
)
if
d_colorspaces
then
trace_flush
(
"
colorspaces
"
)
pdfimmediateobject
(
r_colorspaces
,
tostring
(
d_colorspaces
)
)
end
end
1246
local
function
flushpatterns
(
)
if
d_patterns
then
trace_flush
(
"
patterns
"
)
pdfimmediateobject
(
r_patterns
,
tostring
(
d_patterns
)
)
end
end
1247
local
function
flushshades
(
)
if
d_shades
then
trace_flush
(
"
shades
"
)
pdfimmediateobject
(
r_shades
,
tostring
(
d_shades
)
)
end
end
1248 1249
-- patterns are special as they need resources to so we can get recursive references and in that case
1250
-- acrobat doesn't show anything (other viewers handle it well)
1251
--
1252
-- todo: share them
1253
-- todo: force when not yet set
1254 1255
local
f_font
=
formatters
[
"
%s%d
"
]
1256 1257
function
lpdf
.
collectedresources
(
options
)
1258
local
ExtGState
=
d_extgstates
and
next
(
d_extgstates
)
and
p_extgstates
1259
local
ColorSpace
=
d_colorspaces
and
next
(
d_colorspaces
)
and
p_colorspaces
1260
local
Pattern
=
d_patterns
and
next
(
d_patterns
)
and
p_patterns
1261
local
Shading
=
d_shades
and
next
(
d_shades
)
and
p_shades
1262
local
Font
1263
if
options
and
options
.
patterns
=
=
false
then
1264
Pattern
=
nil
1265
end
1266
local
fonts
=
options
and
options
.
fonts
1267
if
fonts
and
next
(
fonts
)
then
1268
local
pdfgetfontobjnumber
=
lpdf
.
getfontobjnumber
1269
if
pdfgetfontobjnumber
then
1270
local
prefix
=
options
.
fontprefix
or
"
F
"
1271
Font
=
pdfdictionary
{
}
1272
for
k
,
v
in
sortedhash
(
fonts
)
do
1273
Font
[
f_font
(
prefix
,
v
)
]
=
pdfreference
(
pdfgetfontobjnumber
(
k
)
)
1274
end
1275
end
1276
end
1277
if
ExtGState
or
ColorSpace
or
Pattern
or
Shading
or
Font
then
1278
local
collected
=
pdfdictionary
{
1279
ExtGState
=
ExtGState
,
1280
ColorSpace
=
ColorSpace
,
1281
Pattern
=
Pattern
,
1282
Shading
=
Shading
,
1283
Font
=
Font
,
1284
}
1285
if
options
and
options
.
serialize
=
=
false
then
1286
return
collected
1287
else
1288
return
collected
(
)
1289
end
1290
elseif
options
and
options
.
notempty
then
1291
return
nil
1292
elseif
options
and
options
.
serialize
=
=
false
then
1293
return
pdfdictionary
{
}
1294
else
1295
return
"
"
1296
end
1297
end
1298 1299
function
lpdf
.
adddocumentextgstate
(
k
,
v
)
1300
if
not
d_extgstates
then
1301
r_extgstates
=
pdfreserveobject
(
)
1302
d_extgstates
=
pdfdictionary
(
)
1303
p_extgstates
=
pdfreference
(
r_extgstates
)
1304
end
1305
d_extgstates
[
k
]
=
v
1306
end
1307 1308
function
lpdf
.
adddocumentcolorspace
(
k
,
v
)
1309
if
not
d_colorspaces
then
1310
r_colorspaces
=
pdfreserveobject
(
)
1311
d_colorspaces
=
pdfdictionary
(
)
1312
p_colorspaces
=
pdfreference
(
r_colorspaces
)
1313
end
1314
d_colorspaces
[
k
]
=
v
1315
end
1316 1317
function
lpdf
.
adddocumentpattern
(
k
,
v
)
1318
if
not
d_patterns
then
1319
r_patterns
=
pdfreserveobject
(
)
1320
d_patterns
=
pdfdictionary
(
)
1321
p_patterns
=
pdfreference
(
r_patterns
)
1322
end
1323
d_patterns
[
k
]
=
v
1324
end
1325 1326
function
lpdf
.
adddocumentshade
(
k
,
v
)
1327
if
not
d_shades
then
1328
r_shades
=
pdfreserveobject
(
)
1329
d_shades
=
pdfdictionary
(
)
1330
p_shades
=
pdfreference
(
r_shades
)
1331
end
1332
d_shades
[
k
]
=
v
1333
end
1334 1335
registerdocumentfinalizer
(
flushextgstates
,
3
,
"
extended graphic states
"
)
1336
registerdocumentfinalizer
(
flushcolorspaces
,
3
,
"
color spaces
"
)
1337
registerdocumentfinalizer
(
flushpatterns
,
3
,
"
patterns
"
)
1338
registerdocumentfinalizer
(
flushshades
,
3
,
"
shades
"
)
1339 1340
registerdocumentfinalizer
(
flushnames
,
3
,
"
names
"
)
-- before catalog
1341
registerdocumentfinalizer
(
flushcatalog
,
3
,
"
catalog
"
)
1342
registerdocumentfinalizer
(
flushinfo
,
3
,
"
info
"
)
1343 1344
registerpagefinalizer
(
checkextgstates
,
3
,
"
extended graphic states
"
)
1345
registerpagefinalizer
(
checkcolorspaces
,
3
,
"
color spaces
"
)
1346
registerpagefinalizer
(
checkpatterns
,
3
,
"
patterns
"
)
1347
registerpagefinalizer
(
checkshades
,
3
,
"
shades
"
)
1348 1349
end
1350 1351
-- in strc-bkm: lpdf.registerdocumentfinalizer(function() structures.bookmarks.place() end,1)
1352 1353
function
lpdf
.
rotationcm
(
a
)
1354
local
s
=
sind
(
a
)
1355
local
c
=
cosd
(
a
)
1356
return
format
(
"
%.6F %.6F %.6F %.6F 0 0 cm
"
,
c
,
s
,
-
s
,
c
)
1357
end
1358 1359
-- ! -> universaltime
1360 1361
do
1362 1363
-- It's a bit of a historical mess here.
1364 1365
local
metadata
=
nil
1366
local
timestamp
=
backends
.
timestamp
(
)
1367 1368
function
lpdf
.
getmetadata
(
)
1369
if
not
metadata
then
1370
local
contextversion
=
environment
.
version
1371
local
luatexversion
=
format
(
"
%1.2f
"
,
LUATEXVERSION
)
1372
local
luatexfunctionality
=
tostring
(
LUATEXFUNCTIONALITY
)
1373
metadata
=
{
1374
producer
=
format
(
"
LuaTeX-%s
"
,
luatexversion
)
,
1375
creator
=
format
(
"
LuaTeX %s %s + ConTeXt MkIV %s
"
,
luatexversion
,
luatexfunctionality
,
contextversion
)
,
1376
luatexversion
=
luatexversion
,
1377
contextversion
=
contextversion
,
1378
luatexfunctionality
=
luatexfunctionality
,
1379
luaversion
=
tostring
(
LUAVERSION
)
,
1380
platform
=
os
.
platform
,
1381
time
=
timestamp
,
1382
}
1383
end
1384
return
metadata
1385
end
1386 1387
function
lpdf
.
settime
(
n
)
1388
if
n
then
1389
n
=
converters
.
totime
(
n
)
1390
if
n
then
1391
converters
.
settime
(
n
)
1392
timestamp
=
backends
.
timestamp
(
)
1393
end
1394
end
1395
if
metadata
then
1396
metadata
.
time
=
timestamp
1397
end
1398
return
timestamp
1399
end
1400 1401
lpdf
.
settime
(
tonumber
(
resolvers
.
variable
(
"
start_time
"
)
)
or
tonumber
(
resolvers
.
variable
(
"
SOURCE_DATE_EPOCH
"
)
)
)
-- bah
1402 1403
function
lpdf
.
pdftimestamp
(
str
)
1404
local
t
=
type
(
str
)
1405
if
t
=
=
"
string
"
then
1406
local
Y
,
M
,
D
,
h
,
m
,
s
,
Zs
,
Zh
,
Zm
=
match
(
str
,
"
^(%d%d%d%d)%-(%d%d)%-(%d%d)T(%d%d):(%d%d):(%d%d)([%+%-])(%d%d):(%d%d)$
"
)
1407
return
Y
and
format
(
"
D:%s%s%s%s%s%s%s%s'%s'
"
,
Y
,
M
,
D
,
h
,
m
,
s
,
Zs
,
Zh
,
Zm
)
1408
else
1409
return
osdate
(
"
D:%Y%m%d%H%M%S
"
,
t
=
=
"
number
"
and
str
or
ostime
(
)
)
-- maybe "!D..." : universal time
1410
end
1411
end
1412 1413
function
lpdf
.
id
(
date
)
1414
local
banner
=
environment
.
jobname
or
tex
.
jobname
or
"
unknown
"
1415
if
not
date
then
1416
return
banner
1417
else
1418
return
format
(
"
%s | %s
"
,
banner
,
timestamp
)
1419
end
1420
end
1421 1422
end
1423 1424
-- return nil is nicer in test prints
1425 1426
function
lpdf
.
checkedkey
(
t
,
key
,
variant
)
1427
local
pn
=
t
and
t
[
key
]
1428
if
pn
~
=
nil
then
1429
local
tn
=
type
(
pn
)
1430
if
tn
=
=
variant
then
1431
if
variant
=
=
"
string
"
then
1432
if
pn
~
=
"
"
then
1433
return
pn
1434
end
1435
elseif
variant
=
=
"
table
"
then
1436
if
next
(
pn
)
then
1437
return
pn
1438
end
1439
else
1440
return
pn
1441
end
1442
elseif
tn
=
=
"
string
"
then
1443
if
variant
=
=
"
number
"
then
1444
return
tonumber
(
pn
)
1445
elseif
variant
=
=
"
boolean
"
then
1446
return
isboolean
(
pn
,
nil
,
true
)
1447
end
1448
end
1449
end
1450
-- return nil
1451
end
1452 1453
function
lpdf
.
checkedvalue
(
value
,
variant
)
-- code not shared
1454
if
value
~
=
nil
then
1455
local
tv
=
type
(
value
)
1456
if
tv
=
=
variant
then
1457
if
variant
=
=
"
string
"
then
1458
if
value
~
=
"
"
then
1459
return
value
1460
end
1461
elseif
variant
=
=
"
table
"
then
1462
if
next
(
value
)
then
1463
return
value
1464
end
1465
else
1466
return
value
1467
end
1468
elseif
tv
=
=
"
string
"
then
1469
if
variant
=
=
"
number
"
then
1470
return
tonumber
(
value
)
1471
elseif
variant
=
=
"
boolean
"
then
1472
return
isboolean
(
value
,
nil
,
true
)
1473
end
1474
end
1475
end
1476
end
1477 1478
function
lpdf
.
limited
(
n
,
min
,
max
,
default
)
1479
if
not
n
then
1480
return
default
1481
else
1482
n
=
tonumber
(
n
)
1483
if
not
n
then
1484
return
default
1485
elseif
n
>
max
then
1486
return
max
1487
elseif
n
<
min
then
1488
return
min
1489
else
1490
return
n
1491
end
1492
end
1493
end
1494 1495
-- The next variant of ActualText is what Taco and I could come up with
1496
-- eventually. As of September 2013 Acrobat copies okay, Sumatra copies a
1497
-- question mark, pdftotext injects an extra space and Okular adds a
1498
-- newline plus space.
1499 1500
-- return formatters["BT /Span << /ActualText (CONTEXT) >> BDC [<feff>] TJ % t EMC ET"](code)
1501 1502
do
1503 1504
local
f_actual_text_p
=
formatters
[
"
BT /Span << /ActualText <feff%s> >> BDC %s EMC ET
"
]
1505
local
f_actual_text_b
=
formatters
[
"
BT /Span << /ActualText <feff%s> >> BDC
"
]
1506
local
s_actual_text_e
=
"
EMC ET
"
1507
local
f_actual_text_b_not
=
formatters
[
"
/Span << /ActualText <feff%s> >> BDC
"
]
1508
local
s_actual_text_e_not
=
"
EMC
"
1509
local
f_actual_text
=
formatters
[
"
/Span <</ActualText %s >> BDC
"
]
1510 1511
local
context
=
context
1512
local
pdfdirect
=
nodes
.
pool
.
directliteral
-- we can use nuts.write deep down
1513
local
tounicode
=
fonts
.
mappings
.
tounicode
1514 1515
function
codeinjections
.
unicodetoactualtext
(
unicode
,
pdfcode
)
1516
return
f_actual_text_p
(
type
(
unicode
)
=
=
"
string
"
and
unicode
or
tounicode
(
unicode
)
,
pdfcode
)
1517
end
1518 1519
function
codeinjections
.
startunicodetoactualtext
(
unicode
)
1520
return
f_actual_text_b
(
type
(
unicode
)
=
=
"
string
"
and
unicode
or
tounicode
(
unicode
)
)
1521
end
1522 1523
function
codeinjections
.
stopunicodetoactualtext
(
)
1524
return
s_actual_text_e
1525
end
1526 1527
function
codeinjections
.
startunicodetoactualtextdirect
(
unicode
)
1528
return
f_actual_text_b_not
(
type
(
unicode
)
=
=
"
string
"
and
unicode
or
tounicode
(
unicode
)
)
1529
end
1530 1531
function
codeinjections
.
stopunicodetoactualtextdirect
(
)
1532
return
s_actual_text_e_not
1533
end
1534 1535
implement
{
1536
name
=
"
startactualtext
"
,
1537
arguments
=
"
string
"
,
1538
actions
=
function
(
str
)
1539
context
(
pdfdirect
(
f_actual_text
(
tosixteen
(
str
)
)
)
)
1540
end
1541
}
1542 1543
implement
{
1544
name
=
"
stopactualtext
"
,
1545
actions
=
function
(
)
1546
context
(
pdfdirect
(
"
EMC
"
)
)
1547
end
1548
}
1549 1550
end
1551 1552
-- interface
1553 1554
implement
{
name
=
"
lpdf_collectedresources
"
,
actions
=
{
lpdf
.
collectedresources
,
context
}
}
1555
implement
{
name
=
"
lpdf_addtocatalog
"
,
arguments
=
"
2 strings
"
,
actions
=
lpdf
.
addtocatalog
}
1556
implement
{
name
=
"
lpdf_addtoinfo
"
,
arguments
=
"
2 strings
"
,
actions
=
function
(
a
,
b
,
c
)
lpdf
.
addtoinfo
(
a
,
b
,
c
)
end
}
-- gets adapted
1557
implement
{
name
=
"
lpdf_addtonames
"
,
arguments
=
"
2 strings
"
,
actions
=
lpdf
.
addtonames
}
1558
implement
{
name
=
"
lpdf_addtopageattributes
"
,
arguments
=
"
2 strings
"
,
actions
=
lpdf
.
addtopageattributes
}
1559
implement
{
name
=
"
lpdf_addtopagesattributes
"
,
arguments
=
"
2 strings
"
,
actions
=
lpdf
.
addtopagesattributes
}
1560
implement
{
name
=
"
lpdf_addtopageresources
"
,
arguments
=
"
2 strings
"
,
actions
=
lpdf
.
addtopageresources
}
1561
implement
{
name
=
"
lpdf_adddocumentextgstate
"
,
arguments
=
"
2 strings
"
,
actions
=
function
(
a
,
b
)
lpdf
.
adddocumentextgstate
(
a
,
pdfverbose
(
b
)
)
end
}
1562
implement
{
name
=
"
lpdf_adddocumentcolorspace
"
,
arguments
=
"
2 strings
"
,
actions
=
function
(
a
,
b
)
lpdf
.
adddocumentcolorspace
(
a
,
pdfverbose
(
b
)
)
end
}
1563
implement
{
name
=
"
lpdf_adddocumentpattern
"
,
arguments
=
"
2 strings
"
,
actions
=
function
(
a
,
b
)
lpdf
.
adddocumentpattern
(
a
,
pdfverbose
(
b
)
)
end
}
1564
implement
{
name
=
"
lpdf_adddocumentshade
"
,
arguments
=
"
2 strings
"
,
actions
=
function
(
a
,
b
)
lpdf
.
adddocumentshade
(
a
,
pdfverbose
(
b
)
)
end
}
1565 1566
-- more helpers: copy from lepd to lpdf
1567 1568
function
lpdf
.
copyconstant
(
v
)
1569
if
v
~
=
nil
then
1570
return
pdfconstant
(
v
)
1571
end
1572
end
1573 1574
function
lpdf
.
copyboolean
(
v
)
1575
if
v
~
=
nil
then
1576
return
pdfboolean
(
v
)
1577
end
1578
end
1579 1580
function
lpdf
.
copyunicode
(
v
)
1581
if
v
then
1582
return
pdfunicode
(
v
)
1583
end
1584
end
1585 1586
function
lpdf
.
copyarray
(
a
)
1587
if
a
then
1588
local
t
=
pdfarray
(
)
1589
for
i
=
1
,
#
a
do
1590
t
[
i
]
=
a
(
i
)
1591
end
1592
return
t
1593
end
1594
end
1595 1596
function
lpdf
.
copydictionary
(
d
)
1597
if
d
then
1598
local
t
=
pdfdictionary
(
)
1599
for
k
,
v
in
next
,
d
do
1600
t
[
k
]
=
d
(
k
)
1601
end
1602
return
t
1603
end
1604
end
1605 1606
function
lpdf
.
copynumber
(
v
)
1607
return
v
1608
end
1609 1610
function
lpdf
.
copyinteger
(
v
)
1611
return
v
-- maybe checking or round ?
1612
end
1613 1614
function
lpdf
.
copyfloat
(
v
)
1615
return
v
1616
end
1617 1618
function
lpdf
.
copystring
(
v
)
1619
if
v
then
1620
return
pdfstring
(
v
)
1621
end
1622
end
1623 1624
do
1625 1626
local
pdfincludechar
,
pdfincludecharlist
,
pdfincludefont
1627
local
pdfgetfontname
,
pdfgetfontobjnum
1628
local
pdfsetmapfile
,
pdfsetmapline
1629 1630
updaters
.
register
(
"
backend.update.lpdf
"
,
function
(
)
1631
pdfincludechar
=
pdf
.
includechar
1632
pdfincludefont
=
pdf
.
includefont
1633
pdfincludecharlist
=
pdf
.
includecharlist
1634
pdfgetfontname
=
pdf
.
getfontname
1635
pdfgetfontobjnum
=
pdf
.
getfontobjnum
1636
pdfsetmapfile
=
pdf
.
mapfile
1637
pdfsetmapline
=
pdf
.
mapline
1638
end
)
1639 1640
function
lpdf
.
includechar
(
f
,
c
)
pdfincludechar
(
f
,
c
)
end
1641
function
lpdf
.
includefont
(
...
)
pdfincludefont
(
...
)
end
1642 1643
function
lpdf
.
includecharlist
(
f
,
c
)
pdfincludecharlist
(
f
,
c
)
end
-- can be disabled
1644 1645
function
lpdf
.
getfontname
(
id
)
return
pdfgetfontname
(
id
)
end
1646
function
lpdf
.
getfontobjnumber
(
id
)
return
pdfgetfontobjnum
(
id
)
end
1647 1648
function
lpdf
.
setmapfile
(
...
)
pdfsetmapfile
(
...
)
end
1649
function
lpdf
.
setmapline
(
...
)
pdfsetmapline
(
...
)
end
1650 1651
end
1652 1653
do
1654 1655
-- This is obsolete but old viewers might still use it as directive
1656
-- for what to send to a postscript printer.
1657 1658
local
a_procset
,
d_procset
1659 1660
function
lpdf
.
procset
(
dict
)
1661
if
not
a_procset
then
1662
a_procset
=
pdfarray
{
1663
pdfconstant
(
"
PDF
"
)
,
1664
pdfconstant
(
"
Text
"
)
,
1665
pdfconstant
(
"
ImageB
"
)
,
1666
pdfconstant
(
"
ImageC
"
)
,
1667
pdfconstant
(
"
ImageI
"
)
,
1668
}
1669
a_procset
=
pdfreference
(
pdfimmediateobject
(
tostring
(
a_procset
)
)
)
1670
end
1671
if
dict
then
1672
if
not
d_procset
then
1673
d_procset
=
pdfdictionary
{
1674
ProcSet
=
a_procset
1675
}
1676
d_procset
=
pdfreference
(
pdfimmediateobject
(
tostring
(
d_procset
)
)
)
1677
end
1678
return
d_procset
1679
else
1680
return
a_procset
1681
end
1682
end
1683 1684
end
1685 1686
-- a left-over
1687 1688
if
environment
.
arguments
.
nocompression
then
1689
lpdf
.
setcompression
(
0
,
0
,
true
)
1690
end
1691