s-fonts-variable.lua /size: 11 Kb    last modification: 2023-12-21 09:45
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     -- size = fontsize,
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--     if not variabledata then
55--         return
56--     end
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-- print("using",fontspecification)
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 -- local function showregions(tag)
275 --
276 --     local regions = variabledata[tag]
277 --
278 --     context.startsubject { title = tag }
279 --         if regions then
280 --             context.starttabulate { "|r|c|r|r|r|" }
281 --             NC() bold("n")
282 --             NC() bold("axis")
283 --             NC() bold("start")
284 --             NC() bold("peak")
285 --             NC() bold("stop")
286 --             NC() NR()
287 --             HL()
288 --             local designaxis = designaxis or axis
289 --             for i=1,#regions do
290 --                 local axis = regions[i]
291 --                 for j=1,#axis do
292 --                     local a = axis[j]
293 --                     NC() monobold(i)
294 --                     NC() monobold(designaxis[j].tag)
295 --                     NC() context("%0.3f",a.start)
296 --                     NC() context("%0.3f",a.peak)
297 --                     NC() context("%0.3f",a.stop)
298 --                     NC() NR()
299 --                     i = nil
300 --                 end
301 --             end
302 --             context.stoptabulate()
303 --         else
304 --             context("no %s defined",tag)
305 --         end
306 --     context.stopsubject()
307 --
308 -- end
309 --
310 -- showregions("gregions")
311 -- showregions("mregions")
312 -- showregions("hregions")
313
314    context.stoptitle()
315
316end
317