summaryrefslogtreecommitdiff
path: root/src/fontloader/runtime/fontloader-reference.lua
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2016-04-11 21:33:01 +0200
committerPhilipp Gesang <phg@phi-gamma.net>2016-04-11 21:33:05 +0200
commit9f36b1ac422e48e70e11716f5550a833bc8be3f9 (patch)
tree82b202532ee5284c5bc7014811736b7ad30fdb0b /src/fontloader/runtime/fontloader-reference.lua
parent783e94f44ea39df0ae877b289b999e8f13aaf3da (diff)
downloadluaotfload-9f36b1ac422e48e70e11716f5550a833bc8be3f9.tar.gz
[fontloader] sync with Context as of 2016-04-11
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**
Diffstat (limited to 'src/fontloader/runtime/fontloader-reference.lua')
-rw-r--r--src/fontloader/runtime/fontloader-reference.lua183
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