summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--otfl-font-con.lua18
-rw-r--r--otfl-font-def.lua11
-rw-r--r--otfl-font-otf.lua8
-rw-r--r--otfl-font-otn.lua196
-rw-r--r--otfl-node-inj.lua89
5 files changed, 182 insertions, 140 deletions
diff --git a/otfl-font-con.lua b/otfl-font-con.lua
index 42ac8c2..9280996 100644
--- a/otfl-font-con.lua
+++ b/otfl-font-con.lua
@@ -44,7 +44,6 @@ local setmetatableindex = table.setmetatableindex
-- will be directives
constructors.dontembed = allocate()
-constructors.mathactions = { }
constructors.autocleanup = true
constructors.namemode = "fullpath" -- will be a function
@@ -89,7 +88,7 @@ constructors.keys = {
finalized = "boolean",
},
parameters = {
- mathsize = "scaledpoints",
+ mathsize = "number",
scriptpercentage = "float",
scriptscriptpercentage = "float",
units = "cardinal",
@@ -278,6 +277,14 @@ function constructors.assignmathparameters(target,original) -- simple variant, n
end
end
+function constructors.beforecopyingcharacters(target,original)
+ -- can be used for additional tweaking
+end
+
+function constructors.aftercopyingcharacters(target,original)
+ -- can be used for additional tweaking
+end
+
function constructors.enhanceparameters(parameters)
local xheight = parameters.x_height
local quad = parameters.quad
@@ -527,7 +534,7 @@ function constructors.scale(tfmdata,specification)
--
local italickey = "italic"
--
- -- some context specific trickery (we might move this to a plug in into here
+ -- some context specific trickery (this will move to a plugin)
--
if hasmath then
if properties.mathitalics then
@@ -553,6 +560,8 @@ function constructors.scale(tfmdata,specification)
--
-- end of context specific trickery
--
+ constructors.beforecopyingcharacters(target,tfmdata)
+ --
local sharedkerns = { }
--
-- we can have a dumb mode (basemode without math etc) that skips most
@@ -795,6 +804,9 @@ function constructors.scale(tfmdata,specification)
end
targetcharacters[unicode] = chr
end
+ --
+ constructors.aftercopyingcharacters(target,tfmdata)
+ --
return target
end
diff --git a/otfl-font-def.lua b/otfl-font-def.lua
index 5f79170..10958cf 100644
--- a/otfl-font-def.lua
+++ b/otfl-font-def.lua
@@ -214,17 +214,6 @@ function definers.resolve(specification)
else
specification.forced = specification.forced
end
- -- for the moment here (goodies set outside features)
- local goodies = specification.goodies
- if goodies and goodies ~= "" then
- local normal = specification.features.normal
- if not normal then
- specification.features.normal = { goodies = goodies }
- elseif not normal.goodies then
- normal.goodies = goodies
- end
- end
- --
specification.hash = lower(specification.name .. ' @ ' .. constructors.hashfeatures(specification))
if specification.sub and specification.sub ~= "" then
specification.hash = specification.sub .. ' @ ' .. specification.hash
diff --git a/otfl-font-otf.lua b/otfl-font-otf.lua
index 03376f9..27a64e9 100644
--- a/otfl-font-otf.lua
+++ b/otfl-font-otf.lua
@@ -49,7 +49,7 @@ local otf = fonts.handlers.otf
otf.glists = { "gsub", "gpos" }
-otf.version = 2.735 -- beware: also sync font-mis.lua
+otf.version = 2.736 -- beware: also sync font-mis.lua
otf.cache = containers.define("fonts", "otf", otf.version, true)
local fontdata = fonts.hashes.identifiers
@@ -848,7 +848,7 @@ actions["analyze glyphs"] = function(data,filename,raw) -- maybe integrate this
local properties = data.properties
local hasitalics = false
local widths = { }
- local marks = { }
+ local marks = { } -- always present (saves checking)
for unicode, description in next, descriptions do
local glyph = description.glyph
local italic = glyph.italic_correction
@@ -1029,7 +1029,8 @@ actions["reorganize subtables"] = function(data,filename,raw)
for k=1,#dw do
local gk = dw[k]
local features = gk.features
- if features and supported(features) then
+-- if features and supported(features) then
+ if not features or supported(features) then -- not always features !
local typ = gk.type
local chain = g_directions[typ] or 0
local subtables = gk.subtables
@@ -1057,7 +1058,6 @@ actions["reorganize subtables"] = function(data,filename,raw)
--
local name = gk.name
--
- local features = gk.features
if features then
-- scripts, tag, ismac
local f = { }
diff --git a/otfl-font-otn.lua b/otfl-font-otn.lua
index 12ea975..2fd910e 100644
--- a/otfl-font-otn.lua
+++ b/otfl-font-otn.lua
@@ -27,6 +27,7 @@ if not modules then modules = { } end modules ['font-otn'] = {
-- default features (per language, script)
-- handle positions (we need example fonts)
-- handle gpos_single (we might want an extra width field in glyph nodes because adding kerns might interfere)
+-- mark (to mark) code is still not what it should be (too messy but we need some more extreem husayni tests)
--[[ldx--
<p>This module is a bit more split up that I'd like but since we also want to test
@@ -192,14 +193,21 @@ local ligature_code = glyphcodes.ligature
local privateattribute = attributes.private
+-- Something is messed up: we have two mark / ligature indices, one at the injection
+-- end and one here ... this is bases in KE's patches but there is something fishy
+-- there as I'm pretty sure that for husayni we need some connection (as it's much
+-- more complex than an average font) but I need proper examples of all cases, not
+-- of only some.
+
local state = privateattribute('state')
local markbase = privateattribute('markbase')
local markmark = privateattribute('markmark')
-local markdone = privateattribute('markdone')
+local markdone = privateattribute('markdone') -- assigned at the injection end
local cursbase = privateattribute('cursbase')
local curscurs = privateattribute('curscurs')
local cursdone = privateattribute('cursdone')
local kernpair = privateattribute('kernpair')
+local ligacomp = privateattribute('ligacomp') -- assigned here (ideally it should be combined)
local injections = nodes.injections
local setmark = injections.setmark
@@ -367,47 +375,38 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) --
current.subtype = ligature_code
current.components = start
local head = current
- if deletemarks then
- if trace_marks then
- while start do
- if marks[start.char] then
- logwarning("%s: remove mark %s",pref(kind,lookupname),gref(start.char))
- end
- start = start.next
+ -- this is messy ... we should get rid of the components eventually
+ local i = 0 -- is index of base
+ while start do
+ if not marks[start.char] then
+ i = i + 1
+ elseif not deletemarks then -- quite fishy
+ set_attribute(start,ligacomp,i)
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(start.char),i)
end
+ head, current = insert_node_after(head,current,copy_node(start))
end
- else
- local i = 0
- while start do
- if marks[start.char] then
- set_attribute(start,markdone,i)
- if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(start.char),i)
- end
- head, current = insert_node_after(head,current,copy_node(start))
- else
- i = i + 1
- end
- start = start.next
- end
- start = current.next
- while start and start.id == glyph_code do
- if marks[start.char] then
- set_attribute(start,markdone,i)
- if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(start.char),i)
- end
- else
- break
+ start = start.next
+ end
+ start = current.next
+ while start and start.id == glyph_code do
+ if marks[start.char] then
+ set_attribute(start,ligacomp,i)
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(start.char),i)
end
- start = start.next
+ else
+ break
end
+ start = start.next
end
- -- we do need components in funny kerning mode but maybe I can better reconstruct then
- -- as we do have the font components info available; removing components makes the
- -- previous code much simpler
- --
- -- flush_node_list(head.components)
+ --
+ -- we do need components in funny kerning mode but maybe I can better reconstruct then
+ -- as we do have the font components info available; removing components makes the
+ -- previous code much simpler
+ --
+ -- flush_node_list(head.components)
return head
end
end
@@ -659,18 +658,14 @@ function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence)
local markchar = start.char
if marks[markchar] then
local base = start.prev -- [glyph] [optional marks] [start=mark]
- local index = 1
if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then
local basechar = base.char
if marks[basechar] then
- index = index + 1
while true do
base = base.prev
if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then
basechar = base.char
- if marks[basechar] then
- index = index + 1
- else
+ if not marks[basechar] then
break
end
else
@@ -681,8 +676,7 @@ function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence)
end
end
end
- local i = has_attribute(start,markdone)
- if i then index = i end
+ local index = has_attribute(start,ligacomp)
local baseanchors = descriptions[basechar]
if baseanchors then
baseanchors = baseanchors.anchors
@@ -696,7 +690,7 @@ function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence)
if ma then
ba = ba[index]
if ba then
- local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,index)
+ 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)",
pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy)
@@ -727,46 +721,55 @@ end
function handlers.gpos_mark2mark(start,kind,lookupname,markanchors,sequence)
local markchar = start.char
if marks[markchar] then
---~ local alreadydone = markonce and has_attribute(start,markmark)
---~ if not alreadydone then
- local base = start.prev -- [glyph] [basemark] [start=mark]
- if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then -- subtype test can go
- local basechar = base.char
- local baseanchors = descriptions[basechar]
+ local base = start.prev -- [glyph] [basemark] [start=mark]
+ -- while base and has_attribute(base,ligacomp) and has_attribute(base,ligacomp) ~= has_attribute(start,ligacomp) do
+ -- base = base.prev -- KE: prevents mkmk for marks on different components of a ligature
+ -- end
+ local slc = has_attribute(start,ligacomp)
+ if slc then -- a rather messy loop ... needs checking with husayni
+ while base do
+ local blc = has_attribute(base,ligacomp)
+ if blc and blc ~= slc then
+ base = base.prev
+ else
+ break
+ end
+ end
+ end
+ if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then -- subtype test can go
+ local basechar = base.char
+ local baseanchors = descriptions[basechar]
+ if baseanchors then
+ baseanchors = baseanchors.anchors
if baseanchors then
- baseanchors = baseanchors.anchors
+ baseanchors = baseanchors['basemark']
if baseanchors then
- baseanchors = baseanchors['basemark']
- if baseanchors then
- local al = anchorlookups[lookupname]
- for anchor,ba in next, baseanchors do
- if al[anchor] then
- local ma = markanchors[anchor]
- 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)",
- pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
- end
- return start,true
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ 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)",
+ pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
end
+ return start,true
end
end
- if trace_bugs then
- logwarning("%s: no matching anchors for mark %s and basemark %s",pref(kind,lookupname),gref(markchar),gref(basechar))
- end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and basemark %s",pref(kind,lookupname),gref(markchar),gref(basechar))
end
end
- else -- if trace_bugs then
- -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar))
- onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
end
- elseif trace_bugs then
- logwarning("%s: prev node is no mark",pref(kind,lookupname))
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar))
+ onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
end
---~ elseif trace_marks and trace_details then
---~ logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone)
---~ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark",pref(kind,lookupname))
+ end
elseif trace_bugs then
logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
end
@@ -1292,18 +1295,14 @@ function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,
end
if markanchors then
local base = start.prev -- [glyph] [optional marks] [start=mark]
- local index = 1
if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then
local basechar = base.char
if marks[basechar] then
- index = index + 1
while true do
base = base.prev
if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then
basechar = base.char
- if marks[basechar] then
- index = index + 1
- else
+ if not marks[basechar] then
break
end
else
@@ -1315,8 +1314,7 @@ function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,
end
end
-- todo: like marks a ligatures hash
- local i = has_attribute(start,markdone)
- if i then index = i end
+ local index = has_attribute(start,ligacomp)
local baseanchors = descriptions[basechar].anchors
if baseanchors then
local baseanchors = baseanchors['baselig']
@@ -1328,7 +1326,7 @@ function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,
if ma then
ba = ba[index]
if ba then
- local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,index)
+ 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)",
cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy)
@@ -1369,6 +1367,20 @@ function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,look
end
if markanchors then
local base = start.prev -- [glyph] [basemark] [start=mark]
+ -- while (base and has_attribute(base,ligacomp) and has_attribute(base,ligacomp) ~= has_attribute(start,ligacomp)) do
+ -- base = base.prev -- KE: prevents mkmk for marks on different components of a ligature
+ -- end
+ local slc = has_attribute(start,ligacomp)
+ if slc then -- a rather messy loop ... needs checking with husayni
+ while base do
+ local blc = has_attribute(base,ligacomp)
+ if blc and blc ~= slc then
+ base = base.prev
+ else
+ break
+ end
+ end
+ end
if base and base.id == glyph_code and base.subtype<256 and base.font == currentfont then -- subtype test can go
local basechar = base.char
local baseanchors = descriptions[basechar].anchors
@@ -1584,7 +1596,7 @@ local function show_skip(kind,chainname,char,ck,class)
end
local function normal_handle_contextchain(start,kind,chainname,contexts,sequence,lookuphash)
- -- local rule, lookuptype, sequence, f, l, lookups = ck[1], ck[2] ,ck[3], ck[4], ck[5], ck[6]
+ -- local rule, lookuptype, sequence, f, l, lookups = ck[1], ck[2] ,ck[3], ck[4], ck[5], ck[6]
local flags = sequence.flags
local done = false
local skipmark = flags[1]
@@ -1806,11 +1818,15 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence
if nofchainlookups == 1 then
local chainlookupname = chainlookups[1]
local chainlookup = lookuptable[chainlookupname]
- local cp = chainprocs[chainlookup.type]
- if cp then
- start, done = cp(start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence)
- else
- logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type)
+ if chainlookup then
+ local cp = chainprocs[chainlookup.type]
+ if cp then
+ start, done = cp(start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence)
+ else
+ logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type)
+ end
+ else -- shouldn't happen
+ logprocess("%s is not yet supported",cref(kind,chainname,chainlookupname))
end
else
local i = 1
diff --git a/otfl-node-inj.lua b/otfl-node-inj.lua
index 7c91016..246aaad 100644
--- a/otfl-node-inj.lua
+++ b/otfl-node-inj.lua
@@ -45,6 +45,7 @@ local cursbase = attributes.private('cursbase')
local curscurs = attributes.private('curscurs')
local cursdone = attributes.private('cursdone')
local kernpair = attributes.private('kernpair')
+local ligacomp = attributes.private('ligacomp')
local fontkern = attributes.private('fontkern')
if context then
@@ -61,16 +62,21 @@ if context then
end
+-- This injector has been tested by Idris Samawi Hamid (several arabic fonts as well as
+-- the rather demanding Husayni font), Khaled Hosny (latin and arabic) and Kaj Eigner
+-- (arabic, hebrew and thai) and myself (whatever font I come across). I'm pretty sure
+-- that this code is not 100% okay but examples are needed to figure things out.
+
local cursives = { }
local marks = { }
local kerns = { }
--- currently we do gpos/kern in a bit inofficial way but when we
--- have the extra fields in glyphnodes to manipulate ht/dp/wd
--- explicitly i will provide an alternative; also, we can share
--- tables
+-- Currently we do gpos/kern in a bit inofficial way but when we have the extra fields in
+-- glyphnodes to manipulate ht/dp/wd explicitly I will provide an alternative; also, we
+-- can share tables.
--- for the moment we pass the r2l key ... volt/arabtype tests
+-- For the moment we pass the r2l key ... volt/arabtype tests .. idris: this needs
+-- checking with husayni (volt and fontforge).
function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext)
local dx, dy = factor*(exit[1]-entry[1]), factor*(exit[2]-entry[2])
@@ -113,14 +119,16 @@ function injections.setkern(current,factor,rlmode,x,tfmchr)
end
end
-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)
+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]) -- the index argument is no longer used but when this
+ local bound = has_attribute(base,markbase) -- fails again we should pass it
+local index = 1
if bound then
local mb = marks[bound]
if mb then
- if not index then index = #mb + 1 end
- mb[index] = { dx, dy }
+ -- if not index then index = #mb + 1 end
+index = #mb + 1
+ mb[index] = { dx, dy, rlmode }
set_attribute(start,markmark,bound)
set_attribute(start,markdone,index)
return dx, dy, bound
@@ -128,6 +136,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,index) --ba=baseancho
report_injections("possible problem, U+%05X is base mark without data (id: %s)",base.char,bound)
end
end
+-- index = index or 1
index = index or 1
bound = #marks + 1
set_attribute(base,markbase,bound)
@@ -174,7 +183,7 @@ local function trace(head)
end
else
m = m[1]
- report_injections(" 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 and m[1] or "?",m and m[2] or "?")
end
end
if cb then
@@ -192,7 +201,8 @@ end
-- todo: reuse tables (i.e. no collection), but will be extra fields anyway
-- todo: check for attribute
--- we can have a fast test on a font being processed, so we can check faster for marks etc
+-- We can have a fast test on a font being processed, so we can check faster for marks etc
+-- but I'll make a context variant anyway.
function injections.handler(head,where,keep)
local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns)
@@ -330,6 +340,7 @@ function injections.handler(head,where,keep)
local p_markbase = has_attribute(p,markbase)
if p_markbase then
local mrks = marks[p_markbase]
+ local nofmarks = #mrks
for n in traverse_id(glyph_code,p.next) do
local n_markmark = has_attribute(n,markmark)
if p_markbase == n_markmark then
@@ -343,7 +354,7 @@ function injections.handler(head,where,keep)
-- 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
+ -- that enter this branch .. I'm still not sure if this
-- one is right
local k = wx[p]
if k then
@@ -366,9 +377,14 @@ function injections.handler(head,where,keep)
else
n.yoffset = n.yoffset + p.yoffset + d[2]
end
+ if nofmarks == 1 then
+ break
+ else
+ nofmarks = nofmarks - 1
+ end
end
else
- break
+ -- KE: there can be <mark> <mkmk> <mark> sequences in ligatures
end
end
end
@@ -380,23 +396,32 @@ function injections.handler(head,where,keep)
-- todo : combine
if next(wx) then
for n, k in next, wx do
- -- 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 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))
+ -- only w can be nil (kernclasses), can be sped up when w == nil
+ local x, w = k[2] or 0, k[4]
+ if w then
+ local rl = k[1] -- r2l = k[6]
+ local wx = w - x
+ if rl < 0 then -- KE: don't use r2l here
+ 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
+ elseif x ~= 0 then
+ -- 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)
+ insert_node_before(head,n,newkern(x))
end
end
end
@@ -435,9 +460,9 @@ function injections.handler(head,where,keep)
end
if w then
-- copied from above
- local r2l = kk[6]
+ -- local r2l = kk[6]
local wx = w - x
- if r2l then
+ if rl < 0 then -- KE: don't use r2l here
if wx ~= 0 then
insert_node_before(head,n,newkern(wx))
end