From 4ad4129b06a3b631031f39a778ebdd210ed09ab4 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 17 Feb 2012 18:52:00 +0100 Subject: beta 2012.02.17 18:52 --- tex/generic/context/luatex/luatex-fonts-merged.lua | 177 ++++++++++++--------- 1 file changed, 99 insertions(+), 78 deletions(-) (limited to 'tex/generic') diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 6b1a41c09..0966cd3b8 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 02/16/12 23:57:34 +-- merge date : 02/17/12 18:52:08 do -- begin closure to overcome local limits and interference @@ -6191,7 +6191,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 @@ -8127,16 +8127,22 @@ if context then end -local cursives = { } -local marks = { } -local kerns = { } +-- 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). + +local cursives = { } +local marks = { } +local kerns = { } +local markcount = { } -- 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]) @@ -8179,14 +8185,14 @@ 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]) +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]) -- index argument no longer used local bound = has_attribute(base,markbase) if bound then local mb = marks[bound] if mb then if not index then index = #mb + 1 end - mb[index] = { dx, dy } + mb[index] = { dx, dy, rlmode } set_attribute(start,markmark,bound) set_attribute(start,markdone,index) return dx, dy, bound @@ -8240,7 +8246,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 @@ -8259,6 +8265,7 @@ end -- todo: check for attribute -- 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) @@ -8409,7 +8416,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 @@ -8432,37 +8439,51 @@ function injections.handler(head,where,keep) else n.yoffset = n.yoffset + p.yoffset + d[2] end +-- markcount[n_markmark] = (markcount[n_markmark] or 0) + 1 +-- if markcount[n_markmark] == #mrks then +-- break -- KE +-- end end - else - break + -- else + -- break -- KE: there can be sequences in ligatures end end end end if not keep then marks = { } +-- markcount = { } end end -- 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 @@ -8501,9 +8522,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 @@ -8896,7 +8917,7 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- return lignode else -- start is the ligature - local deletemarks = markflag ~= "mark" + -- local deletemarks = markflag ~= "mark" local n = copy_node(start) local current current, start = insert_node_after(start,start,n) @@ -8911,16 +8932,16 @@ 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 - end - end - else + -- if deletemarks then -- KE: was wrong + -- 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 + -- end + -- end + -- else local i = 0 while start do if marks[start.char] then @@ -8946,7 +8967,8 @@ local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- end start = start.next end - end + -- 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 @@ -9225,8 +9247,9 @@ 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 i = has_attribute(start,markdone) +-- if i then index = i end -- needed +local index = has_attribute(start,markdone) local baseanchors = descriptions[basechar] if baseanchors then baseanchors = baseanchors.anchors @@ -9240,7 +9263,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) @@ -9271,46 +9294,44 @@ 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,markdone) and has_attribute(base,markdone) ~= has_attribute(start,markdone) do + base = base.prev -- KE: prevents mknk fo rmarks on different components of a ligature +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 @@ -10128,7 +10149,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] -- cgit v1.2.3