summaryrefslogtreecommitdiff
path: root/tex/context/base/font-def.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/font-def.lua')
-rw-r--r--tex/context/base/font-def.lua186
1 files changed, 101 insertions, 85 deletions
diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua
index af6f5f394..cc7c45a9e 100644
--- a/tex/context/base/font-def.lua
+++ b/tex/context/base/font-def.lua
@@ -19,8 +19,11 @@ fonts.tfm = fonts.tfm or { }
fonts.vf = fonts.vf or { }
fonts.used = fonts.used or { }
-fonts.tfm.version = 1.01
-fonts.tfm.cache = containers.define("fonts", "tfm", fonts.tfm.version, false) -- better in font-tfm
+local tfm = fonts.tfm
+local vf = fonts.vf
+
+tfm.version = 1.01
+tfm.cache = containers.define("fonts", "tfm", tfm.version, false) -- better in font-tfm
--[[ldx--
<p>Choosing a font by name and specififying its size is only part of the
@@ -44,12 +47,12 @@ fonts.define.specify = fonts.define.specify or { }
fonts.define.splitsymbols = ""
fonts.define.methods = fonts.define.methods or { }
-fonts.tfm.fonts = fonts.tfm.fonts or { }
-fonts.tfm.readers = fonts.tfm.readers or { }
-fonts.tfm.internalized = fonts.tfm.internalized or { } -- internal tex numbers
-fonts.tfm.id = fonts.tfm.id or { } -- font data, maybe use just fonts.ids (faster lookup)
+tfm.fonts = tfm.fonts or { }
+tfm.readers = tfm.readers or { }
+tfm.internalized = tfm.internalized or { } -- internal tex numbers
+tfm.id = tfm.id or { } -- font data, maybe use just fonts.ids (faster lookup)
-fonts.tfm.readers.sequence = { 'otf', 'ttf', 'afm', 'tfm' }
+tfm.readers.sequence = { 'otf', 'ttf', 'afm', 'tfm' }
--[[ldx--
<p>We hardly gain anything when we cache the final (pre scaled)
@@ -121,33 +124,39 @@ end
<p>A unique hash value is generated by:</p>
--ldx]]--
-function fonts.tfm.hash_features(specification)
- if specification.features then
+function tfm.hash_features(specification)
+ local features = specification.features
+ if features then
local t = { }
- local normal = specification.features.normal
- if not table.is_empty(normal) then
- for _, v in pairs(table.sortedkeys(normal)) do
+ local normal = features.normal
+ if normal and next(normal) then
+ local f = table.sortedkeys(normal)
+ for i=1,#f do
+ local v = f[i]
if v ~= "number" then
t[#t+1] = v .. '=' .. tostring(normal[v])
end
end
end
- local vtf = specification.features.vtf
- if not table.is_empty(vtf) then
- for _, v in pairs(table.sortedkeys(vtf)) do
+ local vtf = features.vtf
+ if vtf and next(vtf) then
+ local f = table.sortedkeys(vtf)
+ for i=1,#f do
+ local v = f[i]
t[#t+1] = v .. '=' .. tostring(vtf[v])
end
end
- if next(t) then
+ if #t > 0 then
return table.concat(t,"+")
end
end
return "unknown"
end
---~ function fonts.tfm.hash_instance(specification)
+
+--~ function tfm.hash_instance(specification)
--~ if not specification.hash then
---~ specification.hash = fonts.tfm.hash_features(specification)
+--~ specification.hash = tfm.hash_features(specification)
--~ end
--~ return specification.hash .. ' @ ' .. tostring(specification.size)
--~ end
@@ -162,14 +171,14 @@ when we get rid of base mode we can optimize even further by sharing, but then w
loose our testcases for <l n='luatex'/>.</p>
--ldx]]--
-function fonts.tfm.hash_instance(specification,force)
+function tfm.hash_instance(specification,force)
local hash, size = specification.hash, specification.size
if force or not hash then
- hash = fonts.tfm.hash_features(specification)
+ hash = tfm.hash_features(specification)
specification.hash = hash
end
if size < 1000 and fonts.designsizes[hash] then
- size = fonts.tfm.scaled(size, fonts.designsizes[hash])
+ size = tfm.scaled(size, fonts.designsizes[hash])
specification.size = size
end
return hash .. ' @ ' .. tostring(size)
@@ -193,7 +202,7 @@ function fonts.define.resolve(specification)
if specification.forced == "" then
specification.forced = nil
end
- specification.hash = specification.name .. ' @ ' .. fonts.tfm.hash_features(specification)
+ specification.hash = specification.name .. ' @ ' .. tfm.hash_features(specification)
if specification.sub and specification.sub ~= "" then
specification.hash = specification.sub .. ' @ ' .. specification.hash
end
@@ -216,24 +225,24 @@ features (esp in virtual fonts) so let's not do that now.</p>
specification yet.</p>
--ldx]]--
-function fonts.tfm.read(specification)
+function tfm.read(specification)
garbagecollector.push()
input.starttiming(fonts)
- local hash = fonts.tfm.hash_instance(specification)
- local tfmtable = fonts.tfm.fonts[hash] -- hashes by size !
+ local hash = tfm.hash_instance(specification)
+ local tfmtable = tfm.fonts[hash] -- hashes by size !
if not tfmtable then
if specification.forced and specification.forced ~= "" then
- tfmtable = fonts.tfm.readers[specification.forced](specification)
+ tfmtable = tfm.readers[specification.forced](specification)
if not tfmtable then
- logs.error("define font",string.format("forced type %s of %s not found",specification.forced,specification.name))
+ logs.report("define font","forced type %s of %s not found",specification.forced,specification.name)
end
else
- for _, reader in ipairs(fonts.tfm.readers.sequence) do
- if fonts.tfm.readers[reader] then -- not really needed
+ for _, reader in ipairs(tfm.readers.sequence) do
+ if tfm.readers[reader] then -- not really needed
if fonts.trace then
- logs.report("define font",string.format("trying type %s for %s with file %s",reader,specification.name,specification.filename or "unknown"))
+ logs.report("define font","trying type %s for %s with file %s",reader,specification.name,specification.filename or "unknown")
end
- tfmtable = fonts.tfm.readers[reader](specification)
+ tfmtable = tfm.readers[reader](specification)
if tfmtable then break end
end
end
@@ -244,7 +253,7 @@ function fonts.tfm.read(specification)
else
tfmtable.embedding = "subset"
end
- fonts.tfm.fonts[hash] = tfmtable
+ tfm.fonts[hash] = tfmtable
fonts.designsizes[specification.hash] = tfmtable.designsize -- we only know this for sure after loading once
--~ tfmtable.mode = specification.features.normal.mode or "base"
end
@@ -252,7 +261,7 @@ function fonts.tfm.read(specification)
input.stoptiming(fonts)
garbagecollector.pop()
if not tfmtable then
- logs.error("define font",string.format("font with name %s is not found",specification.name))
+ logs.report("define font","font with name %s is not found",specification.name)
end
return tfmtable
end
@@ -261,32 +270,32 @@ end
<p>For virtual fonts we need a slightly different approach:</p>
--ldx]]--
-function fonts.tfm.read_and_define(name,size) -- no id
+function tfm.read_and_define(name,size) -- no id
local specification = fonts.define.analyze(name,size,nil)
if specification.method and fonts.define.specify[specification.method] then
specification = fonts.define.specify[specification.method](specification)
end
specification = fonts.define.resolve(specification)
- local hash = fonts.tfm.hash_instance(specification)
- local id = fonts.tfm.internalized[hash]
+ local hash = tfm.hash_instance(specification)
+ local id = tfm.internalized[hash]
if not id then
- local fontdata = fonts.tfm.read(specification)
+ local fontdata = tfm.read(specification)
if fontdata then
- if not fonts.tfm.internalized[hash] then
+ if not tfm.internalized[hash] then
id = font.define(fontdata)
- fonts.tfm.id[id] = fontdata
- fonts.tfm.internalized[hash] = id
+ tfm.id[id] = fontdata
+ tfm.internalized[hash] = id
if fonts.trace then
- logs.report("define font", string.format("loading at 1 id %s, hash: %s",id,hash))
+ logs.report("define font","loading at 1 id %s, hash: %s",id,hash)
end
else
- id = fonts.tfm.internalized[hash]
+ id = tfm.internalized[hash]
end
else
id = 0 -- signal
end
end
- return fonts.tfm.id[id], id
+ return tfm.id[id], id
end
--[[ldx--
@@ -305,25 +314,25 @@ end)
evolved. Each one has its own way of dealing with its format.</p>
--ldx]]--
-function fonts.tfm.readers.opentype(specification,suffix,what)
+function tfm.readers.opentype(specification,suffix,what)
if fonts.define.auto_otf then
local fullname, tfmtable = nil, nil
- fullname = input.findbinfile(texmf.instance,specification.name,suffix) or ""
+ fullname = input.findbinfile(specification.name,suffix) or ""
if fullname == "" then
local fb = fonts.names.old_to_new[specification.name]
if fb then
- fullname = input.findbinfile(texmf.instance,fb,suffix) or ""
+ fullname = input.findbinfile(fb,suffix) or ""
end
end
if fullname == "" then
local fb = fonts.names.new_to_old[specification.name]
if fb then
- fullname = input.findbinfile(texmf.instance,fb,suffix) or ""
+ fullname = input.findbinfile(fb,suffix) or ""
end
end
if fullname ~= "" then
specification.filename, specification.format = fullname, what -- hm, so we do set the filename, then
- tfmtable = fonts.tfm.read_from_open_type(specification) -- we need to do it for all matches / todo
+ tfmtable = tfm.read_from_open_type(specification) -- we need to do it for all matches / todo
end
return tfmtable
else
@@ -331,34 +340,34 @@ function fonts.tfm.readers.opentype(specification,suffix,what)
end
end
-function fonts.tfm.readers.otf(specification) return fonts.tfm.readers.opentype(specification,"otf","opentype") end
-function fonts.tfm.readers.ttf(specification) return fonts.tfm.readers.opentype(specification,"ttf","truetype") end
-function fonts.tfm.readers.ttc(specification) return fonts.tfm.readers.opentype(specification,"ttf","truetype") end -- !!
+function tfm.readers.otf(specification) return tfm.readers.opentype(specification,"otf","opentype") end
+function tfm.readers.ttf(specification) return tfm.readers.opentype(specification,"ttf","truetype") end
+function tfm.readers.ttc(specification) return tfm.readers.opentype(specification,"ttf","truetype") end -- !!
-function fonts.tfm.readers.afm(specification,method)
+function tfm.readers.afm(specification,method)
local fullname, tfmtable = nil, nil
method = method or fonts.define.method
if method == 2 then
- fullname = input.findbinfile(texmf.instance,specification.name,"ofm") or ""
+ fullname = input.findbinfile(specification.name,"ofm") or ""
if fullname == "" then
- tfmtable = fonts.tfm.read_from_afm(specification)
+ tfmtable = tfm.read_from_afm(specification)
else -- redundant
specification.filename = fullname
- tfmtable = fonts.tfm.read_from_tfm(specification)
+ tfmtable = tfm.read_from_tfm(specification)
end
elseif method == 3 then -- maybe also findbinfile here
if fonts.define.auto_afm then
- tfmtable = fonts.tfm.read_from_afm(specification)
+ tfmtable = tfm.read_from_afm(specification)
end
elseif method == 4 then -- maybe also findbinfile here
- tfmtable = fonts.tfm.read_from_afm(specification)
+ tfmtable = tfm.read_from_afm(specification)
end
return tfmtable
end
-function fonts.tfm.readers.tfm(specification)
+function tfm.readers.tfm(specification)
local fullname, tfmtable = nil, nil
- tfmtable = fonts.tfm.read_from_tfm(specification)
+ tfmtable = tfm.read_from_tfm(specification)
return tfmtable
end
@@ -378,8 +387,12 @@ name*context specification
--ldx]]--
function fonts.define.specify.predefined(specification)
- if specification.detail ~= "" and fonts.define.methods[specification.detail] then
- specification.features.vtf = { preset = specification.detail }
+ local detail = specification.detail
+ if detail ~= "" then
+ detail = detail:gsub("["..fonts.define.splitsymbols.."].*$","") -- get rid of *whatever specs and such
+ if fonts.define.methods[detail] then -- since these may be appended at the
+ specification.features.vtf = { preset = detail } -- tex end by default
+ end
end
return specification
end
@@ -391,7 +404,7 @@ function fonts.define.specify.colonized(specification) -- xetex mode
if specification.detail and specification.detail ~= "" then
local expanded_features = { }
local function expand(features)
- for _,v in pairs(features:split(";")) do
+ for _,v in pairs(features:split(";")) do --just gmatch
expanded_features[#expanded_features+1] = v
end
end
@@ -415,7 +428,7 @@ function fonts.define.specify.colonized(specification) -- xetex mode
return specification
end
-function fonts.tfm.make(specification)
+function tfm.make(specification)
local fvm = fonts.define.methods[specification.features.vtf.preset]
if fvm then
return fvm(specification)
@@ -594,43 +607,46 @@ not gain much. By the way, passing id's back to in the callback was
introduced later in the development.</p>
--ldx]]--
+fonts.define.last = nil
+
function fonts.define.read(name,size,id)
local specification = fonts.define.analyze(name,size,id)
if specification.method and fonts.define.specify[specification.method] then
specification = fonts.define.specify[specification.method](specification)
end
specification = fonts.define.resolve(specification)
- local hash = fonts.tfm.hash_instance(specification)
+ local hash = tfm.hash_instance(specification)
if true then
--~ local fontdata = containers.read(fonts.cache(),hash) -- for tracing purposes
end
- local fontdata = fonts.tfm.internalized[hash] -- id
+ local fontdata = tfm.internalized[hash] -- id
+ fonts.define.last = fontdata or id
if not fontdata then
if specification.features.vtf and specification.features.vtf.preset then
- fontdata = fonts.tfm.make(specification)
+ fontdata = tfm.make(specification)
else
- fontdata = fonts.tfm.read(specification)
+ fontdata = tfm.read(specification)
if fontdata then
- fonts.tfm.check_virtual_id(fontdata)
+ tfm.check_virtual_id(fontdata)
end
end
if true then
--~ fontdata = containers.write(fonts.cache(),hash,fontdata) -- for tracing purposes
end
- if not fonts.tfm.internalized[hash] then
- fonts.tfm.id[id] = fontdata
- fonts.tfm.internalized[hash] = id
+ if not tfm.internalized[hash] then
+ tfm.id[id] = fontdata
+ tfm.internalized[hash] = id
if fonts.trace then
- logs.report("define font", string.format("loading at 2 id %s, hash: %s",id,hash))
+ logs.report("define font","loading at 2 id %s, hash: %s",id,hash)
end
else
- fontdata = fonts.tfm.internalized[hash]
+ fontdata = tfm.internalized[hash]
end
end
if not fontdata then
- logs.error("define font", string.format("unknown font %s, loading aborted",specification.name))
+ logs.report("define font", "unknown font %s, loading aborted",specification.name)
elseif fonts.trace and type(fontdata) == "table" then
- logs.report("define font",string.format("using %s font with id %s, n:%s s:%s b:%s e:%s p:%s f:%s",
+ logs.report("define font","using %s font with id %s, n:%s s:%s b:%s e:%s p:%s f:%s",
fontdata.type or "unknown",
id or "?",
fontdata.name or "?",
@@ -638,16 +654,16 @@ function fonts.define.read(name,size,id)
fontdata.encodingbytes or "?",
fontdata.encodingname or "unicode",
fontdata.fullname or "?",
- file.basename(fontdata.filename or "?")))
+ file.basename(fontdata.filename or "?"))
end
return fontdata
end
---~ table.insert(fonts.tfm.readers.sequence,1,'vtf')
+--~ table.insert(tfm.readers.sequence,1,'vtf')
---~ function fonts.tfm.readers.vtf(specification)
+--~ function tfm.readers.vtf(specification)
--~ if specification.features.vtf and specification.features.vtf.preset then
---~ return fonts.tfm.make(specification)
+--~ return tfm.make(specification)
--~ else
--~ return nil
--~ end
@@ -655,24 +671,24 @@ end
function fonts.vf.find(name)
name = file.removesuffix(file.basename(name))
- if fonts.tfm.resolve_vf then
+ if tfm.resolve_vf then
local format = fonts.logger.format(name)
if format == 'tfm' or format == 'ofm' then
if fonts.trace then
- logs.report("define font",string.format("locating vf for %s",name))
+ logs.report("define font","locating vf for %s",name)
end
- return input.findbinfile(texmf.instance,name,"ovf")
+ return input.findbinfile(name,"ovf")
else
if fonts.trace then
- logs.report("define font",string.format("vf for %s is already taken care of",name))
+ logs.report("define font","vf for %s is already taken care of",name)
end
return nil -- ""
end
else
if fonts.trace then
- logs.report("define font",string.format("locating vf for %s",name))
+ logs.report("define font","locating vf for %s",name)
end
- return input.findbinfile(texmf.instance,name,"ovf")
+ return input.findbinfile(name,"ovf")
end
end