From ff1cc8f4d4e1d52cc1e9df9fd01f74395c782db5 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Thu, 21 Apr 2016 21:40:30 +0200 Subject: [fontloader] sync with Context as of 2016-04-21 Hans fixed a couple issues due to our reports. Also, brand new Lua based PFB loader. --- src/fontloader/misc/fontloader-font-afm.lua | 224 +++++++++++++++++++---- src/fontloader/misc/fontloader-font-con.lua | 11 +- src/fontloader/misc/fontloader-font-map.lua | 4 +- src/fontloader/misc/fontloader-font-otl.lua | 2 +- src/fontloader/misc/fontloader-font-otr.lua | 7 +- src/fontloader/misc/fontloader-font-oup.lua | 14 +- src/fontloader/misc/fontloader-font-tfm.lua | 2 +- src/fontloader/runtime/fontloader-basics-gen.lua | 6 +- src/fontloader/runtime/fontloader-reference.lua | 207 +++++++++++++++------ 9 files changed, 370 insertions(+), 107 deletions(-) (limited to 'src') 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.

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 -- cgit v1.2.3 From 9f3000ade19fda594cef0f5ee37cdb88eb638e87 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Thu, 21 Apr 2016 23:24:27 +0200 Subject: Revert "[db,conf] drop support for PS fonts" This reverts commit c4c250414a83cc8c4ae99d286ed69a3763510609. Partially, anyways: All mentions of the PFA format were stripped. Since the new loader adds back in support for PFB-flavored PS fonts without AFM we should support it from Luaotfload as well. --- src/luaotfload-configuration.lua | 2 +- src/luaotfload-database.lua | 70 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/luaotfload-configuration.lua b/src/luaotfload-configuration.lua index 8faf3d1..92de432 100644 --- a/src/luaotfload-configuration.lua +++ b/src/luaotfload-configuration.lua @@ -89,7 +89,7 @@ local config_paths = { } local valid_formats = tabletohash { - "otf", "ttc", "ttf", "afm", --"pfb", "pfa", + "otf", "ttc", "ttf", "afm", "pfb" } local feature_presets = { diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua index 135ab0e..f18875c 100644 --- a/src/luaotfload-database.lua +++ b/src/luaotfload-database.lua @@ -207,8 +207,7 @@ local make_luanames = function (path) end local format_precedence = { - "otf", "ttc", "ttf", "afm", - --- "pfb", "pfa", + "otf", "ttc", "ttf", "afm", "pfb" } local location_precedence = { @@ -359,7 +358,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 @@ -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 @@ -1617,13 +1617,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, + fontstyle_name = 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! -- cgit v1.2.3 From 76a913948ef596f93a548004f70e933523d13baf Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 24 Apr 2016 13:50:49 +0200 Subject: [aux] fix features table access (issue #338) Fix #338 Due to the new loader, certain tables were relocated inside the fontdata structure. This would cause a crash with certain kinds of fonts, most notably those for which TeX metrics exist. Many thanks to @aminophen and @u-fischer for their help in tracking this down. --- src/luaotfload-auxiliary.lua | 76 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua index 3d300e7..c927471 100644 --- a/src/luaotfload-auxiliary.lua +++ b/src/luaotfload-auxiliary.lua @@ -317,6 +317,12 @@ aux.name_of_slot = name_of_slot ----------------------------------------------------------------------- --- lots of arrowcode ahead +local get_features = function (tfmdata) + local resources = tfmdata.resources if not resources then return false end + local features = resources.features if not features then return false end + return features +end + --[[doc-- This function, modeled after “check_script()” from fontspec, returns true if in the given font, the script “asked_script” is accounted for in at @@ -325,13 +331,23 @@ least one feature. --- int -> string -> bool local provides_script = function (font_id, asked_script) + if not font_id or type (font_id) ~= "number" + or not asked_script or type (asked_script) ~= "string" + then + logreport ("both", 0, "aux", + "invalid parameters to provides_language(%s, %s)", + tostring (font_id), tostring (asked_script)) + return false + end asked_script = stringlower(asked_script) if font_id and font_id > 0 then - local tfmdata = identifiers[font_id] if not tfmdata then return false end - local shared = tfmdata.shared if not shared then return false end - local fontdata = shared.rawdata if not fontdata then return false end - local fontname = fontdata.metadata.fontname - local features = fontdata.resources.features + local tfmdata = identifiers[font_id] + if not tfmdata then return false end + local features = get_features (tfmdata) + if features == false then + logreport ("log", 1, "aux", "font no %d lacks a features table", font_id) + return false + end for method, featuredata in next, features do --- where method: "gpos" | "gsub" for feature, data in next, featuredata do @@ -362,14 +378,27 @@ feature. --- int -> string -> string -> bool local provides_language = function (font_id, asked_script, asked_language) - asked_script = stringlower(asked_script) - asked_language = stringlower(asked_language) + if not font_id or type (font_id) ~= "number" + or not asked_script or type (asked_script) ~= "string" + or not asked_language or type (asked_language) ~= "string" + then + logreport ("both", 0, "aux", + "invalid parameters to provides_language(%s, %s, %s)", + tostring (font_id), + tostring (asked_script), + tostring (asked_language)) + return false + end + asked_script = stringlower(asked_script) + asked_language = stringlower(asked_language) if font_id and font_id > 0 then - local tfmdata = identifiers[font_id] if not tfmdata then return false end - local shared = tfmdata.shared if not shared then return false end - local fontdata = shared.rawdata if not fontdata then return false end - local fontname = fontdata.metadata.fontname - local features = fontdata.resources.features + local tfmdata = identifiers[font_id] + if not tfmdata then return false end + local features = get_features (tfmdata) + if features == false then + logreport ("log", 1, "aux", "font no %d lacks a features table", font_id) + return false + end for method, featuredata in next, features do --- where method: "gpos" | "gsub" for feature, data in next, featuredata do @@ -432,16 +461,29 @@ accounted for in the script with tag “asked_script” in feature --- int -> string -> string -> string -> bool local provides_feature = function (font_id, asked_script, asked_language, asked_feature) + if not font_id or type (font_id) ~= "number" + or not asked_script or type (asked_script) ~= "string" + or not asked_language or type (asked_language) ~= "string" + or not asked_feature or type (asked_feature) ~= "string" + then + logreport ("both", 0, "aux", + "invalid parameters to provides_language(%s, %s, %s, %s)", + tostring (font_id), tostring (asked_script), + tostring (asked_language), tostring (asked_feature)) + return false + end asked_script = stringlower(asked_script) asked_language = stringlower(asked_language) asked_feature = lpegmatch(strip_garbage, asked_feature) if font_id and font_id > 0 then - local tfmdata = identifiers[font_id] if not tfmdata then return false end - local shared = tfmdata.shared if not shared then return false end - local fontdata = shared.rawdata if not fontdata then return false end - local features = fontdata.resources.features - local fontname = fontdata.metadata.fontname + local tfmdata = identifiers[font_id] + if not tfmdata then return false end + local features = get_features (tfmdata) + if features == false then + logreport ("log", 1, "aux", "font no %d lacks a features table", font_id) + return false + end for method, featuredata in next, features do --- where method: "gpos" | "gsub" local feature = featuredata[asked_feature] -- cgit v1.2.3 From 8c3e40f3dc42ec1b5b6cce8f7ee5bbe7b66ddfd0 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 24 Apr 2016 14:06:06 +0200 Subject: [aux] make slot_of_name API more robust --- src/luaotfload-auxiliary.lua | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua index c927471..fc2a191 100644 --- a/src/luaotfload-auxiliary.lua +++ b/src/luaotfload-auxiliary.lua @@ -263,20 +263,27 @@ end --- 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 then - if type(unicode) == "number" then - return unicode - else - return unicode[1] --- for multiple components - end --- else --- --- missing + if not font_id or type (font_id) ~= "number" + or not glyphname or type (glyphname) ~= "string" + then + logreport ("both", 0, "aux", + "invalid parameters to slot_of_name (%s, %s)", + tostring (font_id), tostring (glyphname)) + return false + end + + local tfmdata = identifiers [font_id] + if not tfmdata then return raw_slot_of_name (font_id, glyphname) end + local resources = tfmdata.resources if not resources then return false end + local unicodes = resources.unicodes if not unicodes then return false end + + local unicode = unicodes [glyphname] + if unicode then + if type (unicode) == "number" then + return unicode + else + return unicode [1] --- for multiple components end - elseif unsafe == true then -- for Robert - return raw_slot_of_name(font_id, glyphname) end return false end @@ -335,7 +342,7 @@ local provides_script = function (font_id, asked_script) or not asked_script or type (asked_script) ~= "string" then logreport ("both", 0, "aux", - "invalid parameters to provides_language(%s, %s)", + "invalid parameters to provides_script(%s, %s)", tostring (font_id), tostring (asked_script)) return false end @@ -467,7 +474,7 @@ local provides_feature = function (font_id, asked_script, or not asked_feature or type (asked_feature) ~= "string" then logreport ("both", 0, "aux", - "invalid parameters to provides_language(%s, %s, %s, %s)", + "invalid parameters to provides_feature(%s, %s, %s, %s)", tostring (font_id), tostring (asked_script), tostring (asked_language), tostring (asked_feature)) return false -- cgit v1.2.3 From 61fcc90e47c36c7c8c8bf4a5d46c649942886462 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 24 Apr 2016 14:12:28 +0200 Subject: [aux] make name_of_slot API more robust --- src/luaotfload-auxiliary.lua | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua index fc2a191..347d9f8 100644 --- a/src/luaotfload-auxiliary.lua +++ b/src/luaotfload-auxiliary.lua @@ -305,11 +305,23 @@ local indices --- int -> (string | false) local name_of_slot = function (codepoint) + if not codepoint or type (codepoint) ~= "number" then + logreport ("both", 0, "aux", + "invalid parameters to name_of_slot (%s)", + tostring (codepoint)) + return false + end + if not indices then --- this will load the glyph list local unicodes = encodings.agl.unicodes - indices = table.swapped(unicodes) + if not unicodes or not next (unicodes)then + logreport ("both", 0, "aux", + "name_of_slot: failed to load the AGL.") + end + indices = table.swapped (unicodes) end - local glyphname = indices[codepoint] + + local glyphname = indices [codepoint] if glyphname then return glyphname end -- cgit v1.2.3 From 4f5a4f429479ce16964f7637fe3d92a1d19650af Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 24 Apr 2016 20:08:29 +0200 Subject: [fontloader] sync with Context as of 2016-04-24 --- src/fontloader/misc/fontloader-font-afm.lua | 9 +-- src/fontloader/misc/fontloader-font-otr.lua | 63 +++++++++++++++++--- src/fontloader/misc/fontloader-font-oup.lua | 22 ++++--- src/fontloader/runtime/fontloader-reference.lua | 78 ++++++++++++++++++++----- 4 files changed, 138 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/fontloader/misc/fontloader-font-afm.lua b/src/fontloader/misc/fontloader-font-afm.lua index 3dedf12..7003304 100644 --- a/src/fontloader/misc/fontloader-font-afm.lua +++ b/src/fontloader/misc/fontloader-font-afm.lua @@ -56,7 +56,7 @@ local pfb = constructors.newhandler("pfb") local afmfeatures = constructors.newfeatures("afm") local registerafmfeature = afmfeatures.register -afm.version = 1.500 -- incrementing this number one up will force a re-cache +afm.version = 1.501 -- incrementing this number one up will force a re-cache afm.cache = containers.define("fonts", "afm", afm.version, true) afm.autoprefixed = true -- this will become false some day (catches texnansi-blabla.*) @@ -547,9 +547,10 @@ local uparser = fonts.mappings.makenameparser() unify = function(data, filename) local unicodevector = fonts.encodings.agl.unicodes -- loaded runtime in context - local unicodes, names = { }, { } - local private = constructors.privateoffset - local descriptions = data.descriptions + local unicodes = { } + local names = { } + local private = constructors.privateoffset + local descriptions = data.descriptions for name, blob in next, data.characters do local code = unicodevector[name] -- or characters.name_to_unicode[name] if not code then diff --git a/src/fontloader/misc/fontloader-font-otr.lua b/src/fontloader/misc/fontloader-font-otr.lua index 27bb6a6..a9ad739 100644 --- a/src/fontloader/misc/fontloader-font-otr.lua +++ b/src/fontloader/misc/fontloader-font-otr.lua @@ -60,15 +60,15 @@ if not modules then modules = { } end modules ['font-otr'] = { -- faster but it might not be the real bottleneck as we still need to juggle data. It -- is probably more memory efficient as no intermediate strings are involved. -if not characters then - require("char-def") - require("char-ini") -end +-- if not characters then +-- require("char-def") +-- require("char-ini") +-- end local next, type, unpack = next, type, unpack local byte, lower, char, strip, gsub = string.byte, string.lower, string.char, string.strip, string.gsub local bittest = bit32.btest -local concat, remove, unpack = table.concat, table.remov, table.unpack +local concat, remove, unpack, fastcopy = table.concat, table.remov, table.unpack, table.fastcopy local floor, mod, abs, sqrt, round = math.floor, math.mod, math.abs, math.sqrt, math.round local P, R, S, C, Cs, Cc, Ct, Carg, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Carg, lpeg.Cmt local lpegmatch = lpeg.match @@ -1186,6 +1186,8 @@ local sequence = { { 3, 0, 6 }, -- variants { 0, 5, 14 }, + -- last resort ranges + { 3, 10, 13 }, } -- local sequence = { @@ -1388,7 +1390,7 @@ formatreaders[12] = function(f,fontdata,offset) local last = readulong(f) local index = readulong(f) if trace_cmap then - report("format 12 from %C to %C",first,last) + report("format 12 from %C to %C starts at index %i",first,last,index) end for unicode=first,last do local glyph = glyphs[index] @@ -1416,6 +1418,53 @@ formatreaders[12] = function(f,fontdata,offset) return nofdone end +formatreaders[13] = function(f,fontdata,offset) + -- + -- this fector is only used for simple fallback fonts + -- + setposition(f,offset+2+2+4+4) -- skip format reserved length language + local mapping = fontdata.mapping + local glyphs = fontdata.glyphs + local duplicates = fontdata.duplicates + local nofgroups = readulong(f) + local nofdone = 0 + for i=1,nofgroups do + local first = readulong(f) + local last = readulong(f) + local index = readulong(f) + if first < privateoffset then + if trace_cmap then + report("format 13 from %C to %C get index %i",first,last,index) + end + local glyph = glyphs[index] + local unicode = glyph.unicode + if not unicode then + unicode = first + glyph.unicode = unicode + first = first + 1 + end + local list = duplicates[unicode] + mapping[index] = unicode + if not list then + list = { } + duplicates[unicode] = list + end + if last >= privateoffset then + local limit = privateoffset - 1 + report("format 13 from %C to %C pruned to %C",first,last,limit) + last = limit + end + for unicode=first,last do + list[unicode] = true + end + nofdone = nofdone + last - first + 1 + else + report("format 13 from %C to %C ignored",first,last) + end + end + return nofdone +end + formatreaders[14] = function(f,fontdata,offset) if offset and offset ~= 0 then setposition(f,offset) @@ -2225,7 +2274,7 @@ function readers.extend(fontdata) end end --- +-- for now .. this will move to a context specific file if fonts.hashes then diff --git a/src/fontloader/misc/fontloader-font-oup.lua b/src/fontloader/misc/fontloader-font-oup.lua index a99aaf4..3b6d8ea 100644 --- a/src/fontloader/misc/fontloader-font-oup.lua +++ b/src/fontloader/misc/fontloader-font-oup.lua @@ -367,22 +367,28 @@ local function copyduplicates(fontdata) for u, d in next, duplicates do local du = descriptions[u] if du then - local t = { f_character_y(u), "@", f_index(du.index), "->" } + local t = { f_character_y(u), "@", f_index(du.index), "->" } + local n = 0 + local m = 25 for u in next, d do if descriptions[u] then - t[#t+1] = f_character_n(u) + if n < m then + t[n+4] = f_character_n(u) + end else local c = copy(du) - -- c.unicode = u -- maybe + c.unicode = u -- better this way descriptions[u] = c - t[#t+1] = f_character_y(u) + if n < m then + t[n+4] = f_character_y(u) + end end + n = n + 1 end - local n = #t - if n > 25 then - report("duplicates: %i : %s .. %s ",n,t[1],t[n]) - else + if n <= m then report("duplicates: %i : % t",n,t) + else + report("duplicates: %i : % t ...",n,t) end else -- what a mess diff --git a/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua index 7c06c25..09a24b9 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/21/16 12:13:25 +-- merge date : 04/22/16 09:10:04 do -- begin closure to overcome local limits and interference @@ -7002,7 +7002,7 @@ local afm=constructors.newhandler("afm") local pfb=constructors.newhandler("pfb") local afmfeatures=constructors.newfeatures("afm") local registerafmfeature=afmfeatures.register -afm.version=1.500 +afm.version=1.501 afm.cache=containers.define("fonts","afm",afm.version,true) afm.autoprefixed=true afm.helpdata={} @@ -7367,7 +7367,8 @@ end local uparser=fonts.mappings.makenameparser() unify=function(data,filename) local unicodevector=fonts.encodings.agl.unicodes - local unicodes,names={},{} + local unicodes={} + local names={} local private=constructors.privateoffset local descriptions=data.descriptions for name,blob in next,data.characters do @@ -8244,14 +8245,10 @@ if not modules then modules={} end modules ['font-otr']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -if not characters then - require("char-def") - require("char-ini") -end local next,type,unpack=next,type,unpack local byte,lower,char,strip,gsub=string.byte,string.lower,string.char,string.strip,string.gsub local bittest=bit32.btest -local concat,remove,unpack=table.concat,table.remov,table.unpack +local concat,remove,unpack,fastcopy=table.concat,table.remov,table.unpack,table.fastcopy local floor,mod,abs,sqrt,round=math.floor,math.mod,math.abs,math.sqrt,math.round local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt local lpegmatch=lpeg.match @@ -8896,6 +8893,7 @@ local sequence={ { 0,0,6 }, { 3,0,6 }, { 0,5,14 }, + { 3,10,13 }, } local supported={} for i=1,#sequence do @@ -9067,7 +9065,7 @@ formatreaders[12]=function(f,fontdata,offset) local last=readulong(f) local index=readulong(f) if trace_cmap then - report("format 12 from %C to %C",first,last) + report("format 12 from %C to %C starts at index %i",first,last,index) end for unicode=first,last do local glyph=glyphs[index] @@ -9093,6 +9091,49 @@ formatreaders[12]=function(f,fontdata,offset) end return nofdone end +formatreaders[13]=function(f,fontdata,offset) + setposition(f,offset+2+2+4+4) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofgroups=readulong(f) + local nofdone=0 + for i=1,nofgroups do + local first=readulong(f) + local last=readulong(f) + local index=readulong(f) + if first=privateoffset then + local limit=privateoffset-1 + report("format 13 from %C to %C pruned to %C",first,last,limit) + last=limit + end + for unicode=first,last do + list[unicode]=true + end + nofdone=nofdone+last-first+1 + else + report("format 13 from %C to %C ignored",first,last) + end + end + return nofdone +end formatreaders[14]=function(f,fontdata,offset) if offset and offset~=0 then setposition(f,offset) @@ -13932,20 +13973,27 @@ local function copyduplicates(fontdata) local du=descriptions[u] if du then local t={ f_character_y(u),"@",f_index(du.index),"->" } + local n=0 + local m=25 for u in next,d do if descriptions[u] then - t[#t+1]=f_character_n(u) + if n25 then - report("duplicates: %i : %s .. %s ",n,t[1],t[n]) - else + if n<=m then report("duplicates: %i : % t",n,t) + else + report("duplicates: %i : % t ...",n,t) end else end -- cgit v1.2.3 From 9e1efb4c32dc1ef8319e9fd7bb708aa7eaec43ec Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 24 Apr 2016 20:40:43 +0200 Subject: [db,loaders] clarify support for PFB The current PFB loader, although it is indeed completely independent of the FF libraries, is not yet feature complete. Only the loading of vectors is supported which suffices for font rendering given the AFM information. According to Hans, we have decent chance of it growing into a full-fledged reader for 1.0. --- src/luaotfload-database.lua | 7 ++++--- src/luaotfload-loaders.lua | 10 +++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua index f18875c..d59b7c8 100644 --- a/src/luaotfload-database.lua +++ b/src/luaotfload-database.lua @@ -207,7 +207,8 @@ local make_luanames = function (path) end local format_precedence = { - "otf", "ttc", "ttf", "afm", "pfb" + "otf", "ttc", "ttf", "afm", + -- "pfb" --- may come back before Luatex 1.0 } local location_precedence = { @@ -358,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" | "pfb" + 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 @@ -1681,7 +1682,7 @@ local loaders = { otf = ot_fullinfo, ttc = ot_fullinfo, ttf = ot_fullinfo, - pfb = t1_fullinfo, +--- pfb = t1_fullinfo, } --- not side-effect free! diff --git a/src/luaotfload-loaders.lua b/src/luaotfload-loaders.lua index f0c1913..8a29256 100644 --- a/src/luaotfload-loaders.lua +++ b/src/luaotfload-loaders.lua @@ -49,6 +49,14 @@ local unsupported_reader = function (format) end end +local afm_compat_message = function (specification, method) + logreport ("both", 0, "loaders", + "PFB format only supported with matching \z + AFM; redirecting (“%s”, “%s”).", + tostring (specification.name), tostring (method)) + return fonts.readers.afm (specification, method) +end + local install_formats = function () local fonts = fonts if not fonts then return false end @@ -81,7 +89,7 @@ local install_formats = function () return aux ("evl", eval_reader) and aux ("lua", lua_reader) and aux ("pfa", unsupported_reader "pfa") - and aux ("pfb", unsupported_reader "pfb") + and aux ("pfb", afm_compat_message) --- pfb loader is incomplete and aux ("ofm", readers.tfm) and aux ("dfont", unsupported_reader "dfont") end -- cgit v1.2.3 From cc59be4bd1d31b2bb7207dc60072d2090d045fef Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 24 Apr 2016 20:43:59 +0200 Subject: [db] fix version field Fix #337 This amends the apparent failure of luaotfload-tool as reported by @eg9 and others. --- src/luaotfload-database.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua index d59b7c8..44786a5 100644 --- a/src/luaotfload-database.lua +++ b/src/luaotfload-database.lua @@ -3596,7 +3596,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 -- cgit v1.2.3 From 88636ab5075bad0fdd6c635629fc29a9f95d8cbc Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 25 Apr 2016 07:40:10 +0200 Subject: [loaders,resolvers] tone down default log noise --- src/luaotfload-loaders.lua | 6 +++--- src/luaotfload-resolvers.lua | 12 +++++------- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/luaotfload-loaders.lua b/src/luaotfload-loaders.lua index 8a29256..f6cb272 100644 --- a/src/luaotfload-loaders.lua +++ b/src/luaotfload-loaders.lua @@ -43,14 +43,14 @@ end local unsupported_reader = function (format) return function (specification) - logreport ("both", 0, "loaders", + logreport ("both", 4, "loaders", "font format “%s” unsupported; cannot load %s.", format, tostring (specification.name)) end end local afm_compat_message = function (specification, method) - logreport ("both", 0, "loaders", + logreport ("both", 4, "loaders", "PFB format only supported with matching \z AFM; redirecting (“%s”, “%s”).", tostring (specification.name), tostring (method)) @@ -78,7 +78,7 @@ local install_formats = function () readers [which] = reader handlers [which] = { } if not seqset [which] then - logreport ("both", 0, "loaders", + logreport ("both", 3, "loaders", "Extending reader sequence for “%s”.", which) sequence [#sequence + 1] = which seqset [which] = true diff --git a/src/luaotfload-resolvers.lua b/src/luaotfload-resolvers.lua index 05a0656..ee3b597 100644 --- a/src/luaotfload-resolvers.lua +++ b/src/luaotfload-resolvers.lua @@ -205,20 +205,18 @@ local resolve_sequence = function (seq, specification) for i = 1, #seq do local id = seq [i] local mth = resolve_methods [id] - logreport ("both", 0, "resolve", "step %d: apply method %q (%s)", i, id, mth) + logreport ("both", 3, "resolve", "step %d: apply method %q (%s)", i, id, mth) if mth (specification) == true then - logreport ("both", 0, "resolve", - "%d: method %q indicated lookup success", i, id) - logreport ("both", 0, "resolve", - "method %q resolved %q -> %s (%s)", - id, specification.specification, + logreport ("both", 3, "resolve", + "%d: method %q resolved %q -> %s (%s).", + i, id, specification.specification, specification.name, specification.forcedname) return true end end logreport ("both", 0, "resolve", - "sequence of %d lookups yielded nothing appropriate", #seq) + "sequence of %d lookups yielded nothing appropriate.", #seq) return false end -- cgit v1.2.3 From f5ae057cbe8d00ec09269080ee152fd52dfa931f Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 25 Apr 2016 23:21:28 +0200 Subject: [fontloader] sync with Context as of 2016-04-25 --- src/fontloader/misc/fontloader-font-afm.lua | 4 +-- src/fontloader/misc/fontloader-font-otj.lua | 6 ++--- src/fontloader/misc/fontloader-font-otr.lua | 10 +++---- src/fontloader/misc/fontloader-font-ots.lua | 20 +++++++++++++- src/fontloader/runtime/fontloader-reference.lua | 36 ++++++++++++++++--------- 5 files changed, 53 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/fontloader/misc/fontloader-font-afm.lua b/src/fontloader/misc/fontloader-font-afm.lua index 7003304..99b8577 100644 --- a/src/fontloader/misc/fontloader-font-afm.lua +++ b/src/fontloader/misc/fontloader-font-afm.lua @@ -30,7 +30,7 @@ local fonts, logs, trackers, containers, resolvers = fonts, logs, trackers, cont local next, type, tonumber = next, type, tonumber 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 abs = math.abs 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 @@ -317,7 +317,7 @@ do local function step(c) local cipher = byte(c) local plain = bxor(cipher,rshift(r,8)) - r = mod((cipher + r) * c1 + c2,65536) + r = ((cipher + r) * c1 + c2) % 65536 return char(plain) end diff --git a/src/fontloader/misc/fontloader-font-otj.lua b/src/fontloader/misc/fontloader-font-otj.lua index aae70d1..ebda723 100644 --- a/src/fontloader/misc/fontloader-font-otj.lua +++ b/src/fontloader/misc/fontloader-font-otj.lua @@ -49,8 +49,8 @@ local attributes, nodes, node = attributes, nodes, node fonts = fonts local hashes = fonts.hashes local fontdata = hashes.identifiers -local parameters = fonts.hashes.parameters -local resources = fonts.hashes.resources +----- parameters = fonts.hashes.parameters -- not in generic +----- resources = fonts.hashes.resources -- not in generic nodes.injections = nodes.injections or { } local injections = nodes.injections @@ -1444,7 +1444,7 @@ local function injectspaces(head) -- end leftkerns = trig.left rightkerns = trig.right - local par = parameters[font] + local par = fontdata[font].parameters -- fallback for generic factor = par.factor threshold = par.spacing.width - 1 -- get rid of rounding errors lastfont = font diff --git a/src/fontloader/misc/fontloader-font-otr.lua b/src/fontloader/misc/fontloader-font-otr.lua index a9ad739..24f6854 100644 --- a/src/fontloader/misc/fontloader-font-otr.lua +++ b/src/fontloader/misc/fontloader-font-otr.lua @@ -69,7 +69,7 @@ local next, type, unpack = next, type, unpack local byte, lower, char, strip, gsub = string.byte, string.lower, string.char, string.strip, string.gsub local bittest = bit32.btest local concat, remove, unpack, fastcopy = table.concat, table.remov, table.unpack, table.fastcopy -local floor, mod, abs, sqrt, round = math.floor, math.mod, math.abs, math.sqrt, math.round +local floor, abs, sqrt, round = math.floor, math.abs, math.sqrt, math.round local P, R, S, C, Cs, Cc, Ct, Carg, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Carg, lpeg.Cmt local lpegmatch = lpeg.match @@ -1270,10 +1270,10 @@ formatreaders[4] = function(f,fontdata,offset) -- bad encoding elseif offset == 0 then if trace_cmap then - report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,mod(startchar + delta,65536)) + report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar + delta) % 65536) end for unicode=startchar,endchar do - local index = mod(unicode + delta,65536) + local index = (unicode + delta) % 65536 if index and index > 0 then local glyph = glyphs[index] if glyph then @@ -1303,13 +1303,13 @@ formatreaders[4] = function(f,fontdata,offset) else local shift = (segment-nofsegments+offset/2) - startchar if trace_cmap then - report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,mod(startchar + delta,65536)) + report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar + delta) % 65536) end for unicode=startchar,endchar do local slot = shift + unicode local index = indices[slot] if index and index > 0 then - index = mod(index + delta,65536) + index = (index + delta) % 65536 local glyph = glyphs[index] if glyph then local gu = glyph.unicode diff --git a/src/fontloader/misc/fontloader-font-ots.lua b/src/fontloader/misc/fontloader-font-ots.lua index 6911872..ac81989 100644 --- a/src/fontloader/misc/fontloader-font-ots.lua +++ b/src/fontloader/misc/fontloader-font-ots.lua @@ -9,6 +9,9 @@ if not modules then modules = { } end modules ['font-ots'] = { -- sequences -- to be checked: discrun doesn't seem to do something useful now (except run the -- check again) so if we need it again we'll do a zwnjrun or so +-- components will go away and be replaced by a property table which simplifies +-- code (also more efficient) + -- beware, on my development machine we test a slightly a more optimized version -- assumptions: @@ -566,7 +569,22 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou local pre, post, replace, pretail, posttail, replacetail = getdisc(discfound,true) if not replace then -- todo: signal simple hyphen local prev = getprev(base) - local copied = copy_node_list(comp) +-- local copied = copy_node_list(comp) +local current = comp +local previous = nil +local copied = nil +while current do + if getid(current) == glyph_code then + local n = copy_node(current) + if copied then + setlink(previous,n) + else + copied = n + end + previous = n + end + current = getnext(current) +end setprev(discnext,nil) -- also blocks funny assignments setnext(discprev,nil) -- also blocks funny assignments if pre then diff --git a/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua index 09a24b9..ab81bc6 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/22/16 09:10:04 +-- merge date : 04/25/16 13:30:09 do -- begin closure to overcome local limits and interference @@ -6984,7 +6984,7 @@ local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,re local next,type,tonumber=next,type,tonumber 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 abs=math.abs 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 @@ -7183,7 +7183,7 @@ do local function step(c) local cipher=byte(c) local plain=bxor(cipher,rshift(r,8)) - r=mod((cipher+r)*c1+c2,65536) + r=((cipher+r)*c1+c2)%65536 return char(plain) end decrypt=function(binary) @@ -8249,7 +8249,7 @@ local next,type,unpack=next,type,unpack local byte,lower,char,strip,gsub=string.byte,string.lower,string.char,string.strip,string.gsub local bittest=bit32.btest local concat,remove,unpack,fastcopy=table.concat,table.remov,table.unpack,table.fastcopy -local floor,mod,abs,sqrt,round=math.floor,math.mod,math.abs,math.sqrt,math.round +local floor,abs,sqrt,round=math.floor,math.abs,math.sqrt,math.round local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt local lpegmatch=lpeg.match local setmetatableindex=table.setmetatableindex @@ -8952,10 +8952,10 @@ formatreaders[4]=function(f,fontdata,offset) elseif offset==0xFFFF then elseif offset==0 then if trace_cmap then - report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,mod(startchar+delta,65536)) + report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536) end for unicode=startchar,endchar do - local index=mod(unicode+delta,65536) + local index=(unicode+delta)%65536 if index and index>0 then local glyph=glyphs[index] if glyph then @@ -8984,13 +8984,13 @@ formatreaders[4]=function(f,fontdata,offset) else local shift=(segment-nofsegments+offset/2)-startchar if trace_cmap then - report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,mod(startchar+delta,65536)) + report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536) end for unicode=startchar,endchar do local slot=shift+unicode local index=indices[slot] if index and index>0 then - index=mod(index+delta,65536) + index=(index+delta)%65536 local glyph=glyphs[index] if glyph then local gu=glyph.unicode @@ -16680,8 +16680,6 @@ local attributes,nodes,node=attributes,nodes,node fonts=fonts local hashes=fonts.hashes local fontdata=hashes.identifiers -local parameters=fonts.hashes.parameters -local resources=fonts.hashes.resources nodes.injections=nodes.injections or {} local injections=nodes.injections local tracers=nodes.tracers @@ -17871,7 +17869,7 @@ local function injectspaces(head) local function updatefont(font,trig) leftkerns=trig.left rightkerns=trig.right - local par=parameters[font] + local par=fontdata[font].parameters factor=par.factor threshold=par.spacing.width-1 lastfont=font @@ -18719,7 +18717,21 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true) if not replace then local prev=getprev(base) - local copied=copy_node_list(comp) +local current=comp +local previous=nil +local copied=nil +while current do + if getid(current)==glyph_code then + local n=copy_node(current) + if copied then + setlink(previous,n) + else + copied=n + end + previous=n + end + current=getnext(current) +end setprev(discnext,nil) setnext(discprev,nil) if pre then -- cgit v1.2.3 From 5efcb3555bd11f7caf6bc28d5eae8b0d4ae83026 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 26 Apr 2016 00:22:34 +0200 Subject: [aux] fix \fontdimen8 hack Addresses #341 This cleans up the font patching code we inherited from Fontspec. In addition to treating the bitrot with an extra dose of fungicide, we also make the process in which the final values are chosen more transparent. --- src/luaotfload-auxiliary.lua | 94 +++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua index 347d9f8..22f8201 100644 --- a/src/luaotfload-auxiliary.lua +++ b/src/luaotfload-auxiliary.lua @@ -177,40 +177,72 @@ Comment from fontspec: --doc]]-- +local capheight_reference_char = stringbyte "X" -- might be ‘M’, ‘Ж’, or ‘ξ’. + +local determine_capheight = function (fontdata) + local parameters = fontdata.parameters if not parameters then return false end + local characters = fontdata.characters if not characters then return false end + local refchar = characters [capheight_reference_char] + if refchar then + return refchar.height + end + return false +end + +local query_ascender = function (fontdata) + local parameters = fontdata.parameters if not parameters then return false end + local metadata = fontdata.metadata if not metadata then return false end + local ascender = metadata.ascender if not ascender then return false end + local units = metadata.units if units == 0 then return false end + local size = parameters.size if not size then return false end + return ascender * size / units +end + +local query_capheight = function (fontdata) + local parameters = fontdata.parameters if not parameters then return false end + local metadata = fontdata.metadata if not metadata then return false end + local capheight = metadata.capheight if not capheight then return false end + local units = metadata.units if units == 0 then return false end + local size = parameters.size if not size then return false end + return capheight * size / units +end + +local query_fontdimen8 = function (fontdata) + local parameters = fontdata.parameters if not parameters then return false end + local fontdimen8 = parameters [8] + if fontdimen8 then return fontdimen8 end + return false +end + +local caphtfmt = function (ref, ht) + if not ht then return "" end + if not ref then return tostring (ht) end + return stringformat ("%s(δ=%s)", ht, ht - ref) +end + local set_capheight = function (fontdata) - local shared = fontdata.shared - local parameters = fontdata.parameters - local capheight - if shared - and shared.rawdata.metadata - and shared.rawdata.metadata.pfminfo - then - local units_per_em = parameters.units - local size = parameters.size - local os2_capheight = shared.rawdata.metadata.pfminfo.os2_capheight - - if capheight and os2_capheight > 0 then - capheight = os2_capheight / units_per_em * size - else - local X8_str = stringbyte"X" - local X8_chr = fontdata.characters[X8_str] - if X8_chr then - capheight = X8_chr.height - else - capheight = parameters.ascender / units_per_em * size - end - end - else - local X8_str = stringbyte "X" - local X8_chr = fontdata.characters[X8_str] - if X8_chr then - capheight = X8_chr.height - end + if not fontdata then + logreport ("both", 0, "aux", + "error: set_capheight() received garbage") + return end + local capheight_dimen8 = query_fontdimen8 (fontdata) + local capheight_alleged = query_capheight (fontdata) + local capheight_ascender = query_ascender (fontdata) + local capheight_measured = determine_capheight (fontdata) + logreport ("term", 4, "aux", + "capht: param[8]=%s advertised=%s ascender=%s measured=%s", + tostring (capheight_dimen8), + caphtfmt (capheight_dimen8, capheight_alleged), + caphtfmt (capheight_dimen8, capheight_ascender), + caphtfmt (capheight_dimen8, capheight_measured)) + if capheight_dimen8 then --- nothing to do + return + end + + local capheight = capheight_alleged or capheight_ascender or capheight_measured if capheight then - --- is this legit? afaics there’s nothing else on the - --- array part of that table - fontdata.parameters[8] = capheight + fontdata.parameters [8] = capheight end end -- cgit v1.2.3 From 2a60462172f9e077e6df0887654a5e54fe4ce204 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 26 Apr 2016 00:36:52 +0200 Subject: [aux] probe multiple characters when guessing the capital height MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide fallbacks in case no ‘X’ character is available for capheight measurement. --- src/luaotfload-auxiliary.lua | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua index 22f8201..06821f6 100644 --- a/src/luaotfload-auxiliary.lua +++ b/src/luaotfload-auxiliary.lua @@ -177,14 +177,32 @@ Comment from fontspec: --doc]]-- -local capheight_reference_char = stringbyte "X" -- might be ‘M’, ‘Ж’, or ‘ξ’. +local capheight_reference_chars = { "X", "M", "Ж", "ξ", } +local capheight_reference_codepoints do + local utfbyte = unicode.utf8.byte + capheight_reference_codepoints = { } + for i = 1, #capheight_reference_chars do + local chr = capheight_reference_chars [i] + capheight_reference_codepoints [i] = utfbyte (chr) + end +end local determine_capheight = function (fontdata) local parameters = fontdata.parameters if not parameters then return false end local characters = fontdata.characters if not characters then return false end - local refchar = characters [capheight_reference_char] - if refchar then - return refchar.height + --- Pretty simplistic but it does return *some* value for most fonts; + --- we could also refine the approach to return some kind of average + --- of all capital letters or a user-provided subset. + for i = 1, #capheight_reference_codepoints do + local refcp = capheight_reference_codepoints [i] + local refchar = characters [refcp] + if refchar then + logreport ("both", 4, "aux", + "picked height of character ‘%s’ (U+%d) as \\fontdimen8 \z + candidate", + capheight_reference_chars [i], refcp) + return refchar.height + end end return false end -- cgit v1.2.3 From 73521a6f3d35b8cf0e4cfc5d57f32ee5b7d4d6d3 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 26 Apr 2016 08:15:07 +0200 Subject: [aux] actually pull capheight and ascender values from the correct table --- src/luaotfload-auxiliary.lua | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua index 06821f6..d6835a9 100644 --- a/src/luaotfload-auxiliary.lua +++ b/src/luaotfload-auxiliary.lua @@ -209,19 +209,24 @@ end local query_ascender = function (fontdata) local parameters = fontdata.parameters if not parameters then return false end - local metadata = fontdata.metadata if not metadata then return false end - local ascender = metadata.ascender if not ascender then return false end + local shared = fontdata.shared if not shared then return false end + local rawdata = shared.rawdata if not rawdata then return false end + local metadata = rawdata.metadata if not metadata then return false end + local ascender = parameters.ascender + or metadata.ascender if not ascender then return false end local units = metadata.units if units == 0 then return false end local size = parameters.size if not size then return false end return ascender * size / units end local query_capheight = function (fontdata) - local parameters = fontdata.parameters if not parameters then return false end - local metadata = fontdata.metadata if not metadata then return false end - local capheight = metadata.capheight if not capheight then return false end - local units = metadata.units if units == 0 then return false end - local size = parameters.size if not size then return false end + local parameters = fontdata.parameters if not parameters then return false end + local shared = fontdata.shared if not shared then return false end + local rawdata = shared.rawdata if not rawdata then return false end + local metadata = rawdata.metadata if not metadata then return false end + local capheight = metadata.capheight if not capheight then return false end + local units = metadata.units if units == 0 then return false end + local size = parameters.size if not size then return false end return capheight * size / units end -- cgit v1.2.3 From a62867edb4dc4b5d46fe2b8c34fa4f6dc7fddc5c Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 26 Apr 2016 22:30:01 +0200 Subject: [aux] fix \fontdimen{10,114} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #341 Hironori Kitagawa pointed out that the patch for the other math parameters doesn’t work. Turns out Hans relocated the “mathconstants” table … --- src/luaotfload-auxiliary.lua | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua index d6835a9..e544dd7 100644 --- a/src/luaotfload-auxiliary.lua +++ b/src/luaotfload-auxiliary.lua @@ -88,13 +88,12 @@ package. --doc]]-- local set_sscale_dimens = function (fontdata) - local mathconstants = fontdata.MathConstants - local parameters = fontdata.parameters - if mathconstants then - parameters[10] = mathconstants.ScriptPercentScaleDown or 70 - parameters[11] = mathconstants.ScriptScriptPercentScaleDown or 50 - end - return fontdata + local resources = fontdata.resources if not resources then return end + local mathconstants = resources.MathConstants if not mathconstants then return end + local parameters = fontdata.parameters if not parameters then return end + --- the default values below are complete crap + parameters [10] = mathconstants.ScriptPercentScaleDown or 70 + parameters [11] = mathconstants.ScriptScriptPercentScaleDown or 50 end luaotfload_callbacks [#luaotfload_callbacks + 1] = { @@ -104,8 +103,8 @@ luaotfload_callbacks [#luaotfload_callbacks + 1] = { --- fontobj -> int local lookup_units = function (fontdata) local metadata = fontdata.shared and fontdata.shared.rawdata.metadata - if metadata and metadata.units_per_em then - return metadata.units_per_em + if metadata and metadata.units then + return metadata.units elseif fontdata.parameters and fontdata.parameters.units then return fontdata.parameters.units elseif fontdata.units then --- v1.x @@ -122,9 +121,9 @@ local patch_cambria_domh = function (fontdata) local mathconstants = fontdata.MathConstants if mathconstants and fontdata.psname == "CambriaMath" then --- my test Cambria has 2048 - local units_per_em = fontdata.units_per_em or lookup_units(fontdata) - local sz = fontdata.parameters.size or fontdata.size - local mh = 2800 / units_per_em * sz + local units = fontdata.units or lookup_units(fontdata) + local sz = fontdata.parameters.size or fontdata.size + local mh = 2800 / units * sz if mathconstants.DisplayOperatorMinHeight < mh then mathconstants.DisplayOperatorMinHeight = mh end -- cgit v1.2.3 From ae9a8c83c83a4ad5f6fe0288d801512421e895de Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 26 Apr 2016 23:13:09 +0200 Subject: [main] handle module load failure Forward the errors received from require() in a readable manner and exit on the spot. --- src/luaotfload-main.lua | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/luaotfload-main.lua b/src/luaotfload-main.lua index 51a0657..9e8d088 100644 --- a/src/luaotfload-main.lua +++ b/src/luaotfload-main.lua @@ -111,9 +111,33 @@ local make_loader = function (prefix) return function (name) local t_0 = osgettimeofday () local modname = make_loader_name (prefix, name) - local data = require (modname) + --- We don’t want the stack info from inside, so just pcall(). + local ok, data = pcall (require, modname) local t_end = osgettimeofday () timing_info.t_load [name] = t_end - t_0 + if not ok then + io.write "\n" + local msg = luaotfload.log and luaotfload.log.report or print + msg ("both", 0, "load", "FATAL ERROR") + msg ("both", 0, "load", " × Failed to load module %q.", + tostring (modname)) + local lines = string.split (data, "\n\t") + if not lines then + msg ("both", 0, "load", " × Error message: %q", data) + else + msg ("both", 0, "load", " × Error message:") + for i = 1, #lines do + msg ("both", 0, "load", " × %q.", lines [i]) + end + end + io.write "\n\n" + local debug = debug + if debug then + io.write (debug.traceback()) + io.write "\n\n" + end + os.exit(-1) + end return data end end -- cgit v1.2.3 From e789cc0309f9d850e72dc724c0e686a9c03b7979 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 27 Apr 2016 07:42:49 +0200 Subject: [db] fix family / style matching Fix #342 Due to the reassigned fontname fields, certain values designating styles ended up being interpreted wrongly and members of the font families ended up in the wrong table. Thanks to @dohyunkim for spotting the issue. --- src/luaotfload-database.lua | 89 ++++++++++++--------------------------------- 1 file changed, 24 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua index 44786a5..b8a50d6 100644 --- a/src/luaotfload-database.lua +++ b/src/luaotfload-database.lua @@ -596,11 +596,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 = { @@ -1035,7 +1035,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 @@ -1449,7 +1449,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, @@ -1520,21 +1519,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, @@ -1672,7 +1656,7 @@ t1_fullinfo = function (filename, _subfont, location, basename, format) psname = sanitized.fontname, version = metadata.version, size = false, - fontstyle_name = style ~= "" and style or weight, + prefmodifiers = style ~= "" and style or weight, weight = metadata.pfminfo and pfminfo.weight or 400, italicangle = italicangle, } @@ -2611,19 +2595,13 @@ 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 @@ -2632,10 +2610,9 @@ do --- more aggressive, but only to determine bold faces if pfmweight > 500 or bold_synonym [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 @@ -2643,13 +2620,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 @@ -2664,9 +2640,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 @@ -2693,7 +2671,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 @@ -2758,7 +2735,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 @@ -2766,26 +2742,15 @@ 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 modifier then add_family (familyname, subtable, modifier, entry) @@ -3022,7 +2987,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 @@ -3082,7 +3047,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) @@ -3157,10 +3121,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 @@ -3177,7 +3137,6 @@ local collect_statistics = function (mappings) -- style = { -- subfamily = subfamily, -- prefmodifiers = prefmodifiers, --- fontstyle_name = fontstyle_name, -- }, } end -- cgit v1.2.3 From 08f6c022be4fca298df03fe5582647d5b8c9785e Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 27 Apr 2016 08:00:39 +0200 Subject: [db] adapt call to getinfo() for revised interface --- src/luaotfload-database.lua | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua index b8a50d6..e0f6e61 100644 --- a/src/luaotfload-database.lua +++ b/src/luaotfload-database.lua @@ -1410,7 +1410,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 @@ -3501,8 +3500,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 -- cgit v1.2.3 From 48a7f10116bcdbcfbf427e761c48df33713ba5e5 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 27 Apr 2016 08:20:15 +0200 Subject: [db] disarm fallback assignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When adapting to the new loader we repeated the mistake of classifying “bold” faces by too broad criteria, thereby sabotaging the recognition of large families from Adobe. Restore the old behavior by only treating those faces as bold fallback that advertise and exact weight of 700. --- src/luaotfload-database.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua index e0f6e61..0c2fd40 100644 --- a/src/luaotfload-database.lua +++ b/src/luaotfload-database.lua @@ -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 @@ -2567,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 @@ -2607,7 +2609,7 @@ do 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 + if pfmweight == bold_weight or bold_synonym [weight] then --- bold spectrum matches if italicangle == 0 then return "b" end @@ -2713,7 +2715,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.") @@ -2753,7 +2755,7 @@ collect_families = function (mappings) if modifier then add_family (familyname, subtable, modifier, entry) - elseif pfmweight > 500 then -- in bold spectrum + elseif pfmweight >= bold_spectrum_low then -- in bold spectrum modifier = pick_fallback_style (italicangle, weight, pfmweight) if modifier then add_family (familyname, subtable, modifier, entry) @@ -2776,8 +2778,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" } -- cgit v1.2.3 From 05c1a1f336a3148f9f8e3b02e3944deaebb0357f Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 27 Apr 2016 19:09:28 +0200 Subject: [fontloader] sync with Context as of 2016-04-27 --- src/fontloader/misc/fontloader-font-dsp.lua | 2 +- src/fontloader/misc/fontloader-font-ots.lua | 30 ++++++++++++++++--------- src/fontloader/runtime/fontloader-reference.lua | 26 ++++++++++++--------- 3 files changed, 36 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/fontloader/misc/fontloader-font-dsp.lua b/src/fontloader/misc/fontloader-font-dsp.lua index 14e816d..85a80bd 100644 --- a/src/fontloader/misc/fontloader-font-dsp.lua +++ b/src/fontloader/misc/fontloader-font-dsp.lua @@ -525,7 +525,7 @@ local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof end end local noflookups = readushort(f) - local lookups = { } + local lookups = { } for i=1,noflookups do lookups[readushort(f)+1] = readushort(f) + 1 end diff --git a/src/fontloader/misc/fontloader-font-ots.lua b/src/fontloader/misc/fontloader-font-ots.lua index ac81989..90fcde2 100644 --- a/src/fontloader/misc/fontloader-font-ots.lua +++ b/src/fontloader/misc/fontloader-font-ots.lua @@ -2144,7 +2144,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else local discfound = nil local n = f + 1 - last = getnext(last) + last = getnext(last) -- the second in current (first already matched) while n <= l do if not last and (sweeptype == "post" or sweeptype == "replace") then last = getnext(sweepnode) @@ -2185,7 +2185,6 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end break end - last = getnext(last) elseif char == false then if discfound then notmatchreplace[discfound] = true @@ -2238,6 +2237,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end match = not notmatchpre[last] end + -- maybe only if match last = getnext(last) else match = false @@ -2273,8 +2273,12 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if trace_skips then show_skip(dataset,sequence,char,ck,class) end + prev = getprev(prev) -- moved here elseif seq[n][char] then - n = n -1 + if n > 1 then -- new test + prev = getprev(prev) -- moved here + end + n = n - 1 else if discfound then notmatchreplace[discfound] = true @@ -2293,7 +2297,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end break end - prev = getprev(prev) + -- prev = getprev(prev) -- moved up elseif char == false then if discfound then notmatchreplace[discfound] = true @@ -2357,21 +2361,20 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if not match then break end - else - -- skip 'm end - else - -- skip 'm end + -- maybe only if match + prev = getprev(prev) elseif seq[n][32] then n = n - 1 + prev = getprev(prev) else match = false break end - prev = getprev(prev) elseif seq[n][32] then -- somewhat special, as zapfino can have many preceding spaces n = n - 1 + prev = getprev(prev) -- was absent else match = false break @@ -2409,7 +2412,11 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if trace_skips then show_skip(dataset,sequence,char,ck,class) end + current = getnext(current) -- was absent elseif seq[n][char] then + if n < s then -- new test + current = getnext(current) -- was absent + end n = n + 1 else if discfound then @@ -2485,16 +2492,17 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else -- skip 'm end + -- maybe only if match + current = getnext(current) elseif seq[n][32] then -- brrr n = n + 1 else match = false break end - current = getnext(current) elseif seq[n][32] then n = n + 1 -current = getnext(current) + current = getnext(current) else match = false break diff --git a/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua index ab81bc6..5be6493 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/25/16 13:30:09 +-- merge date : 04/27/16 10:18:10 do -- begin closure to overcome local limits and interference @@ -20036,7 +20036,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else local discfound=nil local n=f+1 - last=getnext(last) + last=getnext(last) while n<=l do if not last and (sweeptype=="post" or sweeptype=="replace") then last=getnext(sweepnode) @@ -20077,7 +20077,6 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end break end - last=getnext(last) elseif char==false then if discfound then notmatchreplace[discfound]=true @@ -20162,8 +20161,12 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if trace_skips then show_skip(dataset,sequence,char,ck,class) end + prev=getprev(prev) elseif seq[n][char] then - n=n -1 + if n>1 then + prev=getprev(prev) + end + n=n-1 else if discfound then notmatchreplace[discfound]=true @@ -20182,7 +20185,6 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end break end - prev=getprev(prev) elseif char==false then if discfound then notmatchreplace[discfound]=true @@ -20244,19 +20246,19 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if not match then break end - else end - else end + prev=getprev(prev) elseif seq[n][32] then n=n-1 + prev=getprev(prev) else match=false break end - prev=getprev(prev) elseif seq[n][32] then n=n-1 + prev=getprev(prev) else match=false break @@ -20291,7 +20293,11 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if trace_skips then show_skip(dataset,sequence,char,ck,class) end + current=getnext(current) elseif seq[n][char] then + if n Date: Wed, 27 Apr 2016 22:26:01 +0200 Subject: [db] restrict bold style fallback heuristic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @dohyunkim pointed out that due to the too broad criteria, secondary style variants like “heavy”, “black” ended up getting picked over the actual “bold”. --- src/luaotfload-database.lua | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua index 0c2fd40..437091f 100644 --- a/src/luaotfload-database.lua +++ b/src/luaotfload-database.lua @@ -2608,8 +2608,17 @@ do end pick_fallback_style = function (italicangle, weight, pfmweight) - --- more aggressive, but only to determine bold faces - if pfmweight == bold_weight 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 "b" end @@ -2753,13 +2762,12 @@ local collect_families = function (mappings) pfmweight) end + if not modifier then + modifier = pick_fallback_style (italicangle, weight, pfmweight) + end + if modifier then add_family (familyname, subtable, modifier, entry) - elseif pfmweight >= bold_spectrum_low then -- in bold spectrum - modifier = pick_fallback_style (italicangle, weight, pfmweight) - if modifier then - add_family (familyname, subtable, modifier, entry) - end end end -- cgit v1.2.3 From 23ff1b009f3b4df6754848196d7556c11c323d83 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 27 Apr 2016 22:34:17 +0200 Subject: [parsers] fix rhs parsing in configuration Fix issue #344 An incomplete matching rule for determining configuration values caused return bytes (0x0d) to leak into the configuration if Windows style newlines are used. Fixed by adapting the pattern. --- src/luaotfload-parsers.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/luaotfload-parsers.lua b/src/luaotfload-parsers.lua index 83e2a54..307c35c 100644 --- a/src/luaotfload-parsers.lua +++ b/src/luaotfload-parsers.lua @@ -722,10 +722,10 @@ local blank_line = ws * eol local skip_line = comment_line + blank_line local ini_id_char = alpha + (dash / "_") local ini_id = Cs(alpha * ini_id_char^0) / stringlower -local ini_value_char = (valid_escapes + (1 - newline - backslash - comment_char)) +local ini_value_char = (valid_escapes + (1 - linebreak - backslash - comment_char)) local ini_value = (Cs (ini_value_char^0) / string.strip) * (comment_char * (1 - eol)^0)^-1 -local ini_string_char = (valid_escapes + (1 - newline - dquote - backslash)) +local ini_string_char = (valid_escapes + (1 - linebreak - dquote - backslash)) local ini_string = dquote * Cs (ini_string_char^0) * dquote -- cgit v1.2.3