diff options
author | Marius <mariausol@gmail.com> | 2013-05-19 20:40:34 +0300 |
---|---|---|
committer | Marius <mariausol@gmail.com> | 2013-05-19 20:40:34 +0300 |
commit | 13ec4b540e0d46c97fd7b089e0b7413da81e0a9f (patch) | |
tree | bebfa563a17c06b3bd3bf8f6f4ba6d025e00d107 /tex/context/base/font-chk.lua | |
parent | 69ad13650cda027526271179e95b5294694143a1 (diff) | |
download | context-13ec4b540e0d46c97fd7b089e0b7413da81e0a9f.tar.gz |
beta 2013.05.19 19:27
Diffstat (limited to 'tex/context/base/font-chk.lua')
-rw-r--r-- | tex/context/base/font-chk.lua | 718 |
1 files changed, 359 insertions, 359 deletions
diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua index 1b89366fd..9e420744a 100644 --- a/tex/context/base/font-chk.lua +++ b/tex/context/base/font-chk.lua @@ -1,359 +1,359 @@ -if not modules then modules = { } end modules ['font-chk'] = { - version = 1.001, - comment = "companion to font-ini.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- possible optimization: delayed initialization of vectors --- move to the nodes namespace - -local format = string.format -local bpfactor = number.dimenfactors.bp - -local report_fonts = logs.reporter("fonts","checking") - -local fonts = fonts - -fonts.checkers = fonts.checkers or { } -local checkers = fonts.checkers - -local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers -local fontcharacters = fonthashes.characters - -local addprivate = fonts.helpers.addprivate -local hasprivate = fonts.helpers.hasprivate -local getprivatenode = fonts.helpers.getprivatenode - -local otffeatures = fonts.constructors.newfeatures("otf") -local registerotffeature = otffeatures.register - -local is_character = characters.is_character -local chardata = characters.data - -local tasks = nodes.tasks -local enableaction = tasks.enableaction -local disableaction = tasks.disableaction - -local glyph_code = nodes.nodecodes.glyph -local traverse_id = node.traverse_id -local remove_node = nodes.remove -local insert_node_after = node.insert_after - --- maybe in fonts namespace --- deletion can be option - -local action = false - --- to tfmdata.properties ? - -local function onetimemessage(font,char,message) -- char == false returns table - local tfmdata = fontdata[font] - local shared = tfmdata.shared - local messages = shared.messages - if not messages then - messages = { } - shared.messages = messages - end - local category = messages[message] - if not category then - category = { } - messages[message] = category - end - if char == false then - return table.sortedkeys(category) - elseif not category[char] then - report_fonts("char %U in font %a with id %a: %s",char,tfmdata.properties.fullname,font,message) - category[char] = true - end -end - -fonts.loggers.onetimemessage = onetimemessage - -local mapping = { -- this is just an experiment to illustrate some principles elsewhere - lu = "placeholder uppercase red", - ll = "placeholder lowercase red", - lt = "placeholder uppercase red", - lm = "placeholder lowercase red", - lo = "placeholder lowercase red", - mn = "placeholder mark green", - mc = "placeholder mark green", - me = "placeholder mark green", - nd = "placeholder lowercase blue", - nl = "placeholder lowercase blue", - no = "placeholder lowercase blue", - pc = "placeholder punctuation cyan", - pd = "placeholder punctuation cyan", - ps = "placeholder punctuation cyan", - pe = "placeholder punctuation cyan", - pi = "placeholder punctuation cyan", - pf = "placeholder punctuation cyan", - po = "placeholder punctuation cyan", - sm = "placeholder lowercase magenta", - sc = "placeholder lowercase yellow", - sk = "placeholder lowercase yellow", - so = "placeholder lowercase yellow", -} - -table.setmetatableindex(mapping,function(t,k) v = "placeholder unknown gray" t[k] = v return v end) - -local fakes = { - { - name = "lowercase", - code = ".025 -.175 m .425 -.175 l .425 .525 l .025 .525 l .025 -.175 l .025 0 l .425 0 l .025 -.175 m h S", - width = .45, - height = .55, - depth = .20, - }, - { - name = "uppercase", - code = ".025 -.225 m .625 -.225 l .625 .675 l .025 .675 l .025 -.225 l .025 0 l .625 0 l .025 -.225 m h S", - width = .65, - height = .70, - depth = .25, - }, - { - name = "mark", - code = ".025 .475 m .125 .475 l .125 .675 l .025 .675 l .025 .475 l h B", - width = .15, - height = .70, - depth = -.50, - }, - { - name = "punctuation", - code = ".025 -.175 m .125 -.175 l .125 .525 l .025 .525 l .025 -.175 l h B", - width = .15, - height = .55, - depth = .20, - }, - { - name = "unknown", - code = ".025 0 m .425 0 l .425 .175 l .025 .175 l .025 0 l h B", - width = .45, - height = .20, - depth = 0, - }, -} - -local variants = { - { tag = "gray", r = .6, g = .6, b = .6 }, - { tag = "red", r = .6, g = 0, b = 0 }, - { tag = "green", r = 0, g = .6, b = 0 }, - { tag = "blue", r = 0, g = 0, b = .6 }, - { tag = "cyan", r = 0, g = .6, b = .6 }, - { tag = "magenta", r = .6, g = 0, b = .6 }, - { tag = "yellow", r = .6, g = .6, b = 0 }, -} - -local package = "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 cache = { } -- saves some tables but not that impressive - -local function addmissingsymbols(tfmdata) -- we can have an alternative with rules - local characters = tfmdata.characters - local size = tfmdata.parameters.size - local privates = tfmdata.properties.privates - local scale = size * bpfactor - for i=1,#variants do - local v = variants[i] - local tag, r, g, b = v.tag, v.r, v.g, v.b - for i =1, #fakes do - local fake = fakes[i] - local name = fake.name - local privatename = format("placeholder %s %s",name,tag) - if not hasprivate(tfmdata,privatename) then - local hash = format("%s_%s_%s_%s_%s_%s",name,tag,r,g,b,size) - local char = cache[hash] - if not char then - char = { - width = size*fake.width, - height = size*fake.height, - depth = size*fake.depth, - -- bah .. low level pdf ... should be a rule or plugged in - commands = { { "special", "pdf: " .. format(package,scale,scale,r,g,b,r,g,b,fake.code) } } - } - cache[hash] = char - end - addprivate(tfmdata, privatename, char) - end - end - end -end - -registerotffeature { - name = "missing", - description = "missing symbols", - manipulators = { - base = addmissingsymbols, - node = addmissingsymbols, - } -} - -fonts.loggers.add_placeholders = function(id) addmissingsymbols(fontdata[id or true]) end -fonts.loggers.category_to_placeholder = mapping - -function commands.getplaceholderchar(name) - local id = font.current() - addmissingsymbols(fontdata[id]) - context(fonts.helpers.getprivatenode(fontdata[id],name)) -end - -function checkers.missing(head) - local lastfont, characters, found = nil, nil, nil - for n in traverse_id(glyph_code,head) do -- faster than while loop so we delay removal - local font = n.font - local char = n.char - if font ~= lastfont then - characters = fontcharacters[font] - end - if 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 - onetimemessage(font,char,"missing (will be flagged)") - else - onetimemessage(font,char,"missing") - end - if not found then - found = { n } - else - found[#found+1] = n - end - end - end - if not found then - -- all well - elseif action == "remove" then - for i=1,#found do - head = remove_node(head,found[i],true) - end - elseif action == "replace" then - for i=1,#found do - local n = found[i] - local font = n.font - local char = n.char - local tfmdata = fontdata[font] - local properties = tfmdata.properties - local privates = properties.privates - local category = chardata[char].category - local fakechar = mapping[category] - local p = privates and privates[fakechar] - if not p then - addmissingsymbols(tfmdata) - p = properties.privates[fakechar] - end - if properties.lateprivates then -- .frozen - -- bad, we don't have them at the tex end - local fake = getprivatenode(tfmdata,fakechar) - insert_node_after(head,n,fake) - head = remove_node(head,n,true) - else - -- good, we have \definefontfeature[default][default][missing=yes] - n.char = p - end - end - else - -- maye write a report to the log - end - return head, false -end - -local relevant = { "missing (will be deleted)", "missing (will be flagged)", "missing" } - -function checkers.getmissing(id) - if id then - local list = checkers.getmissing(font.current()) - if list then - local _, list = next(checkers.getmissing(font.current())) - return list - else - return { } - end - else - local t = { } - for id, d in next, fontdata do - local shared = d.shared - local messages = shared.messages - if messages then - local tf = t[d.properties.filename] or { } - for i=1,#relevant do - local tm = messages[relevant[i]] - if tm then - tf = table.merged(tf,tm) - end - end - if next(tf) then - t[d.properties.filename] = tf - end - end - end - for k, v in next, t do - t[k] = table.sortedkeys(v) - end - return t - end -end - -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) - -function commands.checkcharactersinfont() - enableaction("processors","fonts.checkers.missing") - tracked = true -end - -function commands.removemissingcharacters() - enableaction("processors","fonts.checkers.missing") - action = "remove" - tracked = true -end - -function commands.replacemissingcharacters() - enableaction("processors","fonts.checkers.missing") - action = "replace" - otffeatures.defaults.missing = true - tracked = true -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() - end - logspoptarget() - end - end -end) +if not modules then modules = { } end modules ['font-chk'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- possible optimization: delayed initialization of vectors
+-- move to the nodes namespace
+
+local format = string.format
+local bpfactor = number.dimenfactors.bp
+
+local report_fonts = logs.reporter("fonts","checking")
+
+local fonts = fonts
+
+fonts.checkers = fonts.checkers or { }
+local checkers = fonts.checkers
+
+local fonthashes = fonts.hashes
+local fontdata = fonthashes.identifiers
+local fontcharacters = fonthashes.characters
+
+local addprivate = fonts.helpers.addprivate
+local hasprivate = fonts.helpers.hasprivate
+local getprivatenode = fonts.helpers.getprivatenode
+
+local otffeatures = fonts.constructors.newfeatures("otf")
+local registerotffeature = otffeatures.register
+
+local is_character = characters.is_character
+local chardata = characters.data
+
+local tasks = nodes.tasks
+local enableaction = tasks.enableaction
+local disableaction = tasks.disableaction
+
+local glyph_code = nodes.nodecodes.glyph
+local traverse_id = node.traverse_id
+local remove_node = nodes.remove
+local insert_node_after = node.insert_after
+
+-- maybe in fonts namespace
+-- deletion can be option
+
+local action = false
+
+-- to tfmdata.properties ?
+
+local function onetimemessage(font,char,message) -- char == false returns table
+ local tfmdata = fontdata[font]
+ local shared = tfmdata.shared
+ local messages = shared.messages
+ if not messages then
+ messages = { }
+ shared.messages = messages
+ end
+ local category = messages[message]
+ if not category then
+ category = { }
+ messages[message] = category
+ end
+ if char == false then
+ return table.sortedkeys(category)
+ elseif not category[char] then
+ report_fonts("char %U in font %a with id %a: %s",char,tfmdata.properties.fullname,font,message)
+ category[char] = true
+ end
+end
+
+fonts.loggers.onetimemessage = onetimemessage
+
+local mapping = { -- this is just an experiment to illustrate some principles elsewhere
+ lu = "placeholder uppercase red",
+ ll = "placeholder lowercase red",
+ lt = "placeholder uppercase red",
+ lm = "placeholder lowercase red",
+ lo = "placeholder lowercase red",
+ mn = "placeholder mark green",
+ mc = "placeholder mark green",
+ me = "placeholder mark green",
+ nd = "placeholder lowercase blue",
+ nl = "placeholder lowercase blue",
+ no = "placeholder lowercase blue",
+ pc = "placeholder punctuation cyan",
+ pd = "placeholder punctuation cyan",
+ ps = "placeholder punctuation cyan",
+ pe = "placeholder punctuation cyan",
+ pi = "placeholder punctuation cyan",
+ pf = "placeholder punctuation cyan",
+ po = "placeholder punctuation cyan",
+ sm = "placeholder lowercase magenta",
+ sc = "placeholder lowercase yellow",
+ sk = "placeholder lowercase yellow",
+ so = "placeholder lowercase yellow",
+}
+
+table.setmetatableindex(mapping,function(t,k) v = "placeholder unknown gray" t[k] = v return v end)
+
+local fakes = {
+ {
+ name = "lowercase",
+ code = ".025 -.175 m .425 -.175 l .425 .525 l .025 .525 l .025 -.175 l .025 0 l .425 0 l .025 -.175 m h S",
+ width = .45,
+ height = .55,
+ depth = .20,
+ },
+ {
+ name = "uppercase",
+ code = ".025 -.225 m .625 -.225 l .625 .675 l .025 .675 l .025 -.225 l .025 0 l .625 0 l .025 -.225 m h S",
+ width = .65,
+ height = .70,
+ depth = .25,
+ },
+ {
+ name = "mark",
+ code = ".025 .475 m .125 .475 l .125 .675 l .025 .675 l .025 .475 l h B",
+ width = .15,
+ height = .70,
+ depth = -.50,
+ },
+ {
+ name = "punctuation",
+ code = ".025 -.175 m .125 -.175 l .125 .525 l .025 .525 l .025 -.175 l h B",
+ width = .15,
+ height = .55,
+ depth = .20,
+ },
+ {
+ name = "unknown",
+ code = ".025 0 m .425 0 l .425 .175 l .025 .175 l .025 0 l h B",
+ width = .45,
+ height = .20,
+ depth = 0,
+ },
+}
+
+local variants = {
+ { tag = "gray", r = .6, g = .6, b = .6 },
+ { tag = "red", r = .6, g = 0, b = 0 },
+ { tag = "green", r = 0, g = .6, b = 0 },
+ { tag = "blue", r = 0, g = 0, b = .6 },
+ { tag = "cyan", r = 0, g = .6, b = .6 },
+ { tag = "magenta", r = .6, g = 0, b = .6 },
+ { tag = "yellow", r = .6, g = .6, b = 0 },
+}
+
+local package = "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 cache = { } -- saves some tables but not that impressive
+
+local function addmissingsymbols(tfmdata) -- we can have an alternative with rules
+ local characters = tfmdata.characters
+ local size = tfmdata.parameters.size
+ local privates = tfmdata.properties.privates
+ local scale = size * bpfactor
+ for i=1,#variants do
+ local v = variants[i]
+ local tag, r, g, b = v.tag, v.r, v.g, v.b
+ for i =1, #fakes do
+ local fake = fakes[i]
+ local name = fake.name
+ local privatename = format("placeholder %s %s",name,tag)
+ if not hasprivate(tfmdata,privatename) then
+ local hash = format("%s_%s_%s_%s_%s_%s",name,tag,r,g,b,size)
+ local char = cache[hash]
+ if not char then
+ char = {
+ width = size*fake.width,
+ height = size*fake.height,
+ depth = size*fake.depth,
+ -- bah .. low level pdf ... should be a rule or plugged in
+ commands = { { "special", "pdf: " .. format(package,scale,scale,r,g,b,r,g,b,fake.code) } }
+ }
+ cache[hash] = char
+ end
+ addprivate(tfmdata, privatename, char)
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "missing",
+ description = "missing symbols",
+ manipulators = {
+ base = addmissingsymbols,
+ node = addmissingsymbols,
+ }
+}
+
+fonts.loggers.add_placeholders = function(id) addmissingsymbols(fontdata[id or true]) end
+fonts.loggers.category_to_placeholder = mapping
+
+function commands.getplaceholderchar(name)
+ local id = font.current()
+ addmissingsymbols(fontdata[id])
+ context(fonts.helpers.getprivatenode(fontdata[id],name))
+end
+
+function checkers.missing(head)
+ local lastfont, characters, found = nil, nil, nil
+ for n in traverse_id(glyph_code,head) do -- faster than while loop so we delay removal
+ local font = n.font
+ local char = n.char
+ if font ~= lastfont then
+ characters = fontcharacters[font]
+ end
+ if 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
+ onetimemessage(font,char,"missing (will be flagged)")
+ else
+ onetimemessage(font,char,"missing")
+ end
+ if not found then
+ found = { n }
+ else
+ found[#found+1] = n
+ end
+ end
+ end
+ if not found then
+ -- all well
+ elseif action == "remove" then
+ for i=1,#found do
+ head = remove_node(head,found[i],true)
+ end
+ elseif action == "replace" then
+ for i=1,#found do
+ local n = found[i]
+ local font = n.font
+ local char = n.char
+ local tfmdata = fontdata[font]
+ local properties = tfmdata.properties
+ local privates = properties.privates
+ local category = chardata[char].category
+ local fakechar = mapping[category]
+ local p = privates and privates[fakechar]
+ if not p then
+ addmissingsymbols(tfmdata)
+ p = properties.privates[fakechar]
+ end
+ if properties.lateprivates then -- .frozen
+ -- bad, we don't have them at the tex end
+ local fake = getprivatenode(tfmdata,fakechar)
+ insert_node_after(head,n,fake)
+ head = remove_node(head,n,true)
+ else
+ -- good, we have \definefontfeature[default][default][missing=yes]
+ n.char = p
+ end
+ end
+ else
+ -- maye write a report to the log
+ end
+ return head, false
+end
+
+local relevant = { "missing (will be deleted)", "missing (will be flagged)", "missing" }
+
+function checkers.getmissing(id)
+ if id then
+ local list = checkers.getmissing(font.current())
+ if list then
+ local _, list = next(checkers.getmissing(font.current()))
+ return list
+ else
+ return { }
+ end
+ else
+ local t = { }
+ for id, d in next, fontdata do
+ local shared = d.shared
+ local messages = shared.messages
+ if messages then
+ local tf = t[d.properties.filename] or { }
+ for i=1,#relevant do
+ local tm = messages[relevant[i]]
+ if tm then
+ tf = table.merged(tf,tm)
+ end
+ end
+ if next(tf) then
+ t[d.properties.filename] = tf
+ end
+ end
+ end
+ for k, v in next, t do
+ t[k] = table.sortedkeys(v)
+ end
+ return t
+ end
+end
+
+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)
+
+function commands.checkcharactersinfont()
+ enableaction("processors","fonts.checkers.missing")
+ tracked = true
+end
+
+function commands.removemissingcharacters()
+ enableaction("processors","fonts.checkers.missing")
+ action = "remove"
+ tracked = true
+end
+
+function commands.replacemissingcharacters()
+ enableaction("processors","fonts.checkers.missing")
+ action = "replace"
+ otffeatures.defaults.missing = true
+ tracked = true
+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()
+ end
+ logspoptarget()
+ end
+ end
+end)
|