diff options
| -rw-r--r-- | luaotfload-fonts.lua | 205 | ||||
| -rw-r--r-- | otfl-font-dum.lua | 61 | 
2 files changed, 84 insertions, 182 deletions
| diff --git a/luaotfload-fonts.lua b/luaotfload-fonts.lua index c346f19..732e691 100644 --- a/luaotfload-fonts.lua +++ b/luaotfload-fonts.lua @@ -18,196 +18,91 @@ dofile(kpse.find_file("luaextra.lua"))  local upper, splitpath, expandpath, glob, basename = string.upper, file.split_path, kpse.expand_path, dir.glob, file.basename  luaotfload.fonts.basename   = "otfl-names.lua" -luaotfload.fonts.version    = 2.000 +luaotfload.fonts.version    = 2.001  luaotfload.fonts.log_level  = 1 -local function info(fmt,...) -    texio.write_nl(string.format("luaotfload | %s", string.format(fmt,...))) -end - -local function log(lvl, ...) +local function log(lvl, fmt, ...)      if lvl <= luaotfload.fonts.log_level then -        info(...) +        texio.write_nl(string.format("luaotfload | %s", string.format(fmt,...)))      end  end -local function sanitize(str) -    return string.gsub(string.lower(str), "[^%a%d]", "") -end -  function fontloader.fullinfo(...) -    local t, n = { }, { } +    local t = { }      local f = fontloader.open(...)      local m = f and fontloader.to_table(f)      fontloader.close(f)      if m.names then          for _,v in pairs(m.names) do              if v.lang == "English (US)" then -                n.name   = v.names.compatfull     or v.names.fullname -                n.family = v.names.preffamilyname or v.names.family -                n.style  = v.names.prefmodifiers  or v.names.subfamily +                t.names = { +                    fullname       = v.names.fullname, +                    family         = v.names.family, +                    subfamily      = v.names.subfamily, +                    compatfull     = v.names.compatfull, +                    preffamilyname = v.names.preffamilyname, +                    prefmodifiers  = v.names.prefmodifiers, +                }              end          end      end      if m.fontstyle_name then          for _,v in pairs(m.fontstyle_name) do              if v.lang == 1033 then -                m.style = v.name +                t.fontstyle_name = v.name              end          end      end -    t.psname   = m.fontname -    t.fullname = n.name   or m.fullname -    t.family   = n.family or m.familyname -    t.style    = n.style  or m.style -    for k,v in pairs(t) do -        t[k] = sanitize(v) -    end -    m, n = nil, nil +    if m.pfminfo then +        t.pfminfo = { +            weight = m.pfminfo.weight, +            width  = m.pfminfo.width, +        } +    end +    t.fontname    = m.fontname +    t.fullname    = m.fullname +    t.familyname  = m.familyname +    t.filename    = m.origname +    t.weight      = m.weight +    t.italicangle = m.italicangle +    -- don't waste the space with zero values +    t.design_size         = m.design_size         ~= 0 and m.design_size         or nil +    t.design_range_bottom = m.design_range_bottom ~= 0 and m.design_range_bottom or nil +    t.design_range_top    = m.design_range_top    ~= 0 and m.design_range_top    or nil +    -- used for indexing +    t.family = t.names.preffamilyname or t.names.family or t.familyname      return t  end --- table containing hard to guess styles -local styles = { -    calibrii = "reg-no-no-norm-0-text", -    bookosi = "reg-it-no-norm-0-text", -    bookosb = "bd-no-no-norm-0-text", -    lsansi = "reg-it-no-norm-0-text", -    antquab = "bd-no-no-norm-0-text", -    antquai = "reg-it-no-norm-0-text", -    } - --- euristics to normalize the style -local function normalize_style(style, family) -    local s = {} -    if style:find("semibold") or style:find("demibold") -            or style:find("lightbold") or style:match("lb%d*") then -        s.weight = "smbd" -    elseif style:find("bold") or style:match("xb%d*") -            or style:match("bd%d*") or style:match("bb%d*") then -        s.weight = "bd" -    elseif style:find("narrow") then -        s.weight = "nar" -- ? -    end -    if style:find("italic") or style:match("it%d*") then -        s.italic = "it" -    elseif style:find("oblique") then -        s.italic = "obl" -    end -    if style:find("heavy") then -        s.type = "heavy" -    elseif style:find("medium") or style:find("med") then -        s.type = "med" -    elseif style:find("light") then -        s.type = "light" -    end -    if style:find("regular") or style:match("rg%d*") then -        s.regular = true -    end -    if style:find("condensed") or style:match("cond") then -        s.condensed = true -    end -    if style:find("caption") or style:find("capt") then -        s.size_type = 'capt' -    elseif style:find("display") or style:find("disp") then -        s.size_type = 'disp' -    elseif style:find("subhead") or style:find("subh") then -        s.size_type = 'subh' -    end -    local size = tonumber(string.match(style, "%d+")) -    if size and size > 4 and size < 25 then  -        s.size = size -    end -    if not next(s) then -- more aggressive guessing -        local truncated = style:sub(1,-2) -        local endletter = style:sub(-1, -1) -        if family:find(truncated) and family:sub(-1,-1) ~= endletter then  -            if endletter =='b' then -                s.weight = "bd" -            elseif endletter == 'i' then -                s.italic = "it" -            end -        end -    end -    if not next(s) and styles[style] then -        return styles[style] -    end -    local result = nil -    if s.weight then -        result = s.weight -    else -        result = 'reg' -    end -    if s.italic then -        result = result.."-"..s.italic -    else -        result = result.."-no" -    end -    if s.condensed then -        result = result.."-cond" -    else -        result = result.."-no" -    end -    if s.type then -        result = result.."-"..s.type -    else -        result = result.."-norm" -    end -    if s.size then -        result = result.."-"..s.size -    else -        result = result.."-0" -    end -    if s.size_type then -        result = result.."-"..s.size_type -    else -        result = result.."-text" -    end -    return result -end -  local function load_font(filename, names, texmf)      log(3, "Loading font %s", filename) -    local psnames, families = names.mappings.psnames, names.mappings.families +    local mappings = names.mappings +    local families = names.families      if filename then          local info = fontloader.info(filename)          if info then              if type(info) == "table" and #info > 1 then                  for index,_ in ipairs(info) do                      local fullinfo = fontloader.fullinfo(filename, index-1) +                    if texmf then +                        fullinfo.filename = basename(filename) +                    end +                    mappings[#mappings+1] = fullinfo                      if not families[fullinfo.family] then                          families[fullinfo.family] = { }                      end -                    if not fullinfo.style then -                        fullinfo.style = sanitize(file.nameonly(filename)) -                    end -                    local guessed = normalize_style(fullinfo.style, fullinfo.family) -                    families[fullinfo.family][texmf and basename(filename) or filename] =  -                        { -                          guessed_style = guessed, -                          raw_style = fullinfo.style, -                          index = index-1, -                        } -                    psnames[fullinfo.psname] = {texmf and basename(filename) or filename, index-1} +                    table.insert(families[fullinfo.family], #mappings)                  end              else                  local fullinfo = fontloader.fullinfo(filename) -                if texmf == true then -                    filename = basename(filename) +                if texmf then +                    fullinfo.filename = basename(filename)                  end +                mappings[#mappings+1] = fullinfo                  if not families[fullinfo.family] then                      families[fullinfo.family] = { }                  end -                if not fullinfo.style then -                    fullinfo.style = sanitize(file.nameonly(filename)) -                end -                local guessed = normalize_style(fullinfo.style, fullinfo.family) -                families[fullinfo.family][filename] =  -                    { -                      guessed_style = guessed, -                      raw_style = fullinfo.style, -                    } -                psnames[fullinfo.psname] = {texmf and basename(filename) or filename} +                table.insert(families[fullinfo.family], #mappings)              end          else              log(1, "Failed to load %s", filename) @@ -348,7 +243,7 @@ local function append_fccatdirs(fontdirs)          result = read_fcdata(fontdirs, data, translate)          data:close()          if not result then -            info("Unable to execute fc-cat nor fc-cat.exe, system fonts will not be available") +            log(1, "Unable to execute fc-cat nor fc-cat.exe, system fonts will not be available")              return fontdirs          end      end @@ -373,26 +268,24 @@ end  local function generate()      local fnames = { -        mappings = { -            families = { }, -            psnames  = { }, -        }, -        version  = luaotfload.fonts.version +        mappings = { }, +        families = { }, +        version  = luaotfload.fonts.version,      }      local savepath      scan_all(fnames) -    info("%s fonts saved in the database", #table.keys(fnames.mappings.psnames)) +    log(1, "%s fonts in %s families saved in the database", #fnames.mappings, #table.keys(fnames.families))      savepath = kpse.expand_var("$TEXMFVAR") .. "/tex/"      if not file.isreadable(savepath) then          log(1, "Creating directory %s", savepath)          lfs.mkdir(savepath)      end      if not file.iswritable(savepath) then -        info("Error: cannot write in directory %s\n", savepath) +        log(1, "Error: cannot write in directory %s\n", savepath)      else          savepath = savepath .. luaotfload.fonts.basename          io.savedata(savepath, table.serialize(fnames, true)) -        info("Saved font names database in %s\n", savepath) +        log(1, "Saved font names database in %s\n", savepath)      end  end diff --git a/otfl-font-dum.lua b/otfl-font-dum.lua index e1f7822..7dfdf3d 100644 --- a/otfl-font-dum.lua +++ b/otfl-font-dum.lua @@ -47,15 +47,19 @@ end  fonts.names = fonts.names or { } -fonts.names.version    = 2.000 -- not the same as in context +fonts.names.version    = 2.001 -- not the same as in context  fonts.names.basename   = "otfl-names.lua"  fonts.names.new_to_old = { }  fonts.names.old_to_new = { }  local data, loaded = nil, false +local function sanitize(str) +    return string.gsub(string.lower(str), "[^%a%d]", "") +end +  function fonts.names.resolve(specification) -    local name, sub, style = specification.name, specification.sub, specification.style +    local name, style = specification.name, specification.style or "regular"      if not loaded then          local basename = fonts.names.basename          if basename and basename ~= "" then @@ -70,33 +74,38 @@ function fonts.names.resolve(specification)          loaded = true      end      if type(data) == "table" and data.version == fonts.names.version then -        local condensed = string.gsub(string.lower(name),"[^%a%d]","")          if data.mappings then -            local psnames  = data.mappings.psnames -            local families = data.mappings.families -            local family = families and families[condensed] -	    local psname = psnames and psnames[condensed] -            if family then -                local style = style or "regular" -                local found = family[style] -                if found then -                    local fontname, filename, subfont = found, found[1], found[2] -                    if subfont then -                        return filename, subfont -                    else -                        return filename, false -                    end -                end -            elseif psname then -                local fontname, filename, subfont = psname, psname[1], psname[2] -                if subfont then -                    return filename, subfont -                else -                    return filename, false +            local family = data.families[name] +            if family and type(family) == "table" then +                for _,v in ipairs(family) do +                   local subfamily      = data.mappings[v].names.subfamily +                   local prefmodifiers  = data.mappings[v].names.prefmodifiers +                   local fontstyle_name = data.mappings[v].fontstyle_name +                   local dsize          = data.mappings[v].design_size and data.mappings[v].design_size / 10 +                   local ssize          = specification.size and specification.size / 65536 +                   local optsize        = tonumber(specification.optsize) +                   local maxsize        = data.mappings[v].design_range_bottom +                   local minsize        = data.mappings[v].design_range_top +                   local filename       = data.mappings[v].filename +                   if subfamily and sanitize(subfamily) == style then +                       if not dsize            then return filename, false +                       elseif dsize == optsize then return filename, false +                       elseif dsize == ssize   then return filename, false +                       end +                   elseif prefmodifiers and sanitize(prefmodifiers) == style then +                       if not dsize            then return filename, false +                       elseif dsize == optsize then return filename, false +                       elseif dsize == ssize   then return filename, false +                       end +                   elseif fontstyle_name and sanitize(fontstyle_name) == style then +                       if not dsize            then return filename, false +                       elseif dsize == optsize then return filename, false +                       elseif dsize == ssize   then return filename, false +                       end +                   end                  end -            else -                return name, false -- fallback to filename              end +            return name, false -- fallback to filename          end      end  end | 
