summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/font-con.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/font-con.lua')
-rw-r--r--tex/context/base/mkiv/font-con.lua252
1 files changed, 178 insertions, 74 deletions
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index 85ac33a10..9cffa5927 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -8,12 +8,14 @@ if not modules then modules = { } end modules ['font-con'] = {
-- some names of table entries will be changed (no _)
-local next, tostring, rawget = next, tostring, rawget
+local next, tostring, tonumber, rawget = next, tostring, tonumber, rawget
local format, match, lower, gsub, find = string.format, string.match, string.lower, string.gsub, string.find
local sort, insert, concat = table.sort, table.insert, table.concat
local sortedkeys, sortedhash, serialize, fastcopy = table.sortedkeys, table.sortedhash, table.serialize, table.fastcopy
local derivetable = table.derive
local ioflush = io.flush
+local round = math.round
+local setmetatable, getmetatable, rawget, rawset = setmetatable, getmetatable, rawget, rawset
local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
local trace_scaling = false trackers.register("fonts.scaling", function(v) trace_scaling = v end)
@@ -44,7 +46,7 @@ constructors.namemode = "fullpath" -- will be a function
constructors.version = 1.01
constructors.cache = containers.define("fonts", "constructors", constructors.version, false)
-constructors.privateoffset = 0xF0000 -- 0x10FFFF
+constructors.privateoffset = 0xF0000 -- 0x10FFFF | context also uses privates: 0xE000-0xEFFF
constructors.cacheintex = true -- so we see the original table in fonts.font
@@ -89,6 +91,13 @@ function constructors.scaled(scaledpoints, designsize) -- handles designsize in
end
end
+function constructors.getprivate(tfmdata)
+ local properties = tfmdata.properties
+ local private = properties.private
+ properties.private = private + 1
+ return private
+end
+
--[[ldx--
<p>Beware, the boundingbox is passed as reference so we may not overwrite it
in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to
@@ -222,27 +231,87 @@ function constructors.trytosharefont(target,tfmdata)
end
end
+-- function constructors.enhanceparameters(parameters)
+-- local xheight = parameters.x_height
+-- local quad = parameters.quad
+-- local space = parameters.space
+-- local stretch = parameters.space_stretch
+-- local shrink = parameters.space_shrink
+-- local extra = parameters.extra_space
+-- local slant = parameters.slant
+-- -- synonyms
+-- parameters.xheight = xheight
+-- parameters.spacestretch = stretch
+-- parameters.spaceshrink = shrink
+-- parameters.extraspace = extra
+-- parameters.em = quad
+-- parameters.ex = xheight
+-- parameters.slantperpoint = slant
+-- parameters.spacing = {
+-- width = space,
+-- stretch = stretch,
+-- shrink = shrink,
+-- extra = extra,
+-- }
+-- end
+
+local synonyms = {
+ exheight = "x_height",
+ xheight = "x_height",
+ ex = "x_height",
+ emwidth = "quad",
+ em = "quad",
+ spacestretch = "space_stretch",
+ stretch = "space_stretch",
+ spaceshrink = "space_shrink",
+ shrink = "space_shrink",
+ extraspace = "extra_space",
+ xspace = "extra_space",
+ slantperpoint = "slant",
+}
+
function constructors.enhanceparameters(parameters)
- local xheight = parameters.x_height
- local quad = parameters.quad
- local space = parameters.space
- local stretch = parameters.space_stretch
- local shrink = parameters.space_shrink
- local extra = parameters.extra_space
- local slant = parameters.slant
- parameters.xheight = xheight
- parameters.spacestretch = stretch
- parameters.spaceshrink = shrink
- parameters.extraspace = extra
- parameters.em = quad
- parameters.ex = xheight
- parameters.slantperpoint = slant
- parameters.spacing = {
- width = space,
- stretch = stretch,
- shrink = shrink,
- extra = extra,
- }
+ local mt = getmetatable(parameters)
+ local getter = function(t,k)
+ if not k then
+ return nil
+ end
+ local s = synonyms[k]
+ if s then
+ return rawget(t,s) or (mt and mt[s]) or nil
+ end
+ if k == "spacing" then
+ return {
+ width = t.space,
+ stretch = t.space_stretch,
+ shrink = t.space_shrink,
+ extra = t.extra_space,
+ }
+ end
+ return mt and mt[k] or nil
+ end
+ local setter = function(t,k,v)
+ if not k then
+ return 0
+ end
+ local s = synonyms[k]
+ if s then
+ rawset(t,s,v)
+ elseif k == "spacing" then
+ if type(v) == "table" then
+ rawset(t,"space",v.width or 0)
+ rawset(t,"space_stretch",v.stretch or 0)
+ rawset(t,"space_shrink",v.shrink or 0)
+ rawset(t,"extra_space",v.extra or 0)
+ end
+ else
+ rawset(t,k,v)
+ end
+ end
+ setmetatable(parameters, {
+ __index = getter,
+ __newindex = setter,
+ })
end
local function mathkerns(v,vdelta)
@@ -264,7 +333,7 @@ local psfake = 0
local function fixedpsname(psname,fallback)
local usedname = psname
if psname and psname ~= "" then
- if find(psname," ") then
+ if find(psname," ",1,true) then
usedname = gsub(psname,"[%s]+","-")
else
-- we assume that the name is sane enough (we might sanitize completely some day)
@@ -322,7 +391,7 @@ function constructors.scale(tfmdata,specification)
--
local mathsize = tonumber(specification.mathsize) or 0
local textsize = tonumber(specification.textsize) or scaledpoints
- local forcedsize = tonumber(parameters.mathsize ) or 0
+ local forcedsize = tonumber(parameters.mathsize ) or 0 -- can be set by the feature "mathsize"
local extrafactor = tonumber(specification.factor ) or 1
if (mathsize == 2 or forcedsize == 2) and parameters.scriptpercentage then
scaledpoints = parameters.scriptpercentage * textsize / 100
@@ -330,6 +399,8 @@ function constructors.scale(tfmdata,specification)
scaledpoints = parameters.scriptscriptpercentage * textsize / 100
elseif forcedsize > 1000 then -- safeguard
scaledpoints = forcedsize
+ else
+ -- in context x and xx also use mathsize
end
targetparameters.mathsize = mathsize -- context specific
targetparameters.textsize = textsize -- context specific
@@ -343,10 +414,6 @@ function constructors.scale(tfmdata,specification)
local defaultdepth = resources.defaultdepth or 0
local units = parameters.units or 1000
--
- if target.fonts then
- target.fonts = fastcopy(target.fonts) -- maybe we virtualize more afterwards
- end
- --
-- boundary keys are no longer needed as we now have a string 'right_boundary'
-- that can be used in relevant tables (kerns and ligatures) ... not that I ever
-- used them
@@ -406,15 +473,9 @@ function constructors.scale(tfmdata,specification)
-- expansion (hz)
local expansion = parameters.expansion
if expansion then
- target.stretch = expansion.stretch
- target.shrink = expansion.shrink
- target.step = expansion.step
- target.auto_expand = expansion.auto
- end
- -- protrusion
- local protrusion = parameters.protrusion
- if protrusion then
- target.auto_protrude = protrusion.auto
+ target.stretch = expansion.stretch
+ target.shrink = expansion.shrink
+ target.step = expansion.step
end
-- widening
local extendfactor = parameters.extendfactor or 0
@@ -440,7 +501,7 @@ function constructors.scale(tfmdata,specification)
targetparameters.scaledpoints = askedscaledpoints
--
local isvirtual = properties.virtualized or tfmdata.type == "virtual"
- local hasquality = target.auto_expand or target.auto_protrude
+ local hasquality = parameters.expansion or parameters.protrusion
local hasitalics = properties.hasitalics
local autoitalicamount = properties.autoitalicamount
local stackmath = not properties.nostackmath
@@ -451,6 +512,13 @@ function constructors.scale(tfmdata,specification)
local writingmode = properties.writingmode or "horizontal"
local identity = properties.identity or "horizontal"
--
+ local vfonts = target.fonts
+ if vfonts and #vfonts > 0 then
+ target.fonts = fastcopy(vfonts) -- maybe we virtualize more afterwards
+ elseif isvirtual then
+ target.fonts = { { id = 0 } } -- catch error
+ end
+ --
if changed and not next(changed) then
changed = false
end
@@ -486,7 +554,7 @@ function constructors.scale(tfmdata,specification)
targetparameters.descender = delta * descender
end
--
- constructors.enhanceparameters(targetparameters) -- official copies for us
+ constructors.enhanceparameters(targetparameters) -- official copies for us, now virtual
--
local protrusionfactor = (targetquad ~= 0 and 1000/targetquad) or 0
local scaledwidth = defaultwidth * hdelta
@@ -549,10 +617,15 @@ function constructors.scale(tfmdata,specification)
local chr, description, index
if changed then
local c = changed[unicode]
- if c then
- description = descriptions[c] or descriptions[unicode] or character
- character = characters[c] or character
- index = description.index or c
+ if c and c ~= unicode then
+ if c then
+ description = descriptions[c] or descriptions[unicode] or character
+ character = characters[c] or character
+ index = description.index or c
+ else
+ description = descriptions[unicode] or character
+ index = description.index or unicode
+ end
else
description = descriptions[unicode] or character
index = description.index or unicode
@@ -768,7 +841,7 @@ function constructors.scale(tfmdata,specification)
local ok = false
for i=1,#vc do
local key = vc[i][1]
- if key == "right" or key == "down" then
+ if key == "right" or key == "down" or key == "rule" then
ok = true
break
end
@@ -804,6 +877,21 @@ function constructors.scale(tfmdata,specification)
--
constructors.trytosharefont(target,tfmdata)
--
+ -- catch inconsistencies
+ --
+ local vfonts = target.fonts
+ if isvirtual then
+ if not vfonts or #vfonts == 0 then
+ target.fonts = { { id = 0 } }
+ end
+ elseif vfonts then
+ properties.virtualized = true
+ target.type = "virtual"
+ if #vfonts == 0 then
+ target.fonts = { { id = 0 } }
+ end
+ end
+ --
return target
end
@@ -827,16 +915,9 @@ function constructors.finalize(tfmdata)
--
if not parameters.expansion then
parameters.expansion = {
- stretch = tfmdata.stretch or 0,
- shrink = tfmdata.shrink or 0,
- step = tfmdata.step or 0,
- auto = tfmdata.auto_expand or false,
- }
- end
- --
- if not parameters.protrusion then
- parameters.protrusion = {
- auto = auto_protrude
+ stretch = tfmdata.stretch or 0,
+ shrink = tfmdata.shrink or 0,
+ step = tfmdata.step or 0,
}
end
--
@@ -940,8 +1021,6 @@ function constructors.finalize(tfmdata)
tfmdata.stretch = nil
tfmdata.shrink = nil
tfmdata.step = nil
- tfmdata.auto_expand = nil
- tfmdata.auto_protrude = nil
tfmdata.extend = nil
tfmdata.slant = nil
tfmdata.units = nil
@@ -965,8 +1044,6 @@ function constructors.hashfeatures(specification) -- will be overloaded
local features = specification.features
if features then
local t, n = { }, 0
--- inspect(features)
--- for category, list in next, features do
for category, list in sortedhash(features) do
if next(list) then
local hasher = hashmethods[category]
@@ -1006,7 +1083,7 @@ hashmethods.normal = function(list)
end
--[[ldx--
-<p>In principle we can share tfm tables when we are in node for a font, but then
+<p>In principle we can share tfm tables when we are in need for a font, but then
we need to define a font switch as an id/attr switch which is no fun, so in that
case users can best use dynamic features ... so, we will not use that speedup. Okay,
when we get rid of base mode we can optimize even further by sharing, but then we
@@ -1020,13 +1097,15 @@ function constructors.hashinstance(specification,force)
specification.hash = hash
end
if size < 1000 and designsizes[hash] then
- size = math.round(constructors.scaled(size,designsizes[hash]))
- specification.size = size
+ size = round(constructors.scaled(size,designsizes[hash]))
+ else
+ size = round(size)
end
+ specification.size = size
if fallbacks then
- return hash .. ' @ ' .. tostring(size) .. ' @ ' .. fallbacks
+ return hash .. ' @ ' .. size .. ' @ ' .. fallbacks
else
- return hash .. ' @ ' .. tostring(size)
+ return hash .. ' @ ' .. size
end
end
@@ -1235,11 +1314,13 @@ do
if not enhancers then
- local actions = allocate()
- local before = allocate()
- local after = allocate()
- local order = allocate()
- local patches = { before = before, after = after }
+ local actions = allocate() -- no need to allocate thee
+ local before = allocate()
+ local after = allocate()
+ local order = allocate()
+ local known = { }
+ local nofsteps = 0
+ local patches = { before = before, after = after }
local trace = false
local report = logs.reporter("fonts",format .. " enhancing")
@@ -1265,7 +1346,7 @@ do
report("%s enhancing file %a","start",filename)
end
ioflush() -- we want instant messages
- for e=1,#order do
+ for e=1,nofsteps do
local enhancer = order[e]
local b = before[enhancer]
if b then
@@ -1275,7 +1356,7 @@ do
end
end
end
- enhance(enhancer,data,filename,raw)
+ enhance(enhancer,data,filename,raw) -- we have one installed: check extra features
local a = after[enhancer]
if a then
for pattern, action in next, a do
@@ -1297,7 +1378,9 @@ do
if actions[what] then
-- overloading, e.g."check extra features"
else
- order[#order+1] = what
+ nofsteps = nofsteps + 1
+ order[nofsteps] = what
+ known[what] = nofsteps
end
actions[what] = action
else
@@ -1305,7 +1388,19 @@ do
end
end
- -- fonts.constructors.otf.enhancers.patch("before","migrate metadata","cambria",function() end)
+ -- We used to have a lot of enhancers but no longer with the new font loader. The order of enhancers
+ -- is the order of definition. The before/after patches are there for old times sake and happen
+ -- before or after a (named) enhancer. An example of a set enhancer is "check extra features" so one
+ -- one set patches before or after that is applied. Unknown enhancers are auto-registered. It's a bit
+ -- messy but we keep it for compatibility reasons.
+ --
+ -- fonts.handlers.otf.enhancers.patches.register("before","some patches","somefont",function(data,filename)
+ -- print("!!!!!!!") -- before | after
+ -- end)
+ --
+ -- fonts.handlers.otf.enhancers.register("more patches",function(data,filename)
+ -- print("???????") -- enhance
+ -- end)
local function patch(what,where,pattern,action)
local pw = patches[what]
@@ -1314,7 +1409,12 @@ do
if ww then
ww[pattern] = action
else
- pw[where] = { [pattern] = action}
+ pw[where] = { [pattern] = action }
+ if not known[where] then
+ nofsteps = nofsteps + 1
+ order[nofsteps] = where
+ known[where] = nofsteps
+ end
end
end
end
@@ -1323,7 +1423,11 @@ do
register = register,
apply = apply,
patch = patch,
- patches = { register = patch }, -- for old times sake
+ report = report,
+ patches = {
+ register = patch,
+ report = report,
+ }, -- for old times sake
}
handler.enhancers = enhancers