summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2015-03-11 07:46:44 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2015-03-11 07:46:44 +0100
commitf070e8b5b193c0ce686d2e6448b53338a499aecf (patch)
tree637122d22c56e6ad3a0b3a1a47ae2a2b9c46126b /src
parent380989f0de1f2aa9a8d0a0856de1b1e09321d1e5 (diff)
downloadluaotfload-f070e8b5b193c0ce686d2e6448b53338a499aecf.tar.gz
[fontloader] sync with Context as of 2015-03-11
Diffstat (limited to 'src')
-rw-r--r--src/fontloader/misc/fontloader-font-otf.lua2
-rw-r--r--src/fontloader/misc/fontloader-font-tfm.lua6
-rw-r--r--src/fontloader/misc/fontloader-fonts-cbk.lua13
-rw-r--r--src/fontloader/misc/fontloader-fonts-inj.lua385
-rw-r--r--src/fontloader/misc/fontloader-fonts-otn.lua12
-rw-r--r--src/fontloader/runtime/fontloader-basics-gen.lua9
-rw-r--r--src/fontloader/runtime/fontloader-fontloader.lua402
7 files changed, 460 insertions, 369 deletions
diff --git a/src/fontloader/misc/fontloader-font-otf.lua b/src/fontloader/misc/fontloader-font-otf.lua
index 44ad893..c7e83a4 100644
--- a/src/fontloader/misc/fontloader-font-otf.lua
+++ b/src/fontloader/misc/fontloader-font-otf.lua
@@ -53,7 +53,7 @@ local otf = fonts.handlers.otf
otf.glists = { "gsub", "gpos" }
-otf.version = 2.802 -- beware: also sync font-mis.lua
+otf.version = 2.803 -- beware: also sync font-mis.lua
otf.cache = containers.define("fonts", "otf", otf.version, true)
local hashes = fonts.hashes
diff --git a/src/fontloader/misc/fontloader-font-tfm.lua b/src/fontloader/misc/fontloader-font-tfm.lua
index 49df94e..ab03788 100644
--- a/src/fontloader/misc/fontloader-font-tfm.lua
+++ b/src/fontloader/misc/fontloader-font-tfm.lua
@@ -72,15 +72,15 @@ local function read_from_tfm(specification)
properties.filename = specification.filename
properties.format = fonts.formats.tfm -- better than nothing
parameters.size = size
- shared.rawdata = { }
- shared.features = features
- shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil
--
tfmdata.properties = properties
tfmdata.resources = resources
tfmdata.parameters = parameters
tfmdata.shared = shared
--
+ shared.rawdata = { }
+ shared.features = features
+ shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil
parameters.slant = parameters.slant or parameters[1] or 0
parameters.space = parameters.space or parameters[2] or 0
parameters.space_stretch = parameters.space_stretch or parameters[3] or 0
diff --git a/src/fontloader/misc/fontloader-fonts-cbk.lua b/src/fontloader/misc/fontloader-fonts-cbk.lua
index 414cafb..ce19c88 100644
--- a/src/fontloader/misc/fontloader-fonts-cbk.lua
+++ b/src/fontloader/misc/fontloader-fonts-cbk.lua
@@ -116,13 +116,14 @@ function nodes.handlers.nodepass(head)
if basepass and #basefonts > 0 then
for i=1,#basefonts do
local range = basefonts[i]
- local start, stop = range[1], range[2]
+ local start = range[1]
+ local stop = range[2]
if stop then
- ligaturing(start,stop)
- kerning(start,stop)
- else
- ligaturing(start)
- kerning(start)
+ start, stop = ligaturing(start,stop)
+ start, stop = kerning(start,stop)
+ elseif start then
+ start = ligaturing(start)
+ start = kerning(start)
end
end
end
diff --git a/src/fontloader/misc/fontloader-fonts-inj.lua b/src/fontloader/misc/fontloader-fonts-inj.lua
index 3b93382..cb9ed89 100644
--- a/src/fontloader/misc/fontloader-fonts-inj.lua
+++ b/src/fontloader/misc/fontloader-fonts-inj.lua
@@ -14,13 +14,12 @@ if not nodes.properties then return end
local next, rawget = next, rawget
local utfchar = utf.char
+local fastcopy = table.fastcopy
local trace_injections = false trackers.register("fonts.injections", function(v) trace_injections = v end)
local report_injections = logs.reporter("fonts","injections")
-report_injections("using experimental injector")
-
local attributes, nodes, node = attributes, nodes, node
fonts = fonts
@@ -81,19 +80,42 @@ function injections.resetcounts()
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,start)
- if p and p.injections then
- -- todo: decrement counters? tricky as we then need to change the nof* to not increment
- -- when we change a property
- p.injections = nil -- should we keep the liga index?
+ 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.setligaindex(n,index)
local p = rawget(properties,n)
if p then
- local i = p.injections
+ local i = rawget(p,"injections")
if i then
i.ligaindex = index
else
@@ -113,9 +135,9 @@ end
function injections.getligaindex(n,default)
local p = rawget(properties,n)
if p then
- p = p.injections
- if p then
- return p.ligaindex or default
+ local i = rawget(p,"injections")
+ if i then
+ return i.ligaindex or default
end
end
return default
@@ -134,7 +156,7 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne
--
local p = rawget(properties,start)
if p then
- local i = p.injections
+ local i = rawget(p,"injections")
if i then
i.cursiveanchor = true
else
@@ -151,7 +173,7 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne
end
local p = rawget(properties,nxt)
if p then
- local i = p.injections
+ local i = rawget(p,"injections")
if i then
i.cursivex = dx
i.cursivey = dy
@@ -185,14 +207,16 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) -- r2l
end
local p = rawget(properties,current)
if p then
- local i = p.injections
+ local i = rawget(p,"injections")
if i then
- if leftkern ~= 0 or rightkern ~= 0 then
- i.leftkern = i.leftkern or 0 + leftkern
- i.rightkern = i.rightkern or 0 + rightkern
+ if leftkern ~= 0 then
+ i.leftkern = (i.leftkern or 0) + leftkern
+ end
+ if rightkern ~= 0 then
+ i.rightkern = (i.rightkern or 0) + rightkern
end
if yoffset ~= 0 then
- i.yoffset = i.yoffset or 0 + yoffset
+ i.yoffset = (i.yoffset or 0) + yoffset
end
elseif leftkern ~= 0 or rightkern ~= 0 then
p.injections = {
@@ -240,9 +264,9 @@ function injections.setkern(current,factor,rlmode,x,injection)
injection = "injections"
end
if p then
- local i = p[injection]
+ local i = rawget(p,injection)
if i then
- i.leftkern = dx + i.leftkern or 0
+ i.leftkern = dx + (i.leftkern or 0)
else
p[injection] = {
leftkern = dx,
@@ -270,7 +294,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase) -- ba=basean
end
local p = rawget(properties,start)
if p then
- local i = p.injections
+ local i = rawget(p,"injections")
if i then
i.markx = dx
i.marky = dy
@@ -313,18 +337,18 @@ local function show(n,what,nested,symbol)
if n then
local p = rawget(properties,n)
if p then
- local p = p[what]
- if p then
- local leftkern = p.leftkern or 0
- local rightkern = p.rightkern or 0
- local yoffset = p.yoffset or 0
- local markx = p.markx or 0
- local marky = p.marky or 0
- local markdir = p.markdir or 0
- local markbase = p.markbase or 0 -- will be markbasenode
- local cursivex = p.cursivex or 0
- local cursivey = p.cursivey or 0
- local ligaindex = p.ligaindex or 0
+ local i = rawget(p,what)
+ if i then
+ local leftkern = i.leftkern or 0
+ local rightkern = i.rightkern or 0
+ local yoffset = i.yoffset or 0
+ local markx = i.markx or 0
+ local marky = i.marky or 0
+ local markdir = i.markdir or 0
+ local markbase = i.markbase or 0 -- will be markbasenode
+ local cursivex = i.cursivex or 0
+ local cursivey = i.cursivey or 0
+ local ligaindex = i.ligaindex or 0
local margin = nested and 4 or 2
--
if rightkern ~= 0 or yoffset ~= 0 then
@@ -355,9 +379,9 @@ local function showsub(n,what,where)
report_injections("end subrun")
end
-local function trace(head)
- report_injections("begin run: %s kerns, %s pairs, %s marks and %s cursives registered",
- nofregisteredkerns,nofregisteredpairs,nofregisteredmarks,nofregisteredcursives)
+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)
local n = head
while n do
local id = getid(n)
@@ -414,10 +438,6 @@ local function collect_glyphs_1(head)
local nf, tm = nil, nil
for n in traverse_id(glyph_code,head) do -- only needed for relevant fonts
if getsubtype(n) < 256 then
- local pn = rawget(properties,n)
- if pn then
- pn = pn.injections
- end
local f = getfont(n)
if f ~= nf then
nf = f
@@ -431,10 +451,14 @@ local function collect_glyphs_1(head)
glyphs[nofglyphs] = n
end
-- yoffsets can influence curs steps
- if pn then
- local yoffset = pn.yoffset
- if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
+ local p = rawget(properties,n)
+ if p then
+ local i = rawget(p,"injections")
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setfield(n,"yoffset",yoffset)
+ end
end
end
end
@@ -470,18 +494,20 @@ local function inject_marks(marks,nofmarks)
local n = marks[i]
local pn = rawget(properties,n)
if pn then
- pn = pn.injections
- end
- if pn then
- -- local markbase = pn.markbase
- -- if markbase then
- -- local p = markanchors[markbase]
+ pn = rawget(pn,"injections")
+ if pn then
local p = pn.markbasenode
if p then
local px = getfield(p,"xoffset")
local ox = 0
+ local rightkern = nil
local pp = rawget(properties,p)
- local rightkern = pp and pp.rightkern
+ if pp then
+ pp = rawget(pp,"injections")
+ if pp then
+ rightkern = pp.rightkern
+ end
+ end
if rightkern then -- x and w ~= 0
if pn.markdir < 0 then
-- kern(w-x) glyph(p) kern(x) mark(n)
@@ -490,8 +516,13 @@ local function inject_marks(marks,nofmarks)
else
-- kern(x) glyph(p) kern(w-x) mark(n)
-- ox = px - getfield(p,"width") + pn.markx - pp.leftkern
- ox = px - pn.markx - pp.leftkern
- -- report_injections("l2r case 1: %p",ox)
+ local leftkern = pp.leftkern
+ if leftkern then
+ ox = px - pn.markx
+ else
+ ox = px - pn.markx - leftkern
+ end
+-- report_injections("l2r case 1: %p",ox)
end
else
-- we need to deal with fonts that have marks with width
@@ -525,10 +556,10 @@ local function inject_marks(marks,nofmarks)
end
setfield(n,"yoffset",oy)
else
- -- normally this can't happen (only when in trace mode which is a special case anyway)
+ -- normally this can't happen (only when in trace mode which is a special case anyway)
-- report_injections("missing mark anchor %i",pn.markbase or 0)
end
- -- end
+ end
end
end
end
@@ -540,14 +571,14 @@ local function inject_cursives(glyphs,nofglyphs)
local n = glyphs[i]
local pn = rawget(properties,n)
if pn then
- pn = pn.injections
+ pn = rawget(pn,"injections")
end
if pn then
local cursivex = pn.cursivex
if cursivex then
if cursiveanchor then
if cursivex ~= 0 then
- pn.leftkern = pn.leftkern or 0 + cursivex
+ pn.leftkern = (pn.leftkern or 0) + cursivex
end
if lastanchor then
if maxc == 0 then
@@ -622,16 +653,16 @@ local function inject_kerns(head,glyphs,nofglyphs)
local n = glyphs[i]
local pn = rawget(properties,n)
if pn then
- pn = pn.injections
- end
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
- insert_node_before(head,n,newkern(leftkern)) -- type 0/2
- end
- local rightkern = pn.rightkern
- if rightkern and rightkern ~= 0 then
- insert_node_after(head,n,newkern(rightkern)) -- type 0/2
+ local i = rawget(pn,"injections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ insert_node_before(head,n,newkern(leftkern)) -- type 0/2
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(head,n,newkern(rightkern)) -- type 0/2
+ end
end
end
end
@@ -640,7 +671,7 @@ end
local function inject_everything(head,where)
head = tonut(head)
if trace_injections then
- trace(head)
+ trace(head,"everything")
end
local glyphs, nofglyphs, marks, nofmarks
if nofregisteredpairs > 0 then
@@ -652,7 +683,7 @@ local function inject_everything(head,where)
if nofregisteredcursives > 0 then
inject_cursives(glyphs,nofglyphs)
end
- if nofregisteredmarks > 0 then
+ if nofregisteredmarks > 0 then -- and nofmarks > 0
inject_marks(marks,nofmarks)
end
inject_kerns(head,glyphs,nofglyphs)
@@ -671,7 +702,7 @@ end
local function inject_kerns_only(head,where)
head = tonut(head)
if trace_injections then
- trace(head)
+ trace(head,"kerns")
end
local n = head
local p = nil
@@ -684,10 +715,10 @@ local function inject_kerns_only(head,where)
if p then
local d = getfield(p,"post")
if d then
- local pn = pn.postinjections
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
+ local i = rawget(pn,"postinjections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
local t = find_tail(d)
insert_node_after(d,t,newkern(leftkern))
end
@@ -695,28 +726,28 @@ local function inject_kerns_only(head,where)
end
local d = getfield(p,"replace")
if d then
- local pn = pn.replaceinjections
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
+ local i = rawget(pn,"replaceinjections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
local t = find_tail(d)
insert_node_after(d,t,newkern(leftkern))
end
end
else
- local pn = pn.injections
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
+ local i = rawget(pn,"injections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
setfield(p,"replace",newkern(leftkern))
end
end
end
else
- local pn = pn.injections
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
+ local i = rawget(pn,"injections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
head = insert_node_before(head,n,newkern(leftkern))
end
end
@@ -734,12 +765,12 @@ local function inject_kerns_only(head,where)
if getsubtype(n) < 256 then
local pn = rawget(properties,n)
if pn then
- pn = pn.preinjections
- end
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
- h = insert_node_before(h,n,newkern(leftkern))
+ local i = rawget(pn,"preinjections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ h = insert_node_before(h,n,newkern(leftkern))
+ end
end
end
else
@@ -757,12 +788,12 @@ local function inject_kerns_only(head,where)
if getsubtype(n) < 256 then
local pn = rawget(properties,n)
if pn then
- pn = pn.postinjections
- end
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
- h = insert_node_before(h,n,newkern(leftkern))
+ local i = rawget(pn,"postinjections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ h = insert_node_before(h,n,newkern(leftkern))
+ end
end
end
else
@@ -780,12 +811,12 @@ local function inject_kerns_only(head,where)
if getsubtype(n) < 256 then
local pn = rawget(properties,n) -- why can it be empty { }
if pn then
- pn = pn.replaceinjections
- end
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
- h = insert_node_before(h,n,newkern(leftkern))
+ local i = rawget(pn,"replaceinjections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ h = insert_node_before(h,n,newkern(leftkern))
+ end
end
end
else
@@ -814,7 +845,7 @@ end
local function inject_pairs_only(head,where)
head = tonut(head)
if trace_injections then
- trace(head)
+ trace(head,"pairs")
end
--
local n = head
@@ -828,14 +859,14 @@ local function inject_pairs_only(head,where)
if p then
local d = getfield(p,"post")
if d then
- local pn = pn.postinjections
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
+ local i = rawget(pn,"postinjections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
local t = find_tail(d)
insert_node_after(d,t,newkern(leftkern))
end
- -- local rightkern = pn.rightkern
+ -- local rightkern = i.rightkern
-- if rightkern and rightkern ~= 0 then
-- insert_node_after(head,n,newkern(rightkern))
-- n = getnext(n) -- to be checked
@@ -844,27 +875,27 @@ local function inject_pairs_only(head,where)
end
local d = getfield(p,"replace")
if d then
- local pn = pn.replaceinjections
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
+ local i = rawget(pn,"replaceinjections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
local t = find_tail(d)
insert_node_after(d,t,newkern(leftkern))
end
- -- local rightkern = pn.rightkern
+ -- local rightkern = i.rightkern
-- if rightkern and rightkern ~= 0 then
-- insert_node_after(head,n,newkern(rightkern))
-- n = getnext(n) -- to be checked
-- end
end
else
- local pn = pn.injections
- if pn then
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
+ local i = rawget(pn,"injections")
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
setfield(p,"replace",newkern(leftkern))
end
- -- local rightkern = pn.rightkern
+ -- local rightkern = i.rightkern
-- if rightkern and rightkern ~= 0 then
-- insert_node_after(head,n,newkern(rightkern))
-- n = getnext(n) -- to be checked
@@ -873,17 +904,17 @@ local function inject_pairs_only(head,where)
end
else
-- this is the most common case
- local pn = pn.injections
- if pn then
- local yoffset = pn.yoffset
+ local i = rawget(pn,"injections")
+ if i then
+ local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
setfield(n,"yoffset",yoffset)
end
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
insert_node_before(head,n,newkern(leftkern))
end
- local rightkern = pn.rightkern
+ local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
insert_node_after(head,n,newkern(rightkern))
n = getnext(n) -- to be checked
@@ -901,23 +932,23 @@ local function inject_pairs_only(head,where)
local h = d
for n in traverse_id(glyph_code,d) do
if getsubtype(n) < 256 then
- local pn = rawget(properties,n)
- if pn then
- pn = pn.preinjections
- end
- if pn then
- local yoffset = pn.yoffset
- if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
- end
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
- h = insert_node_before(h,n,newkern(leftkern))
- end
- local rightkern = pn.rightkern
- if rightkern and rightkern ~= 0 then
- insert_node_after(head,n,newkern(rightkern))
- n = getnext(n) -- to be checked
+ local p = rawget(properties,n)
+ if p then
+ local i = rawget(p,"preinjections")
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setfield(n,"yoffset",yoffset)
+ end
+ local leftkern = i.leftkern
+ if leftkern ~= 0 then
+ h = insert_node_before(h,n,newkern(leftkern))
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(head,n,newkern(rightkern))
+ n = getnext(n) -- to be checked
+ end
end
end
else
@@ -933,23 +964,23 @@ local function inject_pairs_only(head,where)
local h = d
for n in traverse_id(glyph_code,d) do
if getsubtype(n) < 256 then
- local pn = rawget(properties,n)
- if pn then
- pn = pn.postinjections
- end
- if pn then
- local yoffset = pn.yoffset
- if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
- end
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
- h = insert_node_before(h,n,newkern(leftkern))
- end
- local rightkern = pn.rightkern
- if rightkern and rightkern ~= 0 then
- insert_node_after(head,n,newkern(rightkern))
- n = getnext(n) -- to be checked
+ local p = rawget(properties,n)
+ if p then
+ local i = rawget(p,"postinjections")
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setfield(n,"yoffset",yoffset)
+ end
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ h = insert_node_before(h,n,newkern(leftkern))
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(head,n,newkern(rightkern))
+ n = getnext(n) -- to be checked
+ end
end
end
else
@@ -965,23 +996,23 @@ local function inject_pairs_only(head,where)
local h = d
for n in traverse_id(glyph_code,d) do
if getsubtype(n) < 256 then
- local pn = rawget(properties,n)
- if pn then
- pn = pn.replaceinjections
- end
- if pn then
- local yoffset = pn.yoffset
- if yoffset and yoffset ~= 0 then
- setfield(n,"yoffset",yoffset)
- end
- local leftkern = pn.leftkern
- if leftkern ~= 0 then
- h = insert_node_before(h,n,newkern(leftkern))
- end
- local rightkern = pn.rightkern
- if rightkern and rightkern ~= 0 then
- insert_node_after(head,n,newkern(rightkern))
- n = getnext(n) -- to be checked
+ local p = rawget(properties,n)
+ if p then
+ local i = rawget(pn,"replaceinjections")
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setfield(n,"yoffset",yoffset)
+ end
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ h = insert_node_before(h,n,newkern(leftkern))
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(head,n,newkern(rightkern))
+ n = getnext(n) -- to be checked
+ end
end
end
else
diff --git a/src/fontloader/misc/fontloader-fonts-otn.lua b/src/fontloader/misc/fontloader-fonts-otn.lua
index 32dc820..3f53078 100644
--- a/src/fontloader/misc/fontloader-fonts-otn.lua
+++ b/src/fontloader/misc/fontloader-fonts-otn.lua
@@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['font-otn'] = {
license = "see context related readme files",
}
+-- todo: looks like we have a leak somewhere (probably in ligatures)
+-- todo: copy attributes to disc
+
-- this is a context version which can contain experimental code, but when we
-- have serious patches we also need to change the other two font-otn files
@@ -243,6 +246,7 @@ local setcursive = injections.setcursive
local setkern = injections.setkern
local setpair = injections.setpair
local resetinjection = injections.reset
+local copyinjection = injections.copy
local setligaindex = injections.setligaindex
local getligaindex = injections.getligaindex
@@ -354,13 +358,19 @@ local function copy_glyph(g) -- next and prev are untouched !
if components then
setfield(g,"components",nil)
local n = copy_node(g)
+ copyinjection(n,g) -- we need to preserve the lig indices
setfield(g,"components",components)
return n
else
- return copy_node(g)
+ local n = copy_node(g)
+ copyinjection(n,g) -- we need to preserve the lig indices
+ return n
end
end
+--
+
+
-- start is a mark and we need to keep that one
local function markstoligature(kind,lookupname,head,start,stop,char)
diff --git a/src/fontloader/runtime/fontloader-basics-gen.lua b/src/fontloader/runtime/fontloader-basics-gen.lua
index e7cdc7b..c4d6536 100644
--- a/src/fontloader/runtime/fontloader-basics-gen.lua
+++ b/src/fontloader/runtime/fontloader-basics-gen.lua
@@ -15,8 +15,13 @@ local dummyfunction = function()
end
local dummyreporter = function(c)
- return function(...)
- (texio.reporter or texio.write_nl)(c .. " : " .. string.formatters(...))
+ return function(f,...)
+ local r = texio.reporter or texio.write_nl
+ if f then
+ r(c .. " : " .. string.formatters(f,...))
+ else
+ r("")
+ end
end
end
diff --git a/src/fontloader/runtime/fontloader-fontloader.lua b/src/fontloader/runtime/fontloader-fontloader.lua
index 6500989..b662152 100644
--- a/src/fontloader/runtime/fontloader-fontloader.lua
+++ b/src/fontloader/runtime/fontloader-fontloader.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 12/31/14 16:52:11
+-- merge date : 03/10/15 12:09:17
do -- begin closure to overcome local limits and interference
@@ -3374,8 +3374,13 @@ end
local dummyfunction=function()
end
local dummyreporter=function(c)
- return function(...)
- (texio.reporter or texio.write_nl)(c.." : "..string.formatters(...))
+ return function(f,...)
+ local r=texio.reporter or texio.write_nl
+ if f then
+ r(c.." : "..string.formatters(f,...))
+ else
+ r("")
+ end
end
end
statistics={
@@ -5794,13 +5799,13 @@ local function read_from_tfm(specification)
properties.filename=specification.filename
properties.format=fonts.formats.tfm
parameters.size=size
- shared.rawdata={}
- shared.features=features
- shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil
tfmdata.properties=properties
tfmdata.resources=resources
tfmdata.parameters=parameters
tfmdata.shared=shared
+ shared.rawdata={}
+ shared.features=features
+ shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil
parameters.slant=parameters.slant or parameters[1] or 0
parameters.space=parameters.space or parameters[2] or 0
parameters.space_stretch=parameters.space_stretch or parameters[3] or 0
@@ -7057,7 +7062,7 @@ local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
otf.glists={ "gsub","gpos" }
-otf.version=2.802
+otf.version=2.803
otf.cache=containers.define("fonts","otf",otf.version,true)
local hashes=fonts.hashes
local definers=fonts.definers
@@ -9840,9 +9845,9 @@ if not modules then modules={} end modules ['font-inj']={
if not nodes.properties then return end
local next,rawget=next,rawget
local utfchar=utf.char
+local fastcopy=table.fastcopy
local trace_injections=false trackers.register("fonts.injections",function(v) trace_injections=v end)
local report_injections=logs.reporter("fonts","injections")
-report_injections("using experimental injector")
local attributes,nodes,node=attributes,nodes,node
fonts=fonts
local fontdata=fonts.hashes.identifiers
@@ -9889,15 +9894,36 @@ function injections.resetcounts()
keepregisteredcounts=false
end
function injections.reset(n)
- local p=rawget(properties,start)
- if p and p.injections then
- p.injections=nil
+ 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.setligaindex(n,index)
local p=rawget(properties,n)
if p then
- local i=p.injections
+ local i=rawget(p,"injections")
if i then
i.ligaindex=index
else
@@ -9916,9 +9942,9 @@ end
function injections.getligaindex(n,default)
local p=rawget(properties,n)
if p then
- p=p.injections
- if p then
- return p.ligaindex or default
+ local i=rawget(p,"injections")
+ if i then
+ return i.ligaindex or default
end
end
return default
@@ -9935,7 +9961,7 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne
end
local p=rawget(properties,start)
if p then
- local i=p.injections
+ local i=rawget(p,"injections")
if i then
i.cursiveanchor=true
else
@@ -9952,7 +9978,7 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne
end
local p=rawget(properties,nxt)
if p then
- local i=p.injections
+ local i=rawget(p,"injections")
if i then
i.cursivex=dx
i.cursivey=dy
@@ -9985,14 +10011,16 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection)
end
local p=rawget(properties,current)
if p then
- local i=p.injections
+ local i=rawget(p,"injections")
if i then
- if leftkern~=0 or rightkern~=0 then
- i.leftkern=i.leftkern or 0+leftkern
- i.rightkern=i.rightkern or 0+rightkern
+ if leftkern~=0 then
+ i.leftkern=(i.leftkern or 0)+leftkern
+ end
+ if rightkern~=0 then
+ i.rightkern=(i.rightkern or 0)+rightkern
end
if yoffset~=0 then
- i.yoffset=i.yoffset or 0+yoffset
+ i.yoffset=(i.yoffset or 0)+yoffset
end
elseif leftkern~=0 or rightkern~=0 then
p.injections={
@@ -10034,9 +10062,9 @@ function injections.setkern(current,factor,rlmode,x,injection)
injection="injections"
end
if p then
- local i=p[injection]
+ local i=rawget(p,injection)
if i then
- i.leftkern=dx+i.leftkern or 0
+ i.leftkern=dx+(i.leftkern or 0)
else
p[injection]={
leftkern=dx,
@@ -10062,7 +10090,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase)
end
local p=rawget(properties,start)
if p then
- local i=p.injections
+ local i=rawget(p,"injections")
if i then
i.markx=dx
i.marky=dy
@@ -10102,18 +10130,18 @@ local function show(n,what,nested,symbol)
if n then
local p=rawget(properties,n)
if p then
- local p=p[what]
- if p then
- local leftkern=p.leftkern or 0
- local rightkern=p.rightkern or 0
- local yoffset=p.yoffset or 0
- local markx=p.markx or 0
- local marky=p.marky or 0
- local markdir=p.markdir or 0
- local markbase=p.markbase or 0
- local cursivex=p.cursivex or 0
- local cursivey=p.cursivey or 0
- local ligaindex=p.ligaindex or 0
+ local i=rawget(p,what)
+ if i then
+ local leftkern=i.leftkern or 0
+ local rightkern=i.rightkern or 0
+ local yoffset=i.yoffset or 0
+ local markx=i.markx or 0
+ local marky=i.marky or 0
+ local markdir=i.markdir or 0
+ local markbase=i.markbase or 0
+ local cursivex=i.cursivex or 0
+ local cursivey=i.cursivey or 0
+ local ligaindex=i.ligaindex or 0
local margin=nested and 4 or 2
if rightkern~=0 or yoffset~=0 then
report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset)
@@ -10141,9 +10169,9 @@ local function showsub(n,what,where)
end
report_injections("end subrun")
end
-local function trace(head)
- report_injections("begin run: %s kerns, %s pairs, %s marks and %s cursives registered",
- nofregisteredkerns,nofregisteredpairs,nofregisteredmarks,nofregisteredcursives)
+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)
local n=head
while n do
local id=getid(n)
@@ -10196,10 +10224,6 @@ local function collect_glyphs_1(head)
local nf,tm=nil,nil
for n in traverse_id(glyph_code,head) do
if getsubtype(n)<256 then
- local pn=rawget(properties,n)
- if pn then
- pn=pn.injections
- end
local f=getfont(n)
if f~=nf then
nf=f
@@ -10212,10 +10236,14 @@ local function collect_glyphs_1(head)
nofglyphs=nofglyphs+1
glyphs[nofglyphs]=n
end
- if pn then
- local yoffset=pn.yoffset
- if yoffset and yoffset~=0 then
- setfield(n,"yoffset",yoffset)
+ local p=rawget(properties,n)
+ if p then
+ local i=rawget(p,"injections")
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setfield(n,"yoffset",yoffset)
+ end
end
end
end
@@ -10249,20 +10277,30 @@ local function inject_marks(marks,nofmarks)
local n=marks[i]
local pn=rawget(properties,n)
if pn then
- pn=pn.injections
- end
- if pn then
+ pn=rawget(pn,"injections")
+ if pn then
local p=pn.markbasenode
if p then
local px=getfield(p,"xoffset")
local ox=0
+ local rightkern=nil
local pp=rawget(properties,p)
- local rightkern=pp and pp.rightkern
+ if pp then
+ pp=rawget(pp,"injections")
+ if pp then
+ rightkern=pp.rightkern
+ end
+ end
if rightkern then
if pn.markdir<0 then
ox=px-pn.markx-rightkern
else
- ox=px-pn.markx-pp.leftkern
+ local leftkern=pp.leftkern
+ if leftkern then
+ ox=px-pn.markx
+ else
+ ox=px-pn.markx-leftkern
+ end
end
else
ox=px-pn.markx
@@ -10283,6 +10321,7 @@ local function inject_marks(marks,nofmarks)
setfield(n,"yoffset",oy)
else
end
+ end
end
end
end
@@ -10293,14 +10332,14 @@ local function inject_cursives(glyphs,nofglyphs)
local n=glyphs[i]
local pn=rawget(properties,n)
if pn then
- pn=pn.injections
+ pn=rawget(pn,"injections")
end
if pn then
local cursivex=pn.cursivex
if cursivex then
if cursiveanchor then
if cursivex~=0 then
- pn.leftkern=pn.leftkern or 0+cursivex
+ pn.leftkern=(pn.leftkern or 0)+cursivex
end
if lastanchor then
if maxc==0 then
@@ -10364,16 +10403,16 @@ local function inject_kerns(head,glyphs,nofglyphs)
local n=glyphs[i]
local pn=rawget(properties,n)
if pn then
- pn=pn.injections
- end
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
- insert_node_before(head,n,newkern(leftkern))
- end
- local rightkern=pn.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(head,n,newkern(rightkern))
+ local i=rawget(pn,"injections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ insert_node_before(head,n,newkern(leftkern))
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,n,newkern(rightkern))
+ end
end
end
end
@@ -10381,7 +10420,7 @@ end
local function inject_everything(head,where)
head=tonut(head)
if trace_injections then
- trace(head)
+ trace(head,"everything")
end
local glyphs,nofglyphs,marks,nofmarks
if nofregisteredpairs>0 then
@@ -10393,7 +10432,7 @@ local function inject_everything(head,where)
if nofregisteredcursives>0 then
inject_cursives(glyphs,nofglyphs)
end
- if nofregisteredmarks>0 then
+ if nofregisteredmarks>0 then
inject_marks(marks,nofmarks)
end
inject_kerns(head,glyphs,nofglyphs)
@@ -10411,7 +10450,7 @@ end
local function inject_kerns_only(head,where)
head=tonut(head)
if trace_injections then
- trace(head)
+ trace(head,"kerns")
end
local n=head
local p=nil
@@ -10424,10 +10463,10 @@ local function inject_kerns_only(head,where)
if p then
local d=getfield(p,"post")
if d then
- local pn=pn.postinjections
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
+ local i=rawget(pn,"postinjections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
local t=find_tail(d)
insert_node_after(d,t,newkern(leftkern))
end
@@ -10435,28 +10474,28 @@ local function inject_kerns_only(head,where)
end
local d=getfield(p,"replace")
if d then
- local pn=pn.replaceinjections
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
+ local i=rawget(pn,"replaceinjections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
local t=find_tail(d)
insert_node_after(d,t,newkern(leftkern))
end
end
else
- local pn=pn.injections
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
+ local i=rawget(pn,"injections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
setfield(p,"replace",newkern(leftkern))
end
end
end
else
- local pn=pn.injections
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
+ local i=rawget(pn,"injections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
head=insert_node_before(head,n,newkern(leftkern))
end
end
@@ -10474,12 +10513,12 @@ local function inject_kerns_only(head,where)
if getsubtype(n)<256 then
local pn=rawget(properties,n)
if pn then
- pn=pn.preinjections
- end
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
- h=insert_node_before(h,n,newkern(leftkern))
+ local i=rawget(pn,"preinjections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ h=insert_node_before(h,n,newkern(leftkern))
+ end
end
end
else
@@ -10497,12 +10536,12 @@ local function inject_kerns_only(head,where)
if getsubtype(n)<256 then
local pn=rawget(properties,n)
if pn then
- pn=pn.postinjections
- end
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
- h=insert_node_before(h,n,newkern(leftkern))
+ local i=rawget(pn,"postinjections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ h=insert_node_before(h,n,newkern(leftkern))
+ end
end
end
else
@@ -10520,12 +10559,12 @@ local function inject_kerns_only(head,where)
if getsubtype(n)<256 then
local pn=rawget(properties,n)
if pn then
- pn=pn.replaceinjections
- end
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
- h=insert_node_before(h,n,newkern(leftkern))
+ local i=rawget(pn,"replaceinjections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ h=insert_node_before(h,n,newkern(leftkern))
+ end
end
end
else
@@ -10552,7 +10591,7 @@ end
local function inject_pairs_only(head,where)
head=tonut(head)
if trace_injections then
- trace(head)
+ trace(head,"pairs")
end
local n=head
local p=nil
@@ -10565,10 +10604,10 @@ local function inject_pairs_only(head,where)
if p then
local d=getfield(p,"post")
if d then
- local pn=pn.postinjections
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
+ local i=rawget(pn,"postinjections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
local t=find_tail(d)
insert_node_after(d,t,newkern(leftkern))
end
@@ -10576,35 +10615,35 @@ local function inject_pairs_only(head,where)
end
local d=getfield(p,"replace")
if d then
- local pn=pn.replaceinjections
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
+ local i=rawget(pn,"replaceinjections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
local t=find_tail(d)
insert_node_after(d,t,newkern(leftkern))
end
end
else
- local pn=pn.injections
- if pn then
- local leftkern=pn.leftkern
- if leftkern~=0 then
+ local i=rawget(pn,"injections")
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
setfield(p,"replace",newkern(leftkern))
end
end
end
else
- local pn=pn.injections
- if pn then
- local yoffset=pn.yoffset
+ local i=rawget(pn,"injections")
+ if i then
+ local yoffset=i.yoffset
if yoffset and yoffset~=0 then
setfield(n,"yoffset",yoffset)
end
- local leftkern=pn.leftkern
- if leftkern~=0 then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
insert_node_before(head,n,newkern(leftkern))
end
- local rightkern=pn.rightkern
+ local rightkern=i.rightkern
if rightkern and rightkern~=0 then
insert_node_after(head,n,newkern(rightkern))
n=getnext(n)
@@ -10622,23 +10661,23 @@ local function inject_pairs_only(head,where)
local h=d
for n in traverse_id(glyph_code,d) do
if getsubtype(n)<256 then
- local pn=rawget(properties,n)
- if pn then
- pn=pn.preinjections
- end
- if pn then
- local yoffset=pn.yoffset
- if yoffset and yoffset~=0 then
- setfield(n,"yoffset",yoffset)
- end
- local leftkern=pn.leftkern
- if leftkern~=0 then
- h=insert_node_before(h,n,newkern(leftkern))
- end
- local rightkern=pn.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(head,n,newkern(rightkern))
- n=getnext(n)
+ local p=rawget(properties,n)
+ if p then
+ local i=rawget(p,"preinjections")
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setfield(n,"yoffset",yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern~=0 then
+ h=insert_node_before(h,n,newkern(leftkern))
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,n,newkern(rightkern))
+ n=getnext(n)
+ end
end
end
else
@@ -10654,23 +10693,23 @@ local function inject_pairs_only(head,where)
local h=d
for n in traverse_id(glyph_code,d) do
if getsubtype(n)<256 then
- local pn=rawget(properties,n)
- if pn then
- pn=pn.postinjections
- end
- if pn then
- local yoffset=pn.yoffset
- if yoffset and yoffset~=0 then
- setfield(n,"yoffset",yoffset)
- end
- local leftkern=pn.leftkern
- if leftkern~=0 then
- h=insert_node_before(h,n,newkern(leftkern))
- end
- local rightkern=pn.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(head,n,newkern(rightkern))
- n=getnext(n)
+ local p=rawget(properties,n)
+ if p then
+ local i=rawget(p,"postinjections")
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setfield(n,"yoffset",yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ h=insert_node_before(h,n,newkern(leftkern))
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,n,newkern(rightkern))
+ n=getnext(n)
+ end
end
end
else
@@ -10686,23 +10725,23 @@ local function inject_pairs_only(head,where)
local h=d
for n in traverse_id(glyph_code,d) do
if getsubtype(n)<256 then
- local pn=rawget(properties,n)
- if pn then
- pn=pn.replaceinjections
- end
- if pn then
- local yoffset=pn.yoffset
- if yoffset and yoffset~=0 then
- setfield(n,"yoffset",yoffset)
- end
- local leftkern=pn.leftkern
- if leftkern~=0 then
- h=insert_node_before(h,n,newkern(leftkern))
- end
- local rightkern=pn.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(head,n,newkern(rightkern))
- n=getnext(n)
+ local p=rawget(properties,n)
+ if p then
+ local i=rawget(pn,"replaceinjections")
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setfield(n,"yoffset",yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ h=insert_node_before(h,n,newkern(leftkern))
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,n,newkern(rightkern))
+ n=getnext(n)
+ end
end
end
else
@@ -11214,6 +11253,7 @@ local setcursive=injections.setcursive
local setkern=injections.setkern
local setpair=injections.setpair
local resetinjection=injections.reset
+local copyinjection=injections.copy
local setligaindex=injections.setligaindex
local getligaindex=injections.getligaindex
local cursonce=true
@@ -11296,10 +11336,13 @@ local function copy_glyph(g)
if components then
setfield(g,"components",nil)
local n=copy_node(g)
+ copyinjection(n,g)
setfield(g,"components",components)
return n
else
- return copy_node(g)
+ local n=copy_node(g)
+ copyinjection(n,g)
+ return n
end
end
local function markstoligature(kind,lookupname,head,start,stop,char)
@@ -15084,13 +15127,14 @@ function nodes.handlers.nodepass(head)
if basepass and #basefonts>0 then
for i=1,#basefonts do
local range=basefonts[i]
- local start,stop=range[1],range[2]
+ local start=range[1]
+ local stop=range[2]
if stop then
- ligaturing(start,stop)
- kerning(start,stop)
- else
- ligaturing(start)
- kerning(start)
+ start,stop=ligaturing(start,stop)
+ start,stop=kerning(start,stop)
+ elseif start then
+ start=ligaturing(start)
+ start=kerning(start)
end
end
end