summaryrefslogtreecommitdiff
path: root/src/fontloader/misc/fontloader-fonts.lua
blob: 1d2f2037fea1889cfbead8c3794f4b33fe590f68 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
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
315
316
if not modules then modules = { } end modules ['luatex-fonts'] = {
    version   = 1.001,
    comment   = "companion to luatex-fonts.tex",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- A merged file is generated with:
--
--   mtxrun --script package --merge ./luatex-fonts.lua
--
-- A needed resource file is made by:
--
--   mtxrun --script context luatex-basics-prepare.tex
--
-- A font (generic) database is created with:
--
--   mtxrun --script font --reload --simple

-- The following code isolates the generic context code from already defined or to be defined
-- namespaces. This is the reference loader for plain tex. This generic code is also used in
-- luaotfload which is a low level lualatex opentype font loader but somehow has gotten a bit
-- too generic name / prefix, originally set up and maintained by Khaled Hosny. Currently that
-- set of derived files is maintained by a larger team lead by Philipp Gesang so when there are
-- issues with this code in latex, you can best contact him. It might make sense then to first
-- check if context has the same issue. We do our best to keep the interface as clean as possible.
--
-- The code base is rather stable now, especially if you stay away from the non generic code. All
-- relevant data is organized in tables within the main table of a font instance. There are a few
-- places where in context other code is plugged in, but this does not affect the core code. Users
-- can (given that their macro package provides this option) access the font data (characters,
-- descriptions, properties, parameters, etc) of this main table. The documentation is part of
-- context. There is also a manual for the helper libraries (maintained as part of the cld manuals).
--
-- Future versions will probably have some more specific context code removed, like tracing and
-- obscure hooks, so that we have a more efficient version (and less files too). So, don't depend
-- too much on low level code that is meant for context as it can change without notice. We might
-- also add more helper code here, but that depends to what extend metatex (sidetrack of context)
-- evolves into a low level layer (depends on time, as usual).

-- The code here is the same as in context version 2015.09.11 but the rendering in context can be
-- different from generic. This can be a side effect of additional callbacks, additional features
-- and interferences between mechanisms between macro packages. We use the rendering in context
-- and luatex-plain as reference for issues.

utf = utf or unicode.utf8

-- We have some (global) hooks (for latex):

if not non_generic_context then
    non_generic_context = { }
end

if not non_generic_context.luatex_fonts then
    non_generic_context.luatex_fonts = {
     -- load_before  = nil,
     -- load_after   = nil,
     -- skip_loading = nil,
    }
end

if not generic_context then
    generic_context  = { }
end

if not generic_context.push_namespaces then

    function generic_context.push_namespaces()
        texio.write(" <push namespace>")
        local normalglobal = { }
        for k, v in next, _G do
            normalglobal[k] = v
        end
        return normalglobal
    end

    function generic_context.pop_namespaces(normalglobal,isolate)
        if normalglobal then
            texio.write(" <pop namespace>")
            for k, v in next, _G do
                if not normalglobal[k] then
                    generic_context[k] = v
                    if isolate then
                        _G[k] = nil
                    end
                end
            end
            for k, v in next, normalglobal do
                _G[k] = v
            end
            -- just to be sure:
            setmetatable(generic_context,_G)
        else
            texio.write(" <fatal error: invalid pop of generic_context>")
            os.exit()
        end
    end

end

local whatever = generic_context.push_namespaces()

-- We keep track of load time by storing the current time. That way we cannot be accused
-- of slowing down loading too much. Anyhow, there is no reason for this library to perform
-- slower in any other package as it does in context.
--
-- Please don't update to this version without proper testing. It might be that this version
-- lags behind stock context and the only formal release takes place around tex live code
-- freeze.

local starttime = os.gettimeofday()

-- As we don't use the context file searching, we need to initialize the kpse library. As the
-- progname can be anything we will temporary switch to the context namespace if needed. Just
-- adding the context paths to the path specification is somewhat faster.
--
-- Now, with lua 5.2 being used we might create a special ENV for this.

-- kpse.set_program_name("luatex")

local ctxkpse = nil
local verbose = true

local function loadmodule(name,continue)
    local foundname = kpse.find_file(name,"tex") or ""
    if not foundname then
        if not ctxkpse then
            ctxkpse = kpse.new("luatex","context")
        end
        foundname = ctxkpse:find_file(name,"tex") or ""
    end
    if foundname == "" then
        if not continue then
            texio.write_nl(string.format(" <luatex-fonts: unable to locate %s>",name))
            os.exit()
        end
    else
        if verbose then
            texio.write(string.format(" <%s>",foundname)) -- no file.basename yet
        end
        dofile(foundname)
    end
end

if non_generic_context.luatex_fonts.load_before then
    loadmodule(non_generic_context.luatex_fonts.load_before,true)
end

if non_generic_context.luatex_fonts.skip_loading ~= true then

    loadmodule('luatex-fonts-merged.lua',true)

    if fonts then

        if not fonts._merge_loaded_message_done_ then
            texio.write_nl("log", "!")
            texio.write_nl("log", "! I am using the merged version of 'luatex-fonts.lua' here. If")
            texio.write_nl("log", "! you run into problems or experience unexpected behaviour, and")
            texio.write_nl("log", "! if you have ConTeXt installed you can try to delete the file")
            texio.write_nl("log", "! 'luatex-font-merged.lua' as I might then use the possibly")
            texio.write_nl("log", "! updated libraries. The merged version is not supported as it")
            texio.write_nl("log", "! is a frozen instance. Problems can be reported to the ConTeXt")
            texio.write_nl("log", "! mailing list.")
            texio.write_nl("log", "!")
        end

        fonts._merge_loaded_message_done_ = true

    else

        -- The following helpers are a bit overkill but I don't want to mess up context code for the
        -- sake of general generality. Around version 1.0 there will be an official api defined.
        --
        -- So, I will strip these libraries and see what is really needed so that we don't have this
        -- overhead in the generic modules. The next section is only there for the packager, so stick
        -- to using luatex-fonts with luatex-fonts-merged.lua and forget about the rest. The following
        -- list might change without prior notice (for instance because we shuffled code around).

        loadmodule("l-lua.lua")
        loadmodule("l-lpeg.lua")
        loadmodule("l-function.lua")
        loadmodule("l-string.lua")
        loadmodule("l-table.lua")
        loadmodule("l-io.lua")
        loadmodule("l-file.lua")
        loadmodule("l-boolean.lua")
        loadmodule("l-math.lua")

        -- A few slightly higher level support modules:

        loadmodule("util-str.lua")
        loadmodule("util-fil.lua")

        -- The following modules contain code that is either not used at all outside context or will
        -- fail when enabled due to lack of other modules.

        -- First we load a few helper modules. This is about the miminum needed to let the font modules
        -- do their work. Don't depend on their functions as we might strip them in future versions of
        -- this generic variant.

        loadmodule('luatex-basics-gen.lua')
        loadmodule('data-con.lua')

        -- We do need some basic node support. The code in there is not for general use as it might
        -- change.

        loadmodule('luatex-basics-nod.lua')

        -- We ship a resources needed for font handling (more might end up here).

        loadmodule('luatex-basics-chr.lua')

        -- Now come the font modules that deal with traditional tex fonts as well as open type fonts.
        --
        -- The font database file (if used at all) must be put someplace visible for kpse and is not
        -- shared with context. The mtx-fonts script can be used to generate this file (using the
        -- --reload --force --simple option).

        loadmodule('font-ini.lua')
        loadmodule('font-con.lua')
        loadmodule('luatex-fonts-enc.lua') -- will load font-age on demand
        loadmodule('font-cid.lua')
        loadmodule('font-map.lua')         -- for loading lum file (will be stripped)

        -- We use a bit simpler database because using the context one demands loading more helper
        -- code and although it is more flexible (more wauys to resolve and so) it will never be
        -- uses in plain/latex anyway, so let's stick to a simple approach.

        loadmodule('luatex-fonts-syn.lua')

        loadmodule('font-tfm.lua')
        loadmodule('font-oti.lua')

        -- These are the old loader and processing modules. These use the built-in font loader and
        -- will stay around (but not be extended), only fixed.

        -- font-otf.lua
        -- font-otb.lua
        -- font-inj.lua
        -- font-ota.lua
        -- font-otn.lua
        -- font-otp.lua

        -- Here come the new loader and processing modules. The loader is written in Lua and although
        -- initial loading is somewhat slower, identifying is faster, cached files can be slightly
        -- more efficient, and processing is somewhat faster (only measureable on complex fonts).

        loadmodule('font-otr.lua')
        loadmodule('font-cff.lua')
        loadmodule('font-ttf.lua')
        loadmodule('font-dsp.lua')
        loadmodule('font-oup.lua')
        loadmodule('font-otl.lua')
        loadmodule('font-oto.lua')
        loadmodule('font-otj.lua')
        loadmodule('font-ota.lua')
        loadmodule('font-ots.lua')
        loadmodule('font-osd.lua')

        -- type one code

        loadmodule('font-one.lua') -- was font-afm.lua
        loadmodule('font-afk.lua')

        -- common code

        loadmodule('font-lua.lua')
        loadmodule('font-def.lua')
        loadmodule('font-xtx.lua')         -- xetex compatible specifiers (plain/latex only)
        loadmodule('luatex-fonts-ext.lua') -- some extensions

        -- We need to plug into a callback and the following module implements the handlers. Actual
        -- plugging in happens later.

        loadmodule('font-gbn.lua')

    end

end

if non_generic_context.luatex_fonts.load_after then
    loadmodule(non_generic_context.luatex_fonts.load_after,true)
end

resolvers.loadmodule = loadmodule

-- In order to deal with the fonts we need to initialize some callbacks. One can overload them later
-- on if needed. First a bit of abstraction.

generic_context.callback_ligaturing           = false
generic_context.callback_kerning              = false
generic_context.callback_pre_linebreak_filter = nodes.simple_font_handler
generic_context.callback_hpack_filter         = nodes.simple_font_handler
generic_context.callback_define_font          = fonts.definers.read

-- The next ones can be done at a different moment if needed. You can create a generic_context namespace
-- and set no_callbacks_yet to true, load this module, and enable the callbacks later. So, there is really
-- *no* need to create a alternative for luatex-fonts.lua and luatex-fonts-merged.lua: just load this one
-- and overload if needed.

if not generic_context.no_callbacks_yet then

    callback.register('ligaturing',           generic_context.callback_ligaturing)
    callback.register('kerning',              generic_context.callback_kerning)
    callback.register('pre_linebreak_filter', generic_context.callback_pre_linebreak_filter)
    callback.register('hpack_filter',         generic_context.callback_hpack_filter)
    callback.register('define_font' ,         generic_context.callback_define_font)

end

-- We're done.

texio.write(string.format(" <luatex-fonts.lua loaded in %0.3f seconds>", os.gettimeofday()-starttime))

generic_context.pop_namespaces(whatever)