1if not modules then modules = { } end modules ['lpdf-swf'] = {
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
10
11
12local format, gsub = string.format, string.gsub
13local concat = table.concat
14local formatters = string.formatters
15
16local backends = backends
17local lpdf = lpdf
18local context = context
19
20local pdfconstant = lpdf.constant
21local pdfstring = lpdf.string
22local pdfdictionary = lpdf.dictionary
23local pdfarray = lpdf.array
24local pdfreference = lpdf.reference
25local pdfflushobject = lpdf.flushobject
26local pdfsharedobject = lpdf.shareobjectreference
27
28local checkedkey = lpdf.checkedkey
29
30local codeinjections = backends.pdf.codeinjections
31local nodeinjections = backends.pdf.nodeinjections
32
33local trace_swf = false trackers.register("backend.swf", function(v) trace_swf = v end)
34
35local report_swf = logs.reporter("backend","swf")
36
37
38
39local createimage = images.create
40local embedimage = images.embed
41
42local basepoints = number.dimenfactors.bp
43
44local f_image = formatters["%.6N 0 0 %.6N 0 0 cm /%s Do"]
45
46local function package(image)
47 local boundingbox = image.bbox
48 local imagetag = "Im" .. image.index
49 local resources = pdfdictionary {
50 ProcSet = lpdf.procset(),
51 Resources = pdfdictionary {
52 XObject = pdfdictionary {
53 [imagetag] = pdfreference(image.objnum)
54 }
55 }
56 }
57 local width = boundingbox[3]
58 local height = boundingbox[4]
59 local xform = createimage {
60 attr = resources(),
61 stream = f_image(width,height,imagetag),
62 bbox = { 0, 0, width/basepoints, height/basepoints },
63 }
64 embedimage(xform)
65 return xform
66end
67
68
69
70local activations = {
71 click = "XA",
72 page = "PO",
73 focus = "PV",
74}
75
76local deactivations = {
77 click = "XD",
78 page = "PI",
79 focus = "PC",
80}
81
82table.setmetatableindex(activations, function() return activations .click end)
83table.setmetatableindex(deactivations,function() return deactivations.focus end)
84
85local function insertswf(spec)
86 local width = spec.width
87 local height = spec.height
88 local filename = spec.foundname
89 local resources = spec.resources
90 local display = spec.display
91 local controls = spec.controls
92 local arguments = spec.arguments
93
94 local resources = resources and parametersets[resources]
95 local display = display and parametersets[display]
96 local controls = controls and parametersets[controls]
97 local arguments = arguments and parametersets[arguments]
98
99 local preview = checkedkey(display,"preview","string")
100 local toolbar = checkedkey(display,"toolbar","boolean")
101
102 local embeddedreference = codeinjections.embedfile {
103 file = filename,
104 compress = false,
105 }
106
107 local flash = pdfdictionary {
108 Subtype = pdfconstant("RichMediaConfiguration"),
109 Instances = pdfarray {
110 pdfdictionary {
111 Type = pdfconstant("RichMediaInstance"),
112 Asset = embeddedreference,
113 Subtype = pdfconstant("Flash"),
114 Params = pdfsharedobject(pdfdictionary {
115 Binding = pdfconstant("Background"),
116 FlashVars = arguments and pdfstring(table.sequenced(arguments,"&")) or nil,
117 }),
118 },
119 },
120 }
121
122 local flashreference = pdfreference(pdfflushobject(flash))
123
124 local configuration = pdfdictionary {
125 Configurations = pdfarray { flashreference },
126 Assets = pdfdictionary {
127 Names = pdfarray {
128 pdfstring(filename),
129 embeddedreference,
130 }
131 },
132 }
133
134
135
136
137
138
139
140
141
142
143 local root = file.dirname(filename)
144 local relativepaths = nil
145 local paths = nil
146 if resources then
147 local names = configuration.Assets.Names
148 local prefix = false
149 if root ~= "" and root ~= "." then
150 prefix = format("^%s/",string.topattern(root))
151 end
152 if prefix and trace_swf then
153 report_swf("using strip pattern %a",prefix)
154 end
155 local function add(fullname,strip)
156 local filename = gsub(fullname,"^%./","")
157 local usedname = strip and prefix and gsub(filename,prefix,"") or filename
158 local embeddedreference = codeinjections.embedfile {
159 file = fullname,
160 usedname = usedname,
161 keepdir = true,
162 compress = false,
163 }
164 names[#names+1] = pdfstring(filename)
165 names[#names+1] = embeddedreference
166 if trace_swf then
167 report_swf("embedding file %a as %a",fullname,usedname)
168 end
169 end
170 relativepaths = resources.relativepaths
171 if relativepaths then
172 if trace_swf then
173 report_swf("checking %s relative paths",#relativepaths)
174 end
175 for i=1,#relativepaths do
176 local relativepath = relativepaths[i]
177 if trace_swf then
178 report_swf("checking path %a relative to %a",relativepath,root)
179 end
180 local path = file.join(root == "" and "." or root,relativepath)
181 local files = dir.glob(path .. "/**")
182 for i=1,#files do
183 add(files[i],true)
184 end
185 end
186 end
187 paths = resources.paths
188 if paths then
189 if trace_swf then
190 report_swf("checking absolute %s paths",#paths)
191 end
192 for i=1,#paths do
193 local path = paths[i]
194 if trace_swf then
195 report_swf("checking path %a",path)
196 end
197 local files = dir.glob(path .. "/**")
198 for i=1,#files do
199 add(files[i],false)
200 end
201 end
202 end
203 local relativefiles = resources.relativefiles
204 if relativefiles then
205 if trace_swf then
206 report_swf("checking %s relative files",#relativefiles)
207 end
208 for i=1,#relativefiles do
209 add(relativefiles[i],true)
210 end
211 end
212 local files = resources.files
213 if files then
214 if trace_swf then
215 report_swf("checking absolute %s files",#files)
216 end
217 for i=1,#files do
218 add(files[i],false)
219 end
220 end
221 end
222
223 local opendisplay = display and display.open or false
224 local closedisplay = display and display.close or false
225
226 local configurationreference = pdfreference(pdfflushobject(configuration))
227
228 local activation = pdfdictionary {
229 Type = pdfconstant("RichMediaActivation"),
230 Condition = pdfconstant(activations[opendisplay]),
231 Configuration = flashreference,
232 Animation = pdfdictionary {
233 Subtype = pdfconstant("Linear"),
234 Speed = 1,
235 Playcount = 1,
236 },
237 Presentation = pdfdictionary {
238
239 PassContextClick = true,
240 Style = pdfconstant("Embedded"),
241 Toolbar = toolbar,
242 NavigationPane = false,
243 Transparent = true,
244 Window = pdfdictionary {
245 Type = pdfconstant("RichMediaWindow"),
246 Width = pdfdictionary {
247 Default = 100,
248 Min = 100,
249 Max = 100,
250 },
251 Height = pdfdictionary {
252 Default = 100,
253 Min = 100,
254 Max = 100,
255 },
256 Position = pdfdictionary {
257 Type = pdfconstant("RichMediaPosition"),
258 HAlign = pdfconstant("Near"),
259 VAlign = pdfconstant("Near"),
260 HOffset = 0,
261 VOffset = 0,
262 }
263 }
264 },
265
266
267 }
268
269 local deactivation = pdfdictionary {
270 Type = pdfconstant("RichMediaDeactivation"),
271 Condition = pdfconstant(deactivations[closedisplay]),
272 }
273
274 local richmediasettings = pdfdictionary {
275 Type = pdfconstant("RichMediaSettings"),
276 Activation = activation,
277 Deactivation = deactivation,
278 }
279
280 local settingsreference = pdfreference(pdfflushobject(richmediasettings))
281
282 local appearance
283
284 if preview then
285 preview = gsub(preview,"%*",file.nameonly(filename))
286 local figure = codeinjections.getpreviewfigure { name = preview, width = width, height = height }
287 if relativepaths and not figure then
288 for i=1,#relativepaths do
289 local path = file.join(root == "" and "." or root,relativepaths[i])
290 if trace_swf then
291 report_swf("checking preview on relative path %s",path)
292 end
293 local p = file.join(path,preview)
294 figure = codeinjections.getpreviewfigure { name = p, width = width, height = height }
295 if figure then
296 preview = p
297 break
298 end
299 end
300 end
301 if paths and not figure then
302 for i=1,#paths do
303 local path = paths[i]
304 if trace_swf then
305 report_swf("checking preview on absolute path %s",path)
306 end
307 local p = file.join(path,preview)
308 figure = codeinjections.getpreviewfigure { name = p, width = width, height = height }
309 if figure then
310 preview = p
311 break
312 end
313 end
314 end
315 if figure then
316 local image = package(figure.status.private)
317 appearance = pdfdictionary { N = pdfreference(image.objnum) }
318 if trace_swf then
319 report_swf("using preview %s",preview)
320 end
321 end
322 end
323
324 local annotation = pdfdictionary {
325 Subtype = pdfconstant("RichMedia"),
326 RichMediaContent = configurationreference,
327 RichMediaSettings = settingsreference,
328 AP = appearance,
329 }
330
331 return annotation, nil, nil
332
333end
334
335function backends.pdf.nodeinjections.insertswf(spec)
336 local annotation, preview, ref = insertswf {
337 foundname = spec.foundname,
338 width = spec.width,
339 height = spec.height,
340 display = spec.display,
341 controls = spec.controls,
342 resources = spec.resources,
343 arguments = spec.arguments,
344
345
346 }
347 context(nodeinjections.annotation(spec.width,spec.height,0,annotation()))
348end
349 |