diff options
author | Context Git Mirror Bot <phg42.2a@gmail.com> | 2016-01-12 17:15:07 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2016-01-12 17:15:07 +0100 |
commit | 8d8d528d2ad52599f11250cfc567fea4f37f2a8b (patch) | |
tree | 94286bc131ef7d994f9432febaf03fe23d10eef8 /tex/context/base/mkiv/typo-dig.lua | |
parent | f5aed2e51223c36c84c5f25a6cad238b2af59087 (diff) | |
download | context-8d8d528d2ad52599f11250cfc567fea4f37f2a8b.tar.gz |
2016-01-12 16:26:00
Diffstat (limited to 'tex/context/base/mkiv/typo-dig.lua')
-rw-r--r-- | tex/context/base/mkiv/typo-dig.lua | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/typo-dig.lua b/tex/context/base/mkiv/typo-dig.lua new file mode 100644 index 000000000..09c2f64ee --- /dev/null +++ b/tex/context/base/mkiv/typo-dig.lua @@ -0,0 +1,181 @@ +if not modules then modules = { } end modules ['typo-dig'] = { + version = 1.001, + comment = "companion to typo-dig.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- we might consider doing this after the otf pass because now osf do not work +-- out well in node mode. + +local next, type = next, type +local format, insert = string.format, table.insert +local round, div = math.round, math.div + +local trace_digits = false trackers.register("typesetters.digits", function(v) trace_digits = v end) + +local report_digits = logs.reporter("typesetting","digits") + +local nodes, node = nodes, node + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode + +local getnext = nuts.getnext +local getprev = nuts.getprev +local getfont = nuts.getfont +local getchar = nuts.getchar +local getid = nuts.getid +local getfield = nuts.getfield +local getattr = nuts.getattr + +local setlink = nuts.setlink +local setnext = nuts.setnext +local setprev = nuts.setprev +local setattr = nuts.setattr + +local hpack_node = nuts.hpack +local traverse_id = nuts.traverse_id +local insert_node_before = nuts.insert_before +local insert_node_after = nuts.insert_after + +local texsetattribute = tex.setattribute +local unsetvalue = attributes.unsetvalue + +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph + +local nodepool = nuts.pool +local tasks = nodes.tasks + +local new_glue = nodepool.glue + +local fonthashes = fonts.hashes +local fontdata = fonthashes.identifiers +local chardata = fonthashes.characters +local quaddata = fonthashes.quads + +local v_reset = interfaces.variables.reset + +local charbase = characters.data +local getdigitwidth = fonts.helpers.getdigitwidth + +typesetters = typesetters or { } +local typesetters = typesetters + +typesetters.digits = typesetters.digits or { } +local digits = typesetters.digits + +digits.actions = { } +local actions = digits.actions + +local a_digits = attributes.private("digits") + +-- at some point we can manipulate the glyph node so then i need +-- to rewrite this then + +function nodes.aligned(head,start,stop,width,how) + if how == "flushright" or how == "middle" then + head, start = insert_node_before(head,start,new_glue(0,65536,65536)) + end + if how == "flushleft" or how == "middle" then + head, stop = insert_node_after(head,stop,new_glue(0,65536,65536)) + end + local prv = getprev(start) + local nxt = getnext(stop) + setprev(start) + setnext(stop) + local packed = hpack_node(start,width,"exactly") -- no directional mess here, just lr + if prv then + setlink(prv,packed) + end + if nxt then + setlink(packed,nxt) + end + if getprev(packed) then + return head, packed + else + return packed, packed + end +end + +actions[1] = function(head,start,attr) + local font = getfont(start) + local char = getchar(start) + local unic = chardata[font][char].unicode or char + if charbase[unic].category == "nd" then -- ignore unic tables + local oldwidth = getfield(start,"width") + local newwidth = getdigitwidth(font) + if newwidth ~= oldwidth then + if trace_digits then + report_digits("digit trigger %a, instance %a, char %C, unicode %U, delta %s", + attr%100,div(attr,100),char,unic,newwidth-oldwidth) + end + head, start = nodes.aligned(head,start,start,newwidth,"middle") + return head, start, true + end + end + return head, start, false +end + +function digits.handler(head) + head = tonut(head) + local done, current, ok = false, head, false + while current do + if getid(current) == glyph_code then + local attr = getattr(current,a_digits) + if attr and attr > 0 then + setattr(current,a_digits,unsetvalue) + local action = actions[attr%100] -- map back to low number + if action then + head, current, ok = action(head,current,attr) + done = done and ok + elseif trace_digits then + report_digits("unknown digit trigger %a",attr) + end + end + end + if current then + current = getnext(current) + end + end + return tonode(head), done +end + +local m, enabled = 0, false -- a trick to make neighbouring ranges work + +function digits.set(n) -- number or 'reset' + if n == v_reset then + n = unsetvalue + else + n = tonumber(n) + if n then + if not enabled then + tasks.enableaction("processors","typesetters.digits.handler") + if trace_digits then + report_digits("enabling digit handler") + end + enabled = true + end + if m == 100 then + m = 1 + else + m = m + 1 + end + n = m * 100 + n + else + n = unsetvalue + end + end + texsetattribute(a_digits,n) +end + +-- interface + +interfaces.implement { + name = "setdigitsmanipulation", + actions = digits.set, + arguments = "string" +} |