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 |