summaryrefslogtreecommitdiff
path: root/src/fontloader/misc
diff options
context:
space:
mode:
Diffstat (limited to 'src/fontloader/misc')
-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
3 files changed, 182 insertions, 89 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