summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/font-otj.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/font-otj.lua')
-rw-r--r--tex/context/base/mkiv/font-otj.lua215
1 files changed, 143 insertions, 72 deletions
diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua
index 74e052408..1f9fd1ac1 100644
--- a/tex/context/base/mkiv/font-otj.lua
+++ b/tex/context/base/mkiv/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.)
@@ -49,6 +49,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
@@ -157,9 +158,9 @@ 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
@@ -192,7 +193,7 @@ 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 = p.injections
@@ -397,43 +398,43 @@ function injections.setmove(current,factor,rlmode,x,injection)
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)
+ 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
- p[injection] = {
- rightkern = dx,
+ properties[current] = {
+ [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)
+ if p then
+ local i = p[injection]
+ if i then
+ i.leftkern = dx + (i.leftkern or 0)
+ else
+ p[injection] = {
+ leftkern = dx,
+ }
+ end
else
- p[injection] = {
- leftkern = dx,
+ properties[current] = {
+ [injection] = {
+ leftkern = dx,
+ },
}
end
- else
- properties[current] = {
- [injection] = {
- leftkern = dx,
- },
- }
end
-end
return dx, nofregisteredkerns
else
return 0, 0
@@ -454,9 +455,15 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmar
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
@@ -792,12 +799,12 @@ local function inject_positions_only(head,where)
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
+ 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))
@@ -1040,16 +1047,16 @@ local function inject_everything(head,where)
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
if not pn.markmark then
ox = ox + (pn.leftkern or 0)
end
else
-- kern(x) glyph(p) kern(w-x) mark(n)
- -- ox = px - getwidth(p) + 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
@@ -1057,7 +1064,6 @@ local function inject_everything(head,where)
--
-- maybe we need to apply both then
--
- ox = px - pn.markx - rightkern -- seguiemj needs the rightkern
if false then
-- a mark with kerning (maybe husayni needs it )
local leftkern = pp.leftkern
@@ -1067,16 +1073,14 @@ local function inject_everything(head,where)
end
end
else
- if pn.markdir < 0 then
- ox = px - pn.markx
+ 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
- else
- ox = px - pn.markx
end
if pn.checkmark then
local wn = getwidth(n) -- in arial marks have widths
@@ -1101,7 +1105,7 @@ local function inject_everything(head,where)
end
end
end
- local oy = ny + py + pn.marky
+ local oy = ny + py + (pn.marky or 0)
if not pn.markmark then
local yoffset = pn.yoffset
if yoffset then
@@ -1113,15 +1117,72 @@ local function inject_everything(head,where)
showoffset(n,true)
end
end
+ -- begin of temp fix --
+ local base = nil -- bah, some arabic fonts have no mark anchoring
+ -- end of temp fix --
while current do
local next = getnext(current)
local char, id = ischar(current)
if char then
local p = rawget(properties,current)
+ -- begin of temp fix --
+ if hascursives 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 hascursives 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 hascursives 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
@@ -1185,12 +1246,12 @@ local function inject_everything(head,where)
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
+ 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))
@@ -1401,6 +1462,7 @@ end
else
prevglyph = nil
prevdisc = nil
+base = nil
end
prev = current
current = next
@@ -1532,7 +1594,6 @@ local function injectspaces(head)
if not triggers then
return head, false
end
-
local lastfont = nil
local spacekerns = nil
local leftkerns = nil
@@ -1584,23 +1645,25 @@ local function injectspaces(head)
if old > threshold then
if rightkern then
if useitalickerns then
- local new = old + (leftkern + rightkern) * factor
- if trace_spaces then
- report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar)
- end
- setwidth(n,new)
- else
- local new = (leftkern + rightkern) * factor
+ local lnew = leftkern * factor
+ local rnew = rightkern * factor
if trace_spaces then
- report_spaces("%C [%p + %p] %C",prevchar,old,new,nextchar)
+ report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
end
- local h = insert_node_before(nuthead,n,italickern(new))
+ local h = insert_node_before(nuthead,n,italickern(lnew))
if h == nuthead then
head = tonode(h)
nuthead = h
end
+ insert_node_after(nuthead,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
- leftkern = false
+ rightkern = false
else
if useitalickerns then
local new = leftkern * factor
@@ -1621,11 +1684,19 @@ local function injectspaces(head)
elseif rightkern then
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(nuthead,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
- setwidth(n,new)
end
rightkern = false
end