1if not modules then modules = { } end modules ['font-imp-tracing'] = {
2 version = 1.001,
3 comment = "companion to font-ini.mkiv and hand-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
9local abs = math.abs
10
11local next, type = next, type
12local concat = table.concat
13local formatters = string.formatters
14
15local fonts = fonts
16
17local handlers = fonts.handlers
18local registerotffeature = handlers.otf.features.register
19local registerafmfeature = handlers.afm.features.register
20
21local settings_to_array = utilities.parsers.settings_to_array
22local setmetatableindex = table.setmetatableindex
23
24local helpers = fonts.helpers
25local appendcommandtable = helpers.appendcommandtable
26local prependcommands = helpers.prependcommands
27local charcommand = helpers.commands.char
28
29local variables = interfaces.variables
30
31local v_background <const> = variables.background
32local v_frame <const> = variables.frame
33local v_empty <const> = variables.empty
34local v_none <const> = variables.none
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111local function initialize(tfmdata,key,value)
112 if value then
113 local vfspecials = fonts.helpers.vfspecials
114 local vfcommands = fonts.helpers.commands
115
116
117 local characters = tfmdata.characters
118 local rule = { "frame", true, true, true, false, false, false, false, "palegray" }
119 local showchar = true
120 if type(value) == "string" then
121 value = settings_to_array(value)
122 for i=1,#value do
123 local v = value[i]
124 if v == v_frame then
125 rule[6] = true
126 elseif v == v_background then
127 rule[6] = false
128 elseif v == v_empty then
129 showchar = false
130 elseif v == v_none then
131 rule[9] = false
132 else
133 local thickness = string.todimen(v)
134 if thickness and thickness > 0 then
135 rule[5] = thickness
136 else
137 rule[9] = v
138 end
139 end
140 end
141 end
142 if not showchar then
143 rule = { rule }
144 end
145 for unicode, character in next, characters do
146 if characters == 32 then
147
148 elseif showchar then
149 local commands = character.commands
150 if commands then
151 character.commands = prependcommands ( commands, rule )
152 else
153 character.commands = { rule, charcommand[unicode] }
154 end
155 else
156 character.commands = rule
157 end
158 end
159 end
160end
161
162local specification = {
163 name = "boundingbox",
164 description = "show boundingbox",
165 manipulators = {
166 base = initialize,
167 node = initialize,
168 }
169}
170
171registerotffeature(specification)
172registerafmfeature(specification)
173
174local function initialize(tfmdata,key,value)
175 if value then
176 local rawdata = tfmdata.shared.rawdata
177 local rawresources = rawdata and rawdata.resources
178 local mathconstants = rawresources.mathconstants
179 if mathconstants then
180 local vfspecials = fonts.helpers.vfspecials
181 local vfcommands = fonts.helpers.commands
182 local backgrounds = vfspecials.backgrounds
183
184 local characters = tfmdata.characters
185 local rulecache = backgrounds
186 local push = vfcommands.push
187 local pop = vfcommands.pop
188 local black = { "stopcolor" }
189 local itcolor = { "startcolor", "trace:0" }
190 local brcolor = { "startcolor", "trace:1" }
191 local trcolor = { "startcolor", "trace:2" }
192 local blcolor = { "startcolor", "trace:3" }
193 local tlcolor = { "startcolor", "trace:4" }
194 for unicode, character in next, characters do
195 local mathkerns = character.mathkerns
196 local italic = character.vitalic or character.italic
197
198if italic ~= italic then
199
200
201 italic = 0
202end
203
204 if mathkerns or (italic and italic ~= 0) then
205 local width = character.width or 0
206 local height = character.height or 0
207 local depth = character.depth or 0
208 local list = { }
209 local count = 0
210 if italic and italic ~= 0 then
211 count = count + 1 list[count] = itcolor
212 count = count + 1 list[count] = push
213 count = count + 1 list[count] = { "offset", width + (italic < 0 and -italic or 0), 0 }
214 count = count + 1 list[count] = rulecache[height][depth][italic < 0 and -italic or italic]
215 count = count + 1 list[count] = pop
216 count = count + 1 list[count] = black
217 end
218 if mathkerns then
219 local br = mathkerns.bottomright
220 local tr = mathkerns.topright
221 local bl = mathkerns.bottomleft
222 local tl = mathkerns.topleft
223 if br then
224 local done = false
225 for i=1,#br do
226 local l = br[i]
227 local h = l.height or 0
228 local k = l.kern or 0
229 if k ~= 0 then
230 if h == 0 then
231 h = height + depth
232 end
233 if not done then
234 count = count + 1 list[count] = brcolor
235 done = true
236 end
237 count = count + 1 list[count] = push
238 count = count + 1 list[count] = { "offset", width + (k < 0 and k or 0), - depth }
239 count = count + 1 list[count] = rulecache[h][0][k < 0 and -k or k]
240 count = count + 1 list[count] = pop
241 end
242 end
243 if done then
244 count = count + 1 list[count] = black
245 end
246 end
247 if tr then
248 local done = false
249 for i=1,#tr do
250 local l = tr[i]
251 local h = l.height or 0
252 local k = l.kern or 0
253 if k ~= 0 then
254 if h == 0 then
255 h = height + depth
256 end
257 if not done then
258 count = count + 1 list[count] = trcolor
259 done = true
260 end
261 count = count + 1 list[count] = push
262 count = count + 1 list[count] = { "offset", width + (k < 0 and k or 0), height - h }
263 count = count + 1 list[count] = rulecache[h][0][k < 0 and k or k]
264 count = count + 1 list[count] = pop
265 end
266 end
267 if done then
268 count = count + 1 list[count] = black
269 end
270 end
271 if bl then
272 local done = false
273 for i=1,#bl do
274 local l = bl[i]
275 local h = l.height or 0
276 local k = l.kern or 0
277 if k ~= 0 then
278 if h == 0 then
279 h = height + depth
280 end
281 if not done then
282 count = count + 1 list[count] = blcolor
283 done = true
284 end
285 count = count + 1 list[count] = push
286 count = count + 1 list[count] = { "offset", (k < 0 and k or 0), -depth }
287 count = count + 1 list[count] = rulecache[h][0][abs(k)]
288 count = count + 1 list[count] = pop
289 end
290 end
291 if done then
292 count = count + 1 list[count] = black
293 end
294 end
295 if tl then
296 local done = false
297 for i=1,#tl do
298 local l = tl[i]
299 local h = l.height or 0
300 local k = l.kern or 0
301 if k ~= 0 then
302 if h == 0 then
303 h = height + depth
304 end
305 if not done then
306 count = count + 1 list[count] = tlcolor
307 done = true
308 end
309 count = count + 1 list[count] = push
310 count = count + 1 list[count] = { "offset", (k < 0 and k or 0), height - h }
311 count = count + 1 list[count] = rulecache[h][0][abs(k)]
312 count = count + 1 list[count] = pop
313 end
314 end
315 if done then
316 count = count + 1 list[count] = black
317 end
318 end
319 end
320 if count > 0 then
321 local commands = character.commands
322 if commands then
323 character.commands = appendcommandtable(commands,list)
324 else
325 list[#list+1] = charcommand[unicode]
326 character.commands = list
327 end
328 end
329 end
330 end
331 end
332 end
333end
334
335local specification = {
336 name = "staircase",
337 description = "show staircase kerns",
338
339 manipulators = {
340 base = initialize,
341 node = initialize,
342 }
343}
344
345registerotffeature(specification)
346registerafmfeature(specification)
347 |