diff options
Diffstat (limited to 'tex/context/base/font-syn.lua')
-rw-r--r-- | tex/context/base/font-syn.lua | 165 |
1 files changed, 129 insertions, 36 deletions
diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua index 5b50ac75f..bf46c8573 100644 --- a/tex/context/base/font-syn.lua +++ b/tex/context/base/font-syn.lua @@ -33,7 +33,14 @@ local exists = io.exists local findfile = resolvers.findfile local cleanpath = resolvers.cleanpath -local resolveresolved = resolvers.resolve +local resolveprefix = resolvers.resolve + +local fontloader = fontloader +local font_to_table = fontloader.to_table +local open_font = fontloader.open +local get_font_info = fontloader.info +local close_font = fontloader.close +local font_fields = fontloader.fields local settings_to_hash = utilities.parsers.settings_to_hash_tolerant @@ -50,7 +57,7 @@ using a table that has keys filtered from the font related files.</p> fonts = fonts or { } -- also used elsewhere -local names = font.names or allocate { } +local names = fonts.names or allocate { } fonts.names = names local filters = names.filters or { } @@ -81,7 +88,33 @@ directives.register("fonts.usesystemfonts", function(v) usesystemfonts = toboole local P, C, Cc, Cs = lpeg.P, lpeg.C, lpeg.Cc, lpeg.Cs --- what to do with 'thin' +-- -- what to do with these -- -- +-- +-- thin -> thin +-- +-- regu -> regular -> normal +-- norm -> normal -> normal +-- stan -> standard -> normal +-- medi -> medium +-- ultr -> ultra +-- ligh -> light +-- heav -> heavy +-- blac -> black +-- thin +-- book +-- verylight +-- +-- buch -> book +-- buchschrift -> book +-- halb -> demi +-- halbfett -> demi +-- mitt -> medium +-- mittel -> medium +-- fett -> bold +-- mage -> light +-- mager -> light +-- nord -> normal +-- gras -> normal local weights = Cs ( -- not extra P("demibold") @@ -90,6 +123,7 @@ local weights = Cs ( -- not extra + P("ultrabold") + P("extrabold") + P("ultralight") + + P("extralight") + P("bold") + P("demi") + P("semi") @@ -103,6 +137,17 @@ local weights = Cs ( -- not extra + P("regular") / "normal" ) +-- numeric_weights = { +-- 200 = "extralight", +-- 300 = "light", +-- 400 = "book", +-- 500 = "medium", +-- 600 = "demi", +-- 700 = "bold", +-- 800 = "heavy", +-- 900 = "black", +-- } + local normalized_weights = sparse { regular = "normal", } @@ -116,6 +161,7 @@ local styles = Cs ( + P("roman") / "normal" + P("ital") / "italic" -- might be tricky + P("ita") / "italic" -- might be tricky +--+ P("obli") / "oblique" ) local normalized_styles = sparse { @@ -129,6 +175,7 @@ local widths = Cs( + P("thin") + P("expanded") + P("cond") / "condensed" +--+ P("expa") / "expanded" + P("normal") + P("book") / "normal" ) @@ -258,22 +305,25 @@ end but to keep the overview, we define them here.</p> --ldx]]-- -filters.otf = fontloader.info -filters.ttf = fontloader.info -filters.ttc = fontloader.info -filters.dfont = fontloader.info +filters.otf = get_font_info +filters.ttf = get_font_info +filters.ttc = get_font_info +filters.dfont = get_font_info -- We had this as temporary solution because we needed a bit more info but in the -- meantime it got an interesting side effect: currently luatex delays loading of e.g. -- glyphs so here we first load and then discard which is a waste. In the past it did -- free memory because a full load was done. One of these things that goes unnoticed. -- --- function fontloader.fullinfo(...) -- check with taco what we get / could get --- local ff = fontloader.open(...) +-- missing: names, units_per_em, design_range_bottom, design_range_top, design_size, +-- pfminfo, top_side_bearing + +-- local function get_full_info(...) -- check with taco what we get / could get +-- local ff = open_font(...) -- if ff then --- local d = ff -- and fontloader.to_table(ff) +-- local d = ff -- and font_to_table(ff) -- d.glyphs, d.subfonts, d.gpos, d.gsub, d.lookups = nil, nil, nil, nil, nil --- fontloader.close(ff) +-- close_font(ff) -- return d -- else -- return nil, "error in loading font" @@ -283,11 +333,11 @@ filters.dfont = fontloader.info -- Phillip suggested this faster variant but it's still a hack as fontloader.info should -- return these keys/values (and maybe some more) but at least we close the loader which -- might save some memory in the end. --- --- function fontloader.fullinfo(name) --- local ff = fontloader.open(name) + +-- local function get_full_info(name) +-- local ff = open_font(name) -- if ff then --- local fields = table.tohash(fontloader.fields(ff),true) +-- local fields = table.tohash(font_fields(ff),true) -- isn't that one stable -- local d = { -- names = fields.names and ff.names, -- familyname = fields.familyname and ff.familyname, @@ -301,33 +351,73 @@ filters.dfont = fontloader.info -- design_size = fields.design_size and ff.design_size, -- italicangle = fields.italicangle and ff.italicangle, -- pfminfo = fields.pfminfo and ff.pfminfo, +-- top_side_bearing = fields.top_side_bearing and ff.top_side_bearing, -- } --- table.setmetatableindex(d,function(t,k) +-- setmetatableindex(d,function(t,k) -- report_names("warning, trying to access field %a in font table of %a",k,name) -- end) --- fontloader.close(ff) +-- close_font(ff) -- return d -- else -- return nil, "error in loading font" -- end -- end --- As we have lazy loading anyway, this one still is full and with less code than --- the previous one. +-- more efficient: + +local fields = nil -function fontloader.fullinfo(...) - local ff = fontloader.open(...) +local function get_full_info(name) + local ff = open_font(name) if ff then - local d = { } -- ff is userdata so [1] or # fails on it - table.setmetatableindex(d,ff) + if not fields then + fields = table.tohash(font_fields(ff),true) + end + -- unfortunately luatex aborts when a field is not available + local d = { + names = fields.names and ff.names, + familyname = fields.familyname and ff.familyname, + fullname = fields.fullname and ff.fullname, + fontname = fields.fontname and ff.fontname, + weight = fields.weight and ff.weight, + italicangle = fields.italicangle and ff.italicangle, + units_per_em = fields.units_per_em and ff.units_per_em, + design_range_bottom = fields.design_range_bottom and ff.design_range_bottom, + design_range_top = fields.design_range_top and ff.design_range_top, + design_size = fields.design_size and ff.design_size, + italicangle = fields.italicangle and ff.italicangle, + pfminfo = fields.pfminfo and ff.pfminfo, + top_side_bearing = fields.top_side_bearing and ff.top_side_bearing, -- not there + } + setmetatableindex(d,function(t,k) + report_names("warning, trying to access field %a in font table of %a",k,name) + end) + close_font(ff) return d else return nil, "error in loading font" end end -filters.otf = fontloader.fullinfo -filters.ttf = fontloader.fullinfo +-- As we have lazy loading anyway, this one still is full and with less code than +-- the previous one. But this depends on the garbage collector to kick in and in the +-- current version that somehow happens not that often (on my machine I end up with +-- soem 3 GB extra before that happens). + +-- local function get_full_info(...) +-- local ff = open_font(...) +-- if ff then +-- local d = { } -- ff is userdata so [1] or # fails on it +-- setmetatableindex(d,ff) +-- return d -- garbage collection will do the close_font(ff) +-- else +-- return nil, "error in loading font" +-- end +-- end + +fontloader.fullinfo = get_full_info +filters .otf = get_full_info +filters .ttf = get_full_info function filters.afm(name) -- we could parse the afm file as well, and then report an error but @@ -345,7 +435,7 @@ function filters.afm(name) if key and #key > 0 then hash[lower(key)] = value end - if find(line,"StartCharMetrics") then + if find(line,"StartCharMetrics",1,true) then break end end @@ -357,7 +447,7 @@ function filters.afm(name) end function filters.pfb(name) - return fontloader.info(name) + return get_font_info(name) end --[[ldx-- @@ -547,7 +637,7 @@ local function check_name(data,result,filename,modification,suffix,subfont) fullname = fullname or fontname familyname = familyname or fontname -- we do these sparse - local units = result.units_per_em or 1000 + local units = result.units_per_em or 1000 -- can be zero too local minsize = result.design_range_bottom or 0 local maxsize = result.design_range_top or 0 local designsize = result.design_size or 0 @@ -571,7 +661,7 @@ local function check_name(data,result,filename,modification,suffix,subfont) style = style, width = width, variant = variant, - units = units ~= 1000 and unit or nil, + units = units ~= 1000 and units or nil, pfmwidth = pfmwidth ~= 0 and pfmwidth or nil, pfmweight = pfmweight ~= 0 and pfmweight or nil, angle = angle ~= 0 and angle or nil, @@ -580,6 +670,9 @@ local function check_name(data,result,filename,modification,suffix,subfont) designsize = designsize ~= 0 and designsize or nil, modification = modification ~= 0 and modification or nil, } +-- inspect(filename) +-- inspect(result) +-- inspect(specifications[#specifications]) end local function cleanupkeywords() @@ -1011,15 +1104,15 @@ local function analyzefiles(olddata) resolvers.dowithfilesintree(".*%." .. suffix .. "$", function(method,root,path,name) if method == "file" or method == "tree" then local completename = root .."/" .. path .. "/" .. name - completename = resolveresolved(completename) -- no shortcut + completename = resolveprefix(completename) -- no shortcut identify(completename,name,suffix,name) return true end end, function(blobtype,blobpath,pattern) - blobpath = resolveresolved(blobpath) -- no shortcut + blobpath = resolveprefix(blobpath) -- no shortcut report_names("scanning path %a for %s files",blobpath,suffix) end, function(blobtype,blobpath,pattern,total,checked,done) - blobpath = resolveresolved(blobpath) -- no shortcut + blobpath = resolveprefix(blobpath) -- no shortcut report_names("%s entries found, %s %s files checked, %s okay",total,checked,suffix,done) end) end @@ -1747,7 +1840,7 @@ local lastlookups, lastpattern = { }, "" -- local lookups = specifications -- if name then -- lookups = families[name] --- elseif not find(pattern,"=") then +-- elseif not find(pattern,"=",1,true) then -- lookups = families[pattern] -- end -- if trace_names then @@ -1756,7 +1849,7 @@ local lastlookups, lastpattern = { }, "" -- if lookups then -- for key, value in gmatch(pattern,"([^=,]+)=([^=,]+)") do -- local t, n = { }, 0 --- if find(value,"*") then +-- if find(value,"*",1,true) then -- value = topattern(value) -- for i=1,#lookups do -- local s = lookups[i] @@ -1789,7 +1882,7 @@ local lastlookups, lastpattern = { }, "" local function look_them_up(lookups,specification) for key, value in next, specification do local t, n = { }, 0 - if find(value,"*") then + if find(value,"*",1,true) then value = topattern(value) for i=1,#lookups do local s = lookups[i] @@ -1852,7 +1945,7 @@ function names.lookup(pattern,name,reload) -- todo: find lastpattern = false lastlookups = lookups or { } elseif lastpattern ~= pattern then - local lookups = first_look(name or (not find(pattern,"=") and pattern),reload) + local lookups = first_look(name or (not find(pattern,"=",1,true) and pattern),reload) if lookups then if trace_names then report_names("starting with %s lookups for %a",#lookups,pattern) |