summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/node-inj.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/node-inj.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/node-inj.lua241
1 files changed, 116 insertions, 125 deletions
diff --git a/Master/texmf-dist/tex/context/base/node-inj.lua b/Master/texmf-dist/tex/context/base/node-inj.lua
index 9c4612a2299..b9ef9188f94 100644
--- a/Master/texmf-dist/tex/context/base/node-inj.lua
+++ b/Master/texmf-dist/tex/context/base/node-inj.lua
@@ -6,8 +6,6 @@ if not modules then modules = { } end modules ['node-inj'] = {
license = "see context related readme files"
}
--- tricky ... fonts.ids is not yet defined .. to be solved (maybe general tex ini)
-
-- This is very experimental (this will change when we have luatex > .50 and
-- a few pending thingies are available. Also, Idris needs to make a few more
-- test fonts. Btw, future versions of luatex will have extended glyph properties
@@ -17,23 +15,28 @@ local next = next
local trace_injections = false trackers.register("nodes.injections", function(v) trace_injections = v end)
-fonts = fonts or { }
-fonts.tfm = fonts.tfm or { }
-fonts.ids = fonts.ids or { }
+local report_injections = logs.reporter("nodes","injections")
+
+local attributes, nodes, node = attributes, nodes, node
+
+fonts = fonts
+local fontdata = fonts.hashes.identifiers
-local fontdata = fonts.ids
+nodes.injections = nodes.injections or { }
+local injections = nodes.injections
-local glyph = node.id('glyph')
-local kern = node.id('kern')
+local nodecodes = nodes.nodecodes
+local glyph_code = nodecodes.glyph
+local nodepool = nodes.pool
+local newkern = nodepool.kern
local traverse_id = node.traverse_id
+local unset_attribute = node.unset_attribute
local has_attribute = node.has_attribute
local set_attribute = node.set_attribute
local insert_node_before = node.insert_before
local insert_node_after = node.insert_after
-local newkern = nodes.kern
-
local markbase = attributes.private('markbase')
local markmark = attributes.private('markmark')
local markdone = attributes.private('markdone')
@@ -53,7 +56,7 @@ local kerns = { }
-- for the moment we pass the r2l key ... volt/arabtype tests
-function nodes.set_cursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext)
+function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext)
local dx, dy = factor*(exit[1]-entry[1]), factor*(exit[2]-entry[2])
local ws, wn = tfmstart.width, tfmnext.width
local bound = #cursives + 1
@@ -63,7 +66,7 @@ function nodes.set_cursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext)
return dx, dy, bound
end
-function nodes.set_pair(current,factor,rlmode,r2lflag,spec,tfmchr)
+function injections.setpair(current,factor,rlmode,r2lflag,spec,tfmchr)
local x, y, w, h = factor*spec[1], factor*spec[2], factor*spec[3], factor*spec[4]
-- dy = y - h
if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then
@@ -82,17 +85,19 @@ function nodes.set_pair(current,factor,rlmode,r2lflag,spec,tfmchr)
return x, y, w, h -- no bound
end
-function nodes.set_kern(current,factor,rlmode,x,tfmchr)
+function injections.setkern(current,factor,rlmode,x,tfmchr)
local dx = factor*x
if dx ~= 0 then
local bound = #kerns + 1
set_attribute(current,kernpair,bound)
kerns[bound] = { rlmode, dx }
+ return dx, bound
+ else
+ return 0, 0
end
- return dx, bound
end
-function nodes.set_mark(start,base,factor,rlmode,ba,ma,index) --ba=baseanchor, ma=markanchor
+function injections.setmark(start,base,factor,rlmode,ba,ma,index) --ba=baseanchor, ma=markanchor
local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2])
local bound = has_attribute(base,markbase)
if bound then
@@ -104,7 +109,7 @@ function nodes.set_mark(start,base,factor,rlmode,ba,ma,index) --ba=baseanchor, m
set_attribute(start,markdone,index)
return dx, dy, bound
else
- logs.report("nodes mark", "possible problem, U+%04X is base without data (id: %s)",base.char,bound)
+ report_injections("possible problem, U+%05X is base mark without data (id: %s)",base.char,bound)
end
end
index = index or 1
@@ -112,19 +117,17 @@ function nodes.set_mark(start,base,factor,rlmode,ba,ma,index) --ba=baseanchor, m
set_attribute(base,markbase,bound)
set_attribute(start,markmark,bound)
set_attribute(start,markdone,index)
- marks[bound] = { [index] = { dx, dy } }
+ marks[bound] = { [index] = { dx, dy, rlmode } }
return dx, dy, bound
end
-function nodes.trace_injection(head)
- local function dir(n)
- return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or ("unset")
- end
- local function report(...)
- logs.report("nodes finisher",...)
- end
- report("begin run")
- for n in traverse_id(glyph,head) do
+local function dir(n)
+ return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset"
+end
+
+local function trace(head)
+ report_injections("begin run")
+ for n in traverse_id(glyph_code,head) do
if n.subtype < 256 then
local kp = has_attribute(n,kernpair)
local mb = has_attribute(n,markbase)
@@ -132,65 +135,70 @@ function nodes.trace_injection(head)
local md = has_attribute(n,markdone)
local cb = has_attribute(n,cursbase)
local cc = has_attribute(n,curscurs)
- report("char U+%05X, font=%s",n.char,n.font)
+ report_injections("char U+%05X, font=%s",n.char,n.font)
if kp then
local k = kerns[kp]
if k[3] then
- report(" pairkern: dir=%s, x=%s, y=%s, w=%s, h=%s",dir(k[1]),k[2] or "?",k[3] or "?",k[4] or "?",k[5] or "?")
+ report_injections(" pairkern: dir=%s, x=%s, y=%s, w=%s, h=%s",dir(k[1]),k[2] or "?",k[3] or "?",k[4] or "?",k[5] or "?")
else
- report(" kern: dir=%s, dx=%s",dir(k[1]),k[2] or "?")
+ report_injections(" kern: dir=%s, dx=%s",dir(k[1]),k[2] or "?")
end
end
if mb then
- report(" markbase: bound=%s",mb)
+ report_injections(" markbase: bound=%s",mb)
end
if mm then
local m = marks[mm]
if mb then
local m = m[mb]
if m then
- report(" markmark: bound=%s, index=%s, dx=%s, dy=%s",mm,md or "?",m[1] or "?",m[2] or "?")
+ report_injections(" markmark: bound=%s, index=%s, dx=%s, dy=%s",mm,md or "?",m[1] or "?",m[2] or "?")
else
- report(" markmark: bound=%s, missing index",mm)
+ report_injections(" markmark: bound=%s, missing index",mm)
end
else
m = m[1]
- report(" markmark: bound=%s, dx=%s, dy=%s",mm,m[1] or "?",m[2] or "?")
+ report_injections(" markmark: bound=%s, dx=%s, dy=%s",mm,m[1] or "?",m[2] or "?")
end
end
if cb then
- report(" cursbase: bound=%s",cb)
+ report_injections(" cursbase: bound=%s",cb)
end
if cc then
local c = cursives[cc]
- report(" curscurs: bound=%s, dir=%s, dx=%s, dy=%s",cc,dir(c[1]),c[2] or "?",c[3] or "?")
+ report_injections(" curscurs: bound=%s, dir=%s, dx=%s, dy=%s",cc,dir(c[1]),c[2] or "?",c[3] or "?")
end
end
end
- report("end run")
+ report_injections("end run")
end
-- todo: reuse tables (i.e. no collection), but will be extra fields anyway
+-- todo: check for attribute
-function nodes.inject_kerns(head,where,keep)
+-- we can have a fast test on a font being processed, so we can check faster for marks etc
+
+function injections.handler(head,where,keep)
local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns)
if has_marks or has_cursives then
---~ if has_marks or has_cursives or has_kerns then
if trace_injections then
- nodes.trace_injection(head)
+ trace(head)
end
-- in the future variant we will not copy items but refs to tables
- local done, ky, rl, valid, cx, wx, mk = false, { }, { }, { }, { }, { }, { }
+ local done, ky, rl, valid, cx, wx, mk, nofvalid = false, { }, { }, { }, { }, { }, { }, 0
if has_kerns then -- move outside loop
local nf, tm = nil, nil
- for n in traverse_id(glyph,head) do
+ for n in traverse_id(glyph_code,head) do -- only needed for relevant fonts
if n.subtype < 256 then
- valid[#valid+1] = n
+ nofvalid = nofvalid + 1
+ valid[nofvalid] = n
if n.font ~= nf then
nf = n.font
- tm = fontdata[nf].marks
+ tm = fontdata[nf].resources.marks
+ end
+ if tm then
+ mk[n] = tm[n.char]
end
- mk[n] = tm[n.char]
local k = has_attribute(n,kernpair)
if k then
local kk = kerns[k]
@@ -210,18 +218,21 @@ function nodes.inject_kerns(head,where,keep)
end
else
local nf, tm = nil, nil
- for n in traverse_id(glyph,head) do
+ for n in traverse_id(glyph_code,head) do
if n.subtype < 256 then
- valid[#valid+1] = n
+ nofvalid = nofvalid + 1
+ valid[nofvalid] = n
if n.font ~= nf then
nf = n.font
- tm = fontdata[nf].marks
+ tm = fontdata[nf].resources.marks
+ end
+ if tm then
+ mk[n] = tm[n.char]
end
- mk[n] = tm[n.char]
end
end
end
- if #valid > 0 then
+ if nofvalid > 0 then
-- we can assume done == true because we have cursives and marks
local cx = { }
if has_kerns and next(ky) then
@@ -234,7 +245,7 @@ function nodes.inject_kerns(head,where,keep)
local p_cursbase, p = nil, nil
-- since we need valid[n+1] we can also use a "while true do"
local t, d, maxt = { }, { }, 0
- for i=1,#valid do -- valid == glyphs
+ for i=1,nofvalid do -- valid == glyphs
local n = valid[i]
if not mk[n] then
local n_cursbase = has_attribute(n,cursbase)
@@ -298,28 +309,42 @@ function nodes.inject_kerns(head,where,keep)
end
end
if has_marks then
- for i=1,#valid do
+ for i=1,nofvalid do
local p = valid[i]
local p_markbase = has_attribute(p,markbase)
if p_markbase then
local mrks = marks[p_markbase]
- for n in traverse_id(glyph,p.next) do
+ for n in traverse_id(glyph_code,p.next) do
local n_markmark = has_attribute(n,markmark)
if p_markbase == n_markmark then
local index = has_attribute(n,markdone) or 1
local d = mrks[index]
if d then
- -- local rlmode = d[3] -- not used
- -- if rlmode and rlmode > 0 then
- -- todo
- -- else
+ local rlmode = d[3]
+ if rlmode and rlmode >= 0 then
+ -- new per 2010-10-06, width adapted per 2010-02-03
+ -- we used to negate the width of marks because in tfm
+ -- that makes sense but we no longer do that so as a
+ -- consequence the sign of p.width was changed (we need
+ -- to keep an eye on it as we don't have that many fonts
+ -- that enter this branch .. i'm still not sure if this
+ -- one is right
+ local k = wx[p]
+ if k then
+ n.xoffset = p.xoffset + p.width + d[1] - k[2]
+ else
+ -- n.xoffset = p.xoffset + p.width + d[1]
+ -- lucida U\char"032F (default+mark)
+ n.xoffset = p.xoffset - p.width + d[1] -- 01-05-2011
+ end
+ else
local k = wx[p]
if k then
n.xoffset = p.xoffset - d[1] - k[2]
else
n.xoffset = p.xoffset - d[1]
end
- -- end
+ end
if mk[p] then
n.yoffset = p.yoffset + d[2]
else
@@ -342,39 +367,21 @@ function nodes.inject_kerns(head,where,keep)
-- only w can be nil, can be sped up when w == nil
local rl, x, w, r2l = k[1], k[2] or 0, k[4] or 0, k[6]
local wx = w - x
---~ if rl < 0 then
---~ if r2l then
---~ if wx ~= 0 then
---~ insert_node_before(head,n,newkern(wx))
---~ end
---~ if x ~= 0 then
---~ insert_node_after (head,n,newkern(x))
---~ end
---~ else
---~ if x ~= 0 then
---~ insert_node_before(head,n,newkern(x))
---~ end
---~ if wx ~= 0 then
---~ insert_node_after(head,n,newkern(wx))
---~ end
---~ end
---~ else
- if r2l then
- if wx ~= 0 then
- insert_node_before(head,n,newkern(wx))
- end
- if x ~= 0 then
- insert_node_after (head,n,newkern(x))
- end
- else
- if x ~= 0 then
- insert_node_before(head,n,newkern(x))
- end
- if wx ~= 0 then
- insert_node_after(head,n,newkern(wx))
- end
+ if r2l then
+ if wx ~= 0 then
+ insert_node_before(head,n,newkern(wx))
+ end
+ if x ~= 0 then
+ insert_node_after (head,n,newkern(x))
+ end
+ else
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
end
---~ end
+ if wx ~= 0 then
+ insert_node_after(head,n,newkern(wx))
+ end
+ end
end
end
if next(cx) then
@@ -398,38 +405,22 @@ function nodes.inject_kerns(head,where,keep)
end
elseif has_kerns then
if trace_injections then
- nodes.trace_injection(head)
+ trace(head)
end
- for n in traverse_id(glyph,head) do
- local k = has_attribute(n,kernpair)
- if k then
- local kk = kerns[k]
- if kk then
- local rl, x, y, w = kk[1], kk[2] or 0, kk[3], kk[4]
- if y and y ~= 0 then
- n.yoffset = y -- todo: h ?
- end
- if w then
- -- copied from above
- local r2l = kk[6]
- local wx = w - x
---~ if rl < 0 then
---~ if r2l then
---~ if x ~= 0 then
---~ insert_node_before(head,n,newkern(x))
---~ end
---~ if wx ~= 0 then
---~ insert_node_after(head,n,newkern(wx))
---~ end
---~ else
---~ if wx ~= 0 then
---~ insert_node_before(head,n,newkern(wx))
---~ end
---~ if x ~= 0 then
---~ insert_node_after (head,n,newkern(x))
---~ end
---~ end
---~ else
+ for n in traverse_id(glyph_code,head) do
+ if n.subtype < 256 then
+ local k = has_attribute(n,kernpair)
+ if k then
+ local kk = kerns[k]
+ if kk then
+ local rl, x, y, w = kk[1], kk[2] or 0, kk[3], kk[4]
+ if y and y ~= 0 then
+ n.yoffset = y -- todo: h ?
+ end
+ if w then
+ -- copied from above
+ local r2l = kk[6]
+ local wx = w - x
if r2l then
if wx ~= 0 then
insert_node_before(head,n,newkern(wx))
@@ -445,11 +436,11 @@ function nodes.inject_kerns(head,where,keep)
insert_node_after(head,n,newkern(wx))
end
end
---~ end
- else
- -- simple (e.g. kernclass kerns)
- if x ~= 0 then
- insert_node_before(head,n,newkern(x))
+ else
+ -- simple (e.g. kernclass kerns)
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
+ end
end
end
end