diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/typo-krn.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/typo-krn.lua | 84 |
1 files changed, 44 insertions, 40 deletions
diff --git a/Master/texmf-dist/tex/context/base/typo-krn.lua b/Master/texmf-dist/tex/context/base/typo-krn.lua index d3031633d84..746773e0a88 100644 --- a/Master/texmf-dist/tex/context/base/typo-krn.lua +++ b/Master/texmf-dist/tex/context/base/typo-krn.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['typo-krn'] = { version = 1.001, - comment = "companion to typo-krn.tex", + comment = "companion to typo-krn.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" @@ -28,18 +28,29 @@ local glue = node.id('glue') local hlist = node.id('hlist') local vlist = node.id('vlist') -local fontdata = fonts.ids -local chardata = characters.data +local fontdata = fonts.identifiers +local chardata = fonts.characters +local quaddata = fonts.quads kerns = kerns or { } kerns.mapping = kerns.mapping or { } -kerns.enabled = false +kerns.factors = kerns.factors or { } kerns.attribute = attributes.private("kern") storage.register("kerns/mapping", kerns.mapping, "kerns.mapping") +storage.register("kerns/factors", kerns.factors, "kerns.factors") -function kerns.setspacing(id,factor) - kerns.mapping[id] = factor +local mapping = kerns.mapping +local factors = kerns.factors + +function kerns.setspacing(factor) + local a = factors[factor] + if not a then + a = #mapping + 1 + factors[factors], mapping[a] = a, factor + end + tex.attribute[kerns.attribute] = a + return a end -- one must use liga=no and mode=base and kern=yes @@ -47,12 +58,9 @@ end -- make sure it runs after all others -- there will be a width adaptor field in nodes so this will change -- todo: interchar kerns / disc nodes / can be made faster --- todo: cache quad and so - -local mapping = kerns.mapping local function process(namespace,attribute,head,force) - local scale = tex.scale + local scale = tex.scale -- will go local start, done, lastfont = head, false, nil while start do -- faster to test for attr first @@ -92,21 +100,16 @@ local function process(namespace,attribute,head,force) -- nothing elseif pid == kern and prev.subtype == 0 then prev.subtype = 1 - prev.kern = prev.kern + scale(fontdata[lastfont].parameters.quad,krn) + prev.kern = prev.kern + scale(quaddata[lastfont],krn) done = true elseif pid == glyph then - -- fontdata access can be done more efficient if prev.font == lastfont then local prevchar, lastchar = prev.char, start.char - local tfm = fontdata[lastfont].characters[prevchar] - local ickern = tfm.kerns - if ickern and ickern[lastchar] then - krn = scale(ickern[lastchar]+fontdata[lastfont].parameters.quad,krn) - else - krn = scale(fontdata[lastfont].parameters.quad,krn) - end + local kerns = chardata[lastfont][prevchar].kerns + local kern = kerns and kerns[lastchar] or 0 + krn = scale(kern+quaddata[lastfont],krn) else - krn = scale(fontdata[lastfont].parameters.quad,krn) + krn = scale(quaddata[lastfont],krn) end insert_node_before(head,start,make_kern_node(krn)) done = true @@ -115,9 +118,10 @@ local function process(namespace,attribute,head,force) -- but we could have multiple glyphs involved so ... local disc = prev -- disc local pre, post, replace = disc.pre, disc.post, disc.replace - if pre then -- must pair with start.prev + local prv, nxt = disc.prev, disc.next + if pre and prv then -- must pair with start.prev -- this one happens in most cases - local before = copy_node(disc.prev) + local before = copy_node(prv) pre.prev = before before.next = pre before.prev = nil @@ -127,8 +131,8 @@ local function process(namespace,attribute,head,force) disc.pre = pre free_node(before) end - if post then -- must pair with start - local after = copy_node(disc.next) + if post and nxt then -- must pair with start + local after = copy_node(nxt) local tail = find_node_tail(post) tail.next = after after.prev = tail @@ -138,9 +142,9 @@ local function process(namespace,attribute,head,force) disc.post = post free_node(after) end - if replace then -- must pair with start and start.prev - local before = copy_node(disc.prev) - local after = copy_node(disc.next) + if replace and prv and nxt then -- must pair with start and start.prev + local before = copy_node(prv) + local after = copy_node(nxt) local tail = find_node_tail(replace) replace.prev = before before.next = replace @@ -151,22 +155,18 @@ local function process(namespace,attribute,head,force) replace = process(namespace,attribute,before,attr) replace = replace.next replace.prev = nil - tail.next = nil + after.prev.next = nil disc.replace = replace free_node(after) free_node(before) else - if disc.prev.font == lastfont then - local prevchar, lastchar = disc.prev.char, start.char - local tfm = fontdata[lastfont].characters[prevchar] - local ickern = tfm.kerns - if ickern and ickern[lastchar] then - krn = scale(ickern[lastchar]+fontdata[lastfont].parameters.quad,krn) - else - krn = scale(fontdata[lastfont].parameters.quad,krn) - end + if prv and prv.id == glyph and prv.font == lastfont then + local prevchar, lastchar = prv.char, start.char + local kerns = chardata[lastfont][prevchar].kerns + local kern = kerns and kerns[lastchar] or 0 + krn = scale(kern+quaddata[lastfont],krn) else - krn = scale(fontdata[lastfont].parameters.quad,krn) + krn = scale(quaddata[lastfont],krn) end disc.replace = make_kern_node(krn) end @@ -191,11 +191,11 @@ local function process(namespace,attribute,head,force) end elseif lastfont and (id == hlist or id == vlist) then -- todo: lookahead if start.prev then - insert_node_before(head,start,make_kern_node(scale(fontdata[lastfont].parameters.quad,krn))) + insert_node_before(head,start,make_kern_node(scale(quaddata[lastfont],krn))) done = true end if start.next then - insert_node_after(head,start,make_kern_node(scale(fontdata[lastfont].parameters.quad,krn))) + insert_node_after(head,start,make_kern_node(scale(quaddata[lastfont],krn))) done = true end end @@ -217,3 +217,7 @@ lists.handle_kerning = nodes.install_attribute_handler { namespace = kerns, processor = kerns.process, } + +function kerns.enable() + tasks.enableaction("processors","lists.handle_kerning") +end |