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