diff options
Diffstat (limited to 'src/luaotfload-database.lua')
| -rw-r--r-- | src/luaotfload-database.lua | 201 | 
1 files changed, 117 insertions, 84 deletions
| diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua index 135ab0e..437091f 100644 --- a/src/luaotfload-database.lua +++ b/src/luaotfload-database.lua @@ -208,7 +208,7 @@ end  local format_precedence = {      "otf",  "ttc", "ttf", "afm", -    --- "pfb", "pfa", +    -- "pfb" --- may come back before Luatex 1.0  }  local location_precedence = { @@ -359,7 +359,7 @@ This is a sketch of the luaotfload db:          conflicts       : { barename : int; basename : int }; // filename conflict with font at index; happens with subfonts          familyname      : string;   // sanitized name of the font family the font belongs to, usually from the names table          fontname        : string;   // sanitized name of the font -        format          : string;   // "otf" | "ttf" | "afm" +        format          : string;   // "otf" | "ttf" | "afm" (* | "pfb" *)          fullname        : string;   // sanitized full name of the font including style modifiers          fullpath        : string;   // path to font in filesystem          index           : int;      // index in the mappings table @@ -478,7 +478,6 @@ end  --- define locals in scope  local access_font_index -local collect_families  local find_closest  local flush_lookup_cache  local generate_filedata @@ -495,6 +494,7 @@ local lookup_fullpath  local save_lookups  local save_names  local set_font_filter +local t1_fullinfo  local update_names  --- state of the database @@ -595,11 +595,11 @@ load_lookups = function ( )  end  local regular_synonym = { -    book    = "r", -    normal  = "r", -    plain   = "r", -    regular = "r", -    roman   = "r", +    book    = true, +    normal  = true, +    plain   = true, +    regular = true, +    roman   = true,  }  local italic_synonym = { @@ -1034,7 +1034,7 @@ local lookup_fontname = function (specification, name, style)                  lastresort = face              end          elseif face.metafamily == name -            and (regular_synonym [prefmodifiers] +            and (   regular_synonym [prefmodifiers]                   or regular_synonym [subfamily])          then              lastresort = face @@ -1409,7 +1409,6 @@ local map_english_names = function (metadata)          certain.      --]]--      if platformnames then -        --inspect(metadata)          --namesource = platformnames.macintosh or platformnames.windows          namesource = platformnames.windows or platformnames.macintosh      end @@ -1448,7 +1447,6 @@ local get_raw_info = function (metadata, basename)      return {          familyname          = metadata.familyname,          fontname            = fontname, -        fontstyle_name      = metadata.fontstyle_name,          fullname            = fullname,          italicangle         = metadata.italicangle,          names               = metadata.names, @@ -1519,21 +1517,6 @@ local organize_namedata = function (rawinfo,          },      } -    -- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size -    if rawinfo.fontstyle_name then -        --- not present in all fonts, often differs from the preferred -        --- subfamily as well as subfamily fields, e.g. with -        --- LMSans10-BoldOblique: -        ---     subfamily:      “Bold Italic” -        ---     prefmodifiers:  “10 Bold Oblique” -        ---     fontstyle_name: “Bold Oblique” -        for _, name in next, rawinfo.fontstyle_name do -            if name.lang == 1033 then --- I hate magic numbers -                fontnames.fontstyle_name = name.name -            end -        end -    end -      return {          sanitized     = sanitize_fontnames (fontnames),          fontname      = rawinfo.fontname, @@ -1617,13 +1600,71 @@ ot_fullinfo = function (filename,      return res  end +--[[doc-- + +    Type1 font inspector. In comparison with OTF, PFB’s contain a good +    deal less name fields which makes it tricky in some parts to find a +    meaningful representation for the database. + +    Good read: http://www.adobe.com/devnet/font/pdfs/5004.AFM_Spec.pdf + +--doc]]-- + +--- string -> int -> bool -> string -> fontentry + +t1_fullinfo = function (filename, _subfont, location, basename, format) +    local sanitized +    local metadata      = load_font_file (filename) +    local fontname      = metadata.fontname +    local fullname      = metadata.fullname +    local familyname    = metadata.familyname +    local italicangle   = metadata.italicangle +    local style         = "" +    local weight + +    sanitized = sanitize_fontnames ({ +        fontname        = fontname, +        psname          = fullname, +        metafamily      = familyname, +        familyname      = familyname, +        weight          = metadata.weight, --- string identifier +        prefmodifiers   = style, +    }) + +    weight = sanitized.weight + +    if weight == "bold" then +        style = weight +    end + +    if italicangle ~= 0 then +        style = style .. "italic" +    end + +    return { +        basename         = basename, +        fullpath         = filename, +        subfont          = false, +        location         = location or "system", +        format           = format, +        fullname         = sanitized.fullname, +        fontname         = sanitized.fontname, +        familyname       = sanitized.familyname, +        plainname        = fullname, +        psname           = sanitized.fontname, +        version          = metadata.version, +        size             = false, +        prefmodifiers    = style ~= "" and style or weight, +        weight           = metadata.pfminfo and pfminfo.weight or 400, +        italicangle      = italicangle, +    } +end +  local loaders = {      otf     = ot_fullinfo,      ttc     = ot_fullinfo,      ttf     = ot_fullinfo, - -----pfb     = t1_fullinfo, --> may come back one day, so -----pfa     = t1_fullinfo, --> we keep the indirection +--- pfb     = t1_fullinfo,  }  --- not side-effect free! @@ -2525,6 +2566,9 @@ generate_filedata = function (mappings)      return files  end +local bold_spectrum_low  = 501 --- 500 is medium, 900 heavy/black +local bold_weight        = 700 +  local pick_style  local pick_fallback_style  local check_regular @@ -2552,31 +2596,33 @@ do          return false      end -    pick_style = function (fontstyle_name, -                           prefmodifiers, +    pick_style = function (prefmodifiers,                             subfamily)          local style -        if fontstyle_name --[[ff only]] then -            style = choose_exact (fontstyle_name) -        end -        if not style then -            if prefmodifiers then -                style = choose_exact (prefmodifiers) -            elseif subfamily then -                style = choose_exact (subfamily) -            end +        if prefmodifiers then +            style = choose_exact (prefmodifiers) +        elseif subfamily then +            style = choose_exact (subfamily)          end          return style      end      pick_fallback_style = function (italicangle, weight, pfmweight) -        --- more aggressive, but only to determine bold faces -        if pfmweight > 500 or bold_synonym [weight] then --- bold spectrum matches +        --[[-- +            More aggressive, but only to determine bold faces. +            Note: Before you make this test more inclusive, ensure +            no fonts are matched in the bold synonym spectrum over +            a literally “bold[italic]” one. In the past, heuristics +            been tried but ultimately caused unwanted modifiers +            polluting the lookup table. What doesn’t work is, e. g. +            treating weights > 500 as bold or allowing synonyms like +            “heavy”, “black”. +        --]]--  +        if pfmweight == bold_weight then --- bold spectrum matches              if italicangle == 0 then -                return tostring (weight) -            else -                return tostring (weight) .. "i" +                return "b"              end +            return "bi"          end          return false      end @@ -2584,13 +2630,12 @@ do      --- we use only exact matches here since there are constructs      --- like “regularitalic” (Cabin, Bodoni Old Fashion) -    check_regular = function (fontstyle_name, -                              prefmodifiers, +    check_regular = function (prefmodifiers,                                subfamily,                                italicangle,                                weight,                                pfmweight) -        local plausible_weight +        local plausible_weight = false          --[[--            This filters out undesirable candidates that specify their            prefmodifiers or subfamily as “regular” but are actually of @@ -2605,9 +2650,11 @@ do          end          if plausible_weight then -            return fontstyle_name and regular_synonym [fontstyle_name] -                or prefmodifiers  and regular_synonym [prefmodifiers] -                or subfamily      and regular_synonym [subfamily] +            if prefmodifiers  and regular_synonym [prefmodifiers] +            or subfamily      and regular_synonym [subfamily] +            then +                return "r" +            end          end          return false      end @@ -2634,7 +2681,6 @@ local pull_values = function (entry)      entry.fullname          = english.fullname or info.fullname      entry.prefmodifiers     = english.prefmodifiers      entry.familyname        = metadata.familyname or english.preffamily or english.family -    entry.fontstyle_name    = sanitized.fontstyle_name      entry.plainname         = names.fullname      entry.subfamily         = english.subfamily @@ -2678,7 +2724,7 @@ local get_subtable = function (families, entry)      return subtable  end -collect_families = function (mappings) +local collect_families = function (mappings)      logreport ("info", 2, "db", "Analyzing families.") @@ -2699,7 +2745,6 @@ collect_families = function (mappings)          local subtable          = get_subtable (families, entry)          local familyname        = entry.familyname -        local fontstyle_name    = entry.fontstyle_name          local prefmodifiers     = entry.prefmodifiers          local subfamily         = entry.subfamily @@ -2707,34 +2752,22 @@ collect_families = function (mappings)          local pfmweight         = entry.pfmweight          local italicangle       = entry.italicangle -        local modifier          = pick_style (fontstyle_name, -                                              prefmodifiers, -                                              subfamily) +        local modifier          = pick_style (prefmodifiers, subfamily)          if not modifier then --- regular, exact only -            modifier = check_regular (fontstyle_name, -                                      prefmodifiers, +            modifier = check_regular (prefmodifiers,                                        subfamily,                                        italicangle,                                        weight,                                        pfmweight)          end -        --if familyname == "garamondpremierpro" then -        --print(entry.fullname, "reg?",modifier, "->",fontstyle_name, -                              --prefmodifiers, -                              --subfamily, -                              --italicangle, -                              --pfmweight, -                              --weight) -                              --end + +        if not modifier then +            modifier = pick_fallback_style (italicangle, weight, pfmweight) +        end          if modifier then              add_family (familyname, subtable, modifier, entry) -        elseif pfmweight > 500 then -- in bold spectrum -            modifier = pick_fallback_style (italicangle, weight, pfmweight) -            if modifier then -                add_family (familyname, subtable, modifier, entry) -            end          end      end @@ -2753,8 +2786,6 @@ end  --doc]]-- -local bold_spectrum_low  = 501 --- 500 is medium, 900 heavy/black -local bold_weight        = 700  local style_categories   = { "r", "b", "i", "bi" }  local bold_categories    = {      "b",      "bi" } @@ -2963,7 +2994,7 @@ local collect_statistics = function (mappings)      local sum_dsnsize, n_dsnsize = 0, 0      local fullname, family, families = { }, { }, { } -    local subfamily, prefmodifiers, fontstyle_name = { }, { }, { } +    local subfamily, prefmodifiers = { }, { }      local addtohash = function (hash, item)          if item then @@ -3023,7 +3054,6 @@ local collect_statistics = function (mappings)          addtohash (family,          englishnames.family)          addtohash (subfamily,       englishnames.subfamily)          addtohash (prefmodifiers,   englishnames.prefmodifiers) -        addtohash (fontstyle_name,  names.fontstyle_name)          addtoset (families, englishnames.family, englishnames.fullname) @@ -3098,10 +3128,6 @@ local collect_statistics = function (mappings)                     setsize (prefmodifiers))          pprint_top (prefmodifiers, 4) -        logreport ("both", 0, "db", -                   "   · %d different “fontstyle_name” kinds.", -                   setsize (fontstyle_name)) -        pprint_top (fontstyle_name, 4)      end      local mean_dsnsize = 0 @@ -3118,7 +3144,6 @@ local collect_statistics = function (mappings)  --        style = {  --            subfamily = subfamily,  --            prefmodifiers = prefmodifiers, ---            fontstyle_name = fontstyle_name,  --        },      }  end @@ -3483,8 +3508,16 @@ local use_fontforge = function (val)          close_font_file   = fontloader.close          get_english_names = get_english_names_from_ff      else -        read_font_file    = otfhandler.readers.getinfo -        read_font_info    = read_font_file +        local wrapper = function (filename, subfont) +            return otfhandler.readers.getinfo (filename, +                                               { subfont        = subfont +                                               , details        = false +                                               , platformnames  = true +                                               , rawfamilynames = true +                                               }) +        end +        read_font_file    = wrapper +        read_font_info    = wrapper          close_font_file   = function () end          get_english_names = map_english_names      end @@ -3537,7 +3570,7 @@ return {          fonts.definers  = fonts.definers or { resolvers = { } }          names.blacklist = blacklist -        names.version   = 2.6 +        names.version   = 2.7          names.data      = nil      --- contains the loaded database          names.lookups   = nil      --- contains the lookup cache | 
