font-aux.lua /size: 6644 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['font-aux'] = {
2    version   = 1.001,
3    comment   = "companion to font-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 tonumber, type, next = tonumber, type, next
10----- wrap, yield = coroutine.wrap, coroutine.yield
11
12local fonts, font = fonts, font
13
14local fonts       = fonts
15local handlers    = fonts.handlers
16local otf         = handlers.otf -- brrr
17local afm         = handlers.afm -- brrr
18
19local iterators   = { }
20fonts.iterators   = iterators
21
22local currentfont = font.current
23local identifiers = fonts.hashes.identifiers
24local sortedkeys  = table.sortedkeys
25
26-- for unicode, character   in fonts.iterators.characters  () do print(unicode) end
27-- for unicode, description in fonts.iterators.descriptions() do print(unicode) end
28-- for index,   glyph       in fonts.iterators.glyphs      () do print(index  ) end
29
30local function dummy() end
31
32local function checkeddata(data) -- beware, nullfont is the fallback in identifiers
33    local t = type(data)
34    if t == "table" then
35        return data
36    elseif t ~= "number" then
37        data = currentfont()
38    end
39    return identifiers[data] -- has nullfont as fallback
40end
41
42local function getindices(data)
43    data = checkeddata(data)
44    local indices = { }
45    local characters = data.characters
46    if characters then
47        for unicode, character in next, characters do
48            indices[character.index or unicode] = unicode
49        end
50    end
51    return indices
52end
53
54-- function iterators.characters(data)
55--     data = checkeddata(data)
56--     local characters = data.characters
57--     if characters then
58--         local collected = sortedkeys(characters)
59--         return wrap(function()
60--             for c=1,#collected do
61--                 local cc = collected[c]
62--                 local dc = characters[cc]
63--                 if dc then
64--                     yield(cc,dc)
65--                 end
66--             end
67--         end)
68--     else
69--         return wrap(function() end)
70--     end
71-- end
72
73-- function iterators.descriptions(data)
74--     data = checkeddata(data)
75--     local characters = data.characters
76--     local descriptions = data.descriptions
77--     if characters and descriptions then
78--         local collected = sortedkeys(characters)
79--         return wrap(function()
80--             for c=1,#collected do
81--                 local cc = collected[c]
82--                 local dc = descriptions[cc]
83--                 if dc then
84--                     yield(cc,dc)
85--                 end
86--             end
87--         end)
88--     else
89--         return wrap(function() end)
90--     end
91-- end
92
93-- function iterators.glyphs(data)
94--     data = checkeddata(data)
95--     local descriptions = data.descriptions
96--     if descriptions then
97--         local indices = getindices(data)
98--         local collected = sortedkeys(indices)
99--         return wrap(function()
100--             for c=1,#collected do
101--                 local cc = collected[c]
102--                 local dc = descriptions[indices[cc]]
103--                 if dc then
104--                     yield(cc,dc)
105--                 end
106--             end
107--         end)
108--     else
109--         return wrap(function() end)
110--     end
111-- end
112
113function iterators.characters(data)
114    data = checkeddata(data)
115    local characters = data.characters
116    if characters then
117        local collected = sortedkeys(characters)
118        local n, i = #collected, 0
119        return function()
120            i = i + 1
121            if i <= n then
122                local cc = collected[i]
123                local dc = characters[cc]
124                return cc, dc or { }
125            end
126        end
127    else
128        return dummy
129    end
130end
131
132function iterators.descriptions(data)
133    data = checkeddata(data)
134    local characters = data.characters
135    local descriptions = data.descriptions
136    if characters and descriptions then
137        local collected = sortedkeys(characters)
138        local n, i = #collected, 0
139        return function()
140            i = i + 1
141            if i <= n then
142                local cc = collected[i]
143                local dc = descriptions[cc]
144                return cc, dc or { }
145            end
146        end
147    else
148        return dummy
149    end
150end
151
152function iterators.glyphs(data)
153    data = checkeddata(data)
154    local descriptions = data.descriptions
155    if descriptions then
156        local indices = getindices(data)
157        local collected = sortedkeys(indices)
158        local n, i = #collected, 0
159        return function()
160            i = i + 1
161            if i <= n then
162                local cc = collected[i]
163                local dc = descriptions[indices[cc]]
164                return cc, dc or { }
165            end
166        end
167    else
168        return dummy
169    end
170end
171
172-- for the moment here, it might move to some other file later
173
174function afm.getkern(tfmdata,left,right)
175    local c = tfmdata.characters[left]
176    if c then
177        local kerns = c.kerns
178        if kerns then
179            return kerns[right] -- already scaled
180        end
181    end
182    return 0
183end
184
185local getters = { -- maybe better getters[format][...]
186    kern = {
187        ["type1"]    = afm.getkern,
188        ["type3"]    = afm.getkern,
189        ["opentype"] = otf.getkern,
190    },
191    substitution = {
192        ["opentype"] = otf.getsubstitution,
193    },
194    alternate = {
195        ["opentype"] = otf.getalternate,
196    },
197    multiple = {
198        ["opentype"] = otf.getmultiple,
199    }
200}
201
202fonts.getters = getters
203
204function fonts.getkern(tfmdata,left,right)
205    local format = tfmdata.properties.format
206    local getter = getters.kern[format]
207    if getter then
208        return getter(tfmdata,left,right)
209    else
210        return 0
211    end
212end
213
214function fonts.getsubstitution(tfmdata,k,kind)
215    local format = tfmdata.properties.format
216    local getter = getters.substitution[format]
217    if getter then
218        return getter(tfmdata,k,kind,value)
219    else
220        return 0
221    end
222end
223
224function fonts.getalternate(tfmdata,k,kind,value)
225    local format = tfmdata.properties.format
226    local getter = getters.substitution[format]
227    if getter then
228        return getter(tfmdata,k,kind,value)
229    else
230        return 0
231    end
232end
233
234function fonts.getmultiple(tfmdata,k,kind)
235    local format = tfmdata.properties.format
236    local getter = getters.substitution[format]
237    if getter then
238        return getter(tfmdata,k,kind,value)
239    else
240        return 0
241    end
242end
243
244function fonts.getindices(tfmdata)
245    return getindices(tfmdata)
246end
247