From b4b9e98b13cad714598d2183d4156882ed5703c1 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Mon, 18 Mar 2013 18:49:00 +0100 Subject: beta 2013.03.18 18:49 --- tex/context/base/char-utf.lua | 8 +- tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4140 -> 4135 bytes tex/context/base/context-version.png | Bin 40488 -> 40510 bytes tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 7 +- tex/context/base/font-lib.mkvi | 1 + tex/context/base/font-nod.lua | 434 +++++++++++++++++++++ tex/context/base/font-ota.lua | 4 +- tex/context/base/font-otn.lua | 75 ++-- tex/context/base/font-ott.lua | 2 +- tex/context/base/font-tra.mkiv | 109 +++++- tex/context/base/l-lpeg.lua | 6 +- tex/context/base/node-ini.mkiv | 2 - tex/context/base/node-tra.lua | 413 ++------------------ tex/context/base/status-files.pdf | Bin 24750 -> 24768 bytes tex/context/base/status-lua.pdf | Bin 210790 -> 211224 bytes tex/context/base/status-mkiv.lua | 12 + tex/context/base/symb-ini.lua | 6 +- tex/context/base/util-tab.lua | 18 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 81 ++-- 22 files changed, 674 insertions(+), 510 deletions(-) create mode 100644 tex/context/base/font-nod.lua (limited to 'tex') diff --git a/tex/context/base/char-utf.lua b/tex/context/base/char-utf.lua index 54ace8c9b..154213ea8 100644 --- a/tex/context/base/char-utf.lua +++ b/tex/context/base/char-utf.lua @@ -362,7 +362,13 @@ not collecting tokens is not only faster but also saves garbage collecting. --~ return str --~ end -function utffilters.collapse(str) -- not really tested (we could preallocate a table) +local skippable = table.tohash { "mkiv", "mkvi" } +local filesuffix = file.suffix + +function utffilters.collapse(str,filename) -- not really tested (we could preallocate a table) + if skippable[filesuffix(filename)] then + return str + end if str and str ~= "" then local nstr = #str if nstr > 1 then diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 98d024fe4..8e2ab2a89 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.03.17 13:31} +\newcontextversion{2013.03.18 18:49} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 4fa32e48d..fe01546f0 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.03.17 13:31} +\newcontextversion{2013.03.18 18:49} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 676fa1baa..bf250e02e 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png index 0c61f9e1f..094275eeb 100644 Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index eac5a33ae..18c21ca01 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2013.03.17 13:31} +\edef\contextversion{2013.03.18 18:49} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index b33b02fa4..681bbaf99 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2013.03.17 13:31} +\edef\contextversion{2013.03.18 18:49} %D For those who want to use this: @@ -200,7 +200,7 @@ \loadmkvifile{file-job} % why so late? -\loadmarkfile{symb-ini} +\loadmarkfile{symb-ini} % brrr depends on fonts \loadmarkfile{sort-ini} @@ -342,7 +342,7 @@ \loadmarkfile{char-enc} % will move up -\loadmkvifile{font-lib} +\loadmkvifile{font-lib} % way too late \loadmkvifile{font-fil} \loadmkvifile{font-var} \loadmkvifile{font-fea} @@ -351,7 +351,6 @@ \loadmkvifile{font-sym} \loadmkvifile{font-sty} \loadmkvifile{font-set} - \loadmkvifile{font-emp} \loadmarkfile{font-pre} \loadmarkfile{font-unk} diff --git a/tex/context/base/font-lib.mkvi b/tex/context/base/font-lib.mkvi index b234d6f1f..020abad11 100644 --- a/tex/context/base/font-lib.mkvi +++ b/tex/context/base/font-lib.mkvi @@ -30,6 +30,7 @@ \registerctxluafile{font-afk}{1.001} \registerctxluafile{font-hsh}{1.001} % hashes used by context +\registerctxluafile{font-nod}{1.001} \registerctxluafile{font-oti}{1.001} % otf initialization \registerctxluafile{font-ott}{1.001} % otf tables (first) diff --git a/tex/context/base/font-nod.lua b/tex/context/base/font-nod.lua new file mode 100644 index 000000000..f99130279 --- /dev/null +++ b/tex/context/base/font-nod.lua @@ -0,0 +1,434 @@ +if not modules then modules = { } end modules ['font-nod'] = { + 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" +} + +--[[ldx-- +

This is rather experimental. We need more control and some of this +might become a runtime module instead. This module will be cleaned up!

+--ldx]]-- + +local tonumber, tostring = tonumber, tostring +local utfchar = utf.char +local concat = table.concat +local match, gmatch, concat, rep = string.match, string.gmatch, table.concat, string.rep + +local report_nodes = logs.reporter("fonts","tracing") + +fonts = fonts or { } +nodes = nodes or { } + +local fonts, nodes, node, context = fonts, nodes, node, context + +local tracers = nodes.tracers or { } +nodes.tracers = tracers + +local tasks = nodes.tasks or { } +nodes.tasks = tasks + +local handlers = nodes.handlers or { } +nodes.handlers = handlers + +local injections = nodes.injections or { } +nodes.injections = injections + +local char_tracers = tracers.characters or { } +tracers.characters = char_tracers + +local step_tracers = tracers.steppers or { } +tracers.steppers = step_tracers + +local copy_node_list = node.copy_list +local hpack_node_list = node.hpack +local free_node_list = node.flush_list +local traverse_nodes = node.traverse + +local nodecodes = nodes.nodecodes +local whatcodes = nodes.whatcodes + +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local disc_code = nodecodes.disc +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern +local rule_code = nodecodes.rule +local whatsit_code = nodecodes.whatsit +local spec_code = nodecodes.glue_spec + +local localpar_code = whatcodes.localpar +local dir_code = whatcodes.dir + +local nodepool = nodes.pool +local new_glyph = nodepool.glyph + +local formatters = string.formatters +local formatter = string.formatter + +local hashes = fonts.hashes + +local fontidentifiers = hashes.identifiers +local fontdescriptions = hashes.descriptions +local fontcharacters = hashes.characters +local fontproperties = hashes.properties +local fontparameters = hashes.parameters + +function char_tracers.collect(head,list,tag,n) + n = n or 0 + local ok, fn = false, nil + while head do + local id = head.id + if id == glyph_code then + local f = head.font + if f ~= fn then + ok, fn = false, f + end + local c = head.char + local i = fontidentifiers[f].indices[c] or 0 + if not ok then + ok = true + n = n + 1 + list[n] = list[n] or { } + list[n][tag] = { } + end + local l = list[n][tag] + l[#l+1] = { c, f, i } + elseif id == disc_code then + -- skip + else + ok = false + end + head = head.next + end +end + +function char_tracers.equal(ta, tb) + if #ta ~= #tb then + return false + else + for i=1,#ta do + local a, b = ta[i], tb[i] + if a[1] ~= b[1] or a[2] ~= b[2] or a[3] ~= b[3] then + return false + end + end + end + return true +end + +function char_tracers.string(t) + local tt = { } + for i=1,#t do + tt[i] = utfchar(t[i][1]) + end + return concat(tt,"") +end + +local f_unicode = formatters["%U"] + +function char_tracers.unicodes(t,decimal) + local tt = { } + for i=1,#t do + local n = t[i][1] + if n == 0 then + tt[i] = "-" + elseif decimal then + tt[i] = n + else + tt[i] = f_unicode(n) + end + end + return concat(tt," ") +end + +function char_tracers.indices(t,decimal) + local tt = { } + for i=1,#t do + local n = t[i][3] + if n == 0 then + tt[i] = "-" + elseif decimal then + tt[i] = n + else + tt[i] = f_unicode(n) + end + end + return concat(tt," ") +end + +function char_tracers.start() + local npc = handlers.characters + local list = { } + function handlers.characters(head) + local n = #list + char_tracers.collect(head,list,'before',n) + local h, d = npc(head) + char_tracers.collect(head,list,'after',n) + if #list > n then + list[#list+1] = { } + end + return h, d + end + function char_tracers.stop() + tracers.list['characters'] = list + local variables = { + ['title'] = 'ConTeXt Character Processing Information', + ['color-background-one'] = lmx.get('color-background-yellow'), + ['color-background-two'] = lmx.get('color-background-purple'), + } + lmx.show('context-characters.lmx',variables) + handlers.characters = npc + tasks.restart("processors", "characters") + end + tasks.restart("processors", "characters") +end + +local stack = { } + +function tracers.start(tag) + stack[#stack+1] = tag + local tracer = tracers[tag] + if tracer and tracer.start then + tracer.start() + end +end +function tracers.stop() + local tracer = stack[#stack] + if tracer and tracer.stop then + tracer.stop() + end + stack[#stack] = nil +end + +-- experimental + +local collection, collecting, messages = { }, false, { } + +function step_tracers.start() + collecting = true +end + +function step_tracers.stop() + collecting = false +end + +function step_tracers.reset() + for i=1,#collection do + local c = collection[i] + if c then + free_node_list(c) + end + end + collection, messages = { }, { } +end + +function step_tracers.nofsteps() + return context(#collection) +end + +function step_tracers.glyphs(n,i) + local c = collection[i] + if c then + tex.box[n] = hpack_node_list(copy_node_list(c)) + end +end + +function step_tracers.features() + -- we cannot use first_glyph here as it only finds characters with subtype < 256 + local f = collection[1] + while f do + if f.id == glyph_code then + local tfmdata, t = fontidentifiers[f.font], { } + for feature, value in table.sortedhash(tfmdata.shared.features) do + if feature == "number" or feature == "features" then + -- private + elseif type(value) == "boolean" then + if value then + t[#t+1] = formatters["%s=yes"](feature) + else + -- skip + end + else + t[#t+1] = formatters["%s=%s"](feature,value) + end + end + if #t > 0 then + context(concat(t,", ")) + else + context("no features") + end + return + end + f = f.next + end +end + +function tracers.fontchar(font,char) + local n = new_glyph() + n.font, n.char, n.subtype = font, char, 256 + context(n) +end + +function step_tracers.font(command) + local c = collection[1] + while c do + local id = c.id + if id == glyph_code then + local font = c.font + local name = file.basename(fontproperties[font].filename or "unknown") + local size = fontparameters[font].size or 0 + if command then + context[command](font,name,size) -- size in sp + else + context("[%s: %s @ %p]",font,name,size) + end + return + else + c = c.next + end + end +end + +function step_tracers.codes(i,command) + local c = collection[i] + while c do + local id = c.id + if id == glyph_code then + if command then + local f, c = c.font,c.char + local d = fontdescriptions[f] + local d = d and d[c] + context[command](f,c,d and d.class or "") + else + context("[%s:U+%04X]",c.font,c.char) + end + elseif id == whatsit_code and (c.subtype == localpar_code or c.subtype == dir_code) then + context("[%s]",c.dir) + else + context("[%s]",nodecodes[id]) + end + c = c.next + end +end + +function step_tracers.messages(i,command,split) + local list = messages[i] -- or { "no messages" } + if list then + for i=1,#list do + local l = list[i] + if not command then + context("(%s)",l) + elseif split then + local a, b = match(l,"^(.-)%s*:%s*(.*)$") + context[command](a or l or "",b or "") + else + context[command](l) + end + end + end +end + +-- hooks into the node list processor (see otf) + +function step_tracers.check(head) + if collecting then + step_tracers.reset() + local n = copy_node_list(head) + injections.handler(n,nil,"trace",true) + handlers.protectglyphs(n) -- can be option + collection[1] = n + end +end + +function step_tracers.register(head) + if collecting then + local nc = #collection+1 + if messages[nc] then + local n = copy_node_list(head) + injections.handler(n,nil,"trace",true) + handlers.protectglyphs(n) -- can be option + collection[nc] = n + end + end +end + +function step_tracers.message(str,...) + str = formatter(str,...) + if collecting then + local n = #collection + 1 + local m = messages[n] + if not m then m = { } messages[n] = m end + m[#m+1] = str + end + return str -- saves an intermediate var in the caller +end + +-- + +local threshold = 65536 + +local function toutf(list,result,nofresult,stopcriterium) + if list then + for n in traverse_nodes(list) do + local id = n.id + if id == glyph_code then + local components = n.components + if components then + result, nofresult = toutf(components,result,nofresult) + else + local c = n.char + local fc = fontcharacters[n.font] + if fc then + local u = fc[c].tounicode + if u then + for s in gmatch(u,"....") do + nofresult = nofresult + 1 + result[nofresult] = utfchar(tonumber(s,16)) + end + else + nofresult = nofresult + 1 + result[nofresult] = utfchar(c) + end + else + nofresult = nofresult + 1 + result[nofresult] = utfchar(c) + end + end + elseif id == disc_code then + result, nofresult = toutf(n.replace,result,nofresult) -- needed? + elseif id == hlist_code or id == vlist_code then + -- if nofresult > 0 and result[nofresult] ~= " " then + -- nofresult = nofresult + 1 + -- result[nofresult] = " " + -- end + result, nofresult = toutf(n.list,result,nofresult) + elseif id == glue_code then + if nofresult > 0 and result[nofresult] ~= " " then + nofresult = nofresult + 1 + result[nofresult] = " " + end + elseif id == kern_code and n.kern > threshold then + if nofresult > 0 and result[nofresult] ~= " " then + nofresult = nofresult + 1 + result[nofresult] = " " + end + end + if n == stopcriterium then + break + end + end + end + if nofresult > 0 and result[nofresult] == " " then + result[nofresult] = nil + nofresult = nofresult - 1 + end + return result, nofresult +end + +function nodes.toutf(list,stopcriterium) + local result, nofresult = toutf(list,{},0,stopcriterium) + return concat(result) +end diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua index a13d3bc2c..b80241a06 100644 --- a/tex/context/base/font-ota.lua +++ b/tex/context/base/font-ota.lua @@ -12,7 +12,7 @@ local type = type if not trackers then trackers = { register = function() end } end -local trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end) +----- trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end) local fonts, nodes, node = fonts, nodes, node @@ -89,12 +89,12 @@ analyzers.features = features function analyzers.setstate(head,font) local useunicodemarks = analyzers.useunicodemarks local tfmdata = fontdata[font] - local characters = tfmdata.characters local descriptions = tfmdata.descriptions local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean while current do local id = current.id if id == glyph_code and current.font == font then + done = true local char = current.char local d = descriptions[char] if d then diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index 3b0e44e17..90f053bcc 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -123,10 +123,11 @@ results in different tables.

-- Todo: make plugin feature that operates on char/glyphnode arrays local concat, insert, remove = table.concat, table.insert, table.remove -local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip +local gmatch, gsub, find, match, lower, strip = string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring = type, next, tonumber, tostring local lpegmatch = lpeg.match local random = math.random +local formatters = string.formatters local logs, trackers, nodes, attributes = logs, trackers, nodes, attributes @@ -271,7 +272,6 @@ local function logwarning(...) report_direct(...) end -local formatters = string.formatters local f_unicode = formatters["%U"] local f_uniname = formatters["%U (%s)"] local f_unilist = formatters["% t (% t)"] @@ -464,41 +464,36 @@ function handlers.gsub_single(head,start,kind,lookupname,replacement) return head, start, true end -local function get_alternative_glyph(start,alternatives,value) - -- needs checking: (global value, brrr) - local choice = nil - local n = #alternatives - local char = start.char - -- +local function get_alternative_glyph(start,alternatives,value,trace_alternatives) + local n = #alternatives if value == "random" then local r = random(1,n) - value, choice = format("random, choice %s",r), alternatives[r] + return alternatives[r], trace_alternatives and formatters["value %a, taking %a"](value,r) elseif value == "first" then - value, choice = format("first, choice %s",1), alternatives[1] + return alternatives[1], trace_alternatives and formatters["value %a, taking %a"](value,1) elseif value == "last" then - value, choice = format("last, choice %s",n), alternatives[n] + return alternatives[n], trace_alternatives and formatters["value %a, taking %a"](value,n) else value = tonumber(value) if type(value) ~= "number" then - value, choice = "default, choice 1", alternatives[1] + return alternatives[1], trace_alternatives and formatters["invalid value %s, taking %a"](value,1) elseif value > n then local defaultalt = otf.defaultnodealternate if defaultalt == "first" then - value, choice = format("no %s variants, taking %s",value,n), alternatives[n] + return alternatives[n], trace_alternatives and formatters["invalid value %s, taking %a"](value,1) elseif defaultalt == "last" then - value, choice = format("no %s variants, taking %s",value,1), alternatives[1] + return alternatives[1], trace_alternatives and formatters["invalid value %s, taking %a"](value,n) else - value, choice = format("no %s variants, ignoring",value), false + return false, trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") end elseif value == 0 then - value, choice = format("choice %s (no change)",value), char + return start.char, trace_alternatives and formatters["invalid value %a, %s"](value,"no change") elseif value < 1 then - value, choice = format("no %s variants, taking %s",value,1), alternatives[1] + return alternatives[1], trace_alternatives and formatters["invalid value %a, taking %a"](value,1) else - value, choice = format("choice %s",value), alternatives[value] + return alternatives[value], trace_alternatives and formatters["value %a, taking %a"](value,value) end end - return choice end local function multiple_glyphs(head,start,multiple) -- marks ? @@ -530,15 +525,15 @@ end function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence) local value = featurevalue == true and tfmdata.shared.features[kind] or featurevalue - local choice = get_alternative_glyph(start,alternative,value) + local choice, comment = get_alternative_glyph(start,alternative,value,trace_alternatives) if choice then if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s",pref(kind,lookupname),gref(start.char),choice,gref(choice)) + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(start.char),choice,gref(choice),comment) end start.char = choice else if trace_alternatives then - logwarning("%s: no variant %a for %s",pref(kind,lookupname),value,gref(start.char)) + logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(start.char),comment) end end return head, start, true @@ -674,7 +669,7 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence if ma then local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end return head, start, true @@ -737,7 +732,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ if ba then local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index if trace_marks then - logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)", + logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) end return head, start, true @@ -793,7 +788,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence if ma then local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end return head, start, true @@ -848,7 +843,7 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) if exit then local dx, dy, bound = setcursive(start,nxt,tfmdata.parameters.factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) if trace_cursive then - logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) + logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) end done = true break @@ -878,7 +873,7 @@ function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) local startchar = start.char local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then - logprocess("%s: shifting single %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) end return head, start, false end @@ -910,14 +905,14 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) local startchar = start.char local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then - logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b > 0 then local startchar = start.char local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then - logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end else -- wrong ... position has different entries @@ -1158,19 +1153,19 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext else alternatives = alternatives[currentchar] if alternatives then - local choice = get_alternative_glyph(current,alternatives,value) + local choice, comment = get_alternative_glyph(current,alternatives,value,trace_alternatives) if choice then if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice)) + logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment) end start.char = choice else if trace_alternatives then - logwarning("%s: no variant %a for %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char)) + logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment) end end elseif trace_bugs then - logwarning("%s: no alternative for %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar)) + logwarning("%s: no alternative for %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar),comment) end end return head, start, true @@ -1304,7 +1299,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext if ma then local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end return head, start, true @@ -1372,7 +1367,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon if ba then local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) end return head, start, true @@ -1435,7 +1430,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext if ma then local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end return head, start, true @@ -1499,7 +1494,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l if exit then local dx, dy, bound = setcursive(start,nxt,tfmdata.parameters.factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) if trace_cursive then - logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) + logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) end done = true break @@ -1538,7 +1533,7 @@ function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lo if kerns then local dx, dy, w, h = setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then - logprocess("%s: shifting single %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) end end end @@ -1577,14 +1572,14 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look local startchar = start.char local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then - logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b > 0 then local startchar = start.char local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then - logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end else diff --git a/tex/context/base/font-ott.lua b/tex/context/base/font-ott.lua index c5430a828..8a5579c02 100644 --- a/tex/context/base/font-ott.lua +++ b/tex/context/base/font-ott.lua @@ -788,7 +788,7 @@ setmetatablenewindex(features, assign) local checkers = { rand = function(v) - return v and "random" + return v == true and "random" or v end } diff --git a/tex/context/base/font-tra.mkiv b/tex/context/base/font-tra.mkiv index e838d4938..d1778c15d 100644 --- a/tex/context/base/font-tra.mkiv +++ b/tex/context/base/font-tra.mkiv @@ -120,6 +120,11 @@ \doif{#3}{mark}{\underbar}{U+\hexnumber{#2}}:\ruledhbox{\ctxlua{nodes.tracers.fontchar(#1,#2)}}% \hskip.5\emwidth \s!plus .125\emwidth\relax} +\unexpanded\def\otfstepfontcommand#1#2#3% id font size + {\begingroup + \tttf #1: #2 @ \the\dimexpr#3\scaledpoint\relax + \endgroup} + \unexpanded\def\otfstepmessagecommand#1#2% {\begingroup \tttf\language\minusone @@ -128,11 +133,14 @@ \forgeteverypar \hangindent\emwidth \hangafter\plusone - \dontleavehmode\hbox{\detokenize{#1}}\removeunwantedspaces - \doifsomething{#2}{\break\detokenize{#2}}\endgraf + \dontleavehmode\detokenize{#1}\removeunwantedspaces + \doifsomething{#2}{,\space\detokenize{#2}}\endgraf \endgroup \blank} +\unexpanded\def\showotfstepfont + {\ctxlua{nodes.tracers.steppers.font("otfstepfontcommand")}} + \unexpanded\def\showotfstepchars#1% {\ctxlua{nodes.tracers.steppers.codes(#1,"otfstepcharcommand")}} @@ -142,30 +150,93 @@ \unexpanded\def\showotfstepfeatures {\ctxlua{nodes.tracers.steppers.features()}} +\unexpanded\def\otfnoffeaturesteps + {\ctxlua{nodes.tracers.steppers.nofsteps()}} + +% \unexpanded\def\showotfsteps +% {\begingroup +% \veryraggedright +% \forgetparindent +% \forgeteverypar +% \dontleavehmode\bgroup\tttf \language\minusone features: \showotfstepfeatures\egroup +% \blank +% \dontleavehmode\bgroup\tttf result:\egroup +% \blank +% \startlinecorrection +% \ruledhbox\bgroup\box\otfcompositionbox\egroup +% \stoplinecorrection +% \dorecurse\otfnoffeaturesteps +% {\blank +% \showotfstepmessages\recurselevel +% \blank +% \startlinecorrection +% \dontleavehmode\bgroup\resetallattributes\pardir TLT\textdir TLT\relax\tttf\recurselevel: \showotfstepchars\recurselevel\egroup +% \stoplinecorrection +% \blank +% \startlinecorrection +% \ruledhbox % can be mode +% \bgroup\resetallattributes\showotfstepglyphs\recurselevel\egroup % reset is new, we don't want additional processing +% \stoplinecorrection +% \blank}% +% \endgroup} + \unexpanded\def\showotfsteps {\begingroup \veryraggedright \forgetparindent \forgeteverypar - \dontleavehmode\bgroup\tttf \language\minusone features: \showotfstepfeatures\egroup + \tt + \hbox to \hsize \bgroup + \hbox to 6\emwidth{\bf font\hss}% + \vtop \bgroup + \hsize\dimexpr\hsize-6\emwidth\relax + \language\minusone + \bf + \showotfstepfont + \egroup + \egroup \blank - \dontleavehmode\bgroup\tttf result:\egroup + \hbox to \hsize \bgroup + \hbox to 6\emwidth{\bf features\hss}% + \vtop \bgroup + \hsize\dimexpr\hsize-6\emwidth\relax + \language\minusone + \showotfstepfeatures + \egroup + \egroup \blank - \startlinecorrection - \ruledhbox\bgroup\box\otfcompositionbox\egroup - \stoplinecorrection - \dorecurse{\ctxlua{nodes.tracers.steppers.nofsteps()}} + \scratchcounter\otfnoffeaturesteps\relax + \dorecurse\scratchcounter {\blank - \showotfstepmessages\recurselevel - \blank - \startlinecorrection - \dontleavehmode\bgroup\resetallattributes\pardir TLT\textdir TLT\relax\tttf\recurselevel: \showotfstepchars\recurselevel\egroup - \stoplinecorrection + \begingroup + \advance\leftskip6\emwidth + \showotfstepmessages\recurselevel + \par + \endgroup \blank - \startlinecorrection - \ruledhbox % can be mode - \bgroup\resetallattributes\showotfstepglyphs\recurselevel\egroup % reset is new, we don't want additional processing - \stoplinecorrection + \dontleavehmode + \hbox to \hsize \bgroup + \hbox to 6\emwidth \bgroup + \bf + \ifnum\recurselevel=\scratchcounter result\else step \recurselevel\fi + \hss + \egroup + \vtop \bgroup + \hsize\dimexpr\hsize-6\emwidth\relax + \resetallattributes + \pardir TLT\textdir TLT\relax + \dontleavehmode + \ifnum\recurselevel=\scratchcounter + \ruledhbox{\box\otfcompositionbox}% + \else + \ruledhbox{\showotfstepglyphs\recurselevel}% + \fi + \quad + \showotfstepchars\recurselevel + \hfill + \par + \egroup + \egroup \blank}% \endgroup} @@ -198,10 +269,10 @@ \unexpanded\def\showotfcomposition#1#2#3% {font*features at size}, rl=-1, text {\begingroup - \veryraggedright \forgetparindent \forgeteverypar - \setupcolors[\c!state=\v!start]% can be option + \setupcolors[\c!state=\v!start]% + \setupalign[\v!verytolerant,\v!flushleft]% \startotfsample \global\setbox\otfcompositionbox\hbox{\definedfont[#1]\relax\getvalue{\??otfcompositiondir#2}\relax#3}% \stopotfsample diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua index 9f51c644f..323c73b69 100644 --- a/tex/context/base/l-lpeg.lua +++ b/tex/context/base/l-lpeg.lua @@ -505,9 +505,11 @@ end -- utf extensies +utf = utf or (unicode and unicode.utf8) or { } + local utfcharacters = utf and utf.characters or string.utfcharacters -local utfgmatch = unicode and unicode.utf8.gmatch -local utfchar = utf and utf.char or (unicode and unicode.utf8 and unicode.utf8.char) +local utfgmatch = utf and utf.gmatch +local utfchar = utf and utf.char lpeg.UP = lpeg.P diff --git a/tex/context/base/node-ini.mkiv b/tex/context/base/node-ini.mkiv index 4eeafe442..12798e161 100644 --- a/tex/context/base/node-ini.mkiv +++ b/tex/context/base/node-ini.mkiv @@ -26,10 +26,8 @@ \registerctxluafile{node-tsk}{1.001} \registerctxluafile{node-tex}{1.001} \registerctxluafile{node-pro}{1.001} -%registerctxluafile{node-shp}{1.001} % moved to node-fin.mkiv \registerctxluafile{node-ser}{1.001} \registerctxluafile{node-ext}{1.001} -%registerctxluafile{node-inj}{1.001} % we might split it off \registerctxluafile{node-acc}{1.001} % experimental %registerctxluafile{node-prp}{1.001} % makes no sense (yet) diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua index 48d6310b0..10d44a4cc 100644 --- a/tex/context/base/node-tra.lua +++ b/tex/context/base/node-tra.lua @@ -12,341 +12,54 @@ might become a runtime module instead. This module will be cleaned up!

--ldx]]-- local utfchar = utf.char -local concat = table.concat local format, match, gmatch, concat, rep = string.format, string.match, string.gmatch, table.concat, string.rep local lpegmatch = lpeg.match local clock = os.gettimeofday or os.clock -- should go in environment local report_nodes = logs.reporter("nodes","tracing") -fonts = fonts or { } nodes = nodes or { } -local fonts, nodes, node, context = fonts, nodes, node, context +local nodes, node, context = nodes, node, context -nodes.tracers = nodes.tracers or { } -local tracers = nodes.tracers +local tracers = nodes.tracers or { } +nodes.tracers = tracers -nodes.tasks = nodes.tasks or { } -local tasks = nodes.tasks +local tasks = nodes.tasks or { } +nodes.tasks = tasks -nodes.handlers = nodes.handlers or { } -local handlers = nodes.handlers +local handlers = nodes.handlers or {} +nodes.handlers = handlers -nodes.injections = nodes.injections or { } -local injections = nodes.injections +local injections = nodes.injections or { } +nodes.injections = injections -tracers.characters = tracers.characters or { } -tracers.steppers = tracers.steppers or { } +local traverse_nodes = node.traverse +local traverse_by_id = node.traverse_id +local count_nodes = nodes.count -local char_tracers = tracers.characters -local step_tracers = tracers.steppers +local nodecodes = nodes.nodecodes +local whatcodes = nodes.whatcodes +local skipcodes = nodes.skipcodes +local fillcodes = nodes.fillcodes -local copy_node_list = node.copy_list -local hpack_node_list = node.hpack -local free_node_list = node.flush_list -local traverse_nodes = node.traverse -local traverse_by_id = node.traverse_id -local count_nodes = nodes.count +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local disc_code = nodecodes.disc +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern +local rule_code = nodecodes.rule +local whatsit_code = nodecodes.whatsit +local spec_code = nodecodes.glue_spec -local nodecodes = nodes.nodecodes -local whatcodes = nodes.whatcodes -local skipcodes = nodes.skipcodes -local fillcodes = nodes.fillcodes +local localpar_code = whatcodes.localpar +local dir_code = whatcodes.dir -local glyph_code = nodecodes.glyph -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local disc_code = nodecodes.disc -local glue_code = nodecodes.glue -local kern_code = nodecodes.kern -local rule_code = nodecodes.rule -local whatsit_code = nodecodes.whatsit -local spec_code = nodecodes.glue_spec +local nodepool = nodes.pool -local localpar_code = whatcodes.localpar -local dir_code = whatcodes.dir - -local nodepool = nodes.pool - -local new_glyph = nodepool.glyph - -local dimenfactors = number.dimenfactors -local formatters = string.formatters - -function char_tracers.collect(head,list,tag,n) - local fontdata = fonts.hashes.identifiers - n = n or 0 - local ok, fn = false, nil - while head do - local id = head.id - if id == glyph_code then - local f = head.font - if f ~= fn then - ok, fn = false, f - end - local c = head.char - local i = fontdata[f].indices[c] or 0 - if not ok then - ok = true - n = n + 1 - list[n] = list[n] or { } - list[n][tag] = { } - end - local l = list[n][tag] - l[#l+1] = { c, f, i } - elseif id == disc_code then - -- skip - else - ok = false - end - head = head.next - end -end - -function char_tracers.equal(ta, tb) - if #ta ~= #tb then - return false - else - for i=1,#ta do - local a, b = ta[i], tb[i] - if a[1] ~= b[1] or a[2] ~= b[2] or a[3] ~= b[3] then - return false - end - end - end - return true -end - -function char_tracers.string(t) - local tt = { } - for i=1,#t do - tt[i] = utfchar(t[i][1]) - end - return concat(tt,"") -end - -local f_unicode = formatters["%U"] - -function char_tracers.unicodes(t,decimal) - local tt = { } - for i=1,#t do - local n = t[i][1] - if n == 0 then - tt[i] = "-" - elseif decimal then - tt[i] = n - else - tt[i] = f_unicode(n) - end - end - return concat(tt," ") -end - -function char_tracers.indices(t,decimal) - local tt = { } - for i=1,#t do - local n = t[i][3] - if n == 0 then - tt[i] = "-" - elseif decimal then - tt[i] = n - else - tt[i] = f_unicode(n) - end - end - return concat(tt," ") -end - -function char_tracers.start() - local npc = handlers.characters - local list = { } - function handlers.characters(head) - local n = #list - char_tracers.collect(head,list,'before',n) - local h, d = npc(head) - char_tracers.collect(head,list,'after',n) - if #list > n then - list[#list+1] = { } - end - return h, d - end - function char_tracers.stop() - tracers.list['characters'] = list - local variables = { - ['title'] = 'ConTeXt Character Processing Information', - ['color-background-one'] = lmx.get('color-background-yellow'), - ['color-background-two'] = lmx.get('color-background-purple'), - } - lmx.show('context-characters.lmx',variables) - handlers.characters = npc - tasks.restart("processors", "characters") - end - tasks.restart("processors", "characters") -end - -local stack = { } - -function tracers.start(tag) - stack[#stack+1] = tag - local tracer = tracers[tag] - if tracer and tracer.start then - tracer.start() - end -end -function tracers.stop() - local tracer = stack[#stack] - if tracer and tracer.stop then - tracer.stop() - end - stack[#stack] = nil -end - --- experimental - -local collection, collecting, messages = { }, false, { } - -function step_tracers.start() - collecting = true -end - -function step_tracers.stop() - collecting = false -end - -function step_tracers.reset() - for i=1,#collection do - local c = collection[i] - if c then - free_node_list(c) - end - end - collection, messages = { }, { } -end - -function step_tracers.nofsteps() - return context(#collection) -end - -function step_tracers.glyphs(n,i) -- no need for hpack - local c = collection[i] - if c then - tex.box[n] = hpack_node_list(copy_node_list(c)) - end -end - -function step_tracers.features() - -- we cannot use first_glyph here as it only finds characters with subtype < 256 - local fontdata = fonts.hashes.identifiers - local f = collection[1] - while f do - if f.id == glyph_code then - local tfmdata, t = fontdata[f.font], { } - for feature, value in table.sortedhash(tfmdata.shared.features) do - if feature == "number" or feature == "features" then - -- private - elseif type(value) == "boolean" then - if value then - t[#t+1] = formatters["%s=yes"](feature) - else - -- skip - end - else - t[#t+1] = formatters["%s=%s"](feature,value) - end - end - if #t > 0 then - context(concat(t,", ")) - else - context("no features") - end - return - end - f = f.next - end -end - -function tracers.fontchar(font,char) - local fontchar = fonts.hashes.characters - local n = new_glyph() - n.font, n.char, n.subtype = font, char, 256 - context(n) -end - -function step_tracers.codes(i,command) - local fontdata = fonts.hashes.identifiers - local c = collection[i] - while c do - local id = c.id - if id == glyph_code then - if command then - local f, c = c.font,c.char - local d = fontdata[f].descriptions - local d = d and d[c] - context[command](f,c,d and d.class or "") - else - context("[%s:U+%04X]",c.font,c.char) - end - elseif id == whatsit_code and (c.subtype == localpar_code or c.subtype == dir_code) then - context("[%s]",c.dir) - else - context("[%s]",nodecodes[id]) - end - c = c.next - end -end - -function step_tracers.messages(i,command,split) - local list = messages[i] -- or { "no messages" } - if list then - for i=1,#list do - local l = list[i] - if not command then - context("(%s)",l) - elseif split then - local a, b = match(l,"^(.-)%s*:%s*(.*)$") - context[command](a or l or "",b or "") - else - context[command](l) - end - end - end -end - --- hooks into the node list processor (see otf) - -function step_tracers.check(head) - if collecting then - step_tracers.reset() - local n = copy_node_list(head) - injections.handler(n,nil,"trace",true) - handlers.protectglyphs(n) -- can be option - collection[1] = n - end -end - -function step_tracers.register(head) - if collecting then - local nc = #collection+1 - if messages[nc] then - local n = copy_node_list(head) - injections.handler(n,nil,"trace",true) - handlers.protectglyphs(n) -- can be option - collection[nc] = n - end - end -end - -function step_tracers.message(str,...) - str = format(str,...) -- maybe: formatters[str](...) - if collecting then - local n = #collection + 1 - local m = messages[n] - if not m then m = { } messages[n] = m end - m[#m+1] = str - end - return str -- saves an intermediate var in the caller -end +local dimenfactors = number.dimenfactors +local formatters = string.formatters -- this will be reorganized: @@ -589,72 +302,6 @@ end nodes.showboxes = showboxes -local threshold = 65536 - -local function toutf(list,result,nofresult,stopcriterium) - if list then - local fontchar = fonts.hashes.characters - for n in traverse_nodes(list) do - local id = n.id - if id == glyph_code then - local components = n.components - if components then - result, nofresult = toutf(components,result,nofresult) - else - local c = n.char - local fc = fontchar[n.font] - if fc then - local u = fc[c].tounicode - if u then - for s in gmatch(u,"....") do - nofresult = nofresult + 1 - result[nofresult] = utfchar(tonumber(s,16)) - end - else - nofresult = nofresult + 1 - result[nofresult] = utfchar(c) - end - else - nofresult = nofresult + 1 - result[nofresult] = utfchar(c) - end - end - elseif id == disc_code then - result, nofresult = toutf(n.replace,result,nofresult) -- needed? - elseif id == hlist_code or id == vlist_code then ---~ if nofresult > 0 and result[nofresult] ~= " " then ---~ nofresult = nofresult + 1 ---~ result[nofresult] = " " ---~ end - result, nofresult = toutf(n.list,result,nofresult) - elseif id == glue_code then - if nofresult > 0 and result[nofresult] ~= " " then - nofresult = nofresult + 1 - result[nofresult] = " " - end - elseif id == kern_code and n.kern > threshold then - if nofresult > 0 and result[nofresult] ~= " " then - nofresult = nofresult + 1 - result[nofresult] = " " - end - end - if n == stopcriterium then - break - end - end - end - if nofresult > 0 and result[nofresult] == " " then - result[nofresult] = nil - nofresult = nofresult - 1 - end - return result, nofresult -end - -function nodes.toutf(list,stopcriterium) - local result, nofresult = toutf(list,{},0,stopcriterium) - return concat(result) -end - local ptfactor = dimenfactors.pt local bpfactor = dimenfactors.bp local stripper = lpeg.patterns.stripzeros diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index a748fb0dd..4c889c2da 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index cc6dd9a7c..2c2d5e0ed 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/status-mkiv.lua b/tex/context/base/status-mkiv.lua index 13ec83255..32ae00cd3 100644 --- a/tex/context/base/status-mkiv.lua +++ b/tex/context/base/status-mkiv.lua @@ -3110,6 +3110,12 @@ return { loading = "font-lib", status = "okay", }, + { + category = "mkvi", + filename = "font-hsh", + loading = "always", + status = "okay", + }, { category = "lua", filename = "font-ini", @@ -3148,6 +3154,12 @@ return { loading = "on demand", status = "okay", }, + { + category = "mkvi", + filename = "font-nod", + loading = "always", + status = "okay", + }, { category = "lua", comment = "when more scripts are supported we might end up with imp files", diff --git a/tex/context/base/symb-ini.lua b/tex/context/base/symb-ini.lua index 9b3f55d2f..deeef667a 100644 --- a/tex/context/base/symb-ini.lua +++ b/tex/context/base/symb-ini.lua @@ -9,8 +9,10 @@ if not modules then modules = { } end modules ['symb-ini'] = { local variables = interfaces.variables -fonts.symbols = fonts.symbols or { } -local symbols = fonts.symbols +fonts = fonts or { } -- brrrr + +local symbols = fonts.symbols or { } +fonts.symbols = symbols local report_symbols = logs.reporter ("fonts","symbols") local status_symbols = logs.messenger("fonts","symbols") diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua index 9efdae4d6..ecf36b137 100644 --- a/tex/context/base/util-tab.lua +++ b/tex/context/base/util-tab.lua @@ -28,12 +28,12 @@ function tables.definetable(target,nofirst,nolast) -- defines undefined tables if composed then composed = shortcut .. "." .. name shortcut = shortcut .. "_" .. name - t[#t+1] = format("local %s = %s if not %s then %s = { } %s = %s end",shortcut,composed,shortcut,shortcut,composed,shortcut) + t[#t+1] = formatters["local %s = %s if not %s then %s = { } %s = %s end"](shortcut,composed,shortcut,shortcut,composed,shortcut) else composed = name shortcut = name if not nofirst then - t[#t+1] = format("%s = %s or { }",composed,composed) + t[#t+1] = formatters["%s = %s or { }"](composed,composed) end end end @@ -269,7 +269,7 @@ function tables.encapsulate(core,capsule,protect) end for key, value in next, core do if capsule[key] then - print(format("\ninvalid inheritance '%s' in '%s': %s",key,tostring(core))) + print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core)) os.exit() else capsule[key] = value @@ -283,7 +283,7 @@ function tables.encapsulate(core,capsule,protect) __index = capsule, __newindex = function(t,key,value) if capsule[key] then - print(format("\ninvalid overload '%s' in '%s'",key,tostring(core))) + print(formatters["\ninvalid %s %a' in %a"]("overload",key,core)) os.exit() else rawset(t,key,value) @@ -433,11 +433,11 @@ local function slowdrop(t) local j = 0 for k, v in next, ti do j = j + 1 - l[j] = format("%s=%q",k,v) + l[j] = formatters["%s=%q"](k,v) end - r[i] = format(" {%s},\n",concat(l)) + r[i] = formatters[" {%t},\n"](l) end - return format("return {\n%s}",concat(r)) + return formatters["return {\n%st}"](r) end local function fastdrop(t) @@ -446,7 +446,7 @@ local function fastdrop(t) local ti = t[i] r[#r+1] = " {" for k, v in next, ti do - r[#r+1] = format("%s=%q",k,v) + r[#r+1] = formatters["%s=%q"](k,v) end r[#r+1] = "},\n" end @@ -454,7 +454,7 @@ local function fastdrop(t) return concat(r) end -function table.drop(t,slow) +function table.drop(t,slow) -- only { { a=2 }, {a=3} } if #t == 0 then return "return { }" elseif slow == true then diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 2a3cf950d..007e762f0 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 03/17/13 13:31:17 +-- merge date : 03/18/13 18:49:25 do -- begin closure to overcome local limits and interference @@ -558,9 +558,10 @@ function lpeg.counter(pattern) return #lpegmatch(pattern,str) end end +utf=utf or (unicode and unicode.utf8) or {} local utfcharacters=utf and utf.characters or string.utfcharacters -local utfgmatch=unicode and unicode.utf8.gmatch -local utfchar=utf and utf.char or (unicode and unicode.utf8 and unicode.utf8.char) +local utfgmatch=utf and utf.gmatch +local utfchar=utf and utf.char lpeg.UP=lpeg.P if utfcharacters then function lpeg.US(str) @@ -7932,7 +7933,6 @@ if not modules then modules={} end modules ['font-ota']={ } local type=type if not trackers then trackers={ register=function() end } end -local trace_analyzing=false trackers.register("otf.analyzing",function(v) trace_analyzing=v end) local fonts,nodes,node=fonts,nodes,node local allocate=utilities.storage.allocate local otf=fonts.handlers.otf @@ -7983,12 +7983,12 @@ analyzers.features=features function analyzers.setstate(head,font) local useunicodemarks=analyzers.useunicodemarks local tfmdata=fontdata[font] - local characters=tfmdata.characters local descriptions=tfmdata.descriptions local first,last,current,n,done=nil,nil,head,0,false while current do local id=current.id if id==glyph_code and current.font==font then + done=true local char=current.char local d=descriptions[char] if d then @@ -8247,10 +8247,11 @@ if not modules then modules={} end modules ['font-otn']={ license="see context related readme files", } local concat,insert,remove=table.concat,table.insert,table.remove -local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip +local gmatch,gsub,find,match,lower,strip=string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip local type,next,tonumber,tostring=type,next,tonumber,tostring local lpegmatch=lpeg.match local random=math.random +local formatters=string.formatters local logs,trackers,nodes,attributes=logs,trackers,nodes,attributes local registertracker=trackers.register local fonts=fonts @@ -8354,7 +8355,6 @@ end local function logwarning(...) report_direct(...) end -local formatters=string.formatters local f_unicode=formatters["%U"] local f_uniname=formatters["%U (%s)"] local f_unilist=formatters["% t (% t)"] @@ -8520,39 +8520,36 @@ function handlers.gsub_single(head,start,kind,lookupname,replacement) start.char=replacement return head,start,true end -local function get_alternative_glyph(start,alternatives,value) - local choice=nil +local function get_alternative_glyph(start,alternatives,value,trace_alternatives) local n=#alternatives - local char=start.char if value=="random" then local r=random(1,n) - value,choice=format("random, choice %s",r),alternatives[r] + return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r) elseif value=="first" then - value,choice=format("first, choice %s",1),alternatives[1] + return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1) elseif value=="last" then - value,choice=format("last, choice %s",n),alternatives[n] + return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n) else value=tonumber(value) if type(value)~="number" then - value,choice="default, choice 1",alternatives[1] + return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) elseif value>n then local defaultalt=otf.defaultnodealternate if defaultalt=="first" then - value,choice=format("no %s variants, taking %s",value,n),alternatives[n] + return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) elseif defaultalt=="last" then - value,choice=format("no %s variants, taking %s",value,1),alternatives[1] + return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n) else - value,choice=format("no %s variants, ignoring",value),false + return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") end elseif value==0 then - value,choice=format("choice %s (no change)",value),char + return start.char,trace_alternatives and formatters["invalid value %a, %s"](value,"no change") elseif value<1 then - value,choice=format("no %s variants, taking %s",value,1),alternatives[1] + return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) else - value,choice=format("choice %s",value),alternatives[value] + return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value) end end - return choice end local function multiple_glyphs(head,start,multiple) local nofmultiples=#multiple @@ -8582,15 +8579,15 @@ local function multiple_glyphs(head,start,multiple) end function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence) local value=featurevalue==true and tfmdata.shared.features[kind] or featurevalue - local choice=get_alternative_glyph(start,alternative,value) + local choice,comment=get_alternative_glyph(start,alternative,value,trace_alternatives) if choice then if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s",pref(kind,lookupname),gref(start.char),choice,gref(choice)) + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(start.char),choice,gref(choice),comment) end start.char=choice else if trace_alternatives then - logwarning("%s: no variant %a for %s",pref(kind,lookupname),value,gref(start.char)) + logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(start.char),comment) end end return head,start,true @@ -8716,7 +8713,7 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence if ma then local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end return head,start,true @@ -8776,7 +8773,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ if ba then local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)", + logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) end return head,start,true @@ -8830,7 +8827,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence if ma then local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end return head,start,true @@ -8882,7 +8879,7 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) if exit then local dx,dy,bound=setcursive(start,nxt,tfmdata.parameters.factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) if trace_cursive then - logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) + logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) end done=true break @@ -8910,7 +8907,7 @@ function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) local startchar=start.char local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then - logprocess("%s: shifting single %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) end return head,start,false end @@ -8938,14 +8935,14 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) local startchar=start.char local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then - logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then local startchar=start.char local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then - logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end else @@ -9110,19 +9107,19 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext else alternatives=alternatives[currentchar] if alternatives then - local choice=get_alternative_glyph(current,alternatives,value) + local choice,comment=get_alternative_glyph(current,alternatives,value,trace_alternatives) if choice then if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice)) + logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment) end start.char=choice else if trace_alternatives then - logwarning("%s: no variant %a for %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char)) + logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment) end end elseif trace_bugs then - logwarning("%s: no alternative for %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar)) + logwarning("%s: no alternative for %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar),comment) end end return head,start,true @@ -9246,7 +9243,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext if ma then local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end return head,start,true @@ -9312,7 +9309,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon if ba then local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) end return head,start,true @@ -9371,7 +9368,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext if ma then local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)", + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end return head,start,true @@ -9430,7 +9427,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l if exit then local dx,dy,bound=setcursive(start,nxt,tfmdata.parameters.factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) if trace_cursive then - logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) + logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode) end done=true break @@ -9466,7 +9463,7 @@ function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lo if kerns then local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then - logprocess("%s: shifting single %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) end end end @@ -9500,14 +9497,14 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look local startchar=start.char local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then - logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then local startchar=start.char local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then - logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end else -- cgit v1.2.3