summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/font-gds.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/font-gds.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/font-gds.lua258
1 files changed, 219 insertions, 39 deletions
diff --git a/Master/texmf-dist/tex/context/base/font-gds.lua b/Master/texmf-dist/tex/context/base/font-gds.lua
index a5c60d252ab..3b87e4c772b 100644
--- a/Master/texmf-dist/tex/context/base/font-gds.lua
+++ b/Master/texmf-dist/tex/context/base/font-gds.lua
@@ -9,12 +9,16 @@ if not modules then modules = { } end modules ['font-gds'] = {
-- depends on ctx
local type, next = type, next
-local gmatch, format = string.gmatch, string.format
+local gmatch, format, lower, find, splitup = string.gmatch, string.format, string.lower, string.find, string.splitup
+local texsp = tex.sp
local fonts, nodes, attributes, node = fonts, nodes, attributes, node
-local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end)
-local report_fonts = logs.reporter("fonts","goodies")
+local trace_goodies = false
+
+trackers.register("fonts.goodies", function(v) trace_goodies = v end)
+
+local report_goodies = logs.reporter("fonts","goodies")
local allocate = utilities.storage.allocate
@@ -46,12 +50,12 @@ function fontgoodies.report(what,trace,goodies)
if trace_goodies or trace then
local whatever = goodies[what]
if whatever then
- report_fonts("goodie '%s' found in '%s'",what,goodies.name)
+ report_goodies("goodie '%s' found in '%s'",what,goodies.name)
end
end
end
-local function getgoodies(filename) -- maybe a merge is better
+local function loadgoodies(filename) -- maybe a merge is better
local goodies = data[filename] -- we assume no suffix is given
if goodies ~= nil then
-- found or tagged unfound
@@ -61,15 +65,15 @@ local function getgoodies(filename) -- maybe a merge is better
fullname = resolvers.findfile(file.addsuffix(filename,"lua")) or "" -- fallback suffix
end
if fullname == "" then
- report_fonts("goodie file '%s.lfg' is not found",filename)
+ report_goodies("goodie file '%s.lfg' is not found",filename)
data[filename] = false -- signal for not found
else
goodies = dofile(fullname) or false
if not goodies then
- report_fonts("goodie file '%s' is invalid",fullname)
+ report_goodies("goodie file '%s' is invalid",fullname)
return nil
elseif trace_goodies then
- report_fonts("goodie file '%s' is loaded",fullname)
+ report_goodies("goodie file '%s' is loaded",fullname)
end
goodies.name = goodies.name or "no name"
for name, fnc in next, list do
@@ -86,7 +90,7 @@ function fontgoodies.register(name,fnc) -- will be a proper sequencer
list[name] = fnc
end
-fontgoodies.get = getgoodies
+fontgoodies.load = loadgoodies
-- register goodies file
@@ -98,8 +102,11 @@ local function setgoodies(tfmdata,value)
end
for filename in gmatch(value,"[^, ]+") do
-- we need to check for duplicates
- local ok = getgoodies(filename)
+ local ok = loadgoodies(filename)
if ok then
+ if trace_goodies then
+ report_goodies("assigning goodie '%s'",filename)
+ end
goodies[#goodies+1] = ok
end
end
@@ -141,7 +148,7 @@ function fontgoodies.prepare_features(goodies,name,set)
local n, s = fonts.specifiers.presetcontext(fullname,"",ff)
goodies.featuresets[name] = s -- set
if trace_goodies then
- report_fonts("feature set '%s' gets number %s and name '%s'",name,n,fullname)
+ report_goodies("feature set '%s' gets number %s and name '%s'",name,n,fullname)
end
return n
end
@@ -152,7 +159,7 @@ local function initialize(goodies,tfmdata)
local goodiesname = goodies.name
if featuresets then
if trace_goodies then
- report_fonts("checking featuresets in '%s'",goodies.name)
+ report_goodies("checking featuresets in '%s'",goodies.name)
end
for name, set in next, featuresets do
fontgoodies.prepare_features(goodies,name,set)
@@ -162,14 +169,13 @@ end
fontgoodies.register("featureset",initialize)
-local function setfeatureset(tfmdata,set)
+local function setfeatureset(tfmdata,set,features)
local goodies = tfmdata.goodies -- shared ?
if goodies then
- local features = tfmdata.shared.features
local properties = tfmdata.properties
local what
for i=1,#goodies do
- -- last one counts
+ -- last one wins
local g = goodies[i]
what = (g.featuresets and g.featuresets[set]) or what
end
@@ -179,13 +185,23 @@ local function setfeatureset(tfmdata,set)
features[feature] = value
end
end
- properties.mode = features.mode or properties.mode
+ properties.mode = what.mode or properties.mode
end
end
end
-- postprocessors (we could hash processor and share code)
+function fontgoodies.registerpostprocessor(tfmdata,f,prepend)
+ if not tfmdata.postprocessors then
+ tfmdata.postprocessors = { f }
+ elseif prepend then
+ table.insert(tfmdata.postprocessors,f,1)
+ else
+ table.insert(tfmdata.postprocessors,f)
+ end
+end
+
local function setpostprocessor(tfmdata,processor)
local goodies = tfmdata.goodies
if goodies and type(processor) == "string" then
@@ -204,7 +220,7 @@ local function setpostprocessor(tfmdata,processor)
end
end
end
- local postprocessors = { }
+ local postprocessors = tfmdata.postprocessors or { }
for i=1,#asked do
local a = asked[i]
local f = found[a]
@@ -218,23 +234,6 @@ local function setpostprocessor(tfmdata,processor)
end
end
--- fontgoodies.postprocessors = fontgoodies.postprocessors or { }
--- local postprocessors = fontgoodies.postprocessors
---
--- function postprocessors.apply(tfmdata)
--- local postprocessors = tfmdata.postprocessors
--- if postprocessors then
--- for i=1,#postprocessors do
--- postprocessors[i](tfmdata)
--- end
--- end
--- end
---
--- function definers.applypostprocessors(tfmdata)
--- fonts.goodies.postprocessors.apply(tfmdata) -- only here
--- return tfmdata
--- end
-
-- colorschemes
local colorschemes = { }
@@ -252,17 +251,42 @@ local function setcolorscheme(tfmdata,scheme)
local g = goodies[i]
what = (g.colorschemes and g.colorschemes[scheme]) or what
end
- if what then
+ if type(what) == "table" then
-- this is font bound but we can share them if needed
-- just as we could hash the conversions (per font)
- local hash, reverse = tfmdata.resources.unicodes, { }
+ local hash = tfmdata.resources.unicodes
+ local reverse = { }
+ local characters = tfmdata.characters
for i=1,#what do
local w = what[i]
for j=1,#w do
local name = w[j]
- local unicode = hash[name]
- if unicode then
- reverse[unicode] = i
+ if name == "*" then
+ -- inefficient but only used for tracing anyway
+ for _, unicode in next, hash do
+ reverse[unicode] = i
+ end
+ elseif type(name) == "number" then
+ reverse[name] = i
+ elseif find(name,":") then
+ local start, stop = splitup(name,":")
+ start = tonumber(start)
+ stop = tonumber(stop)
+ if start and stop then
+ -- limited usage: we only deal with non reassigned
+ -- maybe some day I'll also support the ones with a
+ -- tounicode in this range
+ for unicode=start,stop do
+ if characters[unicode] then
+ reverse[unicode] = i
+ end
+ end
+ end
+ else
+ local unicode = hash[name]
+ if unicode then
+ reverse[unicode] = i
+ end
end
end
end
@@ -446,6 +470,89 @@ fontgoodies.register("mathematics", initialize)
-- },
-- }
+-- math italics
+
+-- it would be nice to have a \noitalics\font option
+
+local function initialize(tfmdata)
+ local goodies = tfmdata.goodies
+ if goodies then
+ local shared = tfmdata.shared
+ for i=1,#goodies do
+ local mathgoodies = goodies[i].mathematics
+ local mathitalics = mathgoodies and mathgoodies.italics
+ if mathitalics then
+ local properties = tfmdata.properties
+ mathitalics = mathitalics[file.nameonly(properties.name)] or mathitalics
+ if mathitalics then
+ if trace_goodies then
+ report_goodies("loading mathitalics for font '%s'",properties.name)
+ end
+ local corrections = mathitalics.corrections
+ local defaultfactor = mathitalics.defaultfactor
+ local disableengine = mathitalics.disableengine
+ properties.hasitalics = true
+ properties.mathitalic_defaultfactor = defaultfactor -- we inherit outer one anyway (name will change)
+ if properties.mathitalics == nil then
+ properties.mathitalics = disableengine
+ end
+ if corrections then
+ -- As we want to set italic_correction (the context one) we need a
+ -- postprocessor instead of messing with the (unscaled) descriptions.
+ fontgoodies.registerpostprocessor(tfmdata, function(tfmdata) -- this is another tfmdata (a copy)
+ -- better make a helper so that we have less code being defined
+ local properties = tfmdata.properties
+ local parameters = tfmdata.parameters
+ local characters = tfmdata.characters
+ properties.hasitalics = true
+ properties.mathitalic_defaultfactor = defaultfactor
+ properties.mathitalic_defaultvalue = defaultfactor * parameters.quad
+ if properties.mathitalics == nil then
+ properties.mathitalics = disableengine
+ end
+ if trace_goodies then
+ report_goodies("assigning mathitalics for font '%s'",properties.name)
+ end
+ local mathitalics = properties.mathitalics
+ local quad = parameters.quad
+ local hfactor = parameters.hfactor
+ for k, v in next, corrections do
+ local c = characters[k]
+ if v > -1 and v < 1 then
+ v = v * quad
+ else
+ v = v * hfactor
+ end
+ c.italic_correction = v -- for context
+ if mathitalics then
+ c.italic = v -- for tex
+ else
+ c.italic = nil
+ end
+ end
+ end)
+ end
+ return -- maybe not as these can accumulate
+ end
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "mathitalics",
+ description = "additional math italic corrections",
+ -- default = true,
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+-- fontgoodies.register("mathitalics", initialize)
+
+-- files
+
local function initialize(goodies)
local files = goodies.files
if files then
@@ -498,6 +605,74 @@ end
fontgoodies.register("compositions", initialize)
+local designsizes = { }
+fontgoodies.designsizes = designsizes
+local designdata = allocate()
+designsizes.data = designdata
+
+local function initialize(goodies) -- design sizes are registered global
+ local gd = goodies.designsizes
+ if gd then
+ for name, data in next, gd do
+ local ranges = { }
+ for size, file in next, data do
+ if size ~= "default" then
+ ranges[#ranges+1] = { texsp(size), file } -- also lower(file)
+ end
+ end
+ table.sort(ranges,function(a,b) return a[1] < b[1] end)
+ designdata[lower(name)] = { -- overloads, doesn't merge!
+ default = data.default,
+ ranges = ranges,
+ }
+ end
+ end
+end
+
+fontgoodies.register("designsizes", initialize)
+
+function fontgoodies.designsizes.register(name,size,specification)
+ local d = designdata[name]
+ if not d then
+ d = {
+ ranges = { },
+ default = nil, -- so we have no default set
+ }
+ designdata[name] = d
+ end
+ if size == "default" then
+ d.default = specification
+ else
+ if type(size) == "string" then
+ size = texsp(size)
+ end
+ local ranges = d.ranges
+ ranges[#ranges+1] = { size, specification }
+ end
+end
+
+function fontgoodies.designsizes.filename(name,spec,size) -- returns nil of no match
+ if spec and spec ~= "" then
+ local data = designdata[lower(name)]
+ if data then
+ if spec == "default" then
+ return data.default
+ elseif spec == "auto" then
+ local ranges = data.ranges
+ if ranges then
+ for i=1,#ranges do
+ local r = ranges[i]
+ if r[1] >= size then -- todo: rounding so maybe size - 100
+ return r[2]
+ end
+ end
+ end
+ return data.default or (ranges and ranges[#ranges][2])
+ end
+ end
+ end
+end
+
-- The following file (husayni.lfg) is the experimental setup that we used
-- for Idris font. For the moment we don't store this in the cache and quite
-- probably these files sit in one of the paths:
@@ -507,3 +682,8 @@ fontgoodies.register("compositions", initialize)
-- tex/fonts/data/foundry/collection
--
-- see lfg files in distribution
+
+-- interface
+
+commands.loadfontgoodies = fontgoodies.load
+commands.enablefontcolorschemes = colorschemes.enable