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