From 9f36b1ac422e48e70e11716f5550a833bc8be3f9 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 11 Apr 2016 21:33:01 +0200 Subject: [fontloader] sync with Context as of 2016-04-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After some discussion, Hans came up with these extensions to the new reader. We get access to more items from the hideous “name” table. On the one hand, this means more brokenness to endure and a less sane matter to work with. But since our tracker was devoid of font-matching related bug reports for some time, it’s the right move nonetheless. In addition to the name table junk, the font loader now also includes the “version” field in the output of “getinfo()”. It’s meaningless per se, but it sure helps to distinguish historical bugs from the ones that matter. **UNTESTED** --- src/fontloader/runtime/fontloader-reference.lua | 183 +++++++++++++++++------- 1 file changed, 133 insertions(+), 50 deletions(-) (limited to 'src/fontloader/runtime') diff --git a/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua index e4ae182..a4677ef 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/04/16 13:06:24 +-- merge date : 04/11/16 19:04:35 do -- begin closure to overcome local limits and interference @@ -8184,7 +8184,7 @@ local reservednames={ [0]="copyright", "manufacturer", "designer", "description", - "venderurl", + "vendorurl", "designerurl", "license", "licenseurl", @@ -8244,7 +8244,15 @@ local decoders={ macintosh={}, iso={}, windows={ - ["unicode bmp"]=utf16_to_utf8_be + ["unicode semantics"]=utf16_to_utf8_be, + ["unicode bmp"]=utf16_to_utf8_be, + ["unicode full"]=utf16_to_utf8_be, + ["unicode 1.0 semantics"]=utf16_to_utf8_be, + ["unicode 1.1 semantics"]=utf16_to_utf8_be, + ["unicode 2.0 bmp"]=utf16_to_utf8_be, + ["unicode 2.0 full"]=utf16_to_utf8_be, + ["unicode variation sequences"]=utf16_to_utf8_be, + ["unicode full repertoire"]=utf16_to_utf8_be, }, custom={}, } @@ -8355,13 +8363,23 @@ local panosewidths={ [ 8]="verycondensed", [ 9]="monospaced", } -function readers.name(f,fontdata) +local platformnames={ + postscriptname=true, + fullname=true, + family=true, + subfamily=true, + typographicfamily=true, + typographicsubfamily=true, + compatiblefullname=true, +} +function readers.name(f,fontdata,specification) local datatable=fontdata.tables.name if datatable then setposition(f,datatable.offset) local format=readushort(f) local nofnames=readushort(f) local offset=readushort(f) + local start=datatable.offset+offset local namelists={ unicode={}, windows={}, @@ -8388,7 +8406,7 @@ function readers.name(f,fontdata) language=language, name=name, length=readushort(f), - offset=readushort(f), + offset=start+readushort(f), } else skipshort(f,2) @@ -8406,7 +8424,6 @@ function readers.name(f,fontdata) skipshort(f,5) end end - local start=datatable.offset+offset local names={} local done={} local function filter(platform,e,l) @@ -8418,7 +8435,7 @@ function readers.name(f,fontdata) local encoding=name.encoding local language=name.language if (not e or encoding==e) and (not l or language==l) then - setposition(f,start+name.offset) + setposition(f,name.offset) local content=readstring(f,name.length) local decoder=decoders[platform] if decoder then @@ -8444,10 +8461,52 @@ function readers.name(f,fontdata) filter("macintosh") filter("unicode") fontdata.names=names + if specification.platformnames then + local collected={} + for platform,namelist in next,namelists do + local filtered=false + for i=1,#namelist do + local entry=namelist[i] + local name=entry.name + if platformnames[name] then + setposition(f,entry.offset) + local content=readstring(f,entry.length) + local encoding=entry.encoding + local decoder=decoders[platform] + if decoder then + decoder=decoder[encoding] + end + if decoder then + content=decoder(content) + end + if filtered then + filtered[name]=content + else + filtered={ [name]=content } + end + end + end + if filtered then + collected[platform]=filtered + end + end + fontdata.platformnames=collected + end else fontdata.names={} end end +local validutf=lpeg.patterns.validutf8 +local function getname(fontdata,key) + local names=fontdata.names + if names then + local value=names[key] + if value then + local content=value.content + return lpegmatch(validutf,content) and content or nil + end + end +end readers["os/2"]=function(f,fontdata) local datatable=fontdata.tables["os/2"] if datatable then @@ -9233,20 +9292,10 @@ local function unpackoutlines(data) end otf.packoutlines=packoutlines otf.unpackoutlines=unpackoutlines -local validutf=lpeg.patterns.validutf8 -local function getname(fontdata,key) - local names=fontdata.names - if names then - local value=names[key] - if value then - local content=value.content - return lpegmatch(validutf,content) and content or nil - end - end -end -local function getinfo(maindata,sub) +local function getinfo(maindata,sub,platformnames) local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata local names=fontdata.names + local info=nil if names then local metrics=fontdata.windowsmetrics or {} local postscript=fontdata.postscript or {} @@ -9255,13 +9304,23 @@ local function getinfo(maindata,sub) local filename=fontdata.filename local weight=getname(fontdata,"weight") or cffinfo.weight or metrics.weight local width=getname(fontdata,"width") or cffinfo.width or metrics.width - return { + local fontname=getname(fontdata,"postscriptname") + local fullname=getname(fontdata,"fullname") + local family=getname(fontdata,"family") + local subfamily=getname(fontdata,"subfamily") + local familyname=getname(fontdata,"typographicfamily") or family + local subfamilyname=getname(fontdata,"typographicsubfamily") or subfamily + local compatiblename=getname(fontdata,"compatiblefullname") + info={ subfontindex=fontdata.subfontindex or sub or 0, - fontname=getname(fontdata,"postscriptname"), - fullname=getname(fontdata,"fullname"), - familyname=getname(fontdata,"typographicfamily") or getname(fontdata,"family"), - subfamily=getname(fontdata,"subfamily"), - modifiers=getname(fontdata,"typographicsubfamily"), + version=getname(fontdata,"version"), + fontname=fontname, + fullname=fullname, + family=family, + subfamily=subfamily, + familyname=familyname, + subfamilyname=subfamilyname, + compatiblename=compatiblename, weight=weight and lower(weight), width=width and lower(width), pfmweight=metrics.weightclass or 400, @@ -9276,20 +9335,23 @@ local function getinfo(maindata,sub) monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced", averagewidth=metrics.averagewidth, xheight=metrics.xheight, + capheight=metrics.capheight, ascender=metrics.typoascender, descender=metrics.typodescender, + platformnames=platformnames and fontdata.platformnames or nil, } elseif n then - return { + info={ filename=fontdata.filename, comment="there is no info for subfont "..n, } else - return { + info={ filename=fontdata.filename, comment="there is no info", } end + return info end local function loadtables(f,specification,offset) if offset then @@ -9470,7 +9532,10 @@ local function loadfont(specification,n) specification.details=true end if specification.details then - specification.info=true + specification.info=true + end + if specification.platformnames then + specification.platformnames=true end local function message(str) report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback()) @@ -9538,27 +9603,36 @@ function readers.loadfont(filename,n) } end end -function readers.getinfo(filename,n,details) +function readers.getinfo(filename,specification) + local subfont=nil + local platformname=false + if type(specification)=="table" then + subfont=tonumber(specification.subfont) + platformnames=specification.platformnames + else + subfont=tonumber(specification) + end local fontdata=loadfont { filename=filename, details=true, + platformnames=platformnames, } if fontdata then local subfonts=fontdata.subfonts if not subfonts then - return getinfo(fontdata) - elseif type(n)~="number" then + return getinfo(fontdata,nil,platformnames) + elseif not subfont then local info={} for i=1,#subfonts do - info[i]=getinfo(fontdata,i) + info[i]=getinfo(fontdata,i,platformnames) end return info - elseif n>1 and n<=subfonts then - return getinfo(fontdata,n) + elseif subfont>1 and subfont<=#subfonts then + return getinfo(fontdata,subfont,platformnames) else return { filename=filename, - comment="there is no subfont "..n.." in this file" + comment="there is no subfont "..subfont.." in this file" } end else @@ -20229,12 +20303,12 @@ function otf.dataset(tfmdata,font) end return rl end -local function report_disc(n) - report_run("kern: %s > %s",disc,languages.serializediscretionary(disc)) +local function report_disc(what,n) + report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) end local function kernrun(disc,k_run,font,attr,...) if trace_kernruns then - report_disc("kern") + report_disc("kern",disc) end local prev,next=getboth(disc) local nextstart=next @@ -20315,7 +20389,7 @@ local function kernrun(disc,k_run,font,attr,...) end local function comprun(disc,c_run,...) if trace_compruns then - report_disc("comp") + report_disc("comp",disc) end local pre,post,replace=getdisc(disc) local renewed=false @@ -20355,20 +20429,20 @@ local function comprun(disc,c_run,...) end local function testrun(disc,t_run,c_run,...) if trace_testruns then - report_disc("test") + report_disc("test",disc) end local prev,next=getboth(disc) if not next then return end - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc) + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) local done=false if replace and prev then setlink(replacetail,next) - if t_run(replace,next,...) then - setfield(disc,"replace",nil) + local ok,overflow=t_run(replace,next,...) + if ok and overflow then + setfield(disc,"replace",nil) setlink(prev,replace) - setlink(replacetail,next) setboth(disc) flush_node_list(disc) return replace,true @@ -20460,7 +20534,13 @@ local function t_run_single(start,stop,font,attr,lookupcache) if lookupmatch then local s=getnext(start) local l=nil + local d=0 while s do + if s==stop then + d=1 + elseif d>0 then + d=d+1 + end local lg=lookupmatch[getchar(s)] if lg then l=lg @@ -20470,7 +20550,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end end if l and l.ligature then - return true + return true,d>1 end end end @@ -20560,7 +20640,13 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) if lookupmatch then local s=getnext(start) local l=nil + local d=0 while s do + if s==stop then + d=1 + elseif d>0 then + d=d+1 + end local lg=lookupmatch[getchar(s)] if lg then l=lg @@ -20570,7 +20656,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end end if l and l.ligature then - return true + return true,d>1 end end else @@ -23666,7 +23752,6 @@ local fonts=fonts local nodes=nodes local nuts=nodes.nuts local traverse_id=nuts.traverse_id -local free_node=nuts.free local remove_node=nuts.remove local glyph_code=nodes.nodecodes.glyph local disc_code=nodes.nodecodes.disc @@ -23769,9 +23854,7 @@ function nodes.handlers.nodepass(head) end if redundant then for i=1,#redundant do - local n=redundant[i] - remove_node(nuthead,n) - free_node(n) + remove_node(nuthead,redundant[i],true) end end for d in traverse_id(disc_code,nuthead) do -- cgit v1.2.3