summaryrefslogtreecommitdiff
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
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**
-rw-r--r--src/fontloader/misc/fontloader-font-gbn.lua5
-rw-r--r--src/fontloader/misc/fontloader-font-otr.lua220
-rw-r--r--src/fontloader/misc/fontloader-font-ots.lua46
-rw-r--r--src/fontloader/runtime/fontloader-reference.lua183
4 files changed, 315 insertions, 139 deletions
diff --git a/src/fontloader/misc/fontloader-font-gbn.lua b/src/fontloader/misc/fontloader-font-gbn.lua
index f81c877..a645a97 100644
--- a/src/fontloader/misc/fontloader-font-gbn.lua
+++ b/src/fontloader/misc/fontloader-font-gbn.lua
@@ -19,7 +19,6 @@ local nodes = nodes
local nuts = nodes.nuts -- context abstraction of direct nodes
local traverse_id = nuts.traverse_id
-local free_node = nuts.free
local remove_node = nuts.remove
local glyph_code = nodes.nodecodes.glyph
@@ -137,9 +136,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
diff --git a/src/fontloader/misc/fontloader-font-otr.lua b/src/fontloader/misc/fontloader-font-otr.lua
index 1fc338b..0ad1e19 100644
--- a/src/fontloader/misc/fontloader-font-otr.lua
+++ b/src/fontloader/misc/fontloader-font-otr.lua
@@ -148,7 +148,7 @@ local function reportskippedtable(tag)
end
-- We have quite some data tables. We are somewhat ff compatible with names but as I used
--- the information form the microsoft site there can be differences. Eventually I might end
+-- the information from the microsoft site there can be differences. Eventually I might end
-- up with a different ordering and naming.
local reservednames = { [0] =
@@ -163,14 +163,14 @@ local reservednames = { [0] =
"manufacturer",
"designer",
"description", -- descriptor in ff
- "venderurl",
+ "vendorurl",
"designerurl",
"license",
"licenseurl",
"reserved",
"typographicfamily", -- preffamilyname
"typographicsubfamily", -- prefmodifiers
- "compatiblefullname", -- for mac
+ "compatiblefullname", -- for mac
"sampletext",
"cidfindfontname",
"wwsfamily",
@@ -244,7 +244,16 @@ local decoders = {
macintosh = { },
iso = { },
windows = {
- ["unicode bmp"] = utf16_to_utf8_be
+ -- maybe always utf16
+ ["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 = { },
}
@@ -702,7 +711,17 @@ local panosewidths = {
-- useful information about what we deal with. The complication is that we need
-- to filter the best one available.
-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)
@@ -710,6 +729,7 @@ function readers.name(f,fontdata)
local nofnames = readushort(f)
local offset = readushort(f)
-- we can also provide a raw list as extra, todo as option
+ local start = datatable.offset + offset
local namelists = {
unicode = { },
windows = { },
@@ -738,7 +758,7 @@ function readers.name(f,fontdata)
language = language,
name = name,
length = readushort(f),
- offset = readushort(f),
+ offset = start + readushort(f),
}
else
skipshort(f,2)
@@ -766,7 +786,6 @@ function readers.name(f,fontdata)
--
-- we need to choose one we like, for instance an unicode one
--
- local start = datatable.offset + offset
local names = { }
local done = { }
--
@@ -783,7 +802,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
@@ -812,11 +831,57 @@ function readers.name(f,fontdata)
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
+----- validutf = lpeg.patterns.utf8character^0 * P(-1)
+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
+
-- This table is an original windows (with its precursor os/2) table. In ff this one is
-- part of the pfminfo table but here we keep it separate (for now). We will create a
-- properties table afterwards.
@@ -1733,69 +1798,69 @@ otf.unpackoutlines = unpackoutlines
-- some properties in order to read following tables. When details is true we also
-- initialize the glyphs data.
------ validutf = lpeg.patterns.utf8character^0 * P(-1)
-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 names = fontdata.names
+ local info = nil
if names then
- local metrics = fontdata.windowsmetrics or { }
- local postscript = fontdata.postscript or { }
- local fontheader = fontdata.fontheader or { }
- local cffinfo = fontdata.cffinfo or { }
- 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 { -- we inherit some inconsistencies/choices from ff
- subfontindex = fontdata.subfontindex or sub or 0,
- -- filename = filename,
- -- version = name("version"),
- -- format = fontdata.format,
- fontname = getname(fontdata,"postscriptname"),
- fullname = getname(fontdata,"fullname"), -- or file.nameonly(filename)
- familyname = getname(fontdata,"typographicfamily") or getname(fontdata,"family"),
- subfamily = getname(fontdata,"subfamily"),
- modifiers = getname(fontdata,"typographicsubfamily"),
- weight = weight and lower(weight),
- width = width and lower(width),
- pfmweight = metrics.weightclass or 400, -- will become weightclass
- pfmwidth = metrics.widthclass or 5, -- will become widthclass
- panosewidth = metrics.panosewidth,
- panoseweight = metrics.panoseweight,
- italicangle = postscript.italicangle or 0,
- units = fontheader.units or 0,
- designsize = fontdata.designsize,
- minsize = fontdata.minsize,
- maxsize = fontdata.maxsize,
- monospaced = (tonumber(postscript.monospaced or 0) > 0) or metrics.panosewidth == "monospaced",
- averagewidth = metrics.averagewidth,
- xheight = metrics.xheight,
- ascender = metrics.typoascender,
- descender = metrics.typodescender,
+ local metrics = fontdata.windowsmetrics or { }
+ local postscript = fontdata.postscript or { }
+ local fontheader = fontdata.fontheader or { }
+ local cffinfo = fontdata.cffinfo or { }
+ 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
+ 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 = { -- we inherit some inconsistencies/choices from ff
+ subfontindex = fontdata.subfontindex or sub or 0,
+ -- filename = filename,
+ version = getname(fontdata,"version"),
+ -- format = fontdata.format,
+ 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, -- will become weightclass
+ pfmwidth = metrics.widthclass or 5, -- will become widthclass
+ panosewidth = metrics.panosewidth,
+ panoseweight = metrics.panoseweight,
+ italicangle = postscript.italicangle or 0,
+ units = fontheader.units or 0,
+ designsize = fontdata.designsize,
+ minsize = fontdata.minsize,
+ maxsize = fontdata.maxsize,
+ monospaced = (tonumber(postscript.monospaced or 0) > 0) or metrics.panosewidth == "monospaced",
+ averagewidth = metrics.averagewidth,
+ xheight = metrics.xheight,
+ capheight = metrics.capheight, -- not always present and probably crap
+ 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
+ -- inspect(info)
+ return info
end
local function loadtables(f,specification,offset)
@@ -1870,6 +1935,7 @@ local function readdata(f,offset,specification)
end
end
--
+ --
readers["os/2"](f,fontdata,specification)
readers["head"](f,fontdata,specification)
readers["maxp"](f,fontdata,specification)
@@ -1989,7 +2055,10 @@ local function loadfont(specification,n)
specification.details = true
end
if specification.details then
- specification.info = true
+ specification.info = true -- not really used any more
+ end
+ if specification.platformnames then
+ specification.platformnames = true -- not really used any more
end
local function message(str)
report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback())
@@ -2043,7 +2112,7 @@ function readers.loadfont(filename,n)
descriptions = fontdata.descriptions,
format = fontdata.format,
goodies = { },
- metadata = getinfo(fontdata,n),
+ metadata = getinfo(fontdata,n), -- no platformnames here !
properties = {
hasitalics = fontdata.hasitalics or false,
},
@@ -2067,27 +2136,38 @@ function readers.loadfont(filename,n)
end
end
-function readers.getinfo(filename,n,details)
+function readers.getinfo(filename,specification) -- string, nil|number|table
+ -- platformnames is optional and not used by context (a too unpredictable mess
+ -- that only add to the confusion) .. so it's only for checking things
+ 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,
+ 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
diff --git a/src/fontloader/misc/fontloader-font-ots.lua b/src/fontloader/misc/fontloader-font-ots.lua
index 4d5e8ec..d67db6d 100644
--- a/src/fontloader/misc/fontloader-font-ots.lua
+++ b/src/fontloader/misc/fontloader-font-ots.lua
@@ -2716,8 +2716,8 @@ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context
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,...)
@@ -2725,7 +2725,7 @@ local function kernrun(disc,k_run,font,attr,...)
-- we catch <font 1><disc font 2>
--
if trace_kernruns then
- report_disc("kern")
+ report_disc("kern",disc)
end
--
local prev, next = getboth(disc)
@@ -2819,7 +2819,7 @@ 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)
@@ -2866,31 +2866,35 @@ 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
-- weird discretionary
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
- -- only look ahead
- -- local nest = getprev(replace)
+ -- this is a bit strange as we only do replace here and not post
+ -- anyway, we only look ahead ... the idea is that we discard a
+ -- disc when there is a ligature crossing the replace boundary
setlink(replacetail,next)
- if t_run(replace,next,...) then
- setfield(disc,"replace",nil) -- beware, side effects of nest so first
+ local ok, overflow = t_run(replace,next,...)
+ if ok and overflow then
+ -- so, we can have crossed the boundary
+ setfield(disc,"replace",nil)
setlink(prev,replace)
- setlink(replacetail,next)
+ -- setlink(replacetail,next)
setboth(disc)
flush_node_list(disc)
return replace, true -- restart .. tricky !
else
+ -- we stay inside the disc
setnext(replacetail)
setprev(next,disc)
end
- -- pre, post, replace, pretail, posttail, replacetail = getdisc(disc)
+ -- pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
end
--
-- like comprun
@@ -2945,7 +2949,7 @@ end
-- local function discrun(disc,drun,krun)
-- local prev, next = getboth(disc)
-- if trace_discruns then
--- report_disc("disc")
+-- report_disc("disc",disc)
-- end
-- if next and prev then
-- setnext(prev,next)
@@ -3043,7 +3047,13 @@ local function t_run_single(start,stop,font,attr,lookupcache)
-- if we need more than ligatures we can outline the code and use functions
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
@@ -3053,7 +3063,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
@@ -3168,7 +3178,13 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
-- if we need more than ligatures we can outline the code and use functions
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
@@ -3178,7 +3194,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
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