diff options
author | Karl Berry <karl@freefriends.org> | 2013-05-18 22:21:33 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2013-05-18 22:21:33 +0000 |
commit | 2472c585a2dee03ef4665514cb651e5976fd134a (patch) | |
tree | cb0475ebdca2ed9ee248dd809f6bcce1671a0afb /Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua | |
parent | 542dd7f24e76ac20da26d1c4d7ceb69baa248133 (diff) |
luaotfload (18may13)
git-svn-id: svn://tug.org/texlive/trunk@30561 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua | 319 |
1 files changed, 291 insertions, 28 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua index 999bc22d36c..2bfcbf0caf1 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua @@ -21,17 +21,22 @@ config.luaotfload = config.luaotfload or { } local aux = luaotfload.aux local log = luaotfload.log local warning = luaotfload.log -local identifiers = fonts.hashes.identifiers +local fonthashes = fonts.hashes +local identifiers = fonthashes.identifiers local fontid = font.id local texsprint = tex.sprint +local dofile = dofile +local getmetatable = getmetatable +local setmetatable = setmetatable local utf8 = unicode.utf8 local stringlower = string.lower local stringformat = string.format local stringgsub = string.gsub local stringbyte = string.byte local stringfind = string.find +local tablecopy = table.copy ----------------------------------------------------------------------- --- font patches @@ -67,7 +72,7 @@ local add_fontdata_fallbacks = function (fontdata) metadata = fontdata.shared.rawdata.metadata fontdata.name = metadata.origname or fontdata.name fontdata.units = fontdata.units_per_em - fontdata.size = fontdata.size or fontparameters.size + fontdata.size = fontdata.size or fontparameters.size local resources = fontdata.resources --- for legacy fontspec.lua and unicode-math.lua fontdata.shared.otfdata = { @@ -75,16 +80,18 @@ local add_fontdata_fallbacks = function (fontdata) metadata = { ascent = metadata.ascent }, } --- for microtype and fontspec - local fake_features = { } -- wrong: table.copy(resources.features) + --local fake_features = { } + local fake_features = table.copy(resources.features) setmetatable(fake_features, { __index = function (tab, idx) - warning("some package (probably fontspec) is outdated") - warning( - "attempt to index " .. - "tfmdata.shared.otfdata.luatex.features (%s)", - idx) - --os.exit(1) - return nil --- empty anyways - end}) + warning("some package (probably fontspec) is outdated") + warning( + "attempt to index " .. + "tfmdata.shared.otfdata.luatex.features (%s)", + idx) + --os.exit(1) + return tab[idx] + end, + }) fontdata.shared.otfdata.luatex = { unicodes = resources.unicodes, features = fake_features, @@ -224,9 +231,11 @@ luatexbase.add_to_callback( "luaotfload.aux.set_capheight") ----------------------------------------------------------------------- ---- glyphs +--- glyphs and characters ----------------------------------------------------------------------- +local agl = fonts.encodings.agl + --- int -> int -> bool local font_has_glyph = function (font_id, codepoint) local fontdata = fonts.hashes.identifiers[font_id] @@ -238,6 +247,20 @@ end aux.font_has_glyph = font_has_glyph +--- undocumented + +local raw_slot_of_name = function (font_id, glyphname) + local fontdata = font.fonts[font_id] + if fontdata.type == "virtual" then --- get base font for glyph idx + local codepoint = agl.unicodes[glyphname] + local glyph = fontdata.characters[codepoint] + if fontdata.characters[codepoint] then + return codepoint + end + end + return false +end + --[[doc-- This one is approximately “name_to_slot” from the microtype package; @@ -246,18 +269,28 @@ aux.font_has_glyph = font_has_glyph http://www.adobe.com/devnet/opentype/archives/glyph.html + The “unsafe” switch triggers a fallback lookup in the raw fonts + table. As some of the information is stored as references, this may + have unpredictable side-effects. + --doc]]-- ---- int -> string -> (int | false) -local slot_of_name = function (font_id, glyphname) +--- int -> string -> bool -> (int | false) +local slot_of_name = function (font_id, glyphname, unsafe) local fontdata = identifiers[font_id] if fontdata then local unicode = fontdata.resources.unicodes[glyphname] - if unicode and type(unicode) == "number" then - return unicode - else - return unicode[1] --- for multiple components + if unicode then + if type(unicode) == "number" then + return unicode + else + return unicode[1] --- for multiple components + end +-- else +-- --- missing end + elseif unsafe == true then -- for Robert + return raw_slot_of_name(font_id, glyphname) end return false end @@ -280,7 +313,7 @@ local indices --- int -> (string | false) local name_of_slot = function (codepoint) if not indices then --- this will load the glyph list - local unicodes = fonts.encodings.agl.unicodes + local unicodes = agl.unicodes indices = table.swapped(unicodes) end local glyphname = indices[codepoint] @@ -292,6 +325,43 @@ end aux.name_of_slot = name_of_slot +--[[doc-- + + In Context, characters.data is where the data from char-def.lua + resides. The file is huge (>3.7 MB as of 2013) and not part of the + isolated font loader. Nevertheless, we include a partial version + generated by the mkcharacters script that contains only the + “direction” and “mirror” fields of each character defined. + +--doc]]-- + +characters = characters or { } --- should be created in basics-gen +characters.data = { } +local chardef = "luaotfload-characters" + +do + local chardata + local index = function (t, k) + if chardata == nil then + log("Loading character metadata from %s.", chardef) + chardata = dofile(kpse.find_file("luaotfload-characters.lua")) + if chardata == nil then + warning("Could not load %s; continuing with empty character table.", + chardef) + chardata = { } + end + end + return chardata[k] + end + + local mt = getmetatable(characters.data) + if mt then + mt.__index = index + else + setmetatable(characters.data, { __index = index }) + end +end + ----------------------------------------------------------------------- --- features / scripts / languages ----------------------------------------------------------------------- @@ -448,23 +518,216 @@ aux.provides_feature = provides_feature --- font dimensions ----------------------------------------------------------------------- ---- string -> string -> int -local get_math_dimension = function (csname, dimenname) - local fontdata = identifiers[fontid(csname)] +--- int -> string -> int +local get_math_dimension = function (font_id, dimenname) + if type(font_id) == "string" then + font_id = fontid(font_id) --- safeguard + end + local fontdata = identifiers[font_id] local mathdata = fontdata.mathparameters - if mathdata then return mathdata[dimenname] or 0 end + if mathdata then + return mathdata[dimenname] or 0 + end return 0 end aux.get_math_dimension = get_math_dimension ---- string -> string -> unit -local sprint_math_dimension = function (csname, dimenname) - local dim = get_math_dimension(csname, dimenname) - texsprint(luatexbase.catcodetables["latex-package"], dim) - texsprint(luatexbase.catcodetables["latex-package"], "sp") +--- int -> string -> unit +local sprint_math_dimension = function (font_id, dimenname) + if type(font_id) == "string" then + font_id = fontid(font_id) + end + local dim = get_math_dimension(font_id, dimenname) + texsprint(luatexbase.catcodetables["latex-package"], dim, "sp") end aux.sprint_math_dimension = sprint_math_dimension +----------------------------------------------------------------------- +--- extra database functions +----------------------------------------------------------------------- + +local namesresolve = fonts.names.resolve +local namesscan_dir = fonts.names.scan_dir + +--- local directories ------------------------------------------------- + +--- migrated from luaotfload-database.lua +--- https://github.com/lualatex/luaotfload/pull/61#issuecomment-17776975 + +--- string -> (int * int) +local scan_external_dir = function (dir) + local old_names, new_names = names.data + if not old_names then + old_names = load_names() + end + new_names = tablecopy(old_names) + local n_scanned, n_new = scan_dir(dir, old_names, new_names) + --- FIXME + --- This doesn’t seem right. If a db update is triggered after this + --- point, then the added fonts will be saved along with it -- + --- which is not as “temporarily” as it should be. (This should be + --- addressed during a refactoring of names_resolve().) + names.data = new_names + return n_scanned, n_new +end + +aux.scan_external_dir = scan_external_dir + +--- db queries -------------------------------------------------------- + +--- https://github.com/lualatex/luaotfload/issues/74 +--- string -> (string * int) +local resolve_fontname = function (name) + local foundname, subfont, success = namesresolve(nil, nil, { + name = name, + lookup = "name", + optsize = 0, + specification = "name:" .. name, + }) + if success then + return foundname, subfont + end + return false, false +end + +aux.resolve_fontname = resolve_fontname + +--- string list -> (string * int) +local resolve_fontlist +resolve_fontlist = function (names, n) + if not n then + return resolve_fontlist(names, 1) + end + local this = names[n] + if this then + local foundname, subfont = resolve_fontname(this) + if foundname then + return foundname, subfont + end + return resolve_fontlist(names, n+1) + end + return false, false +end + +aux.resolve_fontlist = resolve_fontlist + +--- loaded fonts ------------------------------------------------------ + +--- just a proof of concept + +--- fontobj -> string list -> (string list) list +local get_font_data get_font_data = function (tfmdata, keys, acc, n) + if not acc then + return get_font_data(tfmdata, keys, {}, 1) + end + local key = keys[n] + if key then + local val = tfmdata[key] + if val then + acc[#acc+1] = val + else + acc[#acc+1] = false + end + return get_font_data(tfmdata, keys, acc, n+1) + end + return acc +end + +--[[doc-- + + The next one operates on the fonts.hashes.identifiers table. + It returns a list containing tuples of font ids and the + contents of the fields specified in the first argument. + Font table entries that were created indirectly -- e.g. by + \letterspacefont or during font expansion -- will not be + listed. + +--doc]]-- + +local default_keys = { "fullname" } + +--- string list -> (int * string list) list +local get_loaded_fonts get_loaded_fonts = function (keys, acc, lastid) + if not acc then + if not keys then + keys = default_keys + end + return get_loaded_fonts(keys, {}, lastid) + end + local id, tfmdata = next(identifiers, lastid) + if id then + local data = get_font_data(tfmdata, keys) + acc[#acc+1] = { id, data } + return get_loaded_fonts (keys, acc, id) + end + return acc +end + +aux.get_loaded_fonts = get_loaded_fonts + +--- Raw access to the font.* namespace is unsafe so no documentation on +--- this one. +local get_raw_fonts = function ( ) + local res = { } + for i, v in font.each() do + if v.filename then + res[#res+1] = { i, v } + end + end + return res +end + +aux.get_raw_fonts = get_raw_fonts + +----------------------------------------------------------------------- +--- font parameters +----------------------------------------------------------------------- +--- analogy of font-hsh + +fonthashes.parameters = fonthashes.parameters or { } +fonthashes.quads = fonthashes.quads or { } + +local parameters = fonthashes.parameters or { } +local quads = fonthashes.quads or { } + +setmetatable(parameters, { __index = function (t, font_id) + local tfmdata = identifiers[font_id] + if not tfmdata then --- unsafe; avoid + tfmdata = font.fonts[font_id] + end + if tfmdata and type(tfmdata) == "table" then + local fontparameters = tfmdata.parameters + t[font_id] = fontparameters + return fontparameters + end + return nil +end}) + +--[[doc-- + + Note that the reason as to why we prefer functions over table indices + is that functions are much safer against unintended manipulation. + This justifies the overhead they cost. + +--doc]]-- + +--- int -> (number | false) +local get_quad = function (font_id) + local quad = quads[font_id] + if quad then + return quad + end + local fontparameters = parameters[font_id] + if fontparameters then + local quad = fontparameters.quad or 0 + quads[font_id] = quad + return quad + end + return false +end + +aux.get_quad = get_quad + -- vim:tw=71:sw=2:ts=2:expandtab |