diff options
Diffstat (limited to 'src/fontloader/runtime')
-rw-r--r-- | src/fontloader/runtime/fontloader-reference.lua | 183 |
1 files changed, 133 insertions, 50 deletions
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 |