lpdf-col.lmt /size: 25 Kb    last modification: 2021-10-28 13:51
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
lpdf-col
'
]
=
{
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
,
tostring
,
tonumber
=
type
,
next
,
tostring
,
tonumber
10
local
char
,
byte
,
format
,
gsub
,
rep
,
gmatch
=
string
.
char
,
string
.
byte
,
string
.
format
,
string
.
gsub
,
string
.
rep
,
string
.
gmatch
11
local
settings_to_array
,
settings_to_numbers
=
utilities
.
parsers
.
settings_to_array
,
utilities
.
parsers
.
settings_to_numbers
12
local
concat
=
table
.
concat
13
local
round
=
math
.
round
14
local
formatters
=
string
.
formatters
15 16
local
allocate
=
utilities
.
storage
.
allocate
17 18
local
pdfbackend
=
backends
.
registered
.
pdf
19
local
nodeinjections
=
pdfbackend
.
nodeinjections
20
local
codeinjections
=
pdfbackend
.
codeinjections
21
local
registrations
=
pdfbackend
.
registrations
22 23
local
nodes
=
nodes
24
local
nodepool
=
nodes
.
nuts
.
pool
25
local
register
=
nodepool
.
register
26
local
setstate
=
nodepool
.
setstate
27 28
local
lpdf
=
lpdf
29
local
pdfconstant
=
lpdf
.
constant
30
local
pdfdictionary
=
lpdf
.
dictionary
31
local
pdfarray
=
lpdf
.
array
32
local
pdfreference
=
lpdf
.
reference
33
local
pdfverbose
=
lpdf
.
verbose
34 35
local
pdfflushobject
=
lpdf
.
flushobject
36
local
pdfdelayedobject
=
lpdf
.
delayedobject
37
local
pdfflushstreamobject
=
lpdf
.
flushstreamobject
38
local
pdfshareobjectreference
=
lpdf
.
shareobjectreference
39 40
local
addtopageattributes
=
lpdf
.
addtopageattributes
41
local
adddocumentcolorspace
=
lpdf
.
adddocumentcolorspace
42
local
adddocumentextgstate
=
lpdf
.
adddocumentextgstate
43 44
local
colors
=
attributes
.
colors
45
local
registercolor
=
colors
.
register
46
local
colorsvalue
=
colors
.
value
47
local
forcedmodel
=
colors
.
forcedmodel
48
local
getpagecolormodel
=
colors
.
getpagecolormodel
49
local
colortoattributes
=
colors
.
toattributes
50 51
local
transparencies
=
attributes
.
transparencies
52
local
registertransparancy
=
transparencies
.
register
53
local
transparenciesvalue
=
transparencies
.
value
54
local
transparencytoattribute
=
transparencies
.
toattribute
55 56
local
unsetvalue
=
attributes
.
unsetvalue
57 58
local
setmetatableindex
=
table
.
setmetatableindex
59 60
local
c_transparency
=
pdfconstant
(
"
Transparency
"
)
61 62
local
f_gray
=
formatters
[
"
%.3N g %.3N G
"
]
63
local
f_rgb
=
formatters
[
"
%.3N %.3N %.3N rg %.3N %.3N %.3N RG
"
]
64
local
f_cmyk
=
formatters
[
"
%.3N %.3N %.3N %.3N k %.3N %.3N %.3N %.3N K
"
]
65
local
f_spot
=
formatters
[
"
/%s cs /%s CS %s SCN %s scn
"
]
66
local
f_tr
=
formatters
[
"
Tr%s
"
]
67
local
f_cm
=
formatters
[
"
q %.6N %.6N %.6N %.6N %.6N %.6N cm
"
]
68
local
f_effect
=
formatters
[
"
%s Tc %s w %s Tr
"
]
-- %.6N ?
69
local
f_tr_gs
=
formatters
[
"
/Tr%s gs
"
]
70
local
f_num_1
=
formatters
[
"
%.3N %.3N
"
]
71
local
f_num_2
=
formatters
[
"
%.3N %.3N
"
]
72
local
f_num_3
=
formatters
[
"
%.3N %.3N %.3N
"
]
73
local
f_num_4
=
formatters
[
"
%.3N %.3N %.3N %.3N
"
]
74 75
local
report_color
=
logs
.
reporter
(
"
colors
"
,
"
backend
"
)
76 77
-- page groups (might move to lpdf-ini.lua)
78 79
local
colorspaceconstants
=
allocate
{
-- v_none is ignored
80
gray
=
pdfconstant
(
"
DeviceGray
"
)
,
81
rgb
=
pdfconstant
(
"
DeviceRGB
"
)
,
82
cmyk
=
pdfconstant
(
"
DeviceCMYK
"
)
,
83
all
=
pdfconstant
(
"
DeviceRGB
"
)
,
-- brr
84
}
85 86
local
transparencygroups
=
{
}
87 88
lpdf
.
colorspaceconstants
=
colorspaceconstants
89
lpdf
.
transparencygroups
=
transparencygroups
90 91
setmetatableindex
(
transparencygroups
,
function
(
transparencygroups
,
colormodel
)
92
local
cs
=
colorspaceconstants
[
colormodel
]
93
if
cs
then
94
local
d
=
pdfdictionary
{
95
S
=
c_transparency
,
96
CS
=
cs
,
97
I
=
true
,
98
}
99
-- local g = pdfreference(pdfflushobject(tostring(d)))
100
local
g
=
pdfreference
(
pdfdelayedobject
(
tostring
(
d
)
)
)
101
transparencygroups
[
colormodel
]
=
g
102
return
g
103
else
104
transparencygroups
[
colormodel
]
=
false
105
return
false
106
end
107
end
)
108 109
local
function
addpagegroup
(
)
110
local
model
=
getpagecolormodel
(
)
111
if
model
then
112
local
g
=
transparencygroups
[
model
]
113
if
g
then
114
addtopageattributes
(
"
Group
"
,
g
)
115
end
116
end
117
end
118 119
lpdf
.
registerpagefinalizer
(
addpagegroup
,
3
,
"
pagegroup
"
)
120 121
-- injection code (needs a bit reordering)
122 123
-- color injection
124 125
function
nodeinjections
.
rgbcolor
(
r
,
g
,
b
)
126
return
register
(
setstate
(
f_rgb
(
r
,
g
,
b
,
r
,
g
,
b
)
)
)
127
end
128 129
function
nodeinjections
.
cmykcolor
(
c
,
m
,
y
,
k
)
130
return
register
(
setstate
(
f_cmyk
(
c
,
m
,
y
,
k
,
c
,
m
,
y
,
k
)
)
)
131
end
132 133
function
nodeinjections
.
graycolor
(
s
)
-- caching 0/1 does not pay off
134
return
register
(
setstate
(
f_gray
(
s
,
s
)
)
)
135
end
136 137
function
nodeinjections
.
spotcolor
(
n
,
f
,
d
,
p
)
138
if
type
(
p
)
=
=
"
string
"
then
139
p
=
gsub
(
p
,
"
,
"
,
"
"
)
-- brr misuse of spot
140
end
141
return
register
(
setstate
(
f_spot
(
n
,
n
,
p
,
p
)
)
)
142
end
143 144
function
nodeinjections
.
transparency
(
n
)
145
return
register
(
setstate
(
f_tr_gs
(
n
)
)
)
146
end
147 148
-- a bit weird but let's keep it here for a while
149 150
local
effects
=
{
151
normal
=
0
,
152
inner
=
0
,
153
outer
=
1
,
154
both
=
2
,
155
hidden
=
3
,
156
}
157 158
local
bp
=
number
.
dimenfactors
.
bp
159 160
function
nodeinjections
.
effect
(
effect
,
stretch
,
rulethickness
)
161
-- always, no zero test (removed)
162
rulethickness
=
bp
*
rulethickness
163
effect
=
effects
[
effect
]
or
effects
[
'
normal
'
]
164
return
register
(
setstate
(
f_effect
(
stretch
,
rulethickness
,
effect
)
)
)
-- watch order
165
end
166 167
-- spot- and indexcolors
168 169
local
pdf_separation
=
pdfconstant
(
"
Separation
"
)
170
local
pdf_indexed
=
pdfconstant
(
"
Indexed
"
)
171
local
pdf_device_n
=
pdfconstant
(
"
DeviceN
"
)
172
local
pdf_device_rgb
=
pdfconstant
(
"
DeviceRGB
"
)
173
local
pdf_device_cmyk
=
pdfconstant
(
"
DeviceCMYK
"
)
174
local
pdf_device_gray
=
pdfconstant
(
"
DeviceGray
"
)
175
local
pdf_extgstate
=
pdfconstant
(
"
ExtGState
"
)
176 177
local
pdf_rgb_range
=
pdfarray
{
0
,
1
,
0
,
1
,
0
,
1
}
178
local
pdf_cmyk_range
=
pdfarray
{
0
,
1
,
0
,
1
,
0
,
1
,
0
,
1
}
179
local
pdf_gray_range
=
pdfarray
{
0
,
1
}
180 181
local
f_rgb_function
=
formatters
[
"
dup %s mul exch dup %s mul exch %s mul
"
]
182
local
f_cmyk_function
=
formatters
[
"
dup %s mul exch dup %s mul exch dup %s mul exch %s mul
"
]
183
local
f_gray_function
=
formatters
[
"
%s mul
"
]
184 185
local
documentcolorspaces
=
pdfdictionary
(
)
186 187
local
spotcolorhash
=
{
}
-- not needed
188
local
spotcolornames
=
{
}
189
local
indexcolorhash
=
{
}
190
local
delayedindexcolors
=
{
}
191 192
function
registrations
.
spotcolorname
(
name
,
e
)
193
spotcolornames
[
name
]
=
e
or
name
194
end
195 196
function
registrations
.
getspotcolorreference
(
name
)
197
return
spotcolorhash
[
name
]
198
end
199 200
-- beware: xpdf/okular/evince cannot handle the spot->process shade
201 202
-- This should become delayed i.e. only flush when used; in that case we need
203
-- need to store the specification and then flush them when accesssomespotcolor
204
-- is called. At this moment we assume that splotcolors that get defined are
205
-- also used which keeps the overhad small anyway. Tricky for mp ...
206 207
local
processcolors
208 209
local
function
registersomespotcolor
(
name
,
noffractions
,
names
,
p
,
colorspace
,
range
,
funct
)
210
noffractions
=
tonumber
(
noffractions
)
or
1
-- to be checked
211
if
noffractions
=
=
0
then
212
-- can't happen
213
elseif
noffractions
=
=
1
then
214
local
dictionary
=
pdfdictionary
{
215
FunctionType
=
4
,
216
Domain
=
{
0
,
1
}
,
217
Range
=
range
,
218
}
219
local
calculations
=
pdfflushstreamobject
(
format
(
"
{ %s }
"
,
funct
)
,
dictionary
)
220
-- local calculations = pdfobject {
221
-- type = "stream",
222
-- immediate = true,
223
-- string = format("{ %s }",funct),
224
-- attr = dictionary(),
225
-- }
226
local
array
=
pdfarray
{
227
pdf_separation
,
228
pdfconstant
(
spotcolornames
[
name
]
or
name
)
,
229
colorspace
,
230
pdfreference
(
calculations
)
,
231
}
232
local
m
=
pdfflushobject
(
array
)
233
local
mr
=
pdfreference
(
m
)
234
spotcolorhash
[
name
]
=
m
235
documentcolorspaces
[
name
]
=
mr
236
adddocumentcolorspace
(
name
,
mr
)
237
else
238
local
cnames
=
pdfarray
(
)
239
local
domain
=
pdfarray
(
)
240
local
colorants
=
pdfdictionary
(
)
241
for
n
in
gmatch
(
names
,
"
[^,]+
"
)
do
242
local
name
=
spotcolornames
[
n
]
or
n
243
-- the cmyk names assume that they are indeed these colors
244
if
n
=
=
"
cyan
"
then
245
name
=
"
Cyan
"
246
elseif
n
=
=
"
magenta
"
then
247
name
=
"
Magenta
"
248
elseif
n
=
=
"
yellow
"
then
249
name
=
"
Yellow
"
250
elseif
n
=
=
"
black
"
then
251
name
=
"
Black
"
252
else
253
local
sn
=
spotcolorhash
[
name
]
or
spotcolorhash
[
n
]
254
if
not
sn
then
255
report_color
(
"
defining %a as colorant
"
,
name
)
256
colors
.
definespotcolor
(
"
"
,
name
,
"
p=1
"
,
true
)
257
sn
=
spotcolorhash
[
name
]
or
spotcolorhash
[
n
]
258
end
259
if
sn
then
260
colorants
[
name
]
=
pdfreference
(
sn
)
261
else
262
-- maybe some day generate colorants (spot colors for multi) automatically
263
report_color
(
"
unknown colorant %a, using black instead
"
,
name
or
n
)
264
name
=
"
Black
"
265
end
266
end
267
cnames
[
#
cnames
+
1
]
=
pdfconstant
(
name
)
268
domain
[
#
domain
+
1
]
=
0
269
domain
[
#
domain
+
1
]
=
1
270
end
271
if
not
processcolors
then
272
local
specification
=
pdfdictionary
{
273
ColorSpace
=
pdfconstant
(
"
DeviceCMYK
"
)
,
274
Components
=
pdfarray
{
275
pdfconstant
(
"
Cyan
"
)
,
276
pdfconstant
(
"
Magenta
"
)
,
277
pdfconstant
(
"
Yellow
"
)
,
278
pdfconstant
(
"
Black
"
)
279
}
280
}
281
processcolors
=
pdfreference
(
pdfflushobject
(
specification
)
)
282
end
283
local
dictionary
=
pdfdictionary
{
284
FunctionType
=
4
,
285
Domain
=
domain
,
286
Range
=
range
,
287
}
288
local
calculation
=
pdfflushstreamobject
(
format
(
"
{ %s %s }
"
,
rep
(
"
pop
"
,
noffractions
)
,
funct
)
,
dictionary
)
289
local
channels
=
pdfdictionary
{
290
Subtype
=
pdfconstant
(
"
NChannel
"
)
,
291
Colorants
=
colorants
,
292
Process
=
processcolors
,
293
}
294
local
array
=
pdfarray
{
295
pdf_device_n
,
296
cnames
,
297
colorspace
,
298
pdfreference
(
calculation
)
,
299
pdfshareobjectreference
(
tostring
(
channels
)
)
,
-- optional but needed for shades
300
}
301
local
m
=
pdfflushobject
(
array
)
302
local
mr
=
pdfreference
(
m
)
303
spotcolorhash
[
name
]
=
m
304
documentcolorspaces
[
name
]
=
mr
305
adddocumentcolorspace
(
name
,
mr
)
306
end
307
end
308 309
-- wrong name
310 311
local
function
registersomeindexcolor
(
name
,
noffractions
,
names
,
p
,
colorspace
,
range
,
funct
)
312
noffractions
=
tonumber
(
noffractions
)
or
1
-- to be checked
313
local
cnames
=
pdfarray
(
)
314
local
domain
=
pdfarray
(
)
315
local
names
=
settings_to_array
(
#
names
=
=
0
and
name
or
names
)
316
local
values
=
settings_to_numbers
(
p
)
317
names
[
#
names
+
1
]
=
"
None
"
318
values
[
#
values
+
1
]
=
1
319
-- check for #names == #values
320
for
i
=
1
,
#
names
do
321
local
name
=
names
[
i
]
322
local
spot
=
spotcolornames
[
name
]
323
cnames
[
#
cnames
+
1
]
=
pdfconstant
(
spot
~
=
"
"
and
spot
or
name
)
324
domain
[
#
domain
+
1
]
=
0
325
domain
[
#
domain
+
1
]
=
1
326
end
327
local
dictionary
=
pdfdictionary
{
328
FunctionType
=
4
,
329
Domain
=
domain
,
330
Range
=
range
,
331
}
332
local
n
=
pdfflushstreamobject
(
format
(
"
{ %s %s }
"
,
rep
(
"
exch pop
"
,
noffractions
)
,
funct
)
,
dictionary
)
-- exch pop
333
local
a
=
pdfarray
{
334
pdf_device_n
,
335
cnames
,
336
colorspace
,
337
pdfreference
(
n
)
,
338
}
339
local
vector
=
{
}
340
local
set
=
{
}
341
local
n
=
#
values
342
for
i
=
255
,
0
,
-1
do
343
for
j
=
1
,
n
do
344
set
[
j
]
=
format
(
"
%02X
"
,
round
(
values
[
j
]
*
i
)
)
345
end
346
vector
[
#
vector
+
1
]
=
concat
(
set
)
347
end
348
vector
=
pdfverbose
{
"
<
"
,
concat
(
vector
,
"
"
)
,
"
>
"
}
349
local
n
=
pdfflushobject
(
pdfarray
{
pdf_indexed
,
a
,
255
,
vector
}
)
350
adddocumentcolorspace
(
format
(
"
%s_indexed
"
,
name
)
,
pdfreference
(
n
)
)
351
return
n
352
end
353 354
-- actually, names (parent) is the hash
355 356
local
function
delayindexcolor
(
name
,
names
,
func
)
357
local
hash
=
(
names
~
=
"
"
and
names
)
or
name
358
delayedindexcolors
[
hash
]
=
func
359
end
360 361
local
function
indexcolorref
(
name
)
-- actually, names (parent) is the hash
362
local
parent
=
colors
.
spotcolorparent
(
name
)
363
local
data
=
indexcolorhash
[
name
]
364
if
data
=
=
nil
then
365
local
delayedindexcolor
=
delayedindexcolors
[
parent
]
366
if
type
(
delayedindexcolor
)
=
=
"
function
"
then
367
data
=
delayedindexcolor
(
)
368
delayedindexcolors
[
parent
]
=
true
369
end
370
indexcolorhash
[
parent
]
=
data
or
false
371
end
372
return
data
373
end
374 375
function
registrations
.
rgbspotcolor
(
name
,
noffractions
,
names
,
p
,
r
,
g
,
b
)
376
if
noffractions
=
=
1
then
377
registersomespotcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_rgb
,
pdf_rgb_range
,
f_rgb_function
(
r
,
g
,
b
)
)
378
else
379
registersomespotcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_rgb
,
pdf_rgb_range
,
f_num_3
(
r
,
g
,
b
)
)
380
end
381
delayindexcolor
(
name
,
names
,
function
(
)
382
return
registersomeindexcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_rgb
,
pdf_rgb_range
,
f_rgb_function
(
r
,
g
,
b
)
)
383
end
)
384
end
385 386
function
registrations
.
cmykspotcolor
(
name
,
noffractions
,
names
,
p
,
c
,
m
,
y
,
k
)
387
if
noffractions
=
=
1
then
388
registersomespotcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_cmyk
,
pdf_cmyk_range
,
f_cmyk_function
(
c
,
m
,
y
,
k
)
)
389
else
390
registersomespotcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_cmyk
,
pdf_cmyk_range
,
f_num_4
(
c
,
m
,
y
,
k
)
)
391
end
392
delayindexcolor
(
name
,
names
,
function
(
)
393
return
registersomeindexcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_cmyk
,
pdf_cmyk_range
,
f_cmyk_function
(
c
,
m
,
y
,
k
)
)
394
end
)
395
end
396 397
function
registrations
.
grayspotcolor
(
name
,
noffractions
,
names
,
p
,
s
)
398
if
noffractions
=
=
1
then
399
registersomespotcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_gray
,
pdf_gray_range
,
f_gray_function
(
s
)
)
400
else
401
registersomespotcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_gray
,
pdf_gray_range
,
f_num_1
(
s
)
)
402
end
403
delayindexcolor
(
name
,
names
,
function
(
)
404
return
registersomeindexcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_gray
,
pdf_gray_range
,
f_gray_function
(
s
)
)
405
end
)
406
end
407 408
function
registrations
.
rgbindexcolor
(
name
,
noffractions
,
names
,
p
,
r
,
g
,
b
)
409
registersomeindexcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_rgb
,
pdf_rgb_range
,
f_rgb_function
(
r
,
g
,
b
)
)
410
end
411 412
function
registrations
.
cmykindexcolor
(
name
,
noffractions
,
names
,
p
,
c
,
m
,
y
,
k
)
413
registersomeindexcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_cmyk
,
pdf_cmyk_range
,
f_cmyk_function
(
c
,
m
,
y
,
k
)
)
414
end
415 416
function
registrations
.
grayindexcolor
(
name
,
noffractions
,
names
,
p
,
s
)
417
registersomeindexcolor
(
name
,
noffractions
,
names
,
p
,
pdf_device_gray
,
pdf_gray_range
,
f_gray_function
(
s
)
)
418
end
419 420
function
codeinjections
.
setfigurecolorspace
(
data
,
figure
)
421
local
color
=
data
.
request
.
color
422
if
color
then
-- != v_default
423
local
ref
=
indexcolorref
(
color
)
424
if
ref
then
425
figure
.
colorspace
=
ref
426
data
.
used
.
color
=
color
427
data
.
used
.
colorref
=
ref
428
end
429
end
430
end
431 432
-- transparency
433 434
local
pdftransparencies
=
{
[
0
]
=
435
pdfconstant
(
"
Normal
"
)
,
436
pdfconstant
(
"
Normal
"
)
,
437
pdfconstant
(
"
Multiply
"
)
,
438
pdfconstant
(
"
Screen
"
)
,
439
pdfconstant
(
"
Overlay
"
)
,
440
pdfconstant
(
"
SoftLight
"
)
,
441
pdfconstant
(
"
HardLight
"
)
,
442
pdfconstant
(
"
ColorDodge
"
)
,
443
pdfconstant
(
"
ColorBurn
"
)
,
444
pdfconstant
(
"
Darken
"
)
,
445
pdfconstant
(
"
Lighten
"
)
,
446
pdfconstant
(
"
Difference
"
)
,
447
pdfconstant
(
"
Exclusion
"
)
,
448
pdfconstant
(
"
Hue
"
)
,
449
pdfconstant
(
"
Saturation
"
)
,
450
pdfconstant
(
"
Color
"
)
,
451
pdfconstant
(
"
Luminosity
"
)
,
452
pdfconstant
(
"
Compatible
"
)
,
-- obsolete; 'Normal' is used in this case
453
}
454 455
local
documenttransparencies
=
{
}
456
local
transparencyhash
=
{
}
-- share objects
457 458
local
done
,
signaled
=
false
,
false
459 460
function
registrations
.
transparency
(
n
,
a
,
t
)
461
if
not
done
then
462
local
d
=
pdfdictionary
{
463
Type
=
pdf_extgstate
,
464
ca
=
1
,
465
CA
=
1
,
466
BM
=
pdftransparencies
[
1
]
,
467
AIS
=
false
,
468
}
469
local
m
=
pdfflushobject
(
d
)
470
local
mr
=
pdfreference
(
m
)
471
transparencyhash
[
0
]
=
m
472
documenttransparencies
[
0
]
=
mr
473
adddocumentextgstate
(
"
Tr0
"
,
mr
)
474
done
=
true
475
end
476
if
n
>
0
and
not
transparencyhash
[
n
]
then
477
local
d
=
pdfdictionary
{
478
Type
=
pdf_extgstate
,
479
ca
=
tonumber
(
t
)
,
480
CA
=
tonumber
(
t
)
,
481
BM
=
pdftransparencies
[
tonumber
(
a
)
]
or
pdftransparencies
[
0
]
,
482
AIS
=
false
,
483
}
484
local
m
=
pdfflushobject
(
d
)
485
local
mr
=
pdfreference
(
m
)
486
transparencyhash
[
n
]
=
m
487
documenttransparencies
[
n
]
=
mr
488
adddocumentextgstate
(
f_tr
(
n
)
,
mr
)
489
end
490
end
491 492
statistics
.
register
(
"
page group warning
"
,
function
(
)
493
if
done
then
494
local
model
=
getpagecolormodel
(
)
495
if
model
and
not
transparencygroups
[
model
]
then
496
return
"
transparencies are used but no pagecolormodel is set
"
497
end
498
end
499
end
)
500 501
-- Literals needed to inject code in the mp stream, we cannot use attributes there
502
-- since literals may have qQ's, much may go away once we have mplib code in place.
503
--
504
-- This module assumes that some functions are defined in the colors namespace
505
-- which most likely will be loaded later.
506 507
local
function
lpdfcolor
(
model
,
ca
,
default
)
-- todo: use gray when no color
508
if
colors
.
supported
then
509
local
cv
=
colorsvalue
(
ca
)
510
if
cv
then
511
if
model
=
=
1
then
512
model
=
cv
[
1
]
513
end
514
model
=
forcedmodel
(
model
)
515
if
model
=
=
2
then
516
local
s
=
cv
[
2
]
517
return
f_gray
(
s
,
s
)
518
elseif
model
=
=
3
then
519
local
r
=
cv
[
3
]
520
local
g
=
cv
[
4
]
521
local
b
=
cv
[
5
]
522
return
f_rgb
(
r
,
g
,
b
,
r
,
g
,
b
)
523
elseif
model
=
=
4
then
524
local
c
=
cv
[
6
]
525
local
m
=
cv
[
7
]
526
local
y
=
cv
[
8
]
527
local
k
=
cv
[
9
]
528
return
f_cmyk
(
c
,
m
,
y
,
k
,
c
,
m
,
y
,
k
)
529
else
530
local
n
=
cv
[
10
]
531
local
f
=
cv
[
11
]
532
local
d
=
cv
[
12
]
533
local
p
=
cv
[
13
]
534
if
type
(
p
)
=
=
"
string
"
then
535
p
=
gsub
(
p
,
"
,
"
,
"
"
)
-- brr misuse of spot
536
end
537
return
f_spot
(
n
,
n
,
p
,
p
)
538
end
539
else
540
return
f_gray
(
default
or
0
,
default
or
0
)
541
end
542
else
543
return
"
"
544
end
545
end
546 547
lpdf
.
color
=
lpdfcolor
548 549
interfaces
.
implement
{
550
name
=
"
pdfcolor
"
,
551
public
=
true
,
552
untraced
=
true
,
553
actions
=
{
lpdfcolor
,
context
}
,
554
arguments
=
"
integer
"
555
}
556 557
function
lpdf
.
colorspec
(
model
,
ca
,
default
)
558
if
ca
and
ca
>
0
then
559
local
cv
=
colors
.
value
(
ca
)
560
if
cv
then
561
if
model
=
=
1
then
562
model
=
cv
[
1
]
563
end
564
if
model
=
=
2
then
565
return
pdfarray
{
cv
[
2
]
}
566
elseif
model
=
=
3
then
567
return
pdfarray
{
cv
[
3
]
,
cv
[
4
]
,
cv
[
5
]
}
568
elseif
model
=
=
4
then
569
return
pdfarray
{
cv
[
6
]
,
cv
[
7
]
,
cv
[
8
]
,
cv
[
9
]
}
570
elseif
model
=
=
5
then
571
return
pdfarray
{
cv
[
13
]
}
572
end
573
end
574
end
575
if
default
then
576
return
default
577
end
578
end
579 580
function
lpdf
.
pdfcolor
(
attribute
)
-- bonus, for pgf and friends
581
return
lpdfcolor
(
1
,
attribute
)
582
end
583 584
local
function
lpdftransparency
(
ct
,
default
)
-- kind of overlaps with transparencycode
585
-- beware, we need this hack because normally transparencies are not
586
-- yet registered and therefore the number is not not known ... we
587
-- might use the attribute number itself in the future
588
if
transparencies
.
supported
then
589
local
ct
=
transparenciesvalue
(
ct
)
590
if
ct
then
591
return
f_tr_gs
(
registertransparancy
(
nil
,
ct
[
1
]
,
ct
[
2
]
,
true
)
)
592
else
593
return
f_tr_gs
(
0
)
594
end
595
else
596
return
"
"
597
end
598
end
599 600
lpdf
.
transparency
=
lpdftransparency
601 602
function
lpdf
.
colorvalue
(
model
,
ca
,
default
)
603
local
cv
=
colorsvalue
(
ca
)
604
if
cv
then
605
if
model
=
=
1
then
606
model
=
cv
[
1
]
607
end
608
model
=
forcedmodel
(
model
)
609
if
model
=
=
2
then
610
return
f_num_1
(
cv
[
2
]
)
611
elseif
model
=
=
3
then
612
return
f_num_3
(
cv
[
3
]
,
cv
[
4
]
,
cv
[
5
]
)
613
elseif
model
=
=
4
then
614
return
f_num_4
(
cv
[
6
]
,
cv
[
7
]
,
cv
[
8
]
,
cv
[
9
]
)
615
else
616
return
f_num_1
(
cv
[
13
]
)
617
end
618
else
619
return
f_num_1
(
default
or
0
)
620
end
621
end
622 623
function
lpdf
.
colorvalues
(
model
,
ca
,
default
)
624
local
cv
=
colorsvalue
(
ca
)
625
if
cv
then
626
if
model
=
=
1
then
627
model
=
cv
[
1
]
628
end
629
model
=
forcedmodel
(
model
)
630
if
model
=
=
2
then
631
return
cv
[
2
]
632
elseif
model
=
=
3
then
633
return
cv
[
3
]
,
cv
[
4
]
,
cv
[
5
]
634
elseif
model
=
=
4
then
635
return
cv
[
6
]
,
cv
[
7
]
,
cv
[
8
]
,
cv
[
9
]
636
elseif
model
=
=
5
then
637
return
cv
[
13
]
638
end
639
else
640
return
default
or
0
641
end
642
end
643 644
function
lpdf
.
transparencyvalue
(
ta
,
default
)
645
local
tv
=
transparenciesvalue
(
ta
)
646
if
tv
then
647
return
tv
[
2
]
648
else
649
return
default
or
1
650
end
651
end
652 653
function
lpdf
.
colorspace
(
model
,
ca
)
654
local
cv
=
colorsvalue
(
ca
)
655
if
cv
then
656
if
model
=
=
1
then
657
model
=
cv
[
1
]
658
end
659
model
=
forcedmodel
(
model
)
660
if
model
=
=
2
then
661
return
"
DeviceGray
"
662
elseif
model
=
=
3
then
663
return
"
DeviceRGB
"
664
elseif
model
=
=
4
then
665
return
"
DeviceCMYK
"
666
end
667
end
668
return
"
DeviceGRAY
"
669
end
670 671
-- by registering we getconversion for free (ok, at the cost of overhead)
672 673
local
intransparency
=
false
674 675
function
lpdf
.
rgbcode
(
model
,
r
,
g
,
b
)
676
if
colors
.
supported
then
677
return
lpdfcolor
(
model
,
registercolor
(
nil
,
'
rgb
'
,
r
,
g
,
b
)
)
678
else
679
return
"
"
680
end
681
end
682 683
function
lpdf
.
cmykcode
(
model
,
c
,
m
,
y
,
k
)
684
if
colors
.
supported
then
685
return
lpdfcolor
(
model
,
registercolor
(
nil
,
'
cmyk
'
,
c
,
m
,
y
,
k
)
)
686
else
687
return
"
"
688
end
689
end
690 691
function
lpdf
.
graycode
(
model
,
s
)
692
if
colors
.
supported
then
693
return
lpdfcolor
(
model
,
registercolor
(
nil
,
'
gray
'
,
s
)
)
694
else
695
return
"
"
696
end
697
end
698 699
function
lpdf
.
spotcode
(
model
,
n
,
f
,
d
,
p
)
700
if
colors
.
supported
then
701
return
lpdfcolor
(
model
,
registercolor
(
nil
,
'
spot
'
,
n
,
f
,
d
,
p
)
)
-- incorrect
702
else
703
return
"
"
704
end
705
end
706 707
function
lpdf
.
transparencycode
(
a
,
t
)
708
if
transparencies
.
supported
then
709
intransparency
=
true
710
return
f_tr_gs
(
registertransparancy
(
nil
,
a
,
t
,
true
)
)
-- true forces resource
711
else
712
return
"
"
713
end
714
end
715 716
function
lpdf
.
finishtransparencycode
(
)
717
if
transparencies
.
supported
and
intransparency
then
718
intransparency
=
false
719
return
f_tr_gs
(
0
)
-- we happen to know this -)
720
else
721
return
"
"
722
end
723
end
724 725
do
726 727
local
lpdfprint
=
lpdf
.
print
728 729
local
c_cache
=
setmetatableindex
(
function
(
t
,
m
)
730
-- We inherit the outer transparency.
731
local
v
=
setmetatableindex
(
function
(
t
,
c
)
732
local
p
=
"
q
"
.
.
lpdfcolor
(
m
,
c
)
733
t
[
c
]
=
p
734
return
p
735
end
)
736
t
[
m
]
=
v
737
return
v
738
end
)
739 740
local
t_cache
=
setmetatableindex
(
function
(
t
,
transparency
)
741
local
p
=
lpdftransparency
(
transparency
)
742
local
v
=
setmetatableindex
(
function
(
t
,
colormodel
)
743
local
v
=
setmetatableindex
(
function
(
t
,
color
)
744
local
v
=
"
q
"
.
.
lpdfcolor
(
colormodel
,
color
)
.
.
"
"
.
.
p
745
t
[
color
]
=
v
746
return
v
747
end
)
748
t
[
colormodel
]
=
v
749
return
v
750
end
)
751
t
[
transparency
]
=
v
752
return
v
753
end
)
754 755
-- function codeinjections.vfliteral(pos_h,pos_v,packet)
756
-- lpdfprint(packet[2],packet[3])
757
-- end
758 759
function
codeinjections
.
vfstartcolor
(
pos_h
,
pos_v
,
packet
)
760
local
color
=
type
(
packet
)
=
=
"
table
"
and
packet
[
2
]
or
packet
761
if
color
then
762
local
m
,
c
=
colortoattributes
(
color
)
763
local
t
=
transparencytoattribute
(
color
)
764
if
t
and
t
~
=
unsetvalue
then
765
lpdfprint
(
"
page
"
,
t_cache
[
t
]
[
m
]
[
c
]
)
-- "q " .. lpdfcolor(m,c) .. " " .. lpdftransparency(t)
766
else
767
lpdfprint
(
"
page
"
,
c_cache
[
m
]
[
c
]
)
-- "q " .. lpdfcolor(m,c))
768
end
769
else
770
lpdfprint
(
"
page
"
,
"
q
"
)
771
end
772
end
773 774
function
codeinjections
.
vfstopcolor
(
)
775
-- lpdfprint("text", "Q")
776
lpdfprint
(
"
page
"
,
"
Q
"
)
777
end
778 779
end
780 781
-- These generate the in-stream color commands:
782 783
do
784 785
local
fonts
=
{
}
786
lpdf
.
fonts
=
fonts
787 788
fonts
.
color_indirect
=
function
(
c
,
t
)
789
if
c
and
t
then
790
return
lpdfcolor
(
1
,
c
)
.
.
"
"
.
.
lpdftransparency
(
t
)
791
elseif
c
then
792
return
lpdfcolor
(
1
,
c
)
793
elseif
t
then
794
return
lpdftransparency
(
t
)
795
else
796
return
false
797
end
798
end
799 800
local
colors
=
attributes
.
colors
801
local
rgbtocmyk
=
colors
.
rgbtocmyk
802 803
local
f_cmyk
=
formatters
[
"
%.3N %.3N %.3N %.3N k
"
]
804
local
f_rgb
=
formatters
[
"
%.3N %.3N %.3N rg
"
]
805
local
f_gray
=
formatters
[
"
%.3N g
"
]
806 807
fonts
.
color_direct
=
function
(
r
,
g
,
b
)
808
local
m
=
colors
.
model
809
if
r
=
=
g
and
g
=
=
b
then
810
return
f_gray
(
r
)
811
elseif
m
=
=
"
cmyk
"
then
812
return
f_cmyk
(
rgbtocmyk
(
r
,
g
,
b
)
)
813
else
814
return
f_rgb
(
r
,
g
,
b
)
815
end
816
end
817 818
end
819 820