summaryrefslogtreecommitdiff
path: root/tex/context/base/font-otn.lua
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2015-09-04 11:15:09 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2015-09-04 11:15:09 +0200
commitcf4c4c56e5748e91ecc28f8126f5fc6eadfd73fa (patch)
treeca9c7f5782d3622203ade72f1d2d32f6c463bc98 /tex/context/base/font-otn.lua
parentf4508b5b95b4fc2b3ed59aaa28a8dfc1a667360a (diff)
downloadcontext-cf4c4c56e5748e91ecc28f8126f5fc6eadfd73fa.tar.gz
2015-09-04 11:02:00
Diffstat (limited to 'tex/context/base/font-otn.lua')
-rw-r--r--tex/context/base/font-otn.lua256
1 files changed, 72 insertions, 184 deletions
diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua
index 9a85dcf96..9c09185a3 100644
--- a/tex/context/base/font-otn.lua
+++ b/tex/context/base/font-otn.lua
@@ -255,11 +255,7 @@ local math_code = nodecodes.math
local dir_code = whatcodes.dir
local localpar_code = whatcodes.localpar
-
local discretionary_code = disccodes.discretionary
-local regular_code = disccodes.regular
------ automatic_code = disccodes.automatic
-
local ligature_code = glyphcodes.ligature
local privateattribute = attributes.private
@@ -508,8 +504,8 @@ end
-- iteration this becomes a KAF-LAM-ALEF with a SHADDA on the second and a FATHA on the
-- third component.
-local function getcomponentindex(start)
- if getid(start) ~= glyph_code then
+local function getcomponentindex(start) -- we could store this offset in the glyph (nofcomponents)
+ if getid(start) ~= glyph_code then -- and then get rid of all components
return 0
elseif getsubtype(start) == ligature_code then
local i = 0
@@ -526,69 +522,7 @@ local function getcomponentindex(start)
end
end
-local a_noligature = attributes.private("noligature")
-local prehyphenchar = languages and languages.prehyphenchar
-local posthyphenchar = languages and languages.posthyphenchar
------ preexhyphenchar = languages and languages.preexhyphenchar
------ postexhyphenchar = languages and languages.postexhyphenchar
-
-if prehyphenchar then
-
- -- okay
-
-elseif context then
-
- report_warning("no language support") os.exit()
-
-else
-
- local newlang = lang.new
- local getpre = lang.prehyphenchar
- local getpost = lang.posthyphenchar
- -- local getpreex = lang.preexhyphenchar
- -- local getpostex = lang.postexhyphenchar
-
- prehyphenchar = function(l) local l = newlang(l) return l and getpre (l) or -1 end
- posthyphenchar = function(l) local l = newlang(l) return l and getpost (l) or -1 end
- -- preexhyphenchar = function(l) local l = newlang(l) return l and getpreex (l) or -1 end
- -- postexhyphenchar = function(l) local l = newlang(l) return l and getpostex(l) or -1 end
-
-end
-
-local function addhyphens(template,pre,post)
- -- inserted by hyphenation algorithm
- local l = getfield(template,"lang")
- local p = prehyphenchar(l)
- if p and p > 0 then
- local c = copy_node(template)
- setfield(c,"char",p)
- if pre then
- local t = find_node_tail(pre)
- setfield(t,"next",c)
- setfield(c,"prev",t)
- else
- pre = c
- end
- end
- local p = posthyphenchar(l)
- if p and p > 0 then
- local c = copy_node(template)
- setfield(c,"char",p)
- if post then
- -- post has a prev nesting node .. alternatively we could
- local prev = getprev(post)
- setfield(c,"next",post)
- setfield(post,"prev",c)
- if prev then
- setfield(prev,"next",c)
- setfield(c,"prev",prev)
- end
- else
- post = c
- end
- end
- return pre, post
-end
+local a_noligature = attributes.private("noligature")
local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) -- brr head
if getattr(start,a_noligature) == 1 then
@@ -603,8 +537,8 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
-- needs testing (side effects):
local components = getfield(start,"components")
if components then
--- we get a double free .. needs checking
--- flush_node_list(components)
+ -- we get a double free .. needs checking
+ -- flush_node_list(components)
end
--
local prev = getprev(start)
@@ -626,8 +560,8 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
if next then
setfield(next,"prev",base)
end
- setfield(base,"next",next)
setfield(base,"prev",prev)
+ setfield(base,"next",next)
if not discfound then
local deletemarks = markflag ~= "mark"
local components = start
@@ -674,53 +608,34 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
local discprev = getfield(discfound,"prev")
local discnext = getfield(discfound,"next")
if discprev and discnext then
- local subtype = getsubtype(discfound)
- if subtype == discretionary_code then
- local pre = getfield(discfound,"pre")
- local post = getfield(discfound,"post")
- local replace = getfield(discfound,"replace")
- if not replace then -- todo: signal simple hyphen
- local prev = getfield(base,"prev")
- local copied = copy_node_list(comp)
- setfield(discnext,"prev",nil) -- also blocks funny assignments
- setfield(discprev,"next",nil) -- also blocks funny assignments
- if pre then
- setfield(discprev,"next",pre)
- setfield(pre,"prev",discprev)
- end
- pre = comp
- if post then
- local tail = find_node_tail(post)
- setfield(tail,"next",discnext)
- setfield(discnext,"prev",tail)
- setfield(post,"prev",nil)
- else
- post = discnext
- end
- setfield(prev,"next",discfound)
- setfield(next,"prev",discfound)
- setfield(discfound,"next",next)
- setfield(discfound,"prev",prev)
- setfield(base,"next",nil)
- setfield(base,"prev",nil)
- setfield(base,"components",copied)
- setfield(discfound,"pre",pre)
- setfield(discfound,"post",post)
- setfield(discfound,"replace",base)
- setfield(discfound,"subtype",discretionary_code)
- base = prev -- restart
- end
- elseif subtype == regular_code then
- -- local prev = getfield(base,"prev")
- -- local next = getfield(base,"next")
+ -- we assume normalization in context, and don't care about generic ... especially
+ -- \- can give problems as there we can have a negative char but that won't match
+ -- anyway
+ local pre = getfield(discfound,"pre")
+ local post = getfield(discfound,"post")
+ local replace = getfield(discfound,"replace")
+ if not replace then -- todo: signal simple hyphen
+ local prev = getfield(base,"prev")
local copied = copy_node_list(comp)
setfield(discnext,"prev",nil) -- also blocks funny assignments
setfield(discprev,"next",nil) -- also blocks funny assignments
- local pre, post = addhyphens(comp,comp,discnext,subtype) -- takes from components
+ if pre then
+ setfield(discprev,"next",pre)
+ setfield(pre,"prev",discprev)
+ end
+ pre = comp
+ if post then
+ local tail = find_node_tail(post)
+ setfield(tail,"next",discnext)
+ setfield(discnext,"prev",tail)
+ setfield(post,"prev",nil)
+ else
+ post = discnext
+ end
setfield(prev,"next",discfound)
- setfield(next,"prev",discfound)
- setfield(discfound,"next",next)
setfield(discfound,"prev",prev)
+ setfield(discfound,"next",next)
+ setfield(next,"prev",discfound)
setfield(base,"next",nil)
setfield(base,"prev",nil)
setfield(base,"components",copied)
@@ -728,9 +643,7 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
setfield(discfound,"post",post)
setfield(discfound,"replace",base)
setfield(discfound,"subtype",discretionary_code)
- base = next -- or restart
- else
- -- forget about it in generic usage
+ base = prev -- restart
end
end
end
@@ -753,8 +666,8 @@ local function multiple_glyphs(head,start,multiple,ignoremarks)
local n = copy_node(start) -- ignore components
resetinjection(n)
setfield(n,"char",multiple[k])
- setfield(n,"next",sn)
setfield(n,"prev",start)
+ setfield(n,"next",sn)
if sn then
setfield(sn,"prev",n)
end
@@ -949,7 +862,8 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence,lookuphash
if not snext then
return head, start, false
else
- local prev, done = start, false
+ local prev = start
+ local done = false
local factor = tfmdata.parameters.factor
local lookuptype = lookuptypes[lookupname]
while snext and getid(snext) == glyph_code and getfont(snext) == currentfont and getsubtype(snext)<256 do
@@ -1518,11 +1432,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,
else
local schar = getchar(s)
if skipmark and marks[schar] then -- marks
--- if s == stop then -- maybe add this
--- break
--- else
s = getnext(s)
--- end
else
local lg = ligatures[schar]
if lg then
@@ -1955,7 +1865,7 @@ end
local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,chainindex,sequence,chainproc)
if not start then
- return -- safeguard
+ return head, start, false
end
local startishead = start == head
@@ -2165,7 +2075,7 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
setfield(tail,"next",replace)
setfield(replace,"prev",tail)
end
- setfield(lookaheaddisc,"pre",cf) -- also updates tail
+ setfield(lookaheaddisc,"pre",cf) -- also updates tail
setfield(lookaheaddisc,"replace",new) -- also updates tail
start = getprev(lookaheaddisc)
@@ -2248,6 +2158,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
local skipbase = flags[3]
local markclass = sequence.markclass
local skipped = false
+
for k=1,#contexts do -- i've only seen ccmp having > 1 (e.g. dejavu)
local match = true
local current = start
@@ -2316,7 +2227,8 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
notmatchpre[last] = nil
notmatchpost[last] = true
notmatchreplace[last] = nil
- local pre = getfield(last,"pre")
+ local pre = getfield(last,"pre")
+ local replace = getfield(last,"replace")
if pre then
local n = n
while pre do
@@ -2336,7 +2248,6 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
else
notmatchpre[last] = true
end
- local replace = getfield(last,"replace")
if replace then
-- so far we never entered this branch
while replace do
@@ -2361,10 +2272,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
break
end
else
- last = getnext(last) -- no skipping here
+ notmatchreplace[last] = true
end
+ last = getnext(last)
else
- last = getnext(last) -- no skipping here
+ match = false
+ break
end
else
match = false
@@ -2726,7 +2639,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
end
end
end
- if diskchain then -- maybe move up so that we can turn checking on/off
+ if diskseen then -- maybe move up so that we can turn checking on/off
notmatchpre = { }
notmatchpost = { }
notmatchreplace = { }
@@ -2815,7 +2728,7 @@ local function initialize(sequence,script,language,enabled)
local order = sequence.order
if order then
for i=1,#order do --
- local kind = order[i] --
+ local kind = order[i] --
local valid = enabled[kind]
if valid then
local scripts = features[kind] --
@@ -2869,7 +2782,7 @@ end
--
-- * languages that use complex disc nodes
-local function kernrun(disc,run) -- we can assume that prev and next are glyphs
+local function kernrun(disc,run)
--
-- we catch <font 1><disc font 2>
--
@@ -2886,22 +2799,18 @@ local function kernrun(disc,run) -- we can assume that prev and next are glyphs
--
local prevmarks = prev
--
- -- can be optional:
+ -- can be optional, because why on earth do we get a disc after a mark (okay, maybe when a ccmp
+ -- has happened but then it should be in the disc so basically this test indicates an error)
--
- -- while prevmarks and getid(prevmarks) == glyph_code and getfont(prevmarks) == currentfont and marks[getchar(prevmarks)] and getsubtype(prevmarks) < 256 do
while prevmarks and getid(prevmarks) == glyph_code and marks[getchar(prevmarks)] and getfont(prevmarks) == currentfont and getsubtype(prevmarks) < 256 do
prevmarks = getprev(prevmarks)
end
--
- if prev and (pre or replace) then
- if not (getid(prev) == glyph_code and getfont(prev) == currentfont and getsubtype(prev)<256) then
- prev = false
- end
+ if prev and (pre or replace) and not (getid(prev) == glyph_code and getfont(prev) == currentfont and getsubtype(prev)<256) then
+ prev = false
end
- if next and (post or replace) then
- if not (getid(next) == glyph_code and getfont(next) == currentfont and getsubtype(next)<256) then
- next = false
- end
+ if next and (post or replace) and not (getid(next) == glyph_code and getfont(next) == currentfont and getsubtype(next)<256) then
+ next = false
end
--
if not pre then
@@ -3123,8 +3032,6 @@ local function featuresprocessor(head,font,attr)
-- Keeping track of the headnode is needed for devanagari (I generalized it a bit
-- so that multiple cases are also covered.)
- -- todo: retain prev
-
-- We don't goto the next node of a disc node is created so that we can then treat
-- the pre, post and replace. It's abit of a hack but works out ok for most cases.
@@ -3144,7 +3051,6 @@ local function featuresprocessor(head,font,attr)
local gpossing = typ == "gpos_single" or typ == "gpos_pair" -- maybe all of them
local subtables = sequence.subtables
local handler = handlers[typ]
-
if typ == "gsub_reversecontextchain" then -- chain < 0
-- this is a limited case, no special treatments like 'init' etc
-- we need to get rid of this slide! probably no longer needed in latest luatex
@@ -3165,8 +3071,7 @@ local function featuresprocessor(head,font,attr)
local lookupname = subtables[i]
local lookupcache = lookuphash[lookupname]
if lookupcache then
- -- local lookupmatch = lookupcache[getchar(start)]
- local lookupmatch = lookupcache[start]
+ local lookupmatch = lookupcache[char]
if lookupmatch then
-- todo: disc?
head, start, success = handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,i)
@@ -3194,7 +3099,7 @@ local function featuresprocessor(head,font,attr)
local start = head -- local ?
rlmode = 0 -- to be checked ?
if ns == 1 then -- happens often
- local lookupname = subtables[1]
+ local lookupname = subtables[1]
local lookupcache = lookuphash[lookupname]
if not lookupcache then -- also check for empty cache
report_missing_cache(typ,lookupname)
@@ -3294,7 +3199,7 @@ local function featuresprocessor(head,font,attr)
-- sequence kan weg
local h, d, ok = handler(head,prev,kind,lookupname,lookupmatch,sequence,lookuphash,1)
if ok then
- done = true
+ done = true
success = true
end
end
@@ -3320,7 +3225,7 @@ local function featuresprocessor(head,font,attr)
if lookupmatch then
local h, d, ok = handler(sub,n,kind,lookupname,lookupmatch,sequence,lookuphash,1,injection)
if ok then
- done = true
+ done = true
success = true
end
end
@@ -3364,24 +3269,15 @@ local function featuresprocessor(head,font,attr)
start = getnext(start)
end
elseif id == disc_code then
- local discretionary = getsubtype(start) == discretionary_code
- if gpossing then
- if discretionary then
- kernrun(start,k_run)
- else
- discrun(start,d_run,k_run)
- end
- start = getnext(start)
- elseif discretionary then
- if typ == "gsub_ligature" then
- start = testrun(start,t_run,c_run)
- else
- comprun(start,c_run)
- start = getnext(start)
- end
- else
+ if gpossing then
+ kernrun(start,k_run)
+ start = getnext(start)
+ elseif typ == "gsub_ligature" then
+ start = testrun(start,t_run,c_run)
+ else
+ comprun(start,c_run)
start = getnext(start)
- end
+ end
elseif id == whatsit_code then -- will be function
local subtype = getsubtype(start)
if subtype == dir_code then
@@ -3497,7 +3393,7 @@ local function featuresprocessor(head,font,attr)
-- brr prev can be disc
local char = getchar(prev)
for i=1,ns do
- local lookupname = subtables[i]
+ local lookupname = subtables[i]
local lookupcache = lookuphash[lookupname]
if lookupcache then
local lookupmatch = lookupcache[char]
@@ -3532,7 +3428,7 @@ local function featuresprocessor(head,font,attr)
if id == glyph_code then
local char = getchar(n)
for i=1,ns do
- local lookupname = subtables[i]
+ local lookupname = subtables[i]
local lookupcache = lookuphash[lookupname]
if lookupcache then
local lookupmatch = lookupcache[char]
@@ -3567,7 +3463,7 @@ local function featuresprocessor(head,font,attr)
if a then
local char = getchar(start)
for i=1,ns do
- local lookupname = subtables[i]
+ local lookupname = subtables[i]
local lookupcache = lookuphash[lookupname]
if lookupcache then
local lookupmatch = lookupcache[char]
@@ -3612,7 +3508,7 @@ local function featuresprocessor(head,font,attr)
end
if a then
for i=1,ns do
- local lookupname = subtables[i]
+ local lookupname = subtables[i]
local lookupcache = lookuphash[lookupname]
if lookupcache then
local char = getchar(start)
@@ -3645,27 +3541,19 @@ local function featuresprocessor(head,font,attr)
start = getnext(start)
end
elseif id == disc_code then
- local discretionary = getsubtype(start) == discretionary_code
if gpossing then
- if discretionary then
- kernrun(start,k_run)
- else
- discrun(start,d_run,k_run)
- end
+ kernrun(start,k_run)
start = getnext(start)
- elseif discretionary then
- if typ == "gsub_ligature" then
- start = testrun(start,t_run,c_run)
- else
- comprun(start,c_run)
- start = getnext(start)
- end
+ elseif typ == "gsub_ligature" then
+ start = testrun(start,t_run,c_run)
else
+ comprun(start,c_run)
start = getnext(start)
end
elseif id == whatsit_code then
local subtype = getsubtype(start)
if subtype == dir_code then
+ local dir = getfield(start,"dir")
if dir == "+TLT" then
topstack = topstack + 1
dirstack[topstack] = dir