summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/font-chk.lmt
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2021-05-19 18:48:15 +0200
committerContext Git Mirror Bot <phg@phi-gamma.net>2021-05-19 18:48:15 +0200
commitf1772caf425af2fe9be87b788eae63559682d51a (patch)
treece9a813989227bea7191db7a8f8bc87ad6d578dd /tex/context/base/mkxl/font-chk.lmt
parent330909ad62342ff873dc758b909968c66d0252a4 (diff)
downloadcontext-f1772caf425af2fe9be87b788eae63559682d51a.tar.gz
2021-05-19 18:21:00
Diffstat (limited to 'tex/context/base/mkxl/font-chk.lmt')
-rw-r--r--tex/context/base/mkxl/font-chk.lmt101
1 files changed, 100 insertions, 1 deletions
diff --git a/tex/context/base/mkxl/font-chk.lmt b/tex/context/base/mkxl/font-chk.lmt
index eb1be3f1b..2beec268f 100644
--- a/tex/context/base/mkxl/font-chk.lmt
+++ b/tex/context/base/mkxl/font-chk.lmt
@@ -12,7 +12,8 @@ if not modules then modules = { } end modules ['font-chk'] = {
-- instead we just keep the method we use but slightly adapted to the backend
-- of lmtx.
-local next = next
+local type, next = type, next
+local find, lower, gmatch = string.find, string.lower, string.gmatch
local floor = math.floor
local context = context
@@ -22,12 +23,15 @@ local bpfactor = number.dimenfactors.bp
local fastcopy = table.fastcopy
local sortedkeys = table.sortedkeys
local sortedhash = table.sortedhash
+local contains = table.contains
local report = logs.reporter("fonts")
local report_checking = logs.reporter("fonts","checking")
local allocate = utilities.storage.allocate
+local getmacro = tokens.getters.macro
+
local fonts = fonts
fonts.checkers = fonts.checkers or { }
@@ -40,6 +44,7 @@ local fontcharacters = fonthashes.characters
local currentfont = font.current
local addcharacters = font.addcharacters
+local definers = fonts.definers
local helpers = fonts.helpers
local addprivate = helpers.addprivate
@@ -452,3 +457,97 @@ local visualspace_specification = {
registerotffeature(visualspace_specification)
registerafmfeature(visualspace_specification)
+
+do
+
+
+ local reference = 88 -- string.byte("X")
+ local mapping = { ss = "sans", rm = "serif", tt = "mono" }
+ local order = { "sans", "serif", "mono" }
+ local fallbacks = { sans = { }, serif = { }, mono = { } }
+
+ local function locate(fallbacks,n,f,c)
+ for i=1,#fallbacks do
+ local id = fallbacks[i]
+ if type(id) == "string" then
+ id = definers.define { name = id }
+ fallbacks[i] = id
+ end
+ if type(id) == "number" then
+ local cid = fontcharacters[id]
+ if cid[c] then
+ local fc = fontcharacters[f]
+ local sc = (fc[reference].height / cid[reference].height) * (n.scale or 1000)
+ return { id, sc }
+ end
+ end
+ end
+ return false
+ end
+
+ local cache = table.setmetatableindex("table")
+
+ callback.register("missing_character", function(n,f,c)
+ local cached = cache[f]
+ local found = cached[c]
+ if found == nil then
+ local metadata = fontdata[f].shared
+ if metadata then
+ metadata = metadata.rawdata
+ if metadata then
+ metadata = metadata.metadata
+ if metadata then
+ if metadata.monospaced then
+ found = locate(fallbacks.mono,n,f,c)
+ if found then
+ cached[c] = found
+ goto done
+ end
+ end
+ local fn = lower(metadata.fullname)
+ for i=1,3 do
+ local o = order[i]
+ if find(fn,o) then
+ found = locate(fallbacks[o],n,f,c)
+ if found then
+ cached[c] = found
+ goto done
+ end
+ end
+ end
+ end
+ end
+ end
+ found = locate(fallbacks[mapping[getmacro("fontstyle")] or "mono"],n,f,c)
+ if found then
+ cached[c] = found
+ goto done
+ end
+ end
+ ::done::
+ if found then
+ n.font = found[1]
+ n.scale = found[2]
+ end
+ end)
+
+ function definers.registerfallbackfont(style,list)
+ local l = fallbacks[style]
+ if l then
+ for s in gmatch(list,"%S+") do
+ if not contains(l,s) then
+ l[#l+1] = s
+ end
+ end
+ end
+ end
+
+ implement {
+ name = "registerfallbackfont",
+ public = true,
+ protected = true,
+ arguments = { "optional", "optional" },
+ actions = definers.registerfallbackfont,
+ }
+
+end