font-enc.lua /size: 5150 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['font-enc'] = {
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
9-- this module is obsolete
10
11local next, rawget = next, rawget
12local match, gmatch, gsub = string.match, string.gmatch, string.gsub
13
14local setmetatableindex = table.setmetatableindex
15
16local allocate          = utilities.storage.allocate
17local mark              = utilities.storage.mark
18
19--[[ldx--
20<p>Because encodings are going to disappear, we don't bother defining
21them in tables. But we may do so some day, for consistency.</p>
22--ldx]]--
23
24local report_encoding = logs.reporter("fonts","encoding")
25
26local encodings = fonts.encodings or { }
27fonts.encodings = encodings
28
29encodings.version = 1.03
30encodings.cache   = containers.define("fonts", "enc", fonts.encodings.version, true)
31encodings.known   = allocate { -- sort of obsolete
32    texnansi = true,
33    ec       = true,
34    qx       = true,
35    t5       = true,
36    t2a      = true,
37    t2b      = true,
38    t2c      = true,
39    unicode  = true,
40}
41
42function encodings.is_known(encoding)
43    return containers.is_valid(encodings.cache,encoding)
44end
45
46--[[ldx--
47<p>An encoding file looks like this:</p>
48
49<typing>
50/TeXnANSIEncoding [
51/.notdef
52/Euro
53...
54/ydieresis
55] def
56</typing>
57
58<p>Beware! The generic encoding files don't always apply to the ones that
59ship with fonts. This has to do with the fact that names follow (slightly)
60different standards. However, the fonts where this applies to (for instance
61Latin Modern or <l n='tex'> Gyre) come in OpenType variants too, so these
62will be used.</p>
63--ldx]]--
64
65local enccodes = characters.enccodes or { }
66
67function encodings.load(filename)
68    local name = file.removesuffix(filename)
69    local data = containers.read(encodings.cache,name)
70    if data then
71        return data
72    end
73    if name == "unicode" then
74        data = encodings.make_unicode_vector() -- special case, no tex file for this
75    end
76    if data then
77        return data
78    end
79    local vector, tag, hash, unicodes = { }, "", { }, { }
80    local foundname = resolvers.findfile(filename,'enc')
81    if foundname and foundname ~= "" then
82        local ok, encoding, size = resolvers.loadbinfile(foundname)
83        if ok and encoding then
84            encoding = gsub(encoding,"%%(.-)[\n\r]+","")
85            if encoding then
86                local unicoding = fonts.encodings.agl.unicodes
87                local tag, vec = match(encoding,"[/]*(%w+)%s*%[(.*)%]%s*def")
88                if vec then
89                    local i = 0
90                    for ch in gmatch(vec,"/([%a%d%.]+)") do
91                        if ch ~= ".notdef" then
92                            vector[i] = ch
93                            if not hash[ch] then
94                                hash[ch] = i
95                            else
96                                -- duplicate, play safe for tex ligs and take first
97                            end
98                            local u = unicoding[ch] or enccodes[ch] -- enccodes have also context names
99                            if u then
100                                unicodes[u] = i
101                            end
102                        end
103                        i = i + 1
104                    end
105                else
106                    report_encoding("reading vector in encoding file %a fails",filename)
107                end
108            else
109                report_encoding("reading encoding file %a fails",filename)
110            end
111        end
112    end
113    local data = {
114        name     = name,
115        tag      = tag,
116        vector   = vector,
117        hash     = hash,
118        unicodes = unicodes
119    }
120    return containers.write(encodings.cache, name, data)
121end
122
123--[[ldx--
124<p>There is no unicode encoding but for practical purposes we define
125one.</p>
126--ldx]]--
127
128-- maybe make this a function:
129
130function encodings.make_unicode_vector()
131    local vector, hash = { }, { }
132    for code, v in next, characters.data do
133        local name = v.adobename
134        if name then
135            vector[code] = name
136            hash[name]   = code
137        else
138            vector[code] = '.notdef'
139        end
140    end
141    for name, code in next, characters.synonyms do
142        if not vector[code] then
143            vector[code] = name
144        end
145        if not hash[name] then
146            hash[name]   = code
147        end
148    end
149    return containers.write(encodings.cache, 'unicode', { name='unicode', tag='unicode', vector=vector, hash=hash })
150end
151
152if not encodings.agl then
153
154    -- We delay delay loading this rather big vector that is only needed when a
155    -- font is loaded for caching. Once we're further along the route we can also
156    -- delay it in the generic version (which doesn't use this file).
157
158    encodings.agl = allocate { }
159
160    setmetatableindex(encodings.agl, function(t,k)
161        report_encoding("loading (extended) adobe glyph list")
162        dofile(resolvers.findfile("font-agl.lua"))
163        return rawget(encodings.agl,k)
164    end)
165
166end
167