summaryrefslogtreecommitdiff
path: root/otfl-font-otn.lua
diff options
context:
space:
mode:
Diffstat (limited to 'otfl-font-otn.lua')
-rw-r--r--otfl-font-otn.lua366
1 files changed, 182 insertions, 184 deletions
diff --git a/otfl-font-otn.lua b/otfl-font-otn.lua
index ebdeb75..914a7de 100644
--- a/otfl-font-otn.lua
+++ b/otfl-font-otn.lua
@@ -1917,7 +1917,7 @@ local function initialize(sequence,script,language,enabled)
if valid then
local languages = scripts[script] or scripts[wildcard]
if languages and (languages[language] or languages[wildcard]) then
- return { valid, special_attributes[kind] or false, sequence.chain or 0, kind }
+ return { valid, special_attributes[kind] or false, sequence.chain or 0, kind, sequence }
end
end
end
@@ -1925,7 +1925,7 @@ local function initialize(sequence,script,language,enabled)
return false
end
-function otf.dataset(ftfmdata,sequences,font) -- generic variant, overloaded in context
+function otf.dataset(tfmdata,sequences,font) -- generic variant, overloaded in context
local shared = tfmdata.shared
local properties = tfmdata.properties
local language = properties.language or "dflt"
@@ -1954,6 +1954,22 @@ function otf.dataset(ftfmdata,sequences,font) -- generic variant, overloaded in
return rl
end
+-- elseif id == glue_code then
+-- if p[5] then -- chain
+-- local pc = pp[32]
+-- if pc then
+-- start, ok = start, false -- p[1](start,kind,p[2],pc,p[3],p[4])
+-- if ok then
+-- done = true
+-- end
+-- if start then start = start.next end
+-- else
+-- start = start.next
+-- end
+-- else
+-- start = start.next
+-- end
+
local function featuresprocessor(head,font,attr)
local lookuphash = lookuphashes[font] -- we can also check sequences here
@@ -1983,66 +1999,147 @@ local function featuresprocessor(head,font,attr)
local done = false
local datasets = otf.dataset(tfmdata,sequences,font,attr)
+ local dirstack = { } -- could move outside function
+
+ -- We could work on sub start-stop ranges instead but I wonder if there is that
+ -- much speed gain (experiments showed that it made not much sense) and we need
+ -- to keep track of directions anyway. Also at some point I want to play with
+ -- font interactions and then we do need the full sweeps.
+
for s=1,#sequences do
- local dataset = datasets[s] -- cache -- s?
- featurevalue = dataset and dataset[1] -- todo: pass to function instead of using a global
- if featurevalue then
- local sequence = sequences[s]
- local pardir, txtdir, success = 0, { }, false -- we could reuse txtdir and use a top pointer
- local attribute, chain, typ, subtables = dataset[2], dataset[3], sequence.type, sequence.subtables
- if chain < 0 then
- -- this is a limited case, no special treatments like 'init' etc
- local handler = handlers[typ]
- -- we need to get rid of this slide! probably no longer needed in latest luatex
- local start = find_node_tail(head) -- slow (we can store tail because there's always a skip at the end): todo
- while start do
- local id = start.id
- if id == glyph_code then
- if start.subtype<256 and start.font == font then
- local a = has_attribute(start,0)
- if a then
- a = a == attr
- else
- a = true
- end
- if a then
- for i=1,#subtables do
- local lookupname = subtables[i]
- local lookupcache = lookuphash[lookupname]
- if lookupcache then
- local lookupmatch = lookupcache[start.char]
- if lookupmatch then
- start, success = handler(start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
- if success then
- break
+ local dataset = datasets[s]
+ if dataset then
+ featurevalue = dataset[1] -- todo: pass to function instead of using a global
+ if featurevalue then
+ local sequence = sequences[s] -- also dataset[5]
+ local rlparmode = 0
+ local topstack = 0
+ local success = false
+ local attribute = dataset[2]
+ local chain = dataset[3] -- sequence.chain or 0
+ local typ = sequence.type
+ local subtables = sequence.subtables
+ if chain < 0 then
+ -- this is a limited case, no special treatments like 'init' etc
+ local handler = handlers[typ]
+ -- we need to get rid of this slide! probably no longer needed in latest luatex
+ local start = find_node_tail(head) -- slow (we can store tail because there's always a skip at the end): todo
+ while start do
+ local id = start.id
+ if id == glyph_code then
+ if start.subtype<256 and start.font == font then
+ local a = has_attribute(start,0)
+ if a then
+ a = a == attr
+ else
+ a = true
+ end
+ if a then
+ for i=1,#subtables do
+ local lookupname = subtables[i]
+ local lookupcache = lookuphash[lookupname]
+ if lookupcache then
+ local lookupmatch = lookupcache[start.char]
+ if lookupmatch then
+ start, success = handler(start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
+ if success then
+ break
+ end
end
+ else
+ report_missing_cache(typ,lookupname)
end
- else
- report_missing_cache(typ,lookupname)
end
+ if start then start = start.prev end
+ else
+ start = start.prev
end
- if start then start = start.prev end
else
start = start.prev
end
else
start = start.prev
end
- else
- start = start.prev
end
- end
- else
- local handler = handlers[typ]
- local ns = #subtables
- local start = head -- local ?
- rlmode = 0 -- to be checked ?
- if ns == 1 then
- local lookupname = subtables[1]
- local lookupcache = lookuphash[lookupname]
---~ inspect(lookupcache)
- if not lookupcache then -- also check for empty cache
- report_missing_cache(typ,lookupname)
+ else
+ local handler = handlers[typ]
+ local ns = #subtables
+ local start = head -- local ?
+ rlmode = 0 -- to be checked ?
+ if ns == 1 then -- happens often
+ local lookupname = subtables[1]
+ local lookupcache = lookuphash[lookupname]
+ if not lookupcache then -- also check for empty cache
+ report_missing_cache(typ,lookupname)
+ else
+ while start do
+ local id = start.id
+ if id == glyph_code then
+ if start.subtype<256 and start.font == font then
+ local a = has_attribute(start,0)
+ if a then
+ a = (a == attr) and (not attribute or has_attribute(start,state,attribute))
+ else
+ a = not attribute or has_attribute(start,state,attribute)
+ end
+ if a then
+ local lookupmatch = lookupcache[start.char]
+ if lookupmatch then
+ -- sequence kan weg
+ local ok
+ start, ok = handler(start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1)
+ if ok then
+ success = true
+ end
+ end
+ if start then start = start.next end
+ else
+ start = start.next
+ end
+ else
+ start = start.next
+ end
+ elseif id == whatsit_code then -- will be function
+ local subtype = start.subtype
+ if subtype == dir_code then
+ local dir = start.dir
+ if dir == "+TRT" or dir == "+TLT" then
+ topstack = topstack + 1
+ dirstack[topstack] = dir
+ elseif dir == "-TRT" or dir == "-TLT" then
+ topstack = topstack - 1
+ end
+ local newdir = dirstack[topstack]
+ if newdir == "+TRT" then
+ rlmode = -1
+ elseif newdir == "+TLT" then
+ rlmode = 1
+ else
+ rlmode = rlparmode
+ end
+ if trace_directions then
+ report_process("directions after txtdir %s: txtdir=%s:%s, parmode=%s, txtmode=%s",dir,topstack,newdir or "unset",rlparmode,rlmode)
+ end
+ elseif subtype == localpar_code then
+ local dir = start.dir
+ if dir == "TRT" then
+ rlparmode = -1
+ elseif dir == "TLT" then
+ rlparmode = 1
+ else
+ rlparmode = 0
+ end
+ rlmode = rlparmode
+ if trace_directions then
+ report_process("directions after pardir %s: parmode=%s, txtmode=%s",dir,rlparmode,rlmode)
+ end
+ end
+ start = start.next
+ else
+ start = start.next
+ end
+ end
+ end
else
while start do
local id = start.id
@@ -2054,15 +2151,23 @@ local function featuresprocessor(head,font,attr)
else
a = not attribute or has_attribute(start,state,attribute)
end
---~ print(a,start.char)
if a then
- local lookupmatch = lookupcache[start.char]
- if lookupmatch then
- -- sequence kan weg
- local ok
- start, ok = handler(start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1)
- if ok then
- success = true
+ for i=1,ns do
+ local lookupname = subtables[i]
+ local lookupcache = lookuphash[lookupname]
+ if lookupcache then
+ local lookupmatch = lookupcache[start.char]
+ if lookupmatch then
+ -- we could move all code inline but that makes things even more unreadable
+ local ok
+ start, ok = handler(start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
+ if ok then
+ success = true
+ break
+ end
+ end
+ else
+ report_missing_cache(typ,lookupname)
end
end
if start then start = start.next end
@@ -2072,54 +2177,39 @@ local function featuresprocessor(head,font,attr)
else
start = start.next
end
- -- elseif id == glue_code then
- -- if p[5] then -- chain
- -- local pc = pp[32]
- -- if pc then
- -- start, ok = start, false -- p[1](start,kind,p[2],pc,p[3],p[4])
- -- if ok then
- -- done = true
- -- end
- -- if start then start = start.next end
- -- else
- -- start = start.next
- -- end
- -- else
- -- start = start.next
- -- end
elseif id == whatsit_code then
local subtype = start.subtype
if subtype == dir_code then
local dir = start.dir
if dir == "+TRT" or dir == "+TLT" then
- insert(txtdir,dir)
+ topstack = topstack + 1
+ dirstack[topstack] = dir
elseif dir == "-TRT" or dir == "-TLT" then
- remove(txtdir)
+ topstack = topstack - 1
end
- local d = txtdir[#txtdir]
- if d == "+TRT" then
+ local newdir = dirstack[topstack]
+ if newdir == "+TRT" then
rlmode = -1
- elseif d == "+TLT" then
+ elseif newdir == "+TLT" then
rlmode = 1
else
- rlmode = pardir
+ rlmode = rlparmode
end
if trace_directions then
- report_process("directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
+ report_process("directions after txtdir %s: txtdir=%s:%s, parmode=%s, txtmode=%s",dir,topstack,newdir or "unset",rlparmode,rlmode)
end
elseif subtype == localpar_code then
local dir = start.dir
if dir == "TRT" then
- pardir = -1
+ rlparmode = -1
elseif dir == "TLT" then
- pardir = 1
+ rlparmode = 1
else
- pardir = 0
+ rlparmode = 0
end
- rlmode = pardir
- --~ txtdir = { }
+ rlmode = rlparmode
if trace_directions then
- report_process("directions after pardir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
+ report_process("directions after pardir %s: parmode=%s, txtmode=%s",dir,rlparmode,rlmode)
end
end
start = start.next
@@ -2128,105 +2218,13 @@ local function featuresprocessor(head,font,attr)
end
end
end
- else
- while start do
- local id = start.id
- if id == glyph_code then
- if start.subtype<256 and start.font == font then
- local a = has_attribute(start,0)
- if a then
- a = (a == attr) and (not attribute or has_attribute(start,state,attribute))
- else
- a = not attribute or has_attribute(start,state,attribute)
- end
- if a then
- for i=1,ns do
- local lookupname = subtables[i]
- local lookupcache = lookuphash[lookupname]
- if lookupcache then
- local lookupmatch = lookupcache[start.char]
- if lookupmatch then
- -- we could move all code inline but that makes things even more unreadable
- local ok
- start, ok = handler(start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
- if ok then
- success = true
- break
- end
- end
- else
- report_missing_cache(typ,lookupname)
- end
- end
- if start then start = start.next end
- else
- start = start.next
- end
- else
- start = start.next
- end
- -- elseif id == glue_code then
- -- if p[5] then -- chain
- -- local pc = pp[32]
- -- if pc then
- -- start, ok = start, false -- p[1](start,kind,p[2],pc,p[3],p[4])
- -- if ok then
- -- done = true
- -- end
- -- if start then start = start.next end
- -- else
- -- start = start.next
- -- end
- -- else
- -- start = start.next
- -- end
- elseif id == whatsit_code then
- local subtype = start.subtype
- if subtype == dir_code then
- local dir = start.dir
- if dir == "+TRT" or dir == "+TLT" then
- insert(txtdir,dir)
- elseif dir == "-TRT" or dir == "-TLT" then
- remove(txtdir)
- end
- local d = txtdir[#txtdir]
- if d == "+TRT" then
- rlmode = -1
- elseif d == "+TLT" then
- rlmode = 1
- else
- rlmode = pardir
- end
- if trace_directions then
- report_process("directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
- end
- elseif subtype == localpar_code then
- local dir = start.dir
- if dir == "TRT" then
- pardir = -1
- elseif dir == "TLT" then
- pardir = 1
- else
- pardir = 0
- end
- rlmode = pardir
- --~ txtdir = { }
- if trace_directions then
- report_process("directions after pardir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
- end
- end
- start = start.next
- else
- start = start.next
- end
- end
end
- end
- if success then
- done = true
- end
- if trace_steps then -- ?
- registerstep(head)
+ if success then
+ done = true
+ end
+ if trace_steps then -- ?
+ registerstep(head)
+ end
end
end
end