1if not modules then modules = { } end modules ['luatex-fonts'] = { 2 version = 1.001, 3 comment = "companion to luatex-fonts.tex", 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-- A merged file is generated with: 10-- 11-- mtxrun --script package --merge --stripcontext luatex-fonts.lua 12-- 13-- A needed resource file is made by: 14-- 15-- mtxrun --script context luatex-basics-prepare.tex 16-- 17-- A font (generic) database is created with: 18-- 19-- mtxrun --script font --reload --simple 20 21-- The following code isolates the generic context code from already defined or to be defined 22-- namespaces. This is the reference loader for plain tex. This generic code is also used in 23-- luaotfload which is a low level lualatex opentype font loader but somehow has gotten a bit 24-- too generic name / prefix, originally set up and maintained by Khaled Hosny. Later that 25-- set of derived files was maintained by a larger team lead by Philipp Gesang, but afaik 26-- maintainance moved to latex team and the wrapper code in the meantime likely differs quite 27-- a bit from what was started with. So, issues with luaotfload shoudl be reported to the latex 28-- folk. If you suspect somethign wong in these files, it makes sense then to first check if 29-- context has the same issue: 30-- 31-- mtxrun --script context contextfile (mkxl aka lmtx) 32-- 33-- mtxrun --script context --luatex contextfile (mkiv) 34-- 35-- mtxrun --script plain --make 36-- mtxrun --script plain plaintexfile (tex) 37-- 38-- We only backport from context lmtx (luametatex) to context mkiv (luatex) if needed and to 39-- this file set (generic) when we think it makes sense. Keep in mind that not all features in 40-- context are supported in generic. 41-- 42-- The code base is rather stable now, especially if you stay away from the non generic code. All 43-- relevant data is organized in tables within the main table of a font instance. There are a few 44-- places where in context other code is plugged in, but this does not affect the core code. Users 45-- can (given that their macro package provides this option) access the font data (characters, 46-- descriptions, properties, parameters, etc) of this main table. The documentation is part of 47-- context. There is also a manual for the helper libraries (maintained as part of the cld manuals). 48-- 49-- Future versions will probably have some more specific context code removed, like tracing and 50-- obscure hooks, so that we have a more efficient version (and less files too). So, don't depend 51-- too much on low level code that is meant for context as it can change without notice. We might 52-- also add more helper code here, but that depends to what extend metatex (sidetrack of context) 53-- evolves into a low level layer (depends on time, as usual). 54 55-- The code here is the same as in context version 2015.09.11 (in the meantime 2024.06.14) but the 56-- rendering in context can be different from generic. This can be a side effect of additional 57-- callbacks, additional features and interferences between mechanisms between macro packages. We 58-- use the rendering in context and luatex-plain as reference for issues (see above for running). 59 60-- I might as well remove some code that is not used in generic (or not used by generic users) 61-- like color fonts (emoji etc) and variable fonts thereby making the code base smaller. However 62-- I might keep ity just for the sake of testing the plain loader that comes with context. We'll 63-- see. 64 65-- As a side effect of cleaning up some context code, like code meant for older version of luatex, 66-- as well replacing code for more recent versions (post 1.12) there can be changes in the modules 67-- used here, especially where we check for 'context' being used. Hopefully there are no side 68-- effects. Because we can now assume that the the glyph injection callback is in recent texlive 69-- installations, the variable font code is now enabled in the generic version that comes with 70-- context (as unofficial bonus; when it was demonstrated at bachotex 2017 it worked ok for the 71-- generic loader but was kind of disabled there as no one needs it). I waited with adding the 72-- pending code for type 3 support till texlive 2020 was fozen but it will be in texlive 2021 (it 73-- is already tested in context back in 2019 and I wanted to release it at the canceled BT 2020 74-- meeting, so I consider it stable, read: this is it). To what extend and when I will adapt the 75-- generic code (for color support) to that is yet to be decided because in context we do things 76-- a bit differently. We anyway have to wait a few years till that callback is omnipresent so I'm 77-- not in that much of a hurry. (There will be a TB article about it first and after that I will 78-- add some examples to the manual.) 79-- 80-- Fonts evolve over time. So if something doesn't work one might want to test older or newer 81-- version. We don't implement heuristics with regards to script/language combinations so that is 82-- often the first to test: what langauge, script, features are available and set. When the backend 83-- is involved macro package dependencies creep in. We've seen reports on something not working as 84-- that was just a matter configuration and not a bug. But we're always willing to fix real bugs, 85-- for which we need the font files then. 86 87utf = utf or (unicode and unicode.utf8) or { } 88 89-- We have some (global) hooks (for latex). Maybe I'll use this signal to disable some of the 90-- more tricky features like variable fonts and emoji (because afaik latex uses hb for that). 91 92if not non_generic_context then 93 non_generic_context = { } 94end 95 96if not non_generic_context.luatex_fonts then 97 non_generic_context.luatex_fonts = { 98 -- load_before = nil, 99 -- load_after = nil, 100 -- skip_loading = nil, 101 } 102end 103 104if not generic_context then 105 generic_context = { } 106end 107 108if not generic_context.push_namespaces then 109 110 function generic_context.push_namespaces() 111 -- logs.report("system","push namespace") 112 local normalglobal = { } 113 for k, v in next, _G do 114 normalglobal[k] = v 115 end 116 return normalglobal 117 end 118 119 function generic_context.pop_namespaces(normalglobal,isolate) 120 if normalglobal then 121 -- logs.report("system","pop namespace") 122 for k, v in next, _G do 123 if not normalglobal[k] then 124 generic_context[k] = v 125 if isolate then 126 _G[k] = nil 127 end 128 end 129 end 130 for k, v in next, normalglobal do 131 _G[k] = v 132 end 133 -- just to be sure: 134 setmetatable(generic_context,_G) 135 else 136 logs.report("system","fatal error: invalid pop of generic_context") 137 os.exit() 138 end 139 end 140 141end 142 143local whatever = generic_context.push_namespaces() 144 145-- We keep track of load time by storing the current time. That way we cannot be accused 146-- of slowing down loading too much. Anyhow, there is no reason for this library to perform 147-- slower in any other package as it does in context. 148-- 149-- Please don't update to this version without proper testing. It might be that this version 150-- lags behind stock context and the only formal release takes place around tex live code 151-- freeze. 152 153local starttime = os.gettimeofday() 154 155-- As we don't use the context file searching, we need to initialize the kpse library. As the 156-- progname can be anything we will temporary switch to the context namespace if needed. Just 157-- adding the context paths to the path specification is somewhat faster. 158-- 159-- Now, with lua 5.2 being used we might create a special ENV for this. 160 161-- kpse.set_program_name("luatex") 162 163-- One can define texio.reporter as alternative terminal/log writer. That's as far 164-- as I want to go with this. 165 166local ctxkpse = nil 167local verbose = true 168 169if not logs or not logs.report then 170 if not logs then 171 logs = { } 172 end 173 function logs.report(c,f,...) 174 local r = texio.reporter or texio.write_nl 175 if f then 176 r(c .. " : " .. string.format(f,...)) 177 else 178 r("") 179 end 180 end 181end 182 183local function loadmodule(name,continue) 184 local foundname = kpse.find_file(name,"tex") or "" 185 if not foundname then 186 if not ctxkpse then 187 ctxkpse = kpse.new("luatex","context") 188 end 189 foundname = ctxkpse:find_file(name,"tex") or "" 190 end 191 if foundname == "" then 192 if not continue then 193 logs.report("system","unable to locate file '%s'",name) 194 os.exit() 195 end 196 else 197 if verbose then 198 logs.report("system","loading '%s'",foundname) -- no file.basename yet 199 end 200 dofile(foundname) 201 end 202end 203 204if non_generic_context.luatex_fonts.load_before then 205 loadmodule(non_generic_context.luatex_fonts.load_before,true) 206end 207 208if non_generic_context.luatex_fonts.skip_loading ~= true then 209 210 loadmodule('luatex-fonts-merged.lua',true) 211 212 if fonts then 213 214 if not fonts._merge_loaded_message_done_ then 215 texio.write_nl("log", "!") 216 texio.write_nl("log", "! I am using the merged version of 'luatex-fonts.lua' here. If") 217 texio.write_nl("log", "! you run into problems or experience unexpected behaviour, and") 218 texio.write_nl("log", "! if you have ConTeXt installed you can try to delete the file") 219 texio.write_nl("log", "! 'luatex-font-merged.lua' as I might then use the possibly") 220 texio.write_nl("log", "! updated libraries. The merged version is not supported as it") 221 texio.write_nl("log", "! is a frozen instance. Problems can be reported to the ConTeXt") 222 texio.write_nl("log", "! mailing list.") 223 texio.write_nl("log", "!") 224 end 225 226 fonts._merge_loaded_message_done_ = true 227 228 else 229 230 -- The following helpers are a bit overkill but I don't want to mess up 231 -- context code for the sake of general generality. Around version 1.0 232 -- there will be an official api defined. 233 -- 234 -- So, I will strip these libraries and see what is really needed so that 235 -- we don't have this overhead in the generic modules. The next section 236 -- is only there for the packager, so stick to using luatex-fonts with 237 -- luatex-fonts-merged.lua and forget about the rest. The following list 238 -- might change without prior notice (for instance because we shuffled 239 -- code around). 240 241 loadmodule("l-lua.lua") 242 loadmodule("l-lpeg.lua") 243 loadmodule("l-function.lua") 244 loadmodule("l-string.lua") 245 loadmodule("l-table.lua") 246 loadmodule("l-io.lua") 247 loadmodule("l-file.lua") 248 loadmodule("l-boolean.lua") 249 loadmodule("l-math.lua") 250 251 -- A few slightly higher level support modules: 252 253 loadmodule("util-str.lua") -- future versions can ship without this one 254 loadmodule("util-fil.lua") -- future versions can ship without this one 255 256 -- The following modules contain code that is either not used at all 257 -- outside context or will fail when enabled due to lack of other 258 -- modules. 259 260 -- First we load a few helper modules. This is about the miminum needed 261 -- to let the font modules do their work. Don't depend on their functions 262 -- as we might strip them in future versions of this generic variant. 263 264 loadmodule('luatex-basics-gen.lua') 265 loadmodule('data-con.lua') 266 267 -- We do need some basic node support. The code in there is not for 268 -- general use as it might change. 269 270 loadmodule('luatex-basics-nod.lua') 271 272 -- We ship a resources needed for font handling (more might end up here). 273 274 loadmodule('luatex-basics-chr.lua') 275 276 -- Now come the font modules that deal with traditional tex fonts as well 277 -- as open type fonts. 278 -- 279 -- The font database file (if used at all) must be put someplace visible 280 -- for kpse and is not shared with context. The mtx-fonts script can be 281 -- used to generate this file (using the --reload --force --simple option). 282 283 loadmodule('font-ini.lua') 284 loadmodule('luatex-fonts-mis.lua') 285 loadmodule('font-con.lua') 286 loadmodule('luatex-fonts-enc.lua') 287 loadmodule('font-cid.lua') 288 loadmodule('font-map.lua') 289 290 -- We use a bit simpler database because using the context one demands 291 -- loading more helper code and although it is more flexible (more ways 292 -- to resolve and so) it will never be uses in plain/latex anyway, so 293 -- let's stick to a simple approach. 294 295 loadmodule('luatex-fonts-syn.lua') 296 297 -- We need some helpers. 298 299 loadmodule('font-vfc.lua') 300 301 -- This is the bulk of opentype code. The color and variable font support (as for 302 -- emoji) can (and might) actually go away here because it has never been used 303 -- outside context so in retrospect there was no need for it being generic. 304 305 loadmodule('font-otr.lua') 306 loadmodule('font-cff.lua') 307 loadmodule('font-ttf.lua') 308 loadmodule('font-dsp.lua') 309 loadmodule('font-oti.lua') 310 loadmodule('font-ott.lua') 311 loadmodule('font-otl.lua') 312 loadmodule('font-oto.lua') 313 loadmodule('font-otj.lua') 314 loadmodule('font-oup.lua') 315 loadmodule('font-ota.lua') 316 loadmodule('font-ots.lua') 317 loadmodule('font-otc.lua') 318 loadmodule('font-osd.lua') 319 loadmodule('font-ocl.lua') 320 321 -- The code for type one fonts. 322 323 loadmodule('font-onr.lua') 324 loadmodule('font-one.lua') 325 loadmodule('font-afk.lua') 326 327 -- And for traditional TeX fonts. 328 329 loadmodule('luatex-fonts-tfm.lua') 330 331 -- Some common code. 332 333 loadmodule('font-lua.lua') 334 loadmodule('font-def.lua') 335 loadmodule('font-shp.lua') 336 337 -- We support xetex compatible specifiers (plain/latex only). 338 339 loadmodule('luatex-fonts-def.lua') -- was font-xtx.lua 340 341 -- Here come some additional features. 342 343 loadmodule('luatex-fonts-ext.lua') 344 loadmodule('font-imp-tex.lua') 345 loadmodule('font-imp-ligatures.lua') 346 loadmodule('font-imp-italics.lua') 347 loadmodule('font-imp-effects.lua') 348 loadmodule('luatex-fonts-lig.lua') 349 350 -- We need to plug into a callback and the following module implements the 351 -- handlers. Actual plugging in happens later. 352 353 loadmodule('luatex-fonts-gbn.lua') 354 355 end 356 357end 358 359if non_generic_context.luatex_fonts.load_after then 360 loadmodule(non_generic_context.luatex_fonts.load_after,true) 361end 362 363resolvers.loadmodule = loadmodule 364 365-- In order to deal with the fonts we need to initialize some callbacks. One can overload them later 366-- on if needed. First a bit of abstraction. 367 368generic_context.callback_ligaturing = false 369generic_context.callback_kerning = false 370generic_context.callback_pre_linebreak_filter = nodes.simple_font_handler 371generic_context.callback_hpack_filter = nodes.simple_font_handler 372generic_context.callback_define_font = fonts.definers.read 373 374-- The next ones can be done at a different moment if needed. You can create a generic_context namespace 375-- and set no_callbacks_yet to true, load this module, and enable the callbacks later. So, there is really 376-- *no* need to create a alternative for luatex-fonts.lua and luatex-fonts-merged.lua: just load this one 377-- and overload if needed. 378 379if not generic_context.no_callbacks_yet then 380 381 callback.register('ligaturing', generic_context.callback_ligaturing) 382 callback.register('kerning', generic_context.callback_kerning) 383 callback.register('pre_linebreak_filter', generic_context.callback_pre_linebreak_filter) 384 callback.register('hpack_filter', generic_context.callback_hpack_filter) 385 callback.register('define_font' , generic_context.callback_define_font) 386 387end 388 389-- We're done. 390 391logs.report("system","luatex-fonts.lua loaded in %0.3f seconds", os.gettimeofday()-starttime) 392 393generic_context.pop_namespaces(whatever) 394 |