summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua1181
1 files changed, 666 insertions, 515 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua
index 68cf608ec94..8d1b540be0f 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua
@@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['font-otj'] = {
}
-- This property based variant is not faster but looks nicer than the attribute one. We
--- need to use rawget (which is apbout 4 times slower than a direct access but we cannot
+-- need to use rawget (which is about 4 times slower than a direct access but we cannot
-- get/set that one for our purpose! This version does a bit more with discretionaries
-- (and Kai has tested it with his collection of weird fonts.)
@@ -16,31 +16,37 @@ if not modules then modules = { } end modules ['font-otj'] = {
-- cleaner to have an identification pass here. Also, I need to keep tracing in mind so
-- being too clever here is dangerous.
--- The subtype test is not needed as there will be no (new) properties set, given that we
--- reset the properties.
-
-- As we have a rawget on properties we don't need one on injections.
--- The use_advance code is just a test and is meant for testing and manuals. There is no
+-- The use_advance code was just a test and is meant for testing and manuals. There is no
-- performance (or whatever) gain and using kerns is somewhat cleaner (at least for now).
--- Maybe: subtype fontkern when pure kerns.
+-- An alternative is to have a list per base of all marks and then do a run over the node
+-- list that resolves the accumulated l/r/x/y and then do an inject pass.
+
+-- if needed we can flag a kern node as immutable
+
+-- The thing with these positioning options is that it is not clear what Uniscribe does with
+-- the 2rl flag and we keep oscillating a between experiments.
if not nodes.properties then return end
-local next, rawget = next, rawget
+local next, rawget, tonumber = next, rawget, tonumber
local fastcopy = table.fastcopy
-local registertracker = trackers.register
+local registertracker = trackers.register
+local registerdirective = directives.register
local trace_injections = false registertracker("fonts.injections", function(v) trace_injections = v end)
local trace_marks = false registertracker("fonts.injections.marks", function(v) trace_marks = v end)
local trace_cursive = false registertracker("fonts.injections.cursive", function(v) trace_cursive = v end)
local trace_spaces = false registertracker("fonts.injections.spaces", function(v) trace_spaces = v end)
--- use_advance is just an experiment: it makes copying glyphs (instead of new_glyph) dangerous
-
-local use_advance = false directives.register("fonts.injections.advance", function(v) use_advance = v end)
+-- local fix_cursive_marks = false
+--
+-- registerdirective("fonts.injections.fixcursivemarks", function(v)
+-- fix_cursive_marks = v
+-- end)
local report_injections = logs.reporter("fonts","injections")
local report_spaces = logs.reporter("fonts","spaces")
@@ -50,6 +56,7 @@ local attributes, nodes, node = attributes, nodes, node
fonts = fonts
local hashes = fonts.hashes
local fontdata = hashes.identifiers
+local fontmarks = hashes.marks
----- parameters = fonts.hashes.parameters -- not in generic
----- resources = fonts.hashes.resources -- not in generic
@@ -69,92 +76,105 @@ local glue_code = nodecodes.glue
local nuts = nodes.nuts
local nodepool = nuts.pool
-local newkern = nodepool.kern
-
local tonode = nuts.tonode
local tonut = nuts.tonut
-local getfield = nuts.getfield
local setfield = nuts.setfield
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
local getfont = nuts.getfont
-local getsubtype = nuts.getsubtype
local getchar = nuts.getchar
+local getoffsets = nuts.getoffsets
local getboth = nuts.getboth
-
-local ischar = nuts.is_char
-
local getdisc = nuts.getdisc
local setdisc = nuts.setdisc
+local setoffsets = nuts.setoffsets
+local ischar = nuts.is_char
+local getkern = nuts.getkern
+local setkern = nuts.setkern
+local setlink = nuts.setlink
+local setwidth = nuts.setwidth
+local getwidth = nuts.getwidth
+
+----- traverse_id = nuts.traverse_id
+----- traverse_char = nuts.traverse_char
+local nextchar = nuts.traversers.char
+local nextglue = nuts.traversers.glue
-local traverse_id = nuts.traverse_id
-local traverse_char = nuts.traverse_char
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
local properties = nodes.properties.data
-function injections.installnewkern(nk)
- newkern = nk or newkern
-end
+local fontkern = nuts.pool and nuts.pool.fontkern -- context
+local italickern = nuts.pool and nuts.pool.italickern -- context
-local nofregisteredkerns = 0
-local nofregisteredpairs = 0
-local nofregisteredmarks = 0
-local nofregisteredcursives = 0
-local keepregisteredcounts = false
+local useitalickerns = false
+
+directives.register("fonts.injections.useitalics", function(v)
+ if v then
+ report_injections("using italics for space kerns (tracing only)")
+ end
+ useitalickerns = v
+end)
+
+do if not fontkern then -- generic
+
+ local thekern = nuts.new("kern",0) -- fontkern
+ local setkern = nuts.setkern
+ local copy_node = nuts.copy_node
+
+ fontkern = function(k)
+ local n = copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+
+end end
+
+do if not italickern then -- generic
+
+ local thekern = nuts.new("kern",3) -- italiccorrection
+ local setkern = nuts.setkern
+ local copy_node = nuts.copy_node
+
+ italickern = function(k)
+ local n = copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+
+end end
+
+function injections.installnewkern() end -- obsolete
+
+local nofregisteredkerns = 0
+local nofregisteredpositions = 0
+local nofregisteredmarks = 0
+local nofregisteredcursives = 0
+local keepregisteredcounts = false
function injections.keepcounts()
keepregisteredcounts = true
end
function injections.resetcounts()
- nofregisteredkerns = 0
- nofregisteredpairs = 0
- nofregisteredmarks = 0
- nofregisteredcursives = 0
- keepregisteredcounts = false
+ nofregisteredkerns = 0
+ nofregisteredpositions = 0
+ nofregisteredmarks = 0
+ nofregisteredcursives = 0
+ keepregisteredcounts = false
end
-- We need to make sure that a possible metatable will not kick in unexpectedly.
--- function injections.reset(n)
--- local p = rawget(properties,n)
--- if p and rawget(p,"injections") then
--- p.injections = nil
--- end
--- end
-
--- function injections.copy(target,source)
--- local sp = rawget(properties,source)
--- if sp then
--- local tp = rawget(properties,target)
--- local si = rawget(sp,"injections")
--- if si then
--- si = fastcopy(si)
--- if tp then
--- tp.injections = si
--- else
--- propertydata[target] = {
--- injections = si,
--- }
--- end
--- else
--- if tp then
--- tp.injections = nil
--- end
--- end
--- end
--- end
-
function injections.reset(n)
local p = rawget(properties,n)
if p then
- p.injections = false -- { }
+ p.injections = false -- { } -- nil should work too as we use rawget
else
- properties[n] = false -- { injections = { } }
+ properties[n] = false -- { injections = { } } -- nil should work too as we use rawget
end
end
@@ -162,14 +182,13 @@ function injections.copy(target,source)
local sp = rawget(properties,source)
if sp then
local tp = rawget(properties,target)
- -- local si = rawget(sp,"injections")
local si = sp.injections
if si then
si = fastcopy(si)
if tp then
tp.injections = si
else
- propertydata[target] = {
+ properties[target] = {
injections = si,
}
end
@@ -188,10 +207,9 @@ function injections.copy(target,source)
end
end
-function injections.setligaindex(n,index)
+function injections.setligaindex(n,index) -- todo: don't set when 0
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections")
local i = p.injections
if i then
i.ligaindex = index
@@ -212,7 +230,6 @@ end
function injections.getligaindex(n,default)
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections")
local i = p.injections
if i then
return i.ligaindex or default
@@ -221,7 +238,15 @@ function injections.getligaindex(n,default)
return default
end
-function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext) -- hm: nuts or nodes
+function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag)
+
+ -- The standard says something about the r2lflag related to the first in a series:
+ --
+ -- When this bit is set, the last glyph in a given sequence to which the cursive
+ -- attachment lookup is applied, will be positioned on the baseline.
+ --
+ -- But it looks like we don't need to consider it.
+
local dx = factor*(exit[1]-entry[1])
local dy = -factor*(exit[2]-entry[2])
local ws = tfmstart.width
@@ -239,7 +264,6 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne
--
local p = rawget(properties,start)
if p then
- -- local i = rawget(p,"injections")
local i = p.injections
if i then
i.cursiveanchor = true
@@ -257,7 +281,6 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne
end
local p = rawget(properties,nxt)
if p then
- -- local i = rawget(p,"injections")
local i = p.injections
if i then
i.cursivex = dx
@@ -279,17 +302,19 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne
return dx, dy, nofregisteredcursives
end
-function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) -- r2lflag & tfmchr not used
- local x = factor*spec[1]
- local y = factor*spec[2]
- local w = factor*spec[3]
- local h = factor*spec[4]
+-- kind: 0=single 1=first of pair, 2=second of pair
+
+function injections.setposition(kind,current,factor,rlmode,spec,injection)
+ local x = factor * (spec[1] or 0)
+ local y = factor * (spec[2] or 0)
+ local w = factor * (spec[3] or 0)
+ local h = factor * (spec[4] or 0)
if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then -- okay?
local yoffset = y - h
local leftkern = x -- both kerns are set in a pair kern compared
local rightkern = w - x -- to normal kerns where we set only leftkern
if leftkern ~= 0 or rightkern ~= 0 or yoffset ~= 0 then
- nofregisteredpairs = nofregisteredpairs + 1
+ nofregisteredpositions = nofregisteredpositions + 1
if rlmode and rlmode < 0 then
leftkern, rightkern = rightkern, leftkern
end
@@ -298,8 +323,7 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) -- r2l
end
local p = rawget(properties,current)
if p then
- -- local i = p[injection]
- local i = rawget(p,injection)
+ local i = p[injection]
if i then
if leftkern ~= 0 then
i.leftkern = (i.leftkern or 0) + leftkern
@@ -336,15 +360,15 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) -- r2l
},
}
end
- return x, y, w, h, nofregisteredpairs
+ return x, y, w, h, nofregisteredpositions
end
end
return x, y, w, h -- no bound
end
--- This needs checking for rl < 0 but it is unlikely that a r2l script uses kernclasses between
--- glyphs so we're probably safe (KE has a problematic font where marks interfere with rl < 0 in
--- the previous case)
+-- The next one is used for simple kerns coming from a truetype kern table. The r2l
+-- variant variant needs checking but it is unlikely that a r2l script uses thsi
+-- feature.
function injections.setkern(current,factor,rlmode,x,injection)
local dx = factor * x
@@ -355,8 +379,7 @@ function injections.setkern(current,factor,rlmode,x,injection)
injection = "injections"
end
if p then
- -- local i = rawget(p,injection)
- local i = rawget(p,injection)
+ local i = p[injection]
if i then
i.leftkern = dx + (i.leftkern or 0)
else
@@ -377,8 +400,62 @@ function injections.setkern(current,factor,rlmode,x,injection)
end
end
-function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) -- ba=baseanchor, ma=markanchor
+-- This one is an optimization of pairs where we have only a "w" entry. This one is
+-- potentially different from the previous one wrt r2l. It needs checking. The
+-- optimization relates to smaller tma files.
+
+function injections.setmove(current,factor,rlmode,x,injection)
+ local dx = factor * x
+ if dx ~= 0 then
+ nofregisteredkerns = nofregisteredkerns + 1
+ local p = rawget(properties,current)
+ if not injection then
+ injection = "injections"
+ end
+ if rlmode and rlmode < 0 then
+ -- we need to swap with a single so then we also need to to it here
+ -- as move is just a simple single
+ if p then
+ local i = p[injection]
+ if i then
+ i.rightkern = dx + (i.rightkern or 0)
+ else
+ p[injection] = {
+ rightkern = dx,
+ }
+ end
+ else
+ properties[current] = {
+ [injection] = {
+ rightkern = dx,
+ },
+ }
+ end
+ else
+ if p then
+ local i = p[injection]
+ if i then
+ i.leftkern = dx + (i.leftkern or 0)
+ else
+ p[injection] = {
+ leftkern = dx,
+ }
+ end
+ else
+ properties[current] = {
+ [injection] = {
+ leftkern = dx,
+ },
+ }
+ end
+ end
+ return dx, nofregisteredkerns
+ else
+ return 0, 0
+ end
+end
+function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) -- ba=baseanchor, ma=markanchor
local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2])
nofregisteredmarks = nofregisteredmarks + 1
if rlmode >= 0 then
@@ -387,15 +464,20 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmar
local p = rawget(properties,start)
-- hm, dejavu serif does a sloppy mark2mark before mark2base
if p then
- -- local i = rawget(p,"injections")
local i = p.injections
if i then
if i.markmark then
-- out of order mkmk: yes or no or option
else
- i.markx = dx
- i.marky = dy
- i.markdir = rlmode or 0
+ if dx ~= 0 then
+ i.markx = dx
+ end
+ if y ~= 0 then
+ i.marky = dy
+ end
+ if rlmode then
+ i.markdir = rlmode
+ end
i.markbase = nofregisteredmarks
i.markbasenode = base
i.markmark = mkmk
@@ -441,7 +523,7 @@ local function show(n,what,nested,symbol)
if n then
local p = rawget(properties,n)
if p then
- local i = rawget(p,what)
+ local i = p[what]
if i then
local leftkern = i.leftkern or 0
local rightkern = i.rightkern or 0
@@ -483,7 +565,7 @@ end
local function showsub(n,what,where)
report_injections("begin subrun: %s",where)
- for n in traverse_id(glyph_code,n) do
+ for n in nextchar, n do
showchar(n,where)
show(n,what,where," ")
end
@@ -491,8 +573,9 @@ local function showsub(n,what,where)
end
local function trace(head,where)
- report_injections("begin run %s: %s kerns, %s pairs, %s marks and %s cursives registered",
- where or "",nofregisteredkerns,nofregisteredpairs,nofregisteredmarks,nofregisteredcursives)
+ report_injections()
+ report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered",
+ where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives)
local n = head
while n do
local id = getid(n)
@@ -527,11 +610,12 @@ local function show_result(head)
while current do
local id = getid(current)
if id == glyph_code then
- report_injections("char: %C, width %p, xoffset %p, yoffset %p",
- getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset"))
+ local w = getwidth(current)
+ local x, y = getoffsets(current)
+ report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y)
skipping = false
elseif id == kern_code then
- report_injections("kern: %p",getfield(current,"kern"))
+ report_injections("kern: %p",getkern(current))
skipping = false
elseif not skipping then
report_injections()
@@ -539,6 +623,7 @@ local function show_result(head)
end
current = getnext(current)
end
+ report_injections()
end
-- G +D-pre G
@@ -550,7 +635,6 @@ end
-- +D-replace +D-replace
local function inject_kerns_only(head,where)
- head = tonut(head)
if trace_injections then
trace(head,"kerns")
end
@@ -558,7 +642,7 @@ local function inject_kerns_only(head,where)
local prev = nil
local next = nil
local prevdisc = nil
- local prevglyph = nil
+ -- local prevglyph = nil
local pre = nil -- saves a lookup
local post = nil -- saves a lookup
local replace = nil -- saves a lookup
@@ -566,96 +650,75 @@ local function inject_kerns_only(head,where)
local posttail = nil -- saves a lookup
local replacetail = nil -- saves a lookup
while current do
- local id = getid(current)
local next = getnext(current)
- if id == glyph_code then
- if getsubtype(current) < 256 then
- local p = rawget(properties,current)
- if p then
- -- local i = rawget(p,"injections")
- local i = p.injections
- if i then
- -- left|glyph|right
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- if use_advance then
- setfield(current,"xoffset",leftkern)
- setfield(current,"xadvance",leftkern)
- else
- insert_node_before(head,current,newkern(leftkern))
+ local char, id = ischar(current)
+ if char then
+ local p = rawget(properties,current)
+ if p then
+ local i = p.injections
+ if i then
+ -- left|glyph|right
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ head = insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if prevdisc then
+ local done = false
+ if post then
+ local i = p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(posttail,fontkern(leftkern))
+ done = true
end
end
end
- if prevdisc then
- local done = false
- if post then
- -- local i = rawget(p,"postinjections")
- local i = p.postinjections
- if i then
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- if use_advance then
- setfield(post,"xadvance",leftkern)
- else
- insert_node_after(post,posttail,newkern(leftkern))
- done = true
- end
- end
+ if replace then
+ local i = p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(replacetail,fontkern(leftkern))
+ done = true
end
end
- if replace then
- -- local i = rawget(p,"replaceinjections")
- local i = p.replaceinjections
- if i then
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- if use_advance then
- setfield(replace,"xadvance",leftkern)
- else
- insert_node_after(replace,replacetail,newkern(leftkern))
- done = true
- end
- end
- end
- else
- -- local i = rawget(p,"emptyinjections")
- local i = p.emptyinjections
- if i then
- -- glyph|disc|glyph (special case)
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- setfield(prev,"replace",newkern(leftkern)) -- maybe also leftkern
- end
+ else
+ local i = p.emptyinjections
+ if i then
+ -- glyph|disc|glyph (special case)
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setfield(prev,"replace",fontkern(leftkern)) -- maybe also leftkern
end
end
- if done then
- setdisc(prevdisc,pre,post,replace)
- end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
end
end
end
prevdisc = nil
- prevglyph = current
+ -- prevglyph = current
+ elseif char == false then
+ -- other font
+ prevdisc = nil
+ -- prevglyph = current
elseif id == disc_code then
pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
local done = false
if pre then
-- left|pre glyphs|right
- for n in traverse_char(pre) do
+ for n in nextchar, pre do
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections") or rawget(p,"preinjections")
local i = p.injections or p.preinjections
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- if use_advance then
- setfield(pre,"xoffset",leftkern)
- setfield(pre,"xadvance",leftkern)
- else
- pre = insert_node_before(pre,n,newkern(leftkern))
- done = true
- end
+ pre = insert_node_before(pre,n,fontkern(leftkern))
+ done = true
end
end
end
@@ -663,21 +726,15 @@ local function inject_kerns_only(head,where)
end
if post then
-- left|post glyphs|right
- for n in traverse_char(post) do
+ for n in nextchar, post do
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections") or rawget(p,"postinjections")
local i = p.injections or p.postinjections
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- if use_advance then
- setfield(post,"xoffset",leftkern)
- setfield(post,"xadvance",leftkern)
- else
- post = insert_node_before(post,n,newkern(leftkern))
- done = true
- end
+ post = insert_node_before(post,n,fontkern(leftkern))
+ done = true
end
end
end
@@ -685,21 +742,15 @@ local function inject_kerns_only(head,where)
end
if replace then
-- left|replace glyphs|right
- for n in traverse_char(replace) do
+ for n in nextchar, replace do
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections") or rawget(p,"replaceinjections")
local i = p.injections or p.replaceinjections
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- if use_advance then
- setfield(replace,"xoffset",leftkern)
- setfield(replace,"xadvance",leftkern)
- else
- replace = insert_node_before(replace,n,newkern(leftkern))
- done = true
- end
+ replace = insert_node_before(replace,n,fontkern(leftkern))
+ done = true
end
end
end
@@ -708,10 +759,10 @@ local function inject_kerns_only(head,where)
if done then
setdisc(current,pre,post,replace)
end
- prevglyph = nil
+ -- prevglyph = nil
prevdisc = current
else
- prevglyph = nil
+ -- prevglyph = nil
prevdisc = nil
end
prev = current
@@ -723,13 +774,15 @@ local function inject_kerns_only(head,where)
else
nofregisteredkerns = 0
end
- return tonode(head), true
+ if trace_injections then
+ show_result(head)
+ end
+ return head
end
-local function inject_pairs_only(head,where)
- head = tonut(head)
+local function inject_positions_only(head,where)
if trace_injections then
- trace(head,"pairs")
+ trace(head,"positions")
end
local current = head
local prev = nil
@@ -743,110 +796,110 @@ local function inject_pairs_only(head,where)
local posttail = nil -- saves a lookup
local replacetail = nil -- saves a lookup
while current do
- local id = getid(current)
local next = getnext(current)
- if id == glyph_code then
- if getsubtype(current) < 256 then
- local p = rawget(properties,current)
- if p then
- -- local i = rawget(p,"injections")
- local i = p.injections
- if i then
- -- left|glyph|right
- local yoffset = i.yoffset
- if yoffset and yoffset ~= 0 then
- setfield(current,"yoffset",yoffset)
- end
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- head = insert_node_before(head,current,newkern(leftkern))
+ local char, id = ischar(current)
+ if char then
+ local p = rawget(properties,current)
+ if p then
+ local i = p.injections
+ if i then
+ -- left|glyph|right
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(current,false,yoffset)
+ end
+ local leftkern = i.leftkern
+ local rightkern = i.rightkern
+ if leftkern and leftkern ~= 0 then
+ if rightkern and leftkern == -rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern = 0
+ else
+ head = insert_node_before(head,current,fontkern(leftkern))
end
+ end
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ -- glyph|disc|glyph (special case)
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- insert_node_after(head,current,newkern(rightkern))
- end
- else
- -- local i = rawget(p,"emptyinjections")
- local i = p.emptyinjections
- if i then
- -- glyph|disc|glyph (special case)
--- is this okay?
- local rightkern = i.rightkern
- if rightkern and rightkern ~= 0 then
- if next and getid(next) == disc_code then
- if replace then
- -- error, we expect an empty one
- else
- setfield(next,"replace",newkern(rightkern)) -- maybe also leftkern
- end
+ if next and getid(next) == disc_code then
+ if replace then
+ -- error, we expect an empty one
+ else
+ setfield(next,"replace",fontkern(rightkern)) -- maybe also leftkern
end
end
end
end
- if prevdisc then
- local done = false
- if post then
- -- local i = rawget(p,"postinjections")
- local i = p.postinjections
- if i then
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- insert_node_after(post,posttail,newkern(leftkern))
- done = true
- end
+ end
+ if prevdisc then
+ local done = false
+ if post then
+ local i = p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(posttail,fontkern(leftkern))
+ done = true
end
end
- if replace then
- -- local i = rawget(p,"replaceinjections")
- local i = p.replaceinjections
- if i then
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- insert_node_after(replace,replacetail,newkern(leftkern))
- done = true
- end
- end
- else
- local i = p.emptyinjections
- if i then
--- new .. okay?
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- setfield(prev,"replace",newkern(leftkern)) -- maybe also leftkern
- end
+ end
+ if replace then
+ local i = p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(replacetail,fontkern(leftkern))
+ done = true
end
end
- if done then
- setdisc(prevdisc,pre,post,replace)
+ else
+ local i = p.emptyinjections
+ if i then
+ -- new .. okay?
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setfield(prev,"replace",fontkern(leftkern)) -- maybe also leftkern
+ end
end
end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
end
end
prevdisc = nil
prevglyph = current
+ elseif char == false then
+ prevdisc = nil
+ prevglyph = current
elseif id == disc_code then
pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
local done = false
if pre then
-- left|pre glyphs|right
- for n in traverse_char(pre) do
+ for n in nextchar, pre do
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections") or rawget(p,"preinjections")
local i = p.injections or p.preinjections
if i then
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
+ setoffsets(n,false,yoffset)
end
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- pre = insert_node_before(pre,n,newkern(leftkern))
+ pre = insert_node_before(pre,n,fontkern(leftkern))
done = true
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- insert_node_after(pre,n,newkern(rightkern))
+ insert_node_after(pre,n,fontkern(rightkern))
done = true
end
end
@@ -855,24 +908,23 @@ local function inject_pairs_only(head,where)
end
if post then
-- left|post glyphs|right
- for n in traverse_char(post) do
+ for n in nextchar, post do
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections") or rawget(p,"postinjections")
local i = p.injections or p.postinjections
if i then
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
+ setoffsets(n,false,yoffset)
end
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- post = insert_node_before(post,n,newkern(leftkern))
+ post = insert_node_before(post,n,fontkern(leftkern))
done = true
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- insert_node_after(post,n,newkern(rightkern))
+ insert_node_after(post,n,fontkern(rightkern))
done = true
end
end
@@ -881,24 +933,23 @@ local function inject_pairs_only(head,where)
end
if replace then
-- left|replace glyphs|right
- for n in traverse_char(replace) do
+ for n in nextchar, replace do
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections") or rawget(p,"replaceinjections")
local i = p.injections or p.replaceinjections
if i then
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
+ setoffsets(n,false,yoffset)
end
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- replace = insert_node_before(replace,n,newkern(leftkern))
+ replace = insert_node_before(replace,n,fontkern(leftkern))
done = true
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- insert_node_after(replace,n,newkern(rightkern))
+ insert_node_after(replace,n,fontkern(rightkern))
done = true
end
end
@@ -909,13 +960,12 @@ local function inject_pairs_only(head,where)
if pre then
local p = rawget(properties,prevglyph)
if p then
- -- local i = rawget(p,"preinjections")
local i = p.preinjections
if i then
-- glyph|pre glyphs
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- pre = insert_node_before(pre,pre,newkern(rightkern))
+ pre = insert_node_before(pre,pre,fontkern(rightkern))
done = true
end
end
@@ -924,13 +974,12 @@ local function inject_pairs_only(head,where)
if replace then
local p = rawget(properties,prevglyph)
if p then
- -- local i = rawget(p,"replaceinjections")
local i = p.replaceinjections
if i then
-- glyph|replace glyphs
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- replace = insert_node_before(replace,replace,newkern(rightkern))
+ replace = insert_node_before(replace,replace,fontkern(rightkern))
done = true
end
end
@@ -953,43 +1002,22 @@ local function inject_pairs_only(head,where)
if keepregisteredcounts then
keepregisteredcounts = false
else
- nofregisteredkerns = 0
+ nofregisteredpositions = 0
+ end
+ if trace_injections then
+ show_result(head)
end
- return tonode(head), true
+ return head
end
--- local function showoffset(n,flag)
--- local ox = getfield(n,"xoffset")
--- local oy = getfield(n,"yoffset")
--- if flag then
--- if ox == 0 then
--- setcolor(n,oy == 0 and "darkgray" or "darkgreen")
--- else
--- setcolor(n,oy == 0 and "darkblue" or "darkred")
--- end
--- else
--- if ox == 0 then
--- setcolor(n,oy == 0 and "gray" or "green")
--- else
--- setcolor(n,oy == 0 and "blue" or "red")
--- end
--- end
--- end
-
local function showoffset(n,flag)
- local o = getfield(n,"xoffset")
- if o == 0 then
- o = getfield(n,"yoffset")
- end
- if o ~= 0 then
- setcolor(n,flag and "darkred" or "darkgreen")
- else
- resetcolor(n)
+ local x, y = getoffsets(n)
+ if x ~= 0 or y ~= 0 then
+ setcolor(n,"darkgray")
end
end
local function inject_everything(head,where)
- head = tonut(head)
if trace_injections then
trace(head,"everything")
end
@@ -998,8 +1026,6 @@ local function inject_everything(head,where)
--
local current = head
local last = nil
- local font = font
- local markdata = nil
local prev = nil
local next = nil
local prevdisc = nil
@@ -1018,262 +1044,333 @@ local function inject_everything(head,where)
local marks = { }
local nofmarks = 0
--
+ -- local applyfix = hascursives and fix_cursive_marks
+ --
-- move out
--
local function processmark(p,n,pn) -- p = basenode
- local px = getfield(p,"xoffset")
+ local px, py = getoffsets(p)
+ local nx, ny = getoffsets(n)
local ox = 0
local rightkern = nil
local pp = rawget(properties,p)
if pp then
- -- pp = rawget(pp,"injections")
pp = pp.injections
if pp then
rightkern = pp.rightkern
end
end
+ local markdir = pn.markdir
if rightkern then -- x and w ~= 0
- if pn.markdir < 0 then
+ ox = px - (pn.markx or 0) - rightkern
+ if markdir and markdir < 0 then
-- kern(w-x) glyph(p) kern(x) mark(n)
- ox = px - pn.markx - rightkern
- -- report_injections("r2l case 1: %p",ox)
+ if not pn.markmark then
+ ox = ox + (pn.leftkern or 0)
+ end
else
-- kern(x) glyph(p) kern(w-x) mark(n)
- -- ox = px - getfield(p,"width") + pn.markx - pp.leftkern
--
-- According to Kai we don't need to handle leftkern here but I'm
-- pretty sure I've run into a case where it was needed so maybe
-- some day we need something more clever here.
--
+ -- maybe we need to apply both then
+ --
if false then
- -- a mark with kerning
+ -- a mark with kerning (maybe husayni needs it )
local leftkern = pp.leftkern
if leftkern then
- ox = px - pn.markx - leftkern
- else
- ox = px - pn.markx
+ ox = ox - leftkern
end
- else
- ox = px - pn.markx
end
end
else
- -- if pn.markdir < 0 then
- -- ox = px - pn.markx
- -- -- report_injections("r2l case 3: %p",ox)
- -- else
- -- -- ox = px - getfield(p,"width") + pn.markx
- ox = px - pn.markx
- -- report_injections("l2r case 3: %p",ox)
- -- end
+ ox = px - (pn.markx or 0)
+ if markdir and markdir < 0 then
+ if not pn.markmark then
+ local leftkern = pn.leftkern
+ if leftkern then
+ ox = ox + leftkern -- husayni needs it
+ end
+ end
+ end
if pn.checkmark then
- local wn = getfield(n,"width") -- in arial marks have widths
- if wn ~= 0 then
+ local wn = getwidth(n) -- in arial marks have widths
+ if wn and wn ~= 0 then
wn = wn/2
if trace_injections then
report_injections("correcting non zero width mark %C",getchar(n))
end
-- -- bad: we should center
+ --
-- pn.leftkern = -wn
-- pn.rightkern = -wn
- -- -- we're too late anyway as kerns are already injected so
- -- -- we do it the ugly way (no checking if the previous is
- -- -- already a kern) .. maybe we should fix the font instead
- insert_node_before(n,n,newkern(-wn))
- insert_node_after(n,n,newkern(-wn))
+ --
+ -- -- we're too late anyway as kerns are already injected so we do it the
+ -- -- ugly way (no checking if the previous is already a kern) .. maybe we
+ -- -- should fix the font instead
+ --
+ -- todo: head and check for prev / next kern
+ --
+ insert_node_before(n,n,fontkern(-wn))
+ insert_node_after(n,n,fontkern(-wn))
end
end
end
- local oy = getfield(n,"yoffset") + getfield(p,"yoffset") + pn.marky
- setfield(n,"xoffset",ox)
- setfield(n,"yoffset",oy)
+ local oy = ny + py + (pn.marky or 0)
+ if not pn.markmark then
+ local yoffset = pn.yoffset
+ if yoffset then
+ oy = oy + yoffset -- husayni needs it
+ end
+ end
+ setoffsets(n,ox,oy)
if trace_marks then
showoffset(n,true)
end
end
- -- todo: marks in disc
+ -- begin of temp fix --
+ -- local base = nil -- bah, some arabic fonts have no mark anchoring
+ -- end of temp fix --
while current do
- local id = getid(current)
local next = getnext(current)
- if id == glyph_code then
- if getsubtype(current) < 256 then
- local p = rawget(properties,current)
- if p then
- -- local i = rawget(p,"injections")
- local i = p.injections
- if i then
- local pm = i.markbasenode
- if pm then
- nofmarks = nofmarks + 1
- marks[nofmarks] = current
- else
- local yoffset = i.yoffset
- if yoffset and yoffset ~= 0 then
- setfield(current,"yoffset",yoffset)
- end
- if hascursives then
- local cursivex = i.cursivex
- if cursivex then
- if cursiveanchor then
- if cursivex ~= 0 then
- i.leftkern = (i.leftkern or 0) + cursivex
- end
- if maxc == 0 then
- minc = 1
- maxc = 1
- glyphs[1] = cursiveanchor
- else
- maxc = maxc + 1
- glyphs[maxc] = cursiveanchor
- end
- properties[cursiveanchor].cursivedy = i.cursivey -- cursiveprops
- last = current
+ local char, id = ischar(current)
+ if char then
+ local p = rawget(properties,current)
+ -- begin of temp fix --
+ -- if applyfix then
+ -- if not p then
+ -- local m = fontmarks[getfont(current)]
+ -- if m and m[char] then
+ -- if base then
+ -- p = { injections = { markbasenode = base } }
+ -- nofmarks = nofmarks + 1
+ -- marks[nofmarks] = current
+ -- properties[current] = p
+ -- hasmarks = true
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- end
+ -- end
+ -- end of temp fix
+ if p then
+ local i = p.injections
+ -- begin of temp fix --
+ -- if applyfix then
+ -- if not i then
+ -- local m = fontmarks[getfont(current)]
+ -- if m and m[char] then
+ -- if base then
+ -- i = { markbasenode = base }
+ -- nofmarks = nofmarks + 1
+ -- marks[nofmarks] = current
+ -- p.injections = i
+ -- hasmarks = true
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- end
+ -- end
+ -- end of temp fix --
+ if i then
+ local pm = i.markbasenode
+ -- begin of temp fix --
+ -- if applyfix then
+ -- if not pm then
+ -- local m = fontmarks[getfont(current)]
+ -- if m and m[char] then
+ -- if base then
+ -- pm = base
+ -- i.markbasenode = pm
+ -- hasmarks = true
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- end
+ -- end of temp fix --
+ if pm then
+ nofmarks = nofmarks + 1
+ marks[nofmarks] = current
+ else
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(current,false,yoffset)
+ end
+ if hascursives then
+ local cursivex = i.cursivex
+ if cursivex then
+ if cursiveanchor then
+ if cursivex ~= 0 then
+ i.leftkern = (i.leftkern or 0) + cursivex
+ end
+ if maxc == 0 then
+ minc = 1
+ maxc = 1
+ glyphs[1] = cursiveanchor
else
- maxc = 0
+ maxc = maxc + 1
+ glyphs[maxc] = cursiveanchor
end
- elseif maxc > 0 then
- local ny = getfield(current,"yoffset")
+ properties[cursiveanchor].cursivedy = i.cursivey -- cursiveprops
+ last = current
+ else
+ maxc = 0
+ end
+ elseif maxc > 0 then
+ local nx, ny = getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti = glyphs[i]
+ ny = ny + properties[ti].cursivedy
+ setoffsets(ti,false,ny) -- why not add ?
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ maxc = 0
+ cursiveanchor = nil
+ end
+ if i.cursiveanchor then
+ cursiveanchor = current -- no need for both now
+ else
+ if maxc > 0 then
+ local nx, ny = getoffsets(current)
for i=maxc,minc,-1 do
local ti = glyphs[i]
ny = ny + properties[ti].cursivedy
- setfield(ti,"yoffset",ny) -- why not add ?
+ setoffsets(ti,false,ny) -- why not add ?
if trace_cursive then
showoffset(ti)
end
end
maxc = 0
- cursiveanchor = nil
- end
- if i.cursiveanchor then
- cursiveanchor = current -- no need for both now
- else
- if maxc > 0 then
- local ny = getfield(current,"yoffset")
- for i=maxc,minc,-1 do
- local ti = glyphs[i]
- ny = ny + properties[ti].cursivedy
- setfield(ti,"yoffset",ny) -- why not add ?
- if trace_cursive then
- showoffset(ti)
- end
- end
- maxc = 0
- end
- cursiveanchor = nil
end
+ cursiveanchor = nil
end
- -- left|glyph|right
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- insert_node_before(head,current,newkern(leftkern))
- end
- local rightkern = i.rightkern
- if rightkern and rightkern ~= 0 then
- insert_node_after(head,current,newkern(rightkern))
+ end
+ -- left|glyph|right
+ local leftkern = i.leftkern
+ local rightkern = i.rightkern
+ if leftkern and leftkern ~= 0 then
+ if rightkern and leftkern == -rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern = 0
+ else
+ head = insert_node_before(head,current,fontkern(leftkern))
end
end
- else
- -- local i = rawget(p,"emptyinjections")
- local i = p.emptyinjections
- if i then
- -- glyph|disc|glyph (special case)
- -- okay?
- local rightkern = i.rightkern
- if rightkern and rightkern ~= 0 then
- if next and getid(next) == disc_code then
- if replace then
- -- error, we expect an empty one
- else
- setfield(next,"replace",newkern(rightkern)) -- maybe also leftkern
- end
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ -- glyph|disc|glyph (special case)
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ if next and getid(next) == disc_code then
+ if replace then
+ -- error, we expect an empty one
+ else
+ setfield(next,"replace",fontkern(rightkern)) -- maybe also leftkern
end
end
end
end
- if prevdisc then
- if p then
- local done = false
- if post then
- -- local i = rawget(p,"postinjections")
- local i = p.postinjections
- if i then
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- insert_node_after(post,posttail,newkern(leftkern))
- done = true
- end
+ end
+ if prevdisc then
+ if p then
+ local done = false
+ if post then
+ local i = p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(posttail,fontkern(leftkern))
+ done = true
end
end
- if replace then
- -- local i = rawget(p,"replaceinjections")
- local i = p.replaceinjections
- if i then
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- insert_node_after(replace,replacetail,newkern(leftkern))
- done = true
- end
- end
- else
- -- local i = rawget(p,"emptyinjections")
- local i = p.emptyinjections
- if i then
- local leftkern = i.leftkern
- if leftkern and leftkern ~= 0 then
- setfield(prev,"replace",newkern(leftkern)) -- maybe also leftkern
- end
+ end
+ if replace then
+ local i = p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(replacetail,fontkern(leftkern))
+ done = true
end
end
- if done then
- setdisc(prevdisc,pre,post,replace)
+ else
+ local i = p.emptyinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setfield(prev,"replace",fontkern(leftkern)) -- maybe also leftkern
+ end
end
end
- end
- else
- -- cursive
- if hascursives and maxc > 0 then
- local ny = getfield(current,"yoffset")
- for i=maxc,minc,-1 do
- local ti = glyphs[i]
- ny = ny + properties[ti].cursivedy
- setfield(ti,"yoffset",getfield(ti,"yoffset") + ny) -- can be mark
+ if done then
+ setdisc(prevdisc,pre,post,replace)
end
- maxc = 0
- cursiveanchor = nil
end
end
+ else
+ -- cursive
+ if hascursives and maxc > 0 then
+ local nx, ny = getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti = glyphs[i]
+ ny = ny + properties[ti].cursivedy
+ local xi, yi = getoffsets(ti)
+ setoffsets(ti,xi,yi + ny) -- can be mark, we could use properties
+ end
+ maxc = 0
+ cursiveanchor = nil
+ end
end
prevdisc = nil
prevglyph = current
+ elseif char == false then
+ -- base = nil
+ prevdisc = nil
+ prevglyph = current
elseif id == disc_code then
+ -- base = nil
pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
local done = false
if pre then
-- left|pre glyphs|right
- for n in traverse_char(pre) do
+ for n in nextchar, pre do
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections") or rawget(p,"preinjections")
local i = p.injections or p.preinjections
if i then
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
+ setoffsets(n,false,yoffset)
end
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- pre = insert_node_before(pre,n,newkern(leftkern))
+ pre = insert_node_before(pre,n,fontkern(leftkern))
done = true
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- insert_node_after(pre,n,newkern(rightkern))
+ insert_node_after(pre,n,fontkern(rightkern))
done = true
end
if hasmarks then
local pm = i.markbasenode
if pm then
- processmark(pm,current,i)
+ processmark(pm,n,i)
end
end
end
@@ -1282,30 +1379,29 @@ local function inject_everything(head,where)
end
if post then
-- left|post glyphs|right
- for n in traverse_char(post) do
+ for n in nextchar, post do
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections") or rawget(p,"postinjections")
local i = p.injections or p.postinjections
if i then
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
+ setoffsets(n,false,yoffset)
end
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- post = insert_node_before(post,n,newkern(leftkern))
+ post = insert_node_before(post,n,fontkern(leftkern))
done = true
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- insert_node_after(post,n,newkern(rightkern))
+ insert_node_after(post,n,fontkern(rightkern))
done = true
end
if hasmarks then
local pm = i.markbasenode
if pm then
- processmark(pm,current,i)
+ processmark(pm,n,i)
end
end
end
@@ -1314,30 +1410,29 @@ local function inject_everything(head,where)
end
if replace then
-- left|replace glyphs|right
- for n in traverse_char(replace) do
+ for n in nextchar, replace do
local p = rawget(properties,n)
if p then
- -- local i = rawget(p,"injections") or rawget(p,"replaceinjections")
local i = p.injections or p.replaceinjections
if i then
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
+ setoffsets(n,false,yoffset)
end
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- replace = insert_node_before(replace,n,newkern(leftkern))
+ replace = insert_node_before(replace,n,fontkern(leftkern))
done = true
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- insert_node_after(replace,n,newkern(rightkern))
+ insert_node_after(replace,n,fontkern(rightkern))
done = true
end
if hasmarks then
local pm = i.markbasenode
if pm then
- processmark(pm,current,i)
+ processmark(pm,n,i)
end
end
end
@@ -1348,13 +1443,12 @@ local function inject_everything(head,where)
if pre then
local p = rawget(properties,prevglyph)
if p then
- -- local i = rawget(p,"preinjections")
local i = p.preinjections
if i then
-- glyph|pre glyphs
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- pre = insert_node_before(pre,pre,newkern(rightkern))
+ pre = insert_node_before(pre,pre,fontkern(rightkern))
done = true
end
end
@@ -1363,13 +1457,12 @@ local function inject_everything(head,where)
if replace then
local p = rawget(properties,prevglyph)
if p then
- -- local i = rawget(p,"replaceinjections")
local i = p.replaceinjections
if i then
-- glyph|replace glyphs
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
- replace = insert_node_before(replace,replace,newkern(rightkern))
+ replace = insert_node_before(replace,replace,fontkern(rightkern))
done = true
end
end
@@ -1382,6 +1475,7 @@ local function inject_everything(head,where)
prevglyph = nil
prevdisc = current
else
+ -- base = nil
prevglyph = nil
prevdisc = nil
end
@@ -1390,11 +1484,11 @@ local function inject_everything(head,where)
end
-- cursive
if hascursives and maxc > 0 then
- local ny = getfield(last,"yoffset")
+ local nx, ny = getoffsets(last)
for i=maxc,minc,-1 do
local ti = glyphs[i]
ny = ny + properties[ti].cursivedy
- setfield(ti,"yoffset",ny) -- why not add ?
+ setoffsets(ti,false,ny) -- why not add ?
if trace_cursive then
showoffset(ti)
end
@@ -1405,7 +1499,6 @@ local function inject_everything(head,where)
for i=1,nofmarks do
local m = marks[i]
local p = rawget(properties,m)
- -- local i = rawget(p,"injections")
local i = p.injections
local b = i.markbasenode
processmark(b,m,i)
@@ -1417,12 +1510,15 @@ local function inject_everything(head,where)
if keepregisteredcounts then
keepregisteredcounts = false
else
- nofregisteredkerns = 0
- nofregisteredpairs = 0
- nofregisteredmarks = 0
- nofregisteredcursives = 0
+ nofregisteredkerns = 0
+ nofregisteredpositions = 0
+ nofregisteredmarks = 0
+ nofregisteredcursives = 0
end
- return tonode(head), true
+ if trace_injections then
+ show_result(head)
+ end
+ return head
end
-- space triggers
@@ -1470,21 +1566,49 @@ end
injections.getthreshold = getthreshold
-function injections.isspace(n,threshold)
- if getid(n) == glue_code then
- local w = getfield(n,"width")
+function injections.isspace(n,threshold,id)
+ if (id or getid(n)) == glue_code then
+ local w = getwidth(n)
if threshold and w > threshold then -- was >=
return 32
end
end
end
+-- We have a plugin so that Kai can use the next in plain. Such a plugin is rather application
+-- specific.
+--
+-- local getboth = nodes.direct.getboth
+-- local getid = nodes.direct.getid
+-- local getprev = nodes.direct.getprev
+-- local getnext = nodes.direct.getnext
+--
+-- local whatsit_code = nodes.nodecodes.whatsit
+-- local glyph_code = nodes.nodecodes.glyph
+--
+-- local function getspaceboth(n) -- fragile: what it prev/next has no width field
+-- local prev, next = getboth(n)
+-- while prev and (getid(prev) == whatsit_code or (getwidth(prev) == 0 and getid(prev) ~= glyph_code)) do
+-- prev = getprev(prev)
+-- end
+-- while next and (getid(next) == whatsit_code or (getwidth(next) == 0 and getid(next) ~= glyph_code)) do
+-- next = getnext(next)
+-- end
+-- end
+--
+-- injections.installgetspaceboth(getspaceboth)
+
+local getspaceboth = getboth
+
+function injections.installgetspaceboth(gb)
+ getspaceboth = gb or getboth
+end
+
local function injectspaces(head)
if not triggers then
- return head, false
+ return head
end
-
local lastfont = nil
local spacekerns = nil
local leftkerns = nil
@@ -1502,10 +1626,10 @@ local function injectspaces(head)
factor = getthreshold(font)
end
- for n in traverse_id(glue_code,tonut(head)) do
- local prev, next = getboth(n)
- local prevchar = ischar(prev)
- local nextchar = ischar(next)
+ for n in nextglue, head do
+ local prev, next = getspaceboth(n)
+ local prevchar = prev and ischar(prev)
+ local nextchar = next and ischar(next)
if nextchar then
local font = getfont(next)
local trig = triggers[font]
@@ -1531,39 +1655,66 @@ local function injectspaces(head)
end
end
if leftkern then
- local old = getfield(n,"width")
+ local old = getwidth(n)
if old > threshold then
if rightkern then
- local new = old + (leftkern + rightkern) * factor
- if trace_spaces then
- report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar)
+ if useitalickerns then
+ local lnew = leftkern * factor
+ local rnew = rightkern * factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
+ end
+ head = insert_node_before(head,n,italickern(lnew))
+ insert_node_after(head,n,italickern(rnew))
+ else
+ local new = old + (leftkern + rightkern) * factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar)
+ end
+ setwidth(n,new)
end
- setfield(n,"width",new)
- leftkern = false
+ rightkern = false
else
- local new = old + leftkern * factor
- if trace_spaces then
- report_spaces("%C [%p -> %p]",prevchar,old,new)
+ if useitalickerns then
+ local new = leftkern * factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",prevchar,old,new)
+ end
+ insert_node_after(head,n,italickern(new)) -- tricky with traverse but ok
+ else
+ local new = old + leftkern * factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p]",prevchar,old,new)
+ end
+ setwidth(n,new)
end
- setfield(n,"width",new)
end
end
leftkern = false
elseif rightkern then
- local old = getfield(n,"width")
+ local old = getwidth(n)
if old > threshold then
- local new = old + rightkern * factor
- if trace_spaces then
- report_spaces("[%p -> %p] %C",nextchar,old,new)
+ if useitalickerns then
+ local new = rightkern * factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",nextchar,old,new)
+ end
+ insert_node_after(head,n,italickern(new))
+ else
+ local new = old + rightkern * factor
+ if trace_spaces then
+ report_spaces("[%p -> %p] %C",nextchar,old,new)
+ end
+ setwidth(n,new)
end
- setfield(n,"width",new)
end
rightkern = false
end
end
triggers = false
- return head, true
+
+ return head
end
--
@@ -1578,17 +1729,17 @@ function injections.handler(head,where)
report_injections("injection variant %a","everything")
end
return inject_everything(head,where)
- elseif nofregisteredpairs > 0 then
+ elseif nofregisteredpositions > 0 then
if trace_injections then
- report_injections("injection variant %a","pairs")
+ report_injections("injection variant %a","positions")
end
- return inject_pairs_only(head,where)
+ return inject_positions_only(head,where)
elseif nofregisteredkerns > 0 then
if trace_injections then
report_injections("injection variant %a","kerns")
end
return inject_kerns_only(head,where)
else
- return head, false
+ return head
end
end