1if not modules then modules = { } end modules ['driv-ini'] = {
2 version = 1.001,
3 comment = "companion to driv-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
12
13local type = type
14local addsuffix = file.addsuffix
15
16local setmetatableindex = table.setmetatableindex
17local formatters = string.formatters
18
19local starttiming = statistics.starttiming
20local stoptiming = statistics.stoptiming
21
22local report = logs.reporter("drivers")
23
24local instances = { }
25local helpers = { }
26local converters = { }
27local prepared = { }
28local wrappedup = { }
29local cleanedup = { }
30local currentdriver = "default"
31local currentinstance = nil
32
33local shipout = tex.shipout
34local texgetbox = tex.getbox
35local texgetcount = tex.getcount
36
37function converters.engine(driver,boxnumber,mode,number,specification)
38 return shipout(boxnumber)
39end
40
41local prepare = nil
42local convert = nil
43local wrapup = nil
44local cleanup = nil
45local outputfilename = nil
46
47drivers = drivers or {
48 instances = instances,
49 helpers = helpers,
50 converters = converters,
51 lmtxversion = 0.10,
52 report = report,
53}
54
55local dummy = function() end
56
57local defaulthandlers = {
58 prepare = dummy,
59 initialize = dummy,
60 finalize = dummy,
61 updatefontstate = dummy,
62 wrapup = dummy,
63 cleanup = dummy,
64 convert = dummy,
65 outputfilename = dummy,
66}
67
68function drivers.install(specification)
69 local name = specification.name
70 if not name then
71 report("missing driver name")
72 return
73 end
74 local actions = specification.actions
75 if not actions then
76 report("no actions for driver %a",name)
77 return
78 end
79 local flushers = specification.flushers
80 if not flushers then
81 report("no flushers for driver %a",name)
82 return
83 end
84
85 setmetatableindex(actions, defaulthandlers)
86 setmetatableindex(flushers, function() return dummy end)
87 instances[name] = specification
88end
89
90function drivers.convert(boxnumber)
91 if currentinstance then
92 callbacks.functions.start_page_number()
93 starttiming(drivers)
94 convert(currentinstance,boxnumber,texgetcount("realpageno"))
95 stoptiming(drivers)
96 callbacks.functions.stop_page_number()
97 end
98end
99
100function drivers.outputfilename()
101 if currentinstance then
102 return outputfilename(currentinstance)
103 end
104end
105
106luatex.wrapup(function()
107 if currentinstance and wrapup and not wrappedup[currentdriver] then
108 starttiming(drivers)
109 wrapup(currentinstance)
110 stoptiming(drivers)
111 wrappedup[currentdriver] = true
112 cleanedup[currentdriver] = true
113 end
114end)
115
116luatex.cleanup(function()
117 if currentinstance and cleanup and not cleanedup[currentdriver] then
118 starttiming(drivers)
119 cleanup(currentinstance)
120 stoptiming(drivers)
121 wrappedup[currentdriver] = true
122 cleanedup[currentdriver] = true
123 end
124end)
125
126function drivers.enable(name)
127 if name ~= currentdriver then
128 if currentinstance then
129 starttiming(drivers)
130 cleanup(currentinstance)
131 stoptiming(drivers)
132 end
133 currentdriver = name or "default"
134 currentinstance = instances[currentdriver]
135 if currentinstance then
136 local actions = currentinstance.actions
137 prepare = actions.prepare
138 wrapup = actions.wrapup
139 cleanup = actions.cleanup
140 convert = actions.convert
141 outputfilename = actions.outputfilename
142
143 if prepare and not prepared[currentdriver] then
144 starttiming(drivers)
145 prepare(currentinstance)
146 stoptiming(drivers)
147 prepared[currentdriver] = true
148 end
149 else
150 report("bad driver")
151 end
152 end
153end
154
155statistics.register("driver time",function()
156 return statistics.elapsedseconds(drivers)
157end)
158
159interfaces.implement {
160 name = "shipoutpage",
161 arguments = "integer",
162 actions = drivers.convert,
163}
164
165interfaces.implement {
166 name = "enabledriver",
167 arguments = "string",
168 actions = drivers.enable,
169}
170
171
172
173do
174
175 local filename = nil
176
177 drivers.install {
178 name = "default",
179 actions = {
180 convert = drivers.converters.engine,
181 outputfilename = function(driver)
182 if not filename then
183 filename = addsuffix(tex.jobname,"pdf")
184 end
185 return filename
186 end,
187 },
188 flushers = {
189
190 },
191 }
192
193end
194
195
196
197do
198
199 drivers.install {
200 name = "none",
201 actions = { },
202 flushers = { },
203 }
204
205end
206
207do
208
209 local function prepare(driver)
210 converter = drivers.converters.lmtx
211 end
212
213 local function convert(driver,boxnumber,pagenumber)
214 converter(driver,texgetbox(boxnumber),"page",pagenumber)
215 end
216
217 drivers.install {
218 name = "empty",
219 actions = {
220 prepare = prepare,
221 convert = convert,
222 },
223 flushers = { },
224 }
225
226end
227
228
229
230setmetatableindex(instances,function() return instances.default end)
231
232
233
234drivers.enable("default")
235
236
237
238local s_matrix_0 = "1 0 0 1"
239local f_matrix_2 = formatters["%.6N 0 0 %.6N"]
240local f_matrix_4 = formatters["%.6N %.6N %.6N %.6N"]
241
242function helpers.tomatrix(rx,sx,sy,ry,tx,ty)
243 if type(rx) == "string" then
244 return rx
245 else
246 if not rx then
247 rx = 1
248 elseif rx == 0 then
249 rx = 0.0001
250 end
251 if not ry then
252 ry = 1
253 elseif ry == 0 then
254 ry = 0.0001
255 end
256 if not sx then
257 sx = 0
258 end
259 if not sy then
260 sy = 0
261 end
262 if sx == 0 and sy == 0 then
263 if rx == 1 and ry == 1 then
264 return s_matrix_0
265 else
266 return f_matrix_2(rx,ry)
267 end
268 else
269 return f_matrix_4(rx,sx,sy,ry)
270 end
271 end
272end
273 |