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 texgetbox = tex.getbox
17local formatters = string.formatters
18
19local rulecodes = nodes.rulecodes
20
21local normalrule_code <const> = rulecodes.normal
22
23
24
25
26
27
28
29
30local outlinerule_code <const> = rulecodes.outline
31
32local bpfactor <const> = number.dimenfactors.bp
33
34local fonts = { }
35local pages = { }
36local buffer = { }
37local b = 0
38local converter = nil
39
40local function reset()
41 buffer = { }
42 b = 0
43end
44
45
46
47local f_font = formatters[ "\\definefont[%s][file:%s*none @ %sbp]\n" ]
48
49local f_glyph = formatters[ [[draw textext.drt("\%s\char%i\relax") shifted (%N,%N);]] ]
50local f_rule = formatters[ [[fill unitsquare xscaled %N yscaled %N shifted (%N,%N);]] ]
51local f_outline = formatters[ [[draw unitsquare xscaled %N yscaled %N shifted (%N,%N);]] ]
52
53
54
55local function outputfilename(driver)
56 return tex.jobname .. "-output.tex"
57end
58
59local function save()
60 starttiming(drivers)
61 if #pages > 0 then
62 local filename = outputfilename()
63 drivers.report("saving result in %a",filename)
64 reset()
65 b = b + 1
66 buffer[b] = "\\starttext\n"
67 for k, v in table.sortedhash(fonts) do
68 b = b + 1
69 buffer[b] = f_font(v.name,v.filename,v.size)
70 end
71 for i=1,#pages do
72 b = b + 1
73 buffer[b] = pages[i]
74 end
75 b = b + 1
76 buffer[b] = "\\stoptext\n"
77 io.savedata(filename,table.concat(buffer,"",1,b))
78 end
79 stoptiming(drivers)
80end
81
82local function prepare(driver)
83 converter = drivers.converters.lmtx
84
85 backends.initialize("mps")
86
87 luatex.registerstopactions(1,function()
88 save()
89 end)
90end
91
92local function initialize(driver,details)
93 reset()
94 b = b + 1
95 buffer[b] = "\n\\startMPpage"
96end
97
98local function finalize(driver,details)
99 b = b + 1
100 buffer[b] = "\\stopMPpage\n"
101 pages[details.pagenumber] = table.concat(buffer,"\n",1,b)
102end
103
104local function wrapup(driver)
105end
106
107local function cleanup(driver)
108 reset()
109end
110
111local function convert(driver,boxnumber,pagenumber)
112 converter(driver,texgetbox(boxnumber),"page",pagenumber)
113end
114
115
116
117local last
118
119local function updatefontstate(id)
120 if fonts[id] then
121 last = fonts[id].name
122 else
123 last = "MPSfont" .. converters.Characters(id)
124 fonts[id] = {
125 filename = file.basename(fontproperties[id].filename),
126 size = fontparameters[id].size * bpfactor,
127 name = last,
128 }
129 end
130end
131
132local function flushcharacter(current, pos_h, pos_v, pos_r, font, char)
133 b = b + 1
134 buffer[b] = f_glyph(last,char,pos_h*bpfactor,pos_v*bpfactor)
135end
136
137local function flushrule(current, pos_h, pos_v, pos_r, size_h, size_v, subtype)
138 if subtype == normalrule_code then
139 b = b + 1
140 buffer[b] = f_rule(size_h*bpfactor,size_v*bpfactor,pos_h*bpfactor,pos_v*bpfactor)
141 elseif subtype == outlinerule_code then
142 b = b + 1
143 buffer[b] = f_outline(size_h*bpfactor,size_v*bpfactor,pos_h*bpfactor,pos_v*bpfactor)
144 end
145end
146
147local function flushsimplerule(pos_h, pos_v, pos_r, size_h, size_v)
148 flushrule(false,pos_h,pos_v,pos_r,size_h,size_v,normalrule_code)
149end
150
151local function flushspecialrule(pos_h, pos_v, pos_r, w, h, d, l, outline)
152 flushrule(false,pos_h,pos_v-d,pos_r,w,h+d,outline and outlinerule_code or normalrule_code)
153end
154
155
156
157drivers.install {
158 name = "mps",
159 actions = {
160 prepare = prepare,
161 initialize = initialize,
162 finalize = finalize,
163 wrapup = wrapup,
164 cleanup = cleanup,
165 convert = convert,
166 outputfilename = outputfilename,
167 },
168 flushers = {
169 updatefontstate = updatefontstate,
170 character = flushcharacter,
171 rule = flushrule,
172 simplerule = flushsimplerule,
173 specialrule = flushspecialrule,
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
217
218 |