summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua205
1 files changed, 143 insertions, 62 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua
index 88d6145665b..e5101e7f656 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua
@@ -11,8 +11,9 @@ if not modules then modules = { } end modules ['font-def'] = {
local lower, gsub = string.lower, string.gsub
local tostring, next = tostring, next
local lpegmatch = lpeg.match
-local suffixonly, removesuffix = file.suffix, file.removesuffix
+local suffixonly, removesuffix, basename = file.suffix, file.removesuffix, file.basename
local formatters = string.formatters
+local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
local allocate = utilities.storage.allocate
@@ -20,7 +21,6 @@ local trace_defining = false trackers .register("fonts.defining", function
local directive_embedall = false directives.register("fonts.embedall", function(v) directive_embedall = v end)
trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading", "tfm.loading")
-trackers.register("fonts.all", "fonts.*", "otf.*", "afm.*", "tfm.*")
local report_defining = logs.reporter("fonts","defining")
@@ -80,53 +80,6 @@ and prepares a table that will move along as we proceed.</p>
-- name name(sub) name(sub)*spec name*spec
-- name@spec*oeps
-local splitter, splitspecifiers = nil, "" -- not so nice
-
-local P, C, S, Cc = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc
-
-local left = P("(")
-local right = P(")")
-local colon = P(":")
-local space = P(" ")
-
-definers.defaultlookup = "file"
-
-local prefixpattern = P(false)
-
-local function addspecifier(symbol)
- splitspecifiers = splitspecifiers .. symbol
- local method = S(splitspecifiers)
- local lookup = C(prefixpattern) * colon
- local sub = left * C(P(1-left-right-method)^1) * right
- local specification = C(method) * C(P(1)^1)
- local name = C((1-sub-specification)^1)
- splitter = P((lookup + Cc("")) * name * (sub + Cc("")) * (specification + Cc("")))
-end
-
-local function addlookup(str,default)
- prefixpattern = prefixpattern + P(str)
-end
-
-definers.addlookup = addlookup
-
-addlookup("file")
-addlookup("name")
-addlookup("spec")
-
-local function getspecification(str)
- return lpegmatch(splitter,str or "") -- weird catch
-end
-
-definers.getspecification = getspecification
-
-function definers.registersplit(symbol,action,verbosename)
- addspecifier(symbol)
- variants[symbol] = action
- if verbosename then
- variants[verbosename] = action
- end
-end
-
local function makespecification(specification,lookup,name,sub,method,detail,size)
size = size or 655360
if not lookup or lookup == "" then
@@ -151,13 +104,65 @@ local function makespecification(specification,lookup,name,sub,method,detail,siz
return t
end
-
definers.makespecification = makespecification
-function definers.analyze(specification, size)
- -- can be optimized with locals
- local lookup, name, sub, method, detail = getspecification(specification or "")
- return makespecification(specification, lookup, name, sub, method, detail, size)
+if context then
+
+ local splitter, splitspecifiers = nil, "" -- not so nice
+
+ local P, C, S, Cc, Cs = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc, lpeg.Cs
+
+ local left = P("(")
+ local right = P(")")
+ local colon = P(":")
+ local space = P(" ")
+ local lbrace = P("{")
+ local rbrace = P("}")
+
+ definers.defaultlookup = "file"
+
+ local prefixpattern = P(false)
+
+ local function addspecifier(symbol)
+ splitspecifiers = splitspecifiers .. symbol
+ local method = S(splitspecifiers)
+ local lookup = C(prefixpattern) * colon
+ local sub = left * C(P(1-left-right-method)^1) * right
+ local specification = C(method) * C(P(1)^1)
+ local name = Cs((lbrace/"") * (1-rbrace)^1 * (rbrace/"") + (1-sub-specification)^1)
+ splitter = P((lookup + Cc("")) * name * (sub + Cc("")) * (specification + Cc("")))
+ end
+
+ local function addlookup(str)
+ prefixpattern = prefixpattern + P(str)
+ end
+
+ definers.addlookup = addlookup
+
+ addlookup("file")
+ addlookup("name")
+ addlookup("spec")
+
+ local function getspecification(str)
+ return lpegmatch(splitter,str or "") -- weird catch
+ end
+
+ definers.getspecification = getspecification
+
+ function definers.registersplit(symbol,action,verbosename)
+ addspecifier(symbol)
+ variants[symbol] = action
+ if verbosename then
+ variants[verbosename] = action
+ end
+ end
+
+ function definers.analyze(specification, size)
+ -- can be optimized with locals
+ local lookup, name, sub, method, detail = getspecification(specification or "")
+ return makespecification(specification, lookup, name, sub, method, detail, size)
+ end
+
end
--[[ldx--
@@ -184,11 +189,30 @@ end
function resolvers.name(specification)
local resolve = fonts.names.resolve
if resolve then
- local resolved, sub, subindex = resolve(specification.name,specification.sub,specification) -- we pass specification for overloaded versions
+ local resolved, sub, subindex, instance = resolve(specification.name,specification.sub,specification) -- we pass specification for overloaded versions
if resolved then
specification.resolved = resolved
specification.sub = sub
specification.subindex = subindex
+ -- new, needed for experiments
+ if instance then
+ specification.instance = instance
+ local features = specification.features
+ if not features then
+ features = { }
+ specification.features = features
+ end
+ local normal = features.normal
+ if not normal then
+ normal = { }
+ features.normal = normal
+ end
+ normal.instance = instance
+ if not callbacks.supported.glyph_stream_provider then
+ normal.variableshapes = true -- for the moment
+ end
+ end
+ --
local suffix = lower(suffixonly(resolved))
if fonts.formats[suffix] then
specification.forced = suffix
@@ -294,10 +318,71 @@ local function checkembedding(tfmdata)
tfmdata.embedding = embedding
end
+local function checkfeatures(tfmdata)
+ local resources = tfmdata.resources
+ local shared = tfmdata.shared
+ if resources and shared then
+ local features = resources.features
+ local usedfeatures = shared.features
+ if features and usedfeatures then
+ local usedlanguage = usedfeatures.language or "dflt"
+ local usedscript = usedfeatures.script or "dflt"
+ local function check(what)
+ if what then
+ local foundlanguages = { }
+ for feature, scripts in next, what do
+ if usedscript == "auto" or scripts["*"] then
+ -- ok
+ elseif not scripts[usedscript] then
+ -- report_defining("font %!font:name!, feature %a, no script %a",
+ -- tfmdata,feature,usedscript)
+ else
+ for script, languages in next, scripts do
+ if languages["*"] then
+ -- ok
+ elseif not languages[usedlanguage] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,usedlanguage)
+ end
+ end
+ end
+ for script, languages in next, scripts do
+ for language in next, languages do
+ foundlanguages[language] = true
+ end
+ end
+ end
+ if false then
+ foundlanguages["*"] = nil
+ foundlanguages = sortedkeys(foundlanguages)
+ for feature, scripts in sortedhash(what) do
+ for script, languages in next, scripts do
+ if not languages["*"] then
+ for i=1,#foundlanguages do
+ local language = foundlanguages[i]
+ if not languages[language] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,language)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ check(features.gsub)
+ check(features.gpos)
+ end
+ end
+end
+
function definers.loadfont(specification)
local hash = constructors.hashinstance(specification)
+ -- todo: also hash by instance / factors
local tfmdata = loadedfonts[hash] -- hashes by size !
if not tfmdata then
+ -- normally context will not end up here often (if so there is an issue somewhere)
local forced = specification.forced or ""
if forced ~= "" then
local reader = readers[lower(forced)] -- normally forced is already lowered
@@ -327,6 +412,7 @@ function definers.loadfont(specification)
checkembedding(tfmdata) -- todo: general postprocessor
loadedfonts[hash] = tfmdata
designsizes[specification.hash] = tfmdata.parameters.designsize
+ checkfeatures(tfmdata)
end
end
if not tfmdata then
@@ -335,10 +421,6 @@ function definers.loadfont(specification)
return tfmdata
end
-function constructors.checkvirtualids()
- -- dummy in plain version
-end
-
function constructors.readanddefine(name,size) -- no id -- maybe a dummy first
local specification = definers.analyze(name,size)
local method = specification.method
@@ -352,7 +434,6 @@ function constructors.readanddefine(name,size) -- no id -- maybe a dummy first
local tfmdata = definers.loadfont(specification)
if tfmdata then
tfmdata.properties.hash = hash
- constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference
id = font.define(tfmdata)
definers.register(tfmdata,id)
else
@@ -437,8 +518,8 @@ function definers.read(specification,size,id) -- id can be optional, name can al
local properties = tfmdata.properties or { }
local parameters = tfmdata.parameters or { }
report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a",
- properties.format or "unknown", id, properties.name, parameters.size, properties.encodingbytes,
- properties.encodingname, properties.fullname, file.basename(properties.filename))
+ properties.format or "unknown", id or "-", properties.name, parameters.size, properties.encodingbytes,
+ properties.encodingname, properties.fullname, basename(properties.filename))
end
statistics.stoptiming(fonts)
return tfmdata