1if not modules then modules = { } end modules ['back-imp-mps'] = {
2 version = 1.001,
3 optimize = true,
4 comment = "companion to back-imp-mps.mkiv",
5 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
6 copyright = "PRAGMA ADE / ConTeXt Development Team",
7 license = "see context related readme files"
8}
9
10local fontproperties = fonts.hashes.properties
11local fontparameters = fonts.hashes.parameters
12
13local starttiming = statistics.starttiming
14local stoptiming = statistics.stoptiming
15
16local bpfactor = number.dimenfactors.bp
17local texgetbox = tex.getbox
18local formatters = string.formatters
19
20local rulecodes = nodes.rulecodes
21local normalrule_code = rulecodes.normal
22
23
24
25
26
27
28
29
30local outlinerule_code = rulecodes.outline
31
32local fonts = { }
33local pages = { }
34local buffer = { }
35local b = 0
36local converter = nil
37
38local function reset()
39 buffer = { }
40 b = 0
41end
42
43
44
45local f_font = formatters[ "\\definefont[%s][file:%s*none @ %sbp]\n" ]
46
47local f_glyph = formatters[ [[draw textext.drt("\%s\char%i\relax") shifted (%N,%N);]] ]
48local f_rule = formatters[ [[fill unitsquare xscaled %N yscaled %N shifted (%N,%N);]] ]
49local f_outline = formatters[ [[draw unitsquare xscaled %N yscaled %N shifted (%N,%N);]] ]
50
51
52
53local function outputfilename(driver)
54 return tex.jobname .. "-output.tex"
55end
56
57local function save()
58 starttiming(drivers)
59 if #pages > 0 then
60 local filename = outputfilename()
61 drivers.report("saving result in %a",filename)
62 reset()
63 b = b + 1
64 buffer[b] = "\\starttext\n"
65 for k, v in table.sortedhash(fonts) do
66 b = b + 1
67 buffer[b] = f_font(v.name,v.filename,v.size)
68 end
69 for i=1,#pages do
70 b = b + 1
71 buffer[b] = pages[i]
72 end
73 b = b + 1
74 buffer[b] = "\\stoptext\n"
75 io.savedata(filename,table.concat(buffer,"",1,b))
76 end
77 stoptiming(drivers)
78end
79
80local function prepare(driver)
81 converter = drivers.converters.lmtx
82
83 backends.initialize("mps")
84
85 luatex.registerstopactions(1,function()
86 save()
87 end)
88end
89
90local function initialize(driver,details)
91 reset()
92 b = b + 1
93 buffer[b] = "\n\\startMPpage"
94end
95
96local function finalize(driver,details)
97 b = b + 1
98 buffer[b] = "\\stopMPpage\n"
99 pages[details.pagenumber] = table.concat(buffer,"\n",1,b)
100end
101
102local function wrapup(driver)
103end
104
105local function cleanup(driver)
106 reset()
107end
108
109local function convert(driver,boxnumber,pagenumber)
110 converter(driver,texgetbox(boxnumber),"page",pagenumber)
111end
112
113
114
115local last
116
117local function updatefontstate(id)
118 if fonts[id] then
119 last = fonts[id].name
120 else
121 last = "MPSfont" .. converters.Characters(id)
122 fonts[id] = {
123 filename = file.basename(fontproperties[id].filename),
124 size = fontparameters[id].size * bpfactor,
125 name = last,
126 }
127 end
128end
129
130local function flushcharacter(current, pos_h, pos_v, pos_r, font, char)
131 b = b + 1
132 buffer[b] = f_glyph(last,char,pos_h*bpfactor,pos_v*bpfactor)
133end
134
135local function flushrule(current, pos_h, pos_v, pos_r, size_h, size_v, subtype)
136 if subtype == normalrule_code then
137 b = b + 1
138 buffer[b] = f_rule(size_h*bpfactor,size_v*bpfactor,pos_h*bpfactor,pos_v*bpfactor)
139 elseif subtype == outlinerule_code then
140 b = b + 1
141 buffer[b] = f_outline(size_h*bpfactor,size_v*bpfactor,pos_h*bpfactor,pos_v*bpfactor)
142 end
143end
144
145local function flushsimplerule(pos_h, pos_v, pos_r, size_h, size_v)
146 flushrule(false,pos_h,pos_v,pos_r,size_h,size_v,normalrule_code)
147end
148
149local function flushspecialrule(pos_h, pos_v, pos_r, w, h, d, l, outline)
150 flushrule(false,pos_h,pos_v-d,pos_r,w,h+d,outline and outlinerule_code or normalrule_code)
151end
152
153
154
155drivers.install {
156 name = "mps",
157 actions = {
158 prepare = prepare,
159 initialize = initialize,
160 finalize = finalize,
161 wrapup = wrapup,
162 cleanup = cleanup,
163 convert = convert,
164 outputfilename = outputfilename,
165 },
166 flushers = {
167 updatefontstate = updatefontstate,
168 character = flushcharacter,
169 rule = flushrule,
170 simplerule = flushsimplerule,
171 specialrule = flushspecialrule,
172 }
173}
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 |