1if not modules then modules = { } end modules ['lpdf-grp'] = {
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
9local type, tonumber = type, tonumber
10local formatters, gsub = string.formatters, string.gsub
11local concat = table.concat
12local round = math.round
13
14local backends, lpdf = backends, lpdf
15
16local nodeinjections = backends.pdf.nodeinjections
17
18local colors = attributes.colors
19local basepoints = number.dimenfactors.bp
20
21local nodeinjections = backends.pdf.nodeinjections
22local codeinjections = backends.pdf.codeinjections
23local registrations = backends.pdf.registrations
24
25local pdfdictionary = lpdf.dictionary
26local pdfarray = lpdf.array
27local pdfconstant = lpdf.constant
28local pdfboolean = lpdf.boolean
29local pdfreference = lpdf.reference
30local pdfflushobject = lpdf.flushobject
31
32local createimage = images.create
33local wrapimage = images.wrap
34local embedimage = images.embed
35
36
37
38
39
40
41
42local function shade(stype,name,domain,color_a,color_b,n,colorspace,coordinates,separation,steps,fractions)
43 local func = nil
44
45
46
47
48 domain = pdfarray(domain)
49 n = tonumber(n)
50
51 if steps then
52 local list = pdfarray()
53 local bounds = pdfarray()
54 local encode = pdfarray()
55 for i=1,steps do
56 if i < steps then
57 bounds[i] = fractions[i] or 1
58 end
59 encode[2*i-1] = 0
60 encode[2*i] = 1
61 list [i] = pdfdictionary {
62 FunctionType = 2,
63 Domain = domain,
64 C0 = pdfarray(color_a[i]),
65 C1 = pdfarray(color_b[i]),
66 N = n,
67 }
68 end
69 func = pdfdictionary {
70 FunctionType = 3,
71 Bounds = bounds,
72 Encode = encode,
73 Functions = list,
74 Domain = domain,
75 }
76 else
77 func = pdfdictionary {
78 FunctionType = 2,
79 Domain = domain,
80 C0 = pdfarray(color_a),
81 C1 = pdfarray(color_b),
82 N = n,
83 }
84 end
85 separation = separation and registrations.getspotcolorreference(separation)
86 local s = pdfdictionary {
87 ShadingType = stype,
88 ColorSpace = separation and pdfreference(separation) or pdfconstant(colorspace),
89 Domain = domain,
90 Function = pdfreference(pdfflushobject(func)),
91 Coords = pdfarray(coordinates),
92 Extend = pdfarray { true, true },
93 AntiAlias = pdfboolean(true),
94 }
95 lpdf.adddocumentshade(name,pdfreference(pdfflushobject(s)))
96end
97
98function lpdf.circularshade(name,domain,color_a,color_b,n,colorspace,coordinates,separation,steps,fractions)
99 shade(3,name,domain,color_a,color_b,n,colorspace,coordinates,separation,steps,fractions)
100end
101
102function lpdf.linearshade(name,domain,color_a,color_b,n,colorspace,coordinates,separation,steps,fractions)
103 shade(2,name,domain,color_a,color_b,n,colorspace,coordinates,separation,steps,fractions)
104end
105
106
107
108
109
110
111local template = "q BI %s ID %s > EI Q"
112local factor = 72/300
113
114function nodeinjections.injectbitmap(t)
115
116 local xresolution, yresolution = t.xresolution or 0, t.yresolution or 0
117 if xresolution == 0 or yresolution == 0 then
118 return
119 end
120 local colorspace = t.colorspace
121 if colorspace ~= "rgb" and colorspace ~= "cmyk" and colorspace ~= "gray" then
122
123 local d = gsub(t.data,"[^0-9a-f]","")
124 local b = math.round(#d / (xresolution * yresolution))
125 if b == 2 then
126 colorspace = "gray"
127 elseif b == 6 then
128 colorspace = "rgb"
129 elseif b == 8 then
130 colorspace = "cmyk"
131 end
132 end
133 colorspace = lpdf.colorspaceconstants[colorspace]
134 if not colorspace then
135 return
136 end
137 local d = pdfdictionary {
138 W = xresolution,
139 H = yresolution,
140 CS = colorspace,
141 BPC = 8,
142 F = pdfconstant("AHx"),
143
144
145
146 }
147
148 local urx, ury = 1/basepoints, 1/basepoints
149
150
151 local width, height = t.width or 0, t.height or 0
152 if width == 0 and height == 0 then
153 width = factor * xresolution / basepoints
154 height = factor * yresolution / basepoints
155 elseif width == 0 then
156 width = height * xresolution / yresolution
157 elseif height == 0 then
158 height = width * yresolution / xresolution
159 end
160 local a = pdfdictionary {
161 BBox = pdfarray { 0, 0, urx * basepoints, ury * basepoints }
162 }
163 local image = createimage {
164 stream = formatters[template](d(),t.data),
165 width = width,
166 height = height,
167 bbox = { 0, 0, urx, ury },
168 attr = a(),
169 nobbox = true,
170 }
171 return wrapimage(image)
172end
173
174
175
176function codeinjections.setfigurealternative(data,figure)
177 local request = data.request
178 local display = request.display
179 if display and display ~= "" then
180 local nested = figures.push {
181 name = display,
182 page = request.page,
183 size = request.size,
184 prefix = request.prefix,
185 cache = request.cache,
186 width = request.width,
187 height = request.height,
188 }
189 figures.identify()
190 local displayfigure = figures.check()
191 if displayfigure then
192
193 embedimage(figure)
194 local a = pdfarray {
195 pdfdictionary {
196 Image = pdfreference(figure.objnum),
197 DefaultForPrinting = true,
198 }
199 }
200 local d = pdfdictionary {
201 Alternates = pdfreference(pdfflushobject(a)),
202 }
203 displayfigure.attr = d()
204 figures.pop()
205 return displayfigure, nested
206 else
207 figures.pop()
208 end
209 end
210end
211
212function codeinjections.getpreviewfigure(request)
213 local figure = figures.initialize(request)
214 if not figure then
215 return
216 end
217 figure = figures.identify(figure)
218 if not (figure and figure.status and figure.status.fullname) then
219 return
220 end
221 figure = figures.check(figure)
222 if not (figure and figure.status and figure.status.fullname) then
223 return
224 end
225 local image = figure.status.private
226 if image then
227 embedimage(image)
228 end
229 return figure
230end
231
232function codeinjections.setfiguremask(data,figure)
233 local request = data.request
234 local mask = request.mask
235 if mask and mask ~= "" then
236 figures.push {
237 name = mask,
238 page = request.page,
239 size = request.size,
240 prefix = request.prefix,
241 cache = request.cache,
242 width = request.width,
243 height = request.height,
244 }
245 mask = figures.identify()
246 mask = figures.check(mask)
247 if mask then
248 local image = mask.status.private
249 if image then
250 figures.include(mask)
251 embedimage(image)
252 local d = pdfdictionary {
253 Interpolate = false,
254 SMask = pdfreference(mask.status.objectnumber),
255 }
256 figure.attr = d()
257 end
258 end
259 figures.pop()
260 end
261end
262
263
264
265local saveboxresource = tex.boxresources.save
266local nofpatterns = 0
267local f_pattern = formatters["q /Pattern cs /%s scn 0 0 %.6N %.6N re f Q"]
268
269function lpdf.registerpattern(specification)
270 nofpatterns = nofpatterns + 1
271 local d = pdfdictionary {
272 Type = pdfconstant("Pattern"),
273 PatternType = 1,
274 PaintType = 1,
275 TilingType = 2,
276 XStep = (specification.width or 10) * basepoints,
277 YStep = (specification.height or 10) * basepoints,
278 Matrix = {
279 1, 0, 0, 1,
280 (specification.hoffset or 0) * basepoints,
281 (specification.voffset or 0) * basepoints,
282 },
283 }
284
285 local resources = lpdf.collectedresources{ patterns = false }
286 local attributes = d()
287 local onlybounds = 1
288 local patternobj = saveboxresource(specification.number,attributes,resources,true,onlybounds)
289 lpdf.adddocumentpattern("Pt" .. nofpatterns,lpdf.reference(patternobj ))
290 return nofpatterns
291end
292
293function lpdf.patternstream(n,width,height)
294 return f_pattern("Pt" .. n,width*basepoints,height*basepoints)
295end
296
297backends.pdf.codeinjections.registerpattern = lpdf.registerpattern
298 |