diff options
| -rw-r--r-- | src/fontloader/misc/fontloader-font-afm.lua | 224 | ||||
| -rw-r--r-- | src/fontloader/misc/fontloader-font-con.lua | 11 | ||||
| -rw-r--r-- | src/fontloader/misc/fontloader-font-map.lua | 4 | ||||
| -rw-r--r-- | src/fontloader/misc/fontloader-font-otl.lua | 2 | ||||
| -rw-r--r-- | src/fontloader/misc/fontloader-font-otr.lua | 7 | ||||
| -rw-r--r-- | src/fontloader/misc/fontloader-font-oup.lua | 14 | ||||
| -rw-r--r-- | src/fontloader/misc/fontloader-font-tfm.lua | 2 | ||||
| -rw-r--r-- | src/fontloader/runtime/fontloader-basics-gen.lua | 6 | ||||
| -rw-r--r-- | src/fontloader/runtime/fontloader-reference.lua | 207 | 
9 files changed, 370 insertions, 107 deletions
diff --git a/src/fontloader/misc/fontloader-font-afm.lua b/src/fontloader/misc/fontloader-font-afm.lua index 329639b..3dedf12 100644 --- a/src/fontloader/misc/fontloader-font-afm.lua +++ b/src/fontloader/misc/fontloader-font-afm.lua @@ -28,9 +28,11 @@ don't have this issue.</p>  local fonts, logs, trackers, containers, resolvers = fonts, logs, trackers, containers, resolvers  local next, type, tonumber = next, type, tonumber -local format, match, gmatch, lower, gsub, strip = string.format, string.match, string.gmatch, string.lower, string.gsub, string.strip -local abs = math.abs -local P, S, C, R, lpegmatch, patterns = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.match, lpeg.patterns +local match, gmatch, lower, gsub, strip, find = string.match, string.gmatch, string.lower, string.gsub, string.strip, string.find +local char, byte, sub = string.char, string.byte, string.sub +local abs, mod = math.abs, math.mod +local bxor, rshift = bit32.bxor, bit32.rshift +local P, S, R, Cmt, C, Ct, Cs, lpegmatch, patterns = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.match, lpeg.patterns  local derivetable = table.derive  local trace_features     = false  trackers.register("afm.features",   function(v) trace_features = v end) @@ -48,11 +50,6 @@ local definers           = fonts.definers  local readers            = fonts.readers  local constructors       = fonts.constructors -local fontloader         = fontloader -local font_to_table      = fontloader.to_table -local open_font          = fontloader.open -local close_font         = fontloader.close -  local afm                = constructors.newhandler("afm")  local pfb                = constructors.newhandler("pfb") @@ -171,7 +168,7 @@ end  local function get_charmetrics(data,charmetrics,vector)      local characters = data.characters      local chr, ind = { }, 0 -    for k,v in gmatch(charmetrics,"([%a]+) +(.-) *;") do +    for k, v in gmatch(charmetrics,"([%a]+) +(.-) *;") do          if k == 'C'  then              v = tonumber(v)              if v < 0 then @@ -225,41 +222,193 @@ local function get_variables(data,fontmetrics)      end  end -local function get_indexes(data,pfbname) -    data.resources.filename = resolvers.unresolve(pfbname) -- no shortcut -    local pfbblob = open_font(pfbname) -    if pfbblob then -        local characters = data.characters -        local pfbdata = font_to_table(pfbblob) -        if pfbdata then -            local glyphs = pfbdata.glyphs -            if glyphs then -                if trace_loading then -                    report_afm("getting index data from %a",pfbname) -                end -                for index, glyph in next, glyphs do -            --  for index, glyph in table.sortedhash(glyphs) do -                    local name = glyph.name -                    if name then -                        local char = characters[name] -                        if char then -                            if trace_indexing then -                                report_afm("glyph %a has index %a",name,index) +local get_indexes + +do + +    -- old font loader + +    local fontloader = fontloader + +    if fontloader then + +        local font_to_table = fontloader.to_table +        local open_font     = fontloader.open +        local close_font    = fontloader.close + +        local function get_indexes_old(data,pfbname) +            local pfbblob = open_font(pfbname) +            if pfbblob then +                local characters = data.characters +                local pfbdata = font_to_table(pfbblob) +                if pfbdata then +                    local glyphs = pfbdata.glyphs +                    if glyphs then +                        if trace_loading then +                            report_afm("getting index data from %a",pfbname) +                        end +                        for index, glyph in next, glyphs do +                            local name = glyph.name +                            if name then +                                local char = characters[name] +                                if char then +                                    if trace_indexing then +                                        report_afm("glyph %a has index %a",name,index) +                                    end +                                    char.index = index +                                end                              end -                            char.index = index                          end +                    elseif trace_loading then +                        report_afm("no glyph data in pfb file %a",pfbname)                      end +                elseif trace_loading then +                    report_afm("no data in pfb file %a",pfbname)                  end +                close_font(pfbblob)              elseif trace_loading then -                report_afm("no glyph data in pfb file %a",pfbname) +                report_afm("invalid pfb file %a",pfbname)              end -        elseif trace_loading then -            report_afm("no data in pfb file %a",pfbname)          end -        close_font(pfbblob) -    elseif trace_loading then -        report_afm("invalid pfb file %a",pfbname) +      end + +    -- new (unfinished) font loader but i see no differences between +    -- old and new (one bad vector with old) + +    local n, m + +    local progress = function(str,position,name,size) +        local forward = position + tonumber(size) + 3 + 2 +        n = n + 1 +        if n >= m then +            return #str, name +        elseif forward < #str then +            return forward, name +        else +            return #str, name +        end +    end + +    local initialize = function(str,position,size) +        n = 0 +        m = tonumber(size) +        return position + 1 +    end + +    local charstrings = P("/CharStrings") +    local name        = P("/") * C((R("az")+R("AZ")+R("09")+S("-_."))^1) +    local size        = C(R("09")^1) +    local spaces      = P(" ")^1 + +    local p_filternames = Ct ( +        (1-charstrings)^0 * charstrings * spaces * Cmt(size,initialize) +      * (Cmt(name * P(" ")^1 * C(R("09")^1), progress) + P(1))^1 +    ) + +    -- if one of first 4 not 0-9A-F then binary else hex + +    local decrypt + +    do + +        local r, c1, c2, n = 0, 0, 0, 0 + +        local function step(c) +            local cipher = byte(c) +            local plain  = bxor(cipher,rshift(r,8)) +            r = mod((cipher + r) * c1 + c2,65536) +            return char(plain) +        end + +        decrypt = function(binary) +            r, c1, c2, n = 55665, 52845, 22719, 4 +            binary       = gsub(binary,".",step) +            return sub(binary,n+1) +        end + +     -- local pattern = Cs((P(1) / step)^1) +     -- +     -- decrypt = function(binary) +     --     r, c1, c2, n = 55665, 52845, 22719, 4 +     --     binary = lpegmatch(pattern,binary) +     --     return sub(binary,n+1) +     -- end + +    end + +    local function loadpfbvector(filename) +        -- for the moment limited to encoding only + +        local data = io.loaddata(resolvers.findfile(filename)) + +        if not find(data,"!PS%-AdobeFont%-") then +            print("no font",filename) +            return +        end + +        if not data then +            print("no data",filename) +            return +        end + +        local ascii, binary = match(data,"(.*)eexec%s+......(.*)") + +        if not binary then +            print("no binary",filename) +            return +        end + +        binary = decrypt(binary,4) + +        local vector = lpegmatch(p_filternames,binary) + +        vector[0] = table.remove(vector,1) + +        if not vector then +            print("no vector",filename) +            return +        end + +        return vector + +    end + +    get_indexes = function(data,pfbname) +        local vector = loadpfbvector(pfbname) +        if vector then +            local characters = data.characters +            if trace_loading then +                report_afm("getting index data from %a",pfbname) +            end +            for index=1,#vector do +                local name = vector[index] +                local char = characters[name] +                if char then +                    if trace_indexing then +                        report_afm("glyph %a has index %a",name,index) +                    end +                    char.index = index +                end +            end +        end +    end + +    if fontloader then + +        afm.use_new_indexer = true +        get_indexes_new     = get_indexes + +        get_indexes = function(data,pfbname) +            if afm.use_new_indexer then +                return get_indexes_new(data,pfbname) +            else +                return get_indexes_old(data,pfbname) +            end +        end + +    end +  end  local function readafm(filename) @@ -351,8 +500,9 @@ function afm.load(filename)              data = readafm(filename)              if data then                  if pfbname ~= "" then +                    data.resources.filename = resolvers.unresolve(pfbname)                      get_indexes(data,pfbname) -                elseif trace_loading then +               elseif trace_loading then                      report_afm("no pfb file for %a",filename)                   -- data.resources.filename = "unset" -- better than loading the afm file                  end diff --git a/src/fontloader/misc/fontloader-font-con.lua b/src/fontloader/misc/fontloader-font-con.lua index f36f750..b118535 100644 --- a/src/fontloader/misc/fontloader-font-con.lua +++ b/src/fontloader/misc/fontloader-font-con.lua @@ -776,9 +776,14 @@ function constructors.scale(tfmdata,specification)          elseif autoitalicamount then -- itlc feature              local vi = description.italic              if not vi then -                local vi = description.boundingbox[3] - description.width + autoitalicamount -                if vi > 0 then -- < 0 indicates no overshoot or a very small auto italic -                    chr.italic = vi*hdelta +                local bb = description.boundingbox +                if bb then +                    local vi = bb[3] - description.width + autoitalicamount +                    if vi > 0 then -- < 0 indicates no overshoot or a very small auto italic +                        chr.italic = vi*hdelta +                    end +                else +                 -- report_defining("no boundingbox for character %C in font %a, fullname %a, filename %a",unicode,name,fullname,filename)                  end              elseif vi ~= 0 then                  chr.italic = vi*hdelta diff --git a/src/fontloader/misc/fontloader-font-map.lua b/src/fontloader/misc/fontloader-font-map.lua index db501f0..509e751 100644 --- a/src/fontloader/misc/fontloader-font-map.lua +++ b/src/fontloader/misc/fontloader-font-map.lua @@ -19,6 +19,8 @@ local trace_mapping = false  trackers.register("fonts.mapping", function(v) trac  local report_fonts  = logs.reporter("fonts","loading") -- not otf only +local force_ligatures = false  directives.register("fonts.mapping.forceligatures",function(v) force_ligatures = v end) +  local fonts         = fonts or { }  local mappings      = fonts.mappings or { }  fonts.mappings      = mappings @@ -443,7 +445,7 @@ function mappings.addtounicode(data,filename,checklookups)      local collected = false      local unicoded  = 0      for unicode, glyph in next, descriptions do -        if not glyph.unicode and glyph.class == "ligature" then +        if glyph.class == "ligature" and (force_ligatures or not glyph.unicode) then              if not collected then                  collected = fonts.handlers.otf.readers.getcomponents(data)                  if not collected then diff --git a/src/fontloader/misc/fontloader-font-otl.lua b/src/fontloader/misc/fontloader-font-otl.lua index 210abfe..bcea275 100644 --- a/src/fontloader/misc/fontloader-font-otl.lua +++ b/src/fontloader/misc/fontloader-font-otl.lua @@ -53,7 +53,7 @@ local report_otf         = logs.reporter("fonts","otf loading")  local fonts              = fonts  local otf                = fonts.handlers.otf -otf.version              = 3.017 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version              = 3.018 -- beware: also sync font-mis.lua and in mtx-fonts  otf.cache                = containers.define("fonts", "otl", otf.version, true)  local otfreaders         = otf.readers diff --git a/src/fontloader/misc/fontloader-font-otr.lua b/src/fontloader/misc/fontloader-font-otr.lua index 3542d18..27bb6a6 100644 --- a/src/fontloader/misc/fontloader-font-otr.lua +++ b/src/fontloader/misc/fontloader-font-otr.lua @@ -1066,14 +1066,13 @@ readers.hmtx = function(f,fontdata,specification)              local nofmetrics      = fontdata.horizontalheader.nofhmetrics              local glyphs          = fontdata.glyphs              local nofglyphs       = fontdata.nofglyphs -            local nofrepeated     = nofglyphs - nofmetrics              local width           = 0 -- advance              local leftsidebearing = 0              for i=0,nofmetrics-1 do                  local glyph     = glyphs[i]                  width           = readshort(f)                  leftsidebearing = readshort(f) -                if advance ~= 0 then +                if width ~= 0 then                      glyph.width = width                  end               -- if leftsidebearing ~= 0 then @@ -1082,8 +1081,8 @@ readers.hmtx = function(f,fontdata,specification)              end              -- The next can happen in for instance a monospace font or in a cjk font              -- with fixed widths. -            for i=nofmetrics,nofrepeated do -                local glyph     = glyphs[i] +            for i=nofmetrics,nofglyphs-1 do +                local glyph = glyphs[i]                  if width ~= 0 then                      glyph.width = width                  end diff --git a/src/fontloader/misc/fontloader-font-oup.lua b/src/fontloader/misc/fontloader-font-oup.lua index 7edaaf6..a99aaf4 100644 --- a/src/fontloader/misc/fontloader-font-oup.lua +++ b/src/fontloader/misc/fontloader-font-oup.lua @@ -378,7 +378,12 @@ local function copyduplicates(fontdata)                              t[#t+1] = f_character_y(u)                          end                      end -                    report("duplicates: % t",t) +                    local n = #t +                    if n > 25 then +                        report("duplicates: %i : %s .. %s ",n,t[1],t[n]) +                    else +                        report("duplicates: %i : % t",n,t) +                    end                  else                      -- what a mess                  end @@ -577,13 +582,12 @@ local function checklookups(fontdata,missing,nofmissing)              if r then                  local name = descriptions[i].name or f_index(i)                  if not ignore[name] then -                    done[#done+1] = name +                    done[name] = true                  end              end          end -        if #done > 0 then -            table.sort(done) -            report("not unicoded: % t",done) +        if next(done) then +            report("not unicoded: % t",table.sortedkeys(done))          end      end  end diff --git a/src/fontloader/misc/fontloader-font-tfm.lua b/src/fontloader/misc/fontloader-font-tfm.lua index 83ac2f0..8e92c48 100644 --- a/src/fontloader/misc/fontloader-font-tfm.lua +++ b/src/fontloader/misc/fontloader-font-tfm.lua @@ -155,7 +155,7 @@ local function read_from_tfm(specification)          end          -- let's play safe:          properties.haskerns     = true -        properties.haslogatures = true +        properties.hasligatures = true          resources.unicodes      = { }          resources.lookuptags    = { }          -- diff --git a/src/fontloader/runtime/fontloader-basics-gen.lua b/src/fontloader/runtime/fontloader-basics-gen.lua index c298f6d..2a68b1c 100644 --- a/src/fontloader/runtime/fontloader-basics-gen.lua +++ b/src/fontloader/runtime/fontloader-basics-gen.lua @@ -92,12 +92,10 @@ local remapper = {      otf    = "opentype fonts",      ttf    = "truetype fonts",      ttc    = "truetype fonts", -    dfont  = "truetype fonts", -- "truetype dictionary",      cid    = "cid maps",      cidmap = "cid maps", -    fea    = "font feature files", -    pfa    = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! -    pfb    = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this! + -- fea    = "font feature files", -- no longer supported +    pfb    = "type1 fonts",        -- needed for vector loading      afm    = "afm",  } diff --git a/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua index e784738..7c06c25 100644 --- a/src/fontloader/runtime/fontloader-reference.lua +++ b/src/fontloader/runtime/fontloader-reference.lua @@ -1,6 +1,6 @@  -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua  -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date  : 04/18/16 22:12:36 +-- merge date  : 04/21/16 12:13:25  do -- begin closure to overcome local limits and interference @@ -3693,11 +3693,8 @@ local remapper={    otf="opentype fonts",    ttf="truetype fonts",    ttc="truetype fonts", -  dfont="truetype fonts",    cid="cid maps",    cidmap="cid maps", -  fea="font feature files", -  pfa="type1 fonts",    pfb="type1 fonts",    afm="afm",  } @@ -5656,9 +5653,13 @@ function constructors.scale(tfmdata,specification)      elseif autoitalicamount then         local vi=description.italic        if not vi then -        local vi=description.boundingbox[3]-description.width+autoitalicamount -        if vi>0 then  -          chr.italic=vi*hdelta +        local bb=description.boundingbox +        if bb then +          local vi=bb[3]-description.width+autoitalicamount +          if vi>0 then  +            chr.italic=vi*hdelta +          end +        else          end        elseif vi~=0 then          chr.italic=vi*hdelta @@ -6408,6 +6409,7 @@ local formatters=string.formatters  local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)  local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_unimapping=v end)  local report_fonts=logs.reporter("fonts","loading")  +local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end)  local fonts=fonts or {}  local mappings=fonts.mappings or {}  fonts.mappings=mappings @@ -6676,7 +6678,7 @@ function mappings.addtounicode(data,filename,checklookups)    local collected=false    local unicoded=0    for unicode,glyph in next,descriptions do -    if not glyph.unicode and glyph.class=="ligature" then +    if glyph.class=="ligature" and (force_ligatures or not glyph.unicode) then        if not collected then          collected=fonts.handlers.otf.readers.getcomponents(data)          if not collected then @@ -6927,7 +6929,7 @@ local function read_from_tfm(specification)        end      end      properties.haskerns=true -    properties.haslogatures=true +    properties.hasligatures=true      resources.unicodes={}      resources.lookuptags={}      depth[filename]=depth[filename]-1 @@ -6980,9 +6982,11 @@ if not modules then modules={} end modules ['font-afm']={  }  local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers  local next,type,tonumber=next,type,tonumber -local format,match,gmatch,lower,gsub,strip=string.format,string.match,string.gmatch,string.lower,string.gsub,string.strip -local abs=math.abs -local P,S,C,R,lpegmatch,patterns=lpeg.P,lpeg.S,lpeg.C,lpeg.R,lpeg.match,lpeg.patterns +local match,gmatch,lower,gsub,strip,find=string.match,string.gmatch,string.lower,string.gsub,string.strip,string.find +local char,byte,sub=string.char,string.byte,string.sub +local abs,mod=math.abs,math.mod +local bxor,rshift=bit32.bxor,bit32.rshift +local P,S,R,Cmt,C,Ct,Cs,lpegmatch,patterns=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.match,lpeg.patterns  local derivetable=table.derive  local trace_features=false trackers.register("afm.features",function(v) trace_features=v end)  local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) @@ -6994,10 +6998,6 @@ local findbinfile=resolvers.findbinfile  local definers=fonts.definers  local readers=fonts.readers  local constructors=fonts.constructors -local fontloader=fontloader -local font_to_table=fontloader.to_table -local open_font=fontloader.open -local close_font=fontloader.close  local afm=constructors.newhandler("afm")  local pfb=constructors.newhandler("pfb")  local afmfeatures=constructors.newfeatures("afm") @@ -7111,39 +7111,140 @@ local function get_variables(data,fontmetrics)      end    end  end -local function get_indexes(data,pfbname) -  data.resources.filename=resolvers.unresolve(pfbname)  -  local pfbblob=open_font(pfbname) -  if pfbblob then -    local characters=data.characters -    local pfbdata=font_to_table(pfbblob) -    if pfbdata then -      local glyphs=pfbdata.glyphs -      if glyphs then -        if trace_loading then -          report_afm("getting index data from %a",pfbname) -        end -        for index,glyph in next,glyphs do -          local name=glyph.name -          if name then -            local char=characters[name] -            if char then -              if trace_indexing then -                report_afm("glyph %a has index %a",name,index) +local get_indexes +do +  local fontloader=fontloader +  if fontloader then +    local font_to_table=fontloader.to_table +    local open_font=fontloader.open +    local close_font=fontloader.close +    local function get_indexes_old(data,pfbname) +      local pfbblob=open_font(pfbname) +      if pfbblob then +        local characters=data.characters +        local pfbdata=font_to_table(pfbblob) +        if pfbdata then +          local glyphs=pfbdata.glyphs +          if glyphs then +            if trace_loading then +              report_afm("getting index data from %a",pfbname) +            end +            for index,glyph in next,glyphs do +              local name=glyph.name +              if name then +                local char=characters[name] +                if char then +                  if trace_indexing then +                    report_afm("glyph %a has index %a",name,index) +                  end +                  char.index=index +                end                end -              char.index=index              end +          elseif trace_loading then +            report_afm("no glyph data in pfb file %a",pfbname)            end +        elseif trace_loading then +          report_afm("no data in pfb file %a",pfbname)          end +        close_font(pfbblob)        elseif trace_loading then -        report_afm("no glyph data in pfb file %a",pfbname) +        report_afm("invalid pfb file %a",pfbname) +      end +    end +  end +  local n,m +  local progress=function(str,position,name,size) +    local forward=position+tonumber(size)+3+2 +    n=n+1 +    if n>=m then +      return #str,name +    elseif forward<#str then +      return forward,name +    else +      return #str,name +    end +  end +  local initialize=function(str,position,size) +    n=0 +    m=tonumber(size) +    return position+1 +  end +  local charstrings=P("/CharStrings") +  local name=P("/")*C((R("az")+R("AZ")+R("09")+S("-_."))^1) +  local size=C(R("09")^1) +  local spaces=P(" ")^1 +  local p_filternames=Ct ( +    (1-charstrings)^0*charstrings*spaces*Cmt(size,initialize)*(Cmt(name*P(" ")^1*C(R("09")^1),progress)+P(1))^1 +  ) +  local decrypt +  do +    local r,c1,c2,n=0,0,0,0 +    local function step(c) +      local cipher=byte(c) +      local plain=bxor(cipher,rshift(r,8)) +      r=mod((cipher+r)*c1+c2,65536) +      return char(plain) +    end +    decrypt=function(binary) +      r,c1,c2,n=55665,52845,22719,4 +      binary=gsub(binary,".",step) +      return sub(binary,n+1) +    end +  end +  local function loadpfbvector(filename) +    local data=io.loaddata(resolvers.findfile(filename)) +    if not find(data,"!PS%-AdobeFont%-") then +      print("no font",filename) +      return +    end +    if not data then +      print("no data",filename) +      return +    end +    local ascii,binary=match(data,"(.*)eexec%s+......(.*)") +    if not binary then +      print("no binary",filename) +      return +    end +    binary=decrypt(binary,4) +    local vector=lpegmatch(p_filternames,binary) +    vector[0]=table.remove(vector,1) +    if not vector then +      print("no vector",filename) +      return +    end +    return vector +  end +  get_indexes=function(data,pfbname) +    local vector=loadpfbvector(pfbname) +    if vector then +      local characters=data.characters +      if trace_loading then +        report_afm("getting index data from %a",pfbname) +      end +      for index=1,#vector do +        local name=vector[index] +        local char=characters[name] +        if char then +          if trace_indexing then +            report_afm("glyph %a has index %a",name,index) +          end +          char.index=index +        end +      end +    end +  end +  if fontloader then +    afm.use_new_indexer=true +    get_indexes_new=get_indexes +    get_indexes=function(data,pfbname) +      if afm.use_new_indexer then +        return get_indexes_new(data,pfbname) +      else +        return get_indexes_old(data,pfbname)        end -    elseif trace_loading then -      report_afm("no data in pfb file %a",pfbname)      end -    close_font(pfbblob) -  elseif trace_loading then -    report_afm("invalid pfb file %a",pfbname)    end  end  local function readafm(filename) @@ -7222,6 +7323,7 @@ function afm.load(filename)        data=readafm(filename)        if data then          if pfbname~="" then +          data.resources.filename=resolvers.unresolve(pfbname)            get_indexes(data,pfbname)          elseif trace_loading then            report_afm("no pfb file for %a",filename) @@ -8701,18 +8803,17 @@ readers.hmtx=function(f,fontdata,specification)        local nofmetrics=fontdata.horizontalheader.nofhmetrics        local glyphs=fontdata.glyphs        local nofglyphs=fontdata.nofglyphs -      local nofrepeated=nofglyphs-nofmetrics        local width=0         local leftsidebearing=0        for i=0,nofmetrics-1 do          local glyph=glyphs[i]          width=readshort(f)          leftsidebearing=readshort(f) -        if advance~=0 then +        if width~=0 then            glyph.width=width          end        end -      for i=nofmetrics,nofrepeated do +      for i=nofmetrics,nofglyphs-1 do          local glyph=glyphs[i]          if width~=0 then            glyph.width=width @@ -13840,7 +13941,12 @@ local function copyduplicates(fontdata)                t[#t+1]=f_character_y(u)              end            end -          report("duplicates: % t",t) +          local n=#t +          if n>25 then +            report("duplicates: %i : %s .. %s ",n,t[1],t[n]) +          else +            report("duplicates: %i : % t",n,t) +          end          else          end        end @@ -14025,13 +14131,12 @@ local function checklookups(fontdata,missing,nofmissing)        if r then          local name=descriptions[i].name or f_index(i)          if not ignore[name] then -          done[#done+1]=name +          done[name]=true          end        end      end -    if #done>0 then -      table.sort(done) -      report("not unicoded: % t",done) +    if next(done) then +      report("not unicoded: % t",table.sortedkeys(done))      end    end  end @@ -15486,7 +15591,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_de  local report_otf=logs.reporter("fonts","otf loading")  local fonts=fonts  local otf=fonts.handlers.otf -otf.version=3.017  +otf.version=3.018   otf.cache=containers.define("fonts","otl",otf.version,true)  local otfreaders=otf.readers  local hashes=fonts.hashes  | 
