1if not modules then modules = { } end modules ['back-mps'] = {
2 version = 1.001,
3 optimize = true,
4 comment = "companion to lpdf-ini.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 luatex.registerstopactions(1,function()
83 save()
84 end)
85end
86
87local function initialize(driver,details)
88 reset()
89 b = b + 1
90 buffer[b] = "\n\\startMPpage"
91end
92
93local function finalize(driver,details)
94 b = b + 1
95 buffer[b] = "\\stopMPpage\n"
96 pages[details.pagenumber] = table.concat(buffer,"\n",1,b)
97end
98
99local function wrapup(driver)
100end
101
102local function cleanup(driver)
103 reset()
104end
105
106local function convert(driver,boxnumber,pagenumber)
107 converter(driver,texgetbox(boxnumber),"page",pagenumber)
108end
109
110
111
112local last
113
114local function updatefontstate(id)
115 if fonts[id] then
116 last = fonts[id].name
117 else
118 last = "MPSfont" .. converters.Characters(id)
119 fonts[id] = {
120 filename = file.basename(fontproperties[id].filename),
121 size = fontparameters[id].size * bpfactor,
122 name = last,
123 }
124 end
125end
126
127local function flushcharacter(current, pos_h, pos_v, pos_r, font, char)
128 b = b + 1
129 buffer[b] = f_glyph(last,char,pos_h*bpfactor,pos_v*bpfactor)
130end
131
132local function flushrule(current, pos_h, pos_v, pos_r, size_h, size_v, subtype)
133 if subtype == normalrule_code then
134 b = b + 1
135 buffer[b] = f_rule(size_h*bpfactor,size_v*bpfactor,pos_h*bpfactor,pos_v*bpfactor)
136 elseif subtype == outlinerule_code then
137 b = b + 1
138 buffer[b] = f_outline(size_h*bpfactor,size_v*bpfactor,pos_h*bpfactor,pos_v*bpfactor)
139 end
140end
141
142local function flushsimplerule(pos_h, pos_v, pos_r, size_h, size_v)
143 flushrule(false,pos_h,pos_v,pos_r,size_h,size_v,normalrule_code)
144end
145
146local function flushspecialrule(pos_h, pos_v, pos_r, w, h, d, l, outline)
147 flushrule(false,pos_h,pos_v-d,pos_r,w,h+d,outline and outlinerule_code or normalrule_code)
148end
149
150
151
152drivers.install {
153 name = "mps",
154 actions = {
155 prepare = prepare,
156 initialize = initialize,
157 finalize = finalize,
158 wrapup = wrapup,
159 cleanup = cleanup,
160 convert = convert,
161 outputfilename = outputfilename,
162 },
163 flushers = {
164 updatefontstate = updatefontstate,
165 character = flushcharacter,
166 rule = flushrule,
167 simplerule = flushsimplerule,
168 specialrule = flushspecialrule,
169 }
170}
171
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 |