1if not modules then modules = { } end modules ['s-fonts-variable'] = {
2 version = 1.001,
3 comment = "companion to s-fonts-variable.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
9moduledata.fonts = moduledata.fonts or { }
10moduledata.fonts.variable = moduledata.fonts.variable or { }
11
12local format = string.format
13local stripstring = string.nospaces
14local lower = string.lower
15local rep = string.rep
16
17local context = context
18local NC, NR, HL, ML = context.NC, context.NR, context.HL, context.ML
19local bold, monobold, mono, formattedmono = context.bold, context.monobold, context.mono, context.formatted.mono
20
21local show_glyphs = false trackers.register("modules.fonts.variables.glyphs", function(v) show_glyphs = v end)
22local show_kerns = false trackers.register("modules.fonts.variables.kerns", function(v) show_kerns = v end)
23
24function moduledata.fonts.variable.showvariations(specification)
25
26 specification = interfaces.checkedspecification(specification)
27
28 local fontfile = specification.font
29 local maximum = tonumber(specification.max) or 0xFFFF
30 local fontname = format("testfont-%s",i)
31 local fontsize = tex.dimen.bodyfontsize
32 if not fontfile then
33 return
34 end
35 local id, fontdata = fonts.definers.define {
36 name = fontfile,
37
38 cs = fontname,
39 }
40
41 if not fontdata then
42 context.type("no font with name %a found",fontname)
43 return
44 end
45
46 local resources = fontdata.resources
47
48 if not resources then
49 return
50 end
51
52 local variabledata = resources.variabledata or { }
53
54
55
56
57
58 if not fontdata.shared.rawdata.metadata.fullname then
59 fontdata.shared.rawdata.metadata.fullname = fontdata.shared.rawdata.metadata.fontname
60 end
61
62 context.starttitle { title = fontdata.shared.rawdata.metadata.fullname }
63
64 local parameters = fontdata.parameters
65
66 context.startsubject { title = "parameters" }
67 if parameters then
68 context.starttabulate { "|||" }
69 NC() monobold("ascender") NC() context("%p",parameters.ascender) NC() NR()
70 NC() monobold("descender") NC() context("%p",parameters.descender) NC() NR()
71 NC() monobold("emwidth") NC() context("%p",parameters.em) NC() NR()
72 NC() monobold("exheight") NC() context("%p",parameters.ex) NC() NR()
73 NC() monobold("size") NC() context("%p",parameters.size) NC() NR()
74 NC() monobold("slant") NC() context("%s",parameters.slant) NC() NR()
75 NC() monobold("space") NC() context("%p",parameters.space) NC() NR()
76 NC() monobold("shrink") NC() context("%p",parameters.spaceshrink) NC() NR()
77 NC() monobold("stretch") NC() context("%p",parameters.spacestretch) NC() NR()
78 NC() monobold("units") NC() context("%s",parameters.units) NC() NR()
79 context.stoptabulate()
80 else
81 context("no parameters")
82 end
83 context.stopsubject()
84
85 local features = fontdata.shared.rawdata.resources.features
86
87 context.startsubject { title = "features" }
88 if features then
89 local function f(g)
90 if g then
91 local t = table.sortedkeys(g)
92 local n = 0
93 for i=1,#t do
94 if #t[i] <= 4 then
95 n = n + 1
96 t[n] = t[i]
97 end
98 end
99 return table.concat(t," ",1,n)
100 end
101 end
102 context.starttabulate { "||p|" }
103 NC() monobold("gpos") NC() mono(f(features.gpos)) NC() NR()
104 NC() monobold("gsub") NC() mono(f(features.gsub)) NC() NR()
105 context.stoptabulate()
106 else
107 context("no features")
108 end
109 context.stopsubject()
110
111 local designaxis = variabledata.designaxis
112
113 context.startsubject { title = "design axis" }
114 if designaxis and #designaxis > 0 then
115 context.starttabulate { "||||c|c|c|c|c|" }
116 NC() bold("tag")
117 NC() bold("name")
118 NC() bold("variant")
119 NC() bold("flags")
120 NC() bold("value")
121 NC() bold("min")
122 NC() bold("max")
123 NC() bold("link")
124 NC() NR()
125 HL()
126 for k=1,#designaxis do
127 local axis = designaxis[k]
128 local tag = axis.tag
129 local name = axis.name
130 local variants = axis.variants
131 local first = variants and variants[1]
132 if first then
133 local haslimits = first.maximum
134 local haslink = first.link
135 for i=1,#variants do
136 local variant = variants[i]
137 NC() monobold(tag)
138 NC() context(name)
139 NC() context(variant.name)
140 NC() formattedmono("0x%04x",variant.flags)
141 NC() context(variant.value)
142 NC() context(variant.minimum or "-")
143 NC() context(variant.maximum or "-")
144 NC() context(variant.link or "-")
145 NC() NR()
146 tag = nil
147 name = nil
148 end
149 end
150 end
151 context.stoptabulate()
152 else
153 context("no design axis defined (no \\type{stat} table)")
154 end
155 context.stopsubject()
156
157 local axis = variabledata.axis
158 local instances = variabledata.instances
159 local list = { }
160
161 context.startsubject { title = "axis" }
162 if axis and #axis > 0 then
163 context.starttabulate { "|||c|c|c|" }
164 NC() bold("tag")
165 NC() bold("name")
166 NC() bold("min")
167 NC() bold("def")
168 NC() bold("max")
169 NC() NR()
170 HL()
171 for k=1,#axis do
172 local a = axis[k]
173 NC() monobold(a.tag)
174 NC() context(a.name)
175 NC() context(a.minimum)
176 NC() context(a.default)
177 NC() context(a.maximum)
178 NC() NR()
179 list[#list+1] = a.tag
180 end
181 context.stoptabulate()
182 else
183 context("no axis defined, incomplete \\type{fvar} table")
184 end
185 context.stopsubject()
186
187 local collected = { }
188
189 context.startsubject { title = "instances" }
190 if not instances or #instances == 0 or not list or #list == 0 then
191 context("no instances defined, incomplete \\type{fvar}/\\type{stat} table")
192 else
193 if #axis > 8 then
194 context.start()
195 context.switchtobodyfont { "small" }
196 if #axis > 12 then
197 context.switchtobodyfont { "small" }
198 end
199 end
200 context.starttabulate { "||" .. rep("c|",#list) .. "|" }
201 NC()
202 for i=1,#list do
203 NC() monobold(list[i])
204 end
205 NC()
206 local fullname = lower(stripstring(fontdata.shared.rawdata.metadata.fullname))
207 formattedmono("%s*",fullname)
208 NC() NR()
209 ML()
210 for k=1,#instances do
211 local i = instances[k]
212 NC() monobold(i.subfamily)
213 local values = i.values
214 local hash = { }
215 for k=1,#values do
216 local v = values[k]
217 hash[v.axis] = v.value
218 end
219 for i=1,#list do
220 NC() context(hash[list[i]])
221 end
222 NC()
223 local instance = lower(stripstring(i.subfamily))
224 mono(instance)
225 collected[#collected+1] = fullname .. instance
226 NC() NR()
227 end
228 context.stoptabulate()
229 if #axis > 8 then
230 context.stop()
231 end
232 end
233 context.stopsubject()
234
235 local sample = specification.sample
236 local features = specification.features or "default"
237
238 for i=1,#collected do
239
240 local instance = collected[i]
241 context.startsubject { title = instance }
242 local fontspecification = "name:" .. instance .. "*" .. features
243 context.start()
244 context.definedfont { fontspecification }
245 context.start()
246 if show_glyphs then
247 context.showglyphs()
248 end
249 if show_kerns then
250 context.showfontkerns()
251 end
252
253 if sample and sample ~= "" then
254 context(sample)
255 else
256 context.input("zapf.tex")
257 end
258 context.stop()
259 context.blank { "big,samepage"}
260 context.showfontspacing()
261 context.par()
262 context.stop()
263 context.stopsubject()
264
265 if i > maximum then
266 context.startsubject { title = "And so on" }
267 context("no more than %i instances are shown",maximum)
268 context.par()
269 context.stopsubject()
270 break
271 end
272 end
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314 context.stoptitle()
315
316end
317 |