summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/font-chk.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/font-chk.lua')
-rw-r--r--tex/context/base/mkiv/font-chk.lua186
1 files changed, 115 insertions, 71 deletions
diff --git a/tex/context/base/mkiv/font-chk.lua b/tex/context/base/mkiv/font-chk.lua
index d9e88c91e..3613432c1 100644
--- a/tex/context/base/mkiv/font-chk.lua
+++ b/tex/context/base/mkiv/font-chk.lua
@@ -10,12 +10,18 @@ if not modules then modules = { } end modules ['font-chk'] = {
-- move to the nodes namespace
local next = next
+local floor = math.floor
+
+local context = context
local formatters = string.formatters
local bpfactor = number.dimenfactors.bp
local fastcopy = table.fastcopy
+local sortedkeys = table.sortedkeys
+local sortedhash = table.sortedhash
-local report_fonts = logs.reporter("fonts","checking") -- replace
+local report = logs.reporter("fonts")
+local report_checking = logs.reporter("fonts","checking")
local allocate = utilities.storage.allocate
@@ -28,6 +34,9 @@ local fonthashes = fonts.hashes
local fontdata = fonthashes.identifiers
local fontcharacters = fonthashes.characters
+local currentfont = font.current
+local addcharacters = font.addcharacters
+
local helpers = fonts.helpers
local addprivate = helpers.addprivate
@@ -52,7 +61,7 @@ local implement = interfaces.implement
local glyph_code = nodes.nodecodes.glyph
-local new_special = nodes.pool.special
+local new_special = nodes.pool.special -- todo: literal
local hpack_node = node.hpack
local nuts = nodes.nuts
@@ -62,7 +71,6 @@ local tonode = nuts.tonode
local getfont = nuts.getfont
local getchar = nuts.getchar
-local setfield = nuts.setfield
local setchar = nuts.setchar
local traverse_id = nuts.traverse_id
@@ -78,7 +86,11 @@ local action = false
local function onetimemessage(font,char,message) -- char == false returns table
local tfmdata = fontdata[font]
- local shared = tfmdata.shared
+ local shared = tfmdata.shared
+ if not shared then
+ shared = { }
+ tfmdata.shared = shared
+ end
local messages = shared.messages
if not messages then
messages = { }
@@ -90,10 +102,14 @@ local function onetimemessage(font,char,message) -- char == false returns table
messages[message] = category
end
if char == false then
- return table.sortedkeys(category)
- elseif not category[char] then
- report_fonts("char %C in font %a with id %a: %s",char,tfmdata.properties.fullname,font,message)
- category[char] = true
+ return sortedkeys(category), category
+ end
+ local cc = category[char]
+ if not cc then
+ report_checking("char %C in font %a with id %a: %s",char,tfmdata.properties.fullname,font,message)
+ category[char] = 1
+ else
+ category[char] = cc + 1
end
end
@@ -180,13 +196,13 @@ local variants = allocate {
{ tag = "yellow", r = .6, g = .6, b = 0 },
}
-local pdf_blob = "pdf: q %0.6F 0 0 %0.6F 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q"
+local pdf_blob = "pdf: q %.6F 0 0 %.6F 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q"
local cache = { } -- saves some tables but not that impressive
local function missingtonode(tfmdata,character)
- local commands = character.commands
- local fake = hpack_node(new_special(commands[1][2]))
+ local commands = character.commands
+ local fake = hpack_node(new_special(commands[1][2])) -- todo: literal
fake.width = character.width
fake.height = character.height
fake.depth = character.depth
@@ -198,7 +214,11 @@ local function addmissingsymbols(tfmdata) -- we can have an alternative with rul
local properties = tfmdata.properties
local size = tfmdata.parameters.size
local scale = size * bpfactor
- local tonode = properties.finalized and missingtonode or nil
+ local tonode = nil
+ local collected = { }
+ if properties.finalized and not addcharacters then
+ tonode = missingtonode
+ end
for i=1,#variants do
local v = variants[i]
local tag, r, g, b = v.tag, v.r, v.g, v.b
@@ -207,7 +227,7 @@ local function addmissingsymbols(tfmdata) -- we can have an alternative with rul
local name = fake.name
local privatename = formatters["placeholder %s %s"](name,tag)
if not hasprivate(tfmdata,privatename) then
- local hash = formatters["%s_%s_%s_%s_%s_%s"](name,tag,r,g,b,size)
+ local hash = formatters["%s_%s_%1.3f_%1.3f_%1.3f_%i"](name,tag,r,g,b,floor(size))
local char = cache[hash]
if not char then
char = {
@@ -220,10 +240,19 @@ local function addmissingsymbols(tfmdata) -- we can have an alternative with rul
}
cache[hash] = char
end
- addprivate(tfmdata, privatename, char)
+ local u = addprivate(tfmdata, privatename, char)
+ if not tonode then
+ collected[u] = char
+ end
end
end
end
+ if #collected > 0 then
+ addcharacters(properties.id, {
+ type = "real",
+ characters = collected,
+ })
+ end
end
registerotffeature {
@@ -239,18 +268,19 @@ fonts.loggers.add_placeholders = function(id) addmissingsymbols(fontdata[
fonts.loggers.category_to_placeholder = mapping
function commands.getplaceholderchar(name)
- local id = font.current()
+ local id = currentfont()
addmissingsymbols(fontdata[id])
context(getprivatenode(fontdata[id],name))
end
-- todo in luatex: option to add characters (just slots, no kerns etc)
+-- we can do that now so ...
local function placeholder(font,char)
local tfmdata = fontdata[font]
local category = chardata[char].category
local fakechar = mapping[category]
- local slot = getprivateslot(font,fakechar)
+ local slot = getprivateslot(font,fakechar)
if not slot then
addmissingsymbols(tfmdata)
slot = getprivateslot(font,fakechar)
@@ -268,9 +298,9 @@ function checkers.missing(head)
local char = getchar(n)
if font ~= lastfont then
characters = fontcharacters[font]
- lastfont = font
+ lastfont = font
end
- if not characters[char] and is_character[chardata[char].category] then
+ if font > 0 and not characters[char] and is_character[chardata[char].category] then
if action == "remove" then
onetimemessage(font,char,"missing (will be deleted)")
elseif action == "replace" then
@@ -318,9 +348,9 @@ local relevant = {
local function getmissing(id)
if id then
- local list = getmissing(font.current())
+ local list = getmissing(currentfont())
if list then
- local _, list = next(getmissing(font.current()))
+ local _, list = next(getmissing(currentfont()))
return list
else
return { }
@@ -328,73 +358,91 @@ local function getmissing(id)
else
local t = { }
for id, d in next, fontdata do
- local shared = d.shared
- local messages = shared.messages
+ local shared = d.shared
+ local messages = shared and shared.messages
if messages then
- local tf = t[d.properties.filename] or { }
+ local filename = d.properties.filename
+ local tf = t[filename] or { }
for i=1,#relevant do
local tm = messages[relevant[i]]
if tm then
- tf = table.merged(tf,tm)
+ for k, v in next, tm do
+ tf[k] = (tf[k] or 0) + v
+ end
end
end
if next(tf) then
- t[d.properties.filename] = tf
+ t[filename] = tf
end
end
end
+ local l = { }
for k, v in next, t do
- t[k] = table.sortedkeys(v)
+ l[k] = sortedkeys(v)
end
- return t
+ return l, t
end
end
checkers.getmissing = getmissing
-local tracked = false
-trackers.register("fonts.missing", function(v)
- if v then
- enableaction("processors","fonts.checkers.missing")
- tracked = true
- else
- disableaction("processors","fonts.checkers.missing")
- end
- if v == "replace" then
- otffeatures.defaults.missing = true
- end
- action = v
-end)
-
-local report_characters = logs.reporter("fonts","characters")
-local report_character = logs.reporter("missing")
-
-local logsnewline = logs.newline
-local logspushtarget = logs.pushtarget
-local logspoptarget = logs.poptarget
-
-luatex.registerstopactions(function()
- if tracked then
- local collected = checkers.getmissing()
- if next(collected) then
- logspushtarget("logfile")
- for filename, list in table.sortedhash(collected) do
- logsnewline()
- report_characters("start missing characters: %s",filename)
- logsnewline()
- for i=1,#list do
- local u = list[i]
- report_character("%U %c %s",u,u,chardata[u].description)
- end
- logsnewline()
- report_characters("stop missing characters")
- logsnewline()
+do
+
+ local reported = true
+ local tracked = false
+
+ callback.register("glyph_not_found",function(font,char)
+ if font > 0 then
+ if char > 0 then
+ onetimemessage(font,char,"missing")
+ else
+ -- we have a special case
end
- logspoptarget()
+ elseif not reported then
+ report("nullfont is used, maybe no bodyfont is defined")
+ reported = true
end
- end
-end)
+ end)
+
+ trackers.register("fonts.missing", function(v)
+ if v then
+ enableaction("processors","fonts.checkers.missing")
+ tracked = true
+ else
+ disableaction("processors","fonts.checkers.missing")
+ end
+ if v == "replace" then
+ otffeatures.defaults.missing = true
+ end
+ action = v
+ end)
+
+ logs.registerfinalactions(function()
+-- if tracked then
+ local collected, details = getmissing()
+ if next(collected) then
+ for filename, list in sortedhash(details) do
+ logs.startfilelogging(report,"missing characters",filename)
+ for u, v in sortedhash(list) do
+ report("%4i %U %c %s",v,u,u,chardata[u].description)
+ end
+ logs.stopfilelogging()
+ end
+ if logs.loggingerrors() then
+ for filename, list in sortedhash(details) do
+ logs.starterrorlogging(report,"missing characters",filename)
+ for u, v in sortedhash(list) do
+ report("%4i %U %c %s",v,u,u,chardata[u].description)
+ end
+ logs.stoperrorlogging()
+ end
+ end
+ end
+-- end
+ end)
+
+end
-- for the moment here
@@ -459,7 +507,3 @@ local dummies_specification = {
registerotffeature(dummies_specification)
registerafmfeature(dummies_specification)
-
--- callback.register("char_exists",function(f,c) -- to slow anyway as called often so we should flag in tfmdata
--- return true
--- end)