summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/mult-nl.mkii1
-rw-r--r--tex/context/base/mkiv/buff-ini.lua2
-rw-r--r--tex/context/base/mkiv/char-utf.lua6
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/font-con.lua32
-rw-r--r--tex/context/base/mkiv/font-onr.lua2
-rw-r--r--tex/context/base/mkiv/font-otd.lua8
-rw-r--r--tex/context/base/mkiv/font-ots.lua1085
-rw-r--r--tex/context/base/mkiv/font-oup.lua38
-rw-r--r--tex/context/base/mkiv/l-string.lua2
-rw-r--r--tex/context/base/mkiv/math-fbk.lua8
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25704 -> 25684 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin425160 -> 425157 bytes
-rw-r--r--tex/context/base/mkiv/util-deb.lua25
-rw-r--r--tex/context/interface/mkii/keys-nl.xml1
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin847900 -> 847911 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60775 -> 60774 bytes
-rw-r--r--tex/context/modules/mkiv/x-asciimath.lua2
-rw-r--r--tex/context/modules/mkiv/x-ldx.lua2
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua298
23 files changed, 1203 insertions, 317 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 5a0456528..7bfcf8614 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.06.29 09:34}
+\newcontextversion{2017.06.30 19:45}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 5b82f4d36..48ef7f4cd 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.06.29 09:34}
+\edef\contextversion{2017.06.30 19:45}
%D For those who want to use this:
diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii
index 30703e4a6..8e5add4dc 100644
--- a/tex/context/base/mkii/mult-nl.mkii
+++ b/tex/context/base/mkii/mult-nl.mkii
@@ -687,6 +687,7 @@
\setinterfaceconstant{bottomoffset}{onderoffset}
\setinterfaceconstant{bottomspace}{bodemwit}
\setinterfaceconstant{bottomstate}{onderstatus}
+\setinterfaceconstant{break}{break}
\setinterfaceconstant{buffer}{buffer}
\setinterfaceconstant{cache}{cache}
\setinterfaceconstant{calculate}{bereken}
diff --git a/tex/context/base/mkiv/buff-ini.lua b/tex/context/base/mkiv/buff-ini.lua
index fd5b047af..e2f0be0dc 100644
--- a/tex/context/base/mkiv/buff-ini.lua
+++ b/tex/context/base/mkiv/buff-ini.lua
@@ -286,7 +286,7 @@ local getmargin = (emptyline + normalline)^1
local function undent(str) -- new version, needs testing: todo: not always needed, like in xtables
nofspaces = #str
local margin = lpegmatch(getmargin,str)
- if nofspaces == #str or nofspaces ==0 then
+ if nofspaces == #str or nofspaces == 0 then
return str
end
local stripper = strippers[nofspaces]
diff --git a/tex/context/base/mkiv/char-utf.lua b/tex/context/base/mkiv/char-utf.lua
index 5b677dbac..901beef6d 100644
--- a/tex/context/base/mkiv/char-utf.lua
+++ b/tex/context/base/mkiv/char-utf.lua
@@ -191,7 +191,7 @@ function utffilters.collapse(str,filename)
if not p_collapse then
prepare()
end
- if not str or #str == "" or #str == 1 then
+ if not str or str == "" or #str == 1 then
return str
elseif filename and skippable[filesuffix(filename)] then -- we could hash the collapsables or do a quicker test
return str
@@ -214,7 +214,7 @@ function utffilters.decompose(str,filename) -- 3 to 4 times faster than the abov
if str and str ~= "" and #str > 1 then
return lpegmatch(p_decompose,str)
end
- if not str or #str == "" or #str < 2 then
+ if not str or str == "" or #str < 2 then
return str
elseif filename and skippable[filesuffix(filename)] then
return str
@@ -339,7 +339,7 @@ function utffilters.reorder(str,filename)
if not p_reorder then
prepare()
end
- if not str or #str == "" or #str < 2 then
+ if not str or str == "" or #str < 2 then
return str
elseif filename and skippable[filesuffix(filename)] then
return str
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index af97f8b50..82888546f 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.06.29 09:34}
+\newcontextversion{2017.06.30 19:45}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 7a2a20e46..73069d51a 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -41,7 +41,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.06.29 09:34}
+\edef\contextversion{2017.06.30 19:45}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index 16dc3c05e..fd3b28612 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -555,22 +555,22 @@ function constructors.scale(tfmdata,specification)
if changed then
local c = changed[unicode]
if c and c ~= unicode then
- while true do
- local cc = changed[c]
- if not cc then
- -- we're done, no (futher) chain
- break
- elseif cc == unicode then
- -- we probably have a bidi swap
- break
- elseif cc == c then
- -- we have a self reference, shouldn't happen
- c = nil
- break
- else
- c = cc
- end
- end
+-- while true do
+-- local cc = changed[c]
+-- if not cc then
+-- -- we're done, no (futher) chain
+-- break
+-- elseif cc == unicode then
+-- -- we probably have a bidi swap
+-- break
+-- elseif cc == c then
+-- -- we have a self reference, shouldn't happen
+-- c = nil
+-- break
+-- else
+-- c = cc
+-- end
+-- end
if c then
description = descriptions[c] or descriptions[unicode] or character
character = characters[c] or character
diff --git a/tex/context/base/mkiv/font-onr.lua b/tex/context/base/mkiv/font-onr.lua
index 9a45d4b73..f1cdefa1b 100644
--- a/tex/context/base/mkiv/font-onr.lua
+++ b/tex/context/base/mkiv/font-onr.lua
@@ -41,7 +41,7 @@ handlers.afm = afm
local readers = afm.readers or { }
afm.readers = readers
-afm.version = 1.512 -- incrementing this number one up will force a re-cache
+afm.version = 1.513 -- incrementing this number one up will force a re-cache
--[[ldx--
<p>We start with the basic reader which we give a name similar to the built in <l n='tfm'/>
diff --git a/tex/context/base/mkiv/font-otd.lua b/tex/context/base/mkiv/font-otd.lua
index 412aad528..c45278826 100644
--- a/tex/context/base/mkiv/font-otd.lua
+++ b/tex/context/base/mkiv/font-otd.lua
@@ -192,15 +192,15 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr
elseif lookupdone then
if trace_applied then
report_process(
- "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a, lookup already set by %a",
- font,attr or 0,dynamic,kind,usedscript,usedlanguage,sequence.name,valid,ra[#ra][4])
+ "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a, nofsteps %a, lookup already set by %a",
+ font,attr or 0,dynamic,kind,usedscript,usedlanguage,sequence.name,valid,sequence.nofsteps,ra[#ra][4])
end
else
ra[#ra+1] = usedlookup
if trace_applied then
report_process(
- "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a",
- font,attr or 0,dynamic,kind,usedscript,usedlanguage,sequence.name,valid)
+ "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a, nofsteps %a",
+ font,attr or 0,dynamic,kind,usedscript,usedlanguage,sequence.name,valid,sequence.nofsteps)
else
return -- no need to look further
end
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index de296e408..c5fa13abe 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -267,13 +267,11 @@ local threshold = 0
local checkmarks = false
local sweepnode = nil
-local sweepprev = nil
-local sweepnext = nil
-local sweephead = { }
+local sweephead = { } -- we don't nil entries but false them (no collection and such)
-local notmatchpre = { }
-local notmatchpost = { }
-local notmatchreplace = { }
+local notmatchpre = { } -- to be checked: can we use false instead of nil / what if a == b tests
+local notmatchpost = { } -- to be checked: can we use false instead of nil / what if a == b tests
+local notmatchreplace = { } -- to be checked: can we use false instead of nil / what if a == b tests
local handlers = { }
@@ -1756,12 +1754,12 @@ end
-- but it takes a bit of work to figure out an efficient way (this is what the sweep*
-- names refer to). I might look into that variant one day again as it can replace
-- some other code too. In that approach we can have a special version for gub and pos
--- which gains some speed. This method does the test and passes info to the handlers
--- (sweepnode, sweepmode, sweepprev, sweepnext, etc). Here collapsing is handled in the
--- main loop which also makes code elsewhere simpler (i.e. no need for the other special
--- runners and disc code in ligature building). I also experimented with pushing preceding
--- glyphs sequences in the replace/pre fields beforehand which saves checking afterwards
--- but at the cost of duplicate glyphs (memory) but it's too much overhead (runtime).
+-- which gains some speed. This method does the test and passes info to the handlers.
+-- Here collapsing is handled in the main loop which also makes code elsewhere simpler
+-- (i.e. no need for the other special runners and disc code in ligature building). I
+-- also experimented with pushing preceding glyphs sequences in the replace/pre fields
+-- beforehand which saves checking afterwards but at the cost of duplicate glyphs
+-- (memory) but it's too much overhead (runtime).
--
-- In the meantime Kai had moved the code from the single chain into a more general handler
-- and this one (renamed to chaindisk) is used now. I optimized the code a bit and brought
@@ -2189,8 +2187,8 @@ local function chaindisk(head,start,dataset,sequence,rlmode,ck,skipped)
setdisc(lookaheaddisc,cf,post,new)
end
start = getprev(lookaheaddisc)
- sweephead[cf] = getnext(clast)
- sweephead[new] = getnext(cl)
+ sweephead[cf] = getnext(clast) or false
+ sweephead[new] = getnext(cl) or false
elseif backtrackdisc then
@@ -2255,8 +2253,8 @@ local function chaindisk(head,start,dataset,sequence,rlmode,ck,skipped)
setdisc(backtrackdisc,pre,post,replace)
end
start = getprev(backtrackdisc)
- sweephead[post] = getnext(clast)
- sweephead[replace] = getnext(last)
+ sweephead[post] = getnext(clast) or false
+ sweephead[replace] = getnext(last) or false
else
@@ -2282,6 +2280,471 @@ local function chaintrac(head,start,dataset,sequence,rlmode,ck,skipped,match)
cref(dataset,sequence),rule,match and "matches" or "nomatch",gref(char),first-1,last-first+1,nofseq-last,lookuptype)
end
+-- local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
+-- local sweepnode = sweepnode
+-- local sweeptype = sweeptype
+-- local currentfont = currentfont
+-- local diskseen = false
+-- local checkdisc = sweeptype and getprev(head)
+-- local flags = sequence.flags or noflags
+-- local done = false
+-- local skipmark = flags[1]
+-- local skipligature = flags[2]
+-- local skipbase = flags[3]
+-- local markclass = sequence.markclass
+-- local skipped = false
+-- local startprev,
+-- startnext = getboth(start)
+--
+-- for k=1,#contexts do -- i've only seen ccmp having > 1 (e.g. dejavu)
+-- local match = true
+-- local current = start
+-- local last = start
+-- local ck = contexts[k]
+-- local seq = ck[3]
+-- local s = #seq
+-- local size = 1
+-- -- f..l = mid string
+-- if s == 1 then
+-- -- this seldom happens as it makes no sense (bril, ebgaramond, husayni, minion)
+-- local char = ischar(current,currentfont)
+-- if char then
+-- if not seq[1][char] then
+-- match = false
+-- end
+-- end
+-- else
+-- -- maybe we need a better space check (maybe check for glue or category or combination)
+-- -- we cannot optimize for n=2 because there can be disc nodes
+-- local f = ck[4]
+-- local l = ck[5]
+-- -- current match
+-- -- seq[f][ischar(current,currentfont)] is not nil
+-- size = l - f + 1
+-- if size > 1 then
+-- -- before/current/after | before/current | current/after
+-- local discfound -- = nil
+-- local n = f + 1
+-- -- last = getnext(last) -- the second in current (first already matched)
+-- last = startnext -- the second in current (first already matched)
+-- while n <= l do
+-- if not last and (sweeptype == "post" or sweeptype == "replace") then
+-- last = getnext(sweepnode)
+-- sweeptype = nil
+-- end
+-- if last then
+-- local char, id = ischar(last,currentfont)
+-- if char then
+-- local class = classes[char]
+-- if class then
+-- if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then
+-- skipped = true
+-- if trace_skips then
+-- show_skip(dataset,sequence,char,ck,class)
+-- end
+-- last = getnext(last)
+-- elseif seq[n][char] then
+-- if n < l then
+-- last = getnext(last)
+-- end
+-- n = n + 1
+-- else
+-- if discfound then
+-- notmatchreplace[discfound] = true
+-- if notmatchpre[discfound] then
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- break
+-- end
+-- else
+-- -- can this happen
+-- if discfound then
+-- notmatchreplace[discfound] = true
+-- if notmatchpre[discfound] then
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- break
+-- end
+-- elseif char == false then
+-- if discfound then
+-- notmatchreplace[discfound] = true
+-- if notmatchpre[discfound] then
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- break
+-- elseif id == disc_code then
+-- diskseen = true
+-- discfound = last
+-- notmatchpre[last] = nil
+-- notmatchpost[last] = true
+-- notmatchreplace[last] = nil
+-- local pre, post, replace = getdisc(last)
+-- if pre then
+-- local n = n
+-- while pre do
+-- if seq[n][getchar(pre)] then
+-- n = n + 1
+-- pre = getnext(pre)
+-- if n > l then
+-- break
+-- end
+-- else
+-- notmatchpre[last] = true
+-- break
+-- end
+-- end
+-- if n <= l then
+-- notmatchpre[last] = true
+-- end
+-- else
+-- notmatchpre[last] = true
+-- end
+-- if replace then
+-- -- so far we never entered this branch
+-- while replace do
+-- if seq[n][getchar(replace)] then
+-- n = n + 1
+-- replace = getnext(replace)
+-- if n > l then
+-- break
+-- end
+-- else
+-- notmatchreplace[last] = true
+-- if notmatchpre[last] then
+-- match = false
+-- end
+-- break
+-- end
+-- end
+-- -- why here again
+-- if notmatchpre[last] then
+-- match = false
+-- end
+-- end
+-- -- maybe only if match
+-- last = getnext(last)
+-- else
+-- match = false
+-- break
+-- end
+-- else
+-- match = false
+-- break
+-- end
+-- end
+-- end
+-- -- before
+-- if match and f > 1 then
+-- -- local prev = getprev(start)
+-- -- if prev then
+-- if startprev then
+-- local prev = startprev
+-- if prev == checkdisc and (sweeptype == "pre" or sweeptype == "replace") then
+-- prev = getprev(sweepnode)
+-- -- sweeptype = nil
+-- end
+-- if prev then
+-- local discfound -- = nil
+-- local n = f - 1
+-- while n >= 1 do
+-- if prev then
+-- local char, id = ischar(prev,currentfont)
+-- if char then
+-- local class = classes[char]
+-- if class then
+-- if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then
+-- skipped = true
+-- if trace_skips then
+-- show_skip(dataset,sequence,char,ck,class)
+-- end
+-- prev = getprev(prev)
+-- elseif seq[n][char] then
+-- if n > 1 then
+-- prev = getprev(prev)
+-- end
+-- n = n - 1
+-- else
+-- if discfound then
+-- notmatchreplace[discfound] = true
+-- if notmatchpost[discfound] then
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- break
+-- end
+-- else
+-- -- can this happen
+-- if discfound then
+-- notmatchreplace[discfound] = true
+-- if notmatchpost[discfound] then
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- break
+-- end
+-- elseif char == false then
+-- if discfound then
+-- notmatchreplace[discfound] = true
+-- if notmatchpost[discfound] then
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- break
+-- elseif id == disc_code then
+-- -- the special case: f i where i becomes dottless i ..
+-- diskseen = true
+-- discfound = prev
+-- notmatchpre[prev] = true
+-- notmatchpost[prev] = nil
+-- notmatchreplace[prev] = nil
+-- local pre, post, replace, pretail, posttail, replacetail = getdisc(prev,true)
+-- if pre ~= start and post ~= start and replace ~= start then
+-- if post then
+-- local n = n
+-- while posttail do
+-- if seq[n][getchar(posttail)] then
+-- n = n - 1
+-- if posttail == post then
+-- break
+-- else
+-- posttail = getprev(posttail)
+-- if n < 1 then
+-- break
+-- end
+-- end
+-- else
+-- notmatchpost[prev] = true
+-- break
+-- end
+-- end
+-- if n >= 1 then
+-- notmatchpost[prev] = true
+-- end
+-- else
+-- notmatchpost[prev] = true
+-- end
+-- if replace then
+-- -- we seldom enter this branch (e.g. on brill efficient)
+-- while replacetail do
+-- if seq[n][getchar(replacetail)] then
+-- n = n - 1
+-- if replacetail == replace then
+-- break
+-- else
+-- replacetail = getprev(replacetail)
+-- if n < 1 then
+-- break
+-- end
+-- end
+-- else
+-- notmatchreplace[prev] = true
+-- if notmatchpost[prev] then
+-- match = false
+-- end
+-- break
+-- end
+-- end
+-- if not match then
+-- break
+-- end
+-- end
+-- end
+-- -- maybe only if match
+-- prev = getprev(prev)
+-- elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then
+-- n = n - 1
+-- prev = getprev(prev)
+-- else
+-- match = false
+-- break
+-- end
+-- else
+-- match = false
+-- break
+-- end
+-- end
+-- else
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- end
+-- -- after
+-- if match and s > l then
+-- local current = last and getnext(last)
+-- if not current and (sweeptype == "post" or sweeptype == "replace") then
+-- current = getnext(sweepnode)
+-- -- sweeptype = nil
+-- end
+-- if current then
+-- local discfound -- = nil
+-- -- removed optimization for s-l == 1, we have to deal with marks anyway
+-- local n = l + 1
+-- while n <= s do
+-- if current then
+-- local char, id = ischar(current,currentfont)
+-- if char then
+-- local class = classes[char]
+-- if class then
+-- if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then
+-- skipped = true
+-- if trace_skips then
+-- show_skip(dataset,sequence,char,ck,class)
+-- end
+-- current = getnext(current) -- was absent
+-- elseif seq[n][char] then
+-- if n < s then -- new test
+-- current = getnext(current) -- was absent
+-- end
+-- n = n + 1
+-- else
+-- if discfound then
+-- notmatchreplace[discfound] = true
+-- if notmatchpre[discfound] then
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- break
+-- end
+-- else
+-- -- can this happen
+-- if discfound then
+-- notmatchreplace[discfound] = true
+-- if notmatchpre[discfound] then
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- break
+-- end
+-- elseif char == false then
+-- if discfound then
+-- notmatchreplace[discfound] = true
+-- if notmatchpre[discfound] then
+-- match = false
+-- end
+-- else
+-- match = false
+-- end
+-- break
+-- elseif id == disc_code then
+-- diskseen = true
+-- discfound = current
+-- notmatchpre[current] = nil
+-- notmatchpost[current] = true
+-- notmatchreplace[current] = nil
+-- local pre, post, replace = getdisc(current)
+-- if pre then
+-- local n = n
+-- while pre do
+-- if seq[n][getchar(pre)] then
+-- n = n + 1
+-- pre = getnext(pre)
+-- if n > s then
+-- break
+-- end
+-- else
+-- notmatchpre[current] = true
+-- break
+-- end
+-- end
+-- if n <= s then
+-- notmatchpre[current] = true
+-- end
+-- else
+-- notmatchpre[current] = true
+-- end
+-- if replace then
+-- -- so far we never entered this branch
+-- while replace do
+-- if seq[n][getchar(replace)] then
+-- n = n + 1
+-- replace = getnext(replace)
+-- if n > s then
+-- break
+-- end
+-- else
+-- notmatchreplace[current] = true
+-- -- different than others, needs checking if "not" is okay
+-- if not notmatchpre[current] then
+-- match = false
+-- end
+-- break
+-- end
+-- end
+-- if not match then
+-- break
+-- end
+-- else
+-- -- skip 'm
+-- end
+-- current = getnext(current)
+-- elseif id == glue_code and seq[n][32] and isspace(current,threshold,id) then
+-- n = n + 1
+-- current = getnext(current)
+-- else
+-- match = false
+-- break
+-- end
+-- else
+-- match = false
+-- break
+-- end
+-- end
+-- else
+-- match = false
+-- end
+-- end
+-- end
+-- if match then
+-- if trace_contexts then
+-- chaintrac(head,start,dataset,sequence,rlmode,ck,skipped,true)
+-- end
+-- if diskseen or sweepnode then
+-- head, start, done = chaindisk(head,start,dataset,sequence,rlmode,ck,skipped)
+-- else
+-- head, start, done = chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
+-- end
+-- if done then
+-- break
+-- else
+-- -- next context
+-- end
+-- -- elseif trace_chains then
+-- -- chaintrac(head,start,dataset,sequence,rlmode,ck,skipped,match)
+-- end
+-- end
+-- if diskseen then
+-- notmatchpre = { }
+-- notmatchpost = { }
+-- notmatchreplace = { }
+-- end
+-- return head, start, done
+-- end
+
+-- a bit optimized but still somewhat slow, fonts like ebgaramong are real torture tests because they
+-- have many steps with one context (having multiple contexts makes more sense) also because we (can)
+-- reduce them
+
local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
local sweepnode = sweepnode
local sweeptype = sweeptype
@@ -2294,6 +2757,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
local skipligature = flags[2]
local skipbase = flags[3]
local markclass = sequence.markclass
+ local skipsome = skipmark ~= false or skipligature ~= false or skipbase ~= false or markclass
local skipped = false
local startprev,
startnext = getboth(start)
@@ -2310,10 +2774,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if s == 1 then
-- this seldom happens as it makes no sense (bril, ebgaramond, husayni, minion)
local char = ischar(current,currentfont)
- if char then
- if not seq[1][char] then
- match = false
- end
+ if char and not seq[1][char] then
+ match = false
end
else
-- maybe we need a better space check (maybe check for glue or category or combination)
@@ -2337,8 +2799,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if last then
local char, id = ischar(last,currentfont)
if char then
- local class = classes[char]
- if class then
+ if skipsome then
+ local class = classes[char]
if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then
skipped = true
if trace_skips then
@@ -2362,15 +2824,22 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
break
end
else
- if discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- match = false
+ if seq[n][char] then
+ if n < l then
+ last = getnext(last)
end
+ n = n + 1
else
- match = false
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ match = false
+ end
+ else
+ match = false
+ end
+ break
end
- break
end
elseif char == false then
if discfound then
@@ -2394,10 +2863,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
while pre do
if seq[n][getchar(pre)] then
n = n + 1
- pre = getnext(pre)
if n > l then
break
end
+ pre = getnext(pre)
else
notmatchpre[last] = true
break
@@ -2414,10 +2883,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
while replace do
if seq[n][getchar(replace)] then
n = n + 1
- replace = getnext(replace)
if n > l then
break
end
+ replace = getnext(replace)
else
notmatchreplace[last] = true
if notmatchpre[last] then
@@ -2460,8 +2929,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if prev then
local char, id = ischar(prev,currentfont)
if char then
- local class = classes[char]
- if class then
+ if skipsome then
+ local class = classes[char]
if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then
skipped = true
if trace_skips then
@@ -2485,15 +2954,22 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
break
end
else
- if discfound then
- notmatchreplace[discfound] = true
- if notmatchpost[discfound] then
- match = false
+ if seq[n][char] then
+ if n > 1 then
+ prev = getprev(prev)
end
+ n = n - 1
else
- match = false
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpost[discfound] then
+ match = false
+ end
+ else
+ match = false
+ end
+ break
end
- break
end
elseif char == false then
if discfound then
@@ -2522,10 +2998,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if posttail == post then
break
else
- posttail = getprev(posttail)
if n < 1 then
break
end
+ posttail = getprev(posttail)
end
else
notmatchpost[prev] = true
@@ -2546,10 +3022,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if replacetail == replace then
break
else
- replacetail = getprev(replacetail)
if n < 1 then
break
end
+ replacetail = getprev(replacetail)
end
else
notmatchreplace[prev] = true
@@ -2600,8 +3076,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if current then
local char, id = ischar(current,currentfont)
if char then
- local class = classes[char]
- if class then
+ if skipsome then
+ local class = classes[char]
if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then
skipped = true
if trace_skips then
@@ -2625,15 +3101,22 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
break
end
else
- if discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- match = false
+ if seq[n][char] then
+ if n < s then -- new test
+ current = getnext(current) -- was absent
end
+ n = n + 1
else
- match = false
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ match = false
+ end
+ else
+ match = false
+ end
+ break
end
- break
end
elseif char == false then
if discfound then
@@ -2657,10 +3140,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
while pre do
if seq[n][getchar(pre)] then
n = n + 1
- pre = getnext(pre)
if n > s then
break
end
+ pre = getnext(pre)
else
notmatchpre[current] = true
break
@@ -2677,10 +3160,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
while replace do
if seq[n][getchar(replace)] then
n = n + 1
- replace = getnext(replace)
if n > s then
break
end
+ replace = getnext(replace)
else
notmatchreplace[current] = true
-- different than others, needs checking if "not" is okay
@@ -2696,7 +3179,6 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
else
-- skip 'm
end
- -- maybe only if match
current = getnext(current)
elseif id == glue_code and seq[n][32] and isspace(current,threshold,id) then
n = n + 1
@@ -2725,7 +3207,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
head, start, done = chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
end
if done then
- break -- out of contexts (new, needs checking)
+ break
+ else
+ -- next context
end
-- elseif trace_chains then
-- chaintrac(head,start,dataset,sequence,rlmode,ck,skipped,match)
@@ -2739,6 +3223,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
return head, start, done
end
+------------------------------
+
handlers.gsub_context = handle_contextchain
handlers.gsub_contextchain = handle_contextchain
handlers.gsub_reversecontextchain = handle_contextchain
@@ -2952,13 +3438,15 @@ local function kernrun(disc,k_run,font,attr,...)
done = true
end
if prev then
- local nest = getprev(pre)
+-- local nest = getprev(pre)
setlink(prev,pre)
if k_run(prevmarks,"preinjections",pre,font,attr,...) then -- or prev?
done = true
end
- setprev(pre,nest)
- setnext(prev,disc)
+-- setprev(pre,nest)
+-- setnext(prev,disc)
+ setprev(pre)
+ setlink(prev,disc)
end
end
--
@@ -2972,7 +3460,8 @@ local function kernrun(disc,k_run,font,attr,...)
done = true
end
setnext(posttail)
- setprev(next,disc)
+-- setprev(next,disc)
+ setlink(disc,next)
end
end
--
@@ -2981,13 +3470,15 @@ local function kernrun(disc,k_run,font,attr,...)
done = true
end
if prev then
- local nest = getprev(replace)
+-- local nest = getprev(replace)
setlink(prev,replace)
if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then -- getnext(replace))
done = true
end
- setprev(replace,nest)
- setnext(prev,disc)
+-- setprev(replace,nest)
+-- setnext(prev,disc)
+ setprev(replace)
+ setlink(prev,disc)
end
if next then
setlink(replacetail,next)
@@ -2995,7 +3486,8 @@ local function kernrun(disc,k_run,font,attr,...)
done = true
end
setnext(replacetail)
- setprev(next,disc)
+-- setprev(next,disc)
+ setlink(disc,next)
end
elseif prev and next then
setlink(prev,next)
@@ -3203,7 +3695,8 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm
local sweep = sweephead[head]
if sweep then
start = sweep
- sweephead[head] = nil
+ -- sweephead[head] = nil
+ sweephead[head] = false
else
start = head
end
@@ -3347,7 +3840,8 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm
local sweep = sweephead[head]
if sweep then
start = sweep
- sweephead[head] = nil
+ -- sweephead[head] = nil
+ sweephead[head] = false
else
start = head
end
@@ -3502,7 +3996,7 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase
if lookupcache then
local lookupmatch = lookupcache[char]
if lookupmatch then
- local h, d, ok = handler(head,n,dataset,sequence,lookupmatch,step,rlmode,i,injection)
+ local h, d, ok = handler(head,n,dataset,sequence,lookupmatch,rlmode,step,i,injection)
if ok then
return true
end
@@ -3578,6 +4072,306 @@ do
directives.register("otf.fastdisc",function(v) fastdisc = v end)
+ -- we keep this as reference because the optimization below is sort of nasty
+
+ -- function otf.featuresprocessor(head,font,attr,direction,n)
+ --
+ -- local sequences = sequencelists[font] -- temp hack
+ --
+ -- if not sequencelists then
+ -- return head, false
+ -- end
+ --
+ -- nesting = nesting + 1
+ --
+ -- if nesting == 1 then
+ -- currentfont = font
+ -- tfmdata = fontdata[font]
+ -- descriptions = tfmdata.descriptions -- only needed in gref so we could pass node there instead
+ -- characters = tfmdata.characters -- but this branch is not entered that often anyway
+ -- local resources = tfmdata.resources
+ -- marks = resources.marks
+ -- classes = resources.classes
+ -- threshold,
+ -- factor = getthreshold(font)
+ -- checkmarks = tfmdata.properties.checkmarks
+ --
+ -- elseif currentfont ~= font then
+ --
+ -- report_warning("nested call with a different font, level %s, quitting",nesting)
+ -- nesting = nesting - 1
+ -- return head, false
+ --
+ -- end
+ --
+ -- -- some 10% faster when no dynamics but hardly measureable on real runs .. but: it only
+ -- -- works when we have no other dynamics as otherwise the zero run will be applied to the
+ -- -- whole stream for which we then need to pass another variable which we won't
+ --
+ -- -- if attr == 0 then
+ -- -- attr = false
+ -- -- end
+ --
+ -- head = tonut(head)
+ --
+ -- if trace_steps then
+ -- checkstep(head)
+ -- end
+ --
+ -- local initialrl = direction == "TRT" and -1 or 0
+ --
+ -- local done = false
+ -- local datasets = otf.dataset(tfmdata,font,attr)
+ -- local dirstack = { } -- could move outside function but we can have local runs
+ -- sweephead = { }
+ --
+ -- -- Keeping track of the headnode is needed for devanagari. (I generalized it a bit
+ -- -- so that multiple cases are also covered.) We could prepend a temp node.
+ --
+ -- -- We don't goto the next node when a disc node is created so that we can then treat
+ -- -- the pre, post and replace. It's a bit of a hack but works out ok for most cases.
+ --
+ -- local discs = fastdisc and n and n > 1 and setmetatableindex(function(t,k)
+ -- local v = usesfont(k,font)
+ -- t[k] = v
+ -- return v
+ -- end)
+ --
+ -- for s=1,#datasets do
+ -- local dataset = datasets[s]
+ -- ----- featurevalue = dataset[1] -- todo: pass to function instead of using a global
+ -- local attribute = dataset[2]
+ -- local sequence = dataset[3] -- sequences[s] -- also dataset[5]
+ -- local rlparmode = initialrl
+ -- local topstack = 0
+ -- local typ = sequence.type
+ -- local gpossing = typ == "gpos_single" or typ == "gpos_pair" -- store in dataset
+ -- local handler = handlers[typ]
+ -- local steps = sequence.steps
+ -- local nofsteps = sequence.nofsteps
+ -- if not steps then
+ -- -- this permits injection, watch the different arguments
+ -- local h, d, ok = handler(head,head,dataset,sequence,nil,nil,nil,0,font,attr)
+ -- if ok then
+ -- done = true
+ -- if h then
+ -- head = h
+ -- end
+ -- end
+ -- elseif typ == "gsub_reversecontextchain" then
+ -- -- This might need a check: if we have #before or #after > 0 then we might need to reverse
+ -- -- the before and after lists in the loader. But first I need to see a font that uses multiple
+ -- -- matches.
+ -- local start = find_node_tail(head)
+ -- local rlmode = 0 -- how important is this .. do we need to check for dir?
+ -- while start do
+ -- local char = ischar(start,font)
+ -- if char then
+ -- local a -- happens often so no assignment is faster
+ -- if attr then
+ -- a = getattr(start,0)
+ -- end
+ -- if not a or (a == attr) then
+ -- for i=1,nofsteps do
+ -- local step = steps[i]
+ -- local lookupcache = step.coverage
+ -- if lookupcache then
+ -- local lookupmatch = lookupcache[char]
+ -- if lookupmatch then
+ -- -- todo: disc?
+ -- local ok
+ -- head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
+ -- if ok then
+ -- done = true
+ -- break
+ -- end
+ -- end
+ -- else
+ -- report_missing_coverage(dataset,sequence)
+ -- end
+ -- end
+ -- if start then
+ -- start = getprev(start)
+ -- end
+ -- else
+ -- start = getprev(start)
+ -- end
+ -- else
+ -- start = getprev(start)
+ -- end
+ -- end
+ -- else
+ -- local start = head
+ -- local rlmode = initialrl
+ -- if nofsteps == 1 then -- happens often
+ -- local step = steps[1]
+ -- local lookupcache = step.coverage
+ -- if not lookupcache then
+ -- report_missing_coverage(dataset,sequence)
+ -- else
+ -- while start do
+ -- local char, id = ischar(start,font)
+ -- if char then
+ -- -- local a = attr and getattr(start,0)
+ -- -- if a then
+ -- -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
+ -- -- else
+ -- -- a = not attribute or getprop(start,a_state) == attribute
+ -- -- end
+ -- local a -- happens often so no assignment is faster
+ -- if attr then
+ -- if getattr(start,0) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ -- a = true
+ -- end
+ -- elseif not attribute or getprop(start,a_state) == attribute then
+ -- a = true
+ -- end
+ -- if a then
+ -- local lookupmatch = lookupcache[char]
+ -- if lookupmatch then
+ -- local ok
+ -- head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1)
+ -- if ok then
+ -- done = true
+ -- end
+ -- end
+ -- if start then
+ -- start = getnext(start)
+ -- end
+ -- else
+ -- start = getnext(start)
+ -- end
+ -- elseif char == false then
+ -- -- whatever glyph
+ -- start = getnext(start)
+ -- elseif id == glue_code then
+ -- -- happens often
+ -- start = getnext(start)
+ -- elseif id == disc_code then
+ -- if not discs or discs[start] == true then
+ -- local ok
+ -- if gpossing then
+ -- start, ok = kernrun(start,k_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ -- elseif typ == "gsub_ligature" then
+ -- start, ok = testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ -- else
+ -- start, ok = comprun(start,c_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ -- end
+ -- if ok then
+ -- done = true
+ -- end
+ -- else
+ -- start = getnext(start)
+ -- end
+ -- elseif id == math_code then
+ -- start = getnext(end_of_math(start))
+ -- elseif id == dir_code then
+ -- start, topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
+ -- elseif id == localpar_code then
+ -- start, rlparmode, rlmode = pardirstate(start)
+ -- else
+ -- start = getnext(start)
+ -- end
+ -- end
+ -- end
+ --
+ -- else
+ -- while start do
+ -- local char, id = ischar(start,font)
+ -- if char then
+ -- -- local a = attr and getattr(start,0)
+ -- -- if a then
+ -- -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
+ -- -- else
+ -- -- a = not attribute or getprop(start,a_state) == attribute
+ -- -- end
+ -- local a -- happens often so no assignment is faster
+ -- if attr then
+ -- if getattr(start,0) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ -- a = true
+ -- end
+ -- elseif not attribute or getprop(start,a_state) == attribute then
+ -- a = true
+ -- end
+ -- if a then
+ -- for i=1,nofsteps do
+ -- local step = steps[i]
+ -- local lookupcache = step.coverage
+ -- if lookupcache then
+ -- local lookupmatch = lookupcache[char]
+ -- if lookupmatch then
+ -- -- we could move all code inline but that makes things even more unreadable
+ -- local ok
+ -- head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
+ -- if ok then
+ -- done = true
+ -- break
+ -- elseif not start then
+ -- -- don't ask why ... shouldn't happen
+ -- break
+ -- end
+ -- end
+ -- else
+ -- report_missing_coverage(dataset,sequence)
+ -- end
+ -- end
+ -- if start then
+ -- start = getnext(start)
+ -- end
+ -- else
+ -- start = getnext(start)
+ -- end
+ -- elseif char == false then
+ -- -- whatever glyph
+ -- start = getnext(start)
+ -- elseif id == glue_code then
+ -- -- happens often
+ -- start = getnext(start)
+ -- elseif id == disc_code then
+ -- if not discs or discs[start] == true then
+ -- local ok
+ -- if gpossing then
+ -- start, ok = kernrun(start,k_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ -- elseif typ == "gsub_ligature" then
+ -- start, ok = testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ -- else
+ -- start, ok = comprun(start,c_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ -- end
+ -- if ok then
+ -- done = true
+ -- end
+ -- else
+ -- start = getnext(start)
+ -- end
+ -- elseif id == math_code then
+ -- start = getnext(end_of_math(start))
+ -- elseif id == dir_code then
+ -- start, topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
+ -- elseif id == localpar_code then
+ -- start, rlparmode, rlmode = pardirstate(start)
+ -- else
+ -- start = getnext(start)
+ -- end
+ -- end
+ -- end
+ -- end
+ --
+ -- if trace_steps then -- ?
+ -- registerstep(head)
+ -- end
+ --
+ -- end
+ --
+ -- nesting = nesting - 1
+ -- head = tonode(head)
+ --
+ -- return head, done
+ -- end
+
+ -- using a merged combined hash as first test saves some 30% on ebgaramond and
+ -- about 15% on arabtype .. then moving the a test also saves a bit (even when
+ -- often a is not set at all so that one is a bit debatable
+
function otf.featuresprocessor(head,font,attr,direction,n)
local sequences = sequencelists[font] -- temp hack
@@ -3663,38 +4457,48 @@ do
end
end
elseif typ == "gsub_reversecontextchain" then
+ --
-- This might need a check: if we have #before or #after > 0 then we might need to reverse
-- the before and after lists in the loader. But first I need to see a font that uses multiple
-- matches.
+ --
local start = find_node_tail(head)
local rlmode = 0 -- how important is this .. do we need to check for dir?
+ local merged = steps.merged
while start do
local char = ischar(start,font)
if char then
- local a -- happens often so no assignment is faster
- if attr then
- a = getattr(start,0)
- end
- if not a or (a == attr) then
- for i=1,nofsteps do
- local step = steps[i]
- local lookupcache = step.coverage
- if lookupcache then
- local lookupmatch = lookupcache[char]
- if lookupmatch then
- -- todo: disc?
- local ok
- head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
- if ok then
- done = true
- break
+ local m = merged[char]
+ if m then
+ local a -- happens often so no assignment is faster
+ if attr then
+ a = getattr(start,0)
+ end
+ if not a or (a == attr) then
+ for i=m[1],m[2] do
+ local step = steps[i]
+ -- for i=1,#m do
+ -- local step = m[i]
+ local lookupcache = step.coverage
+ if lookupcache then
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ -- todo: disc?
+ local ok
+ head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
+ if ok then
+ done = true
+ break
+ end
end
+ else
+ report_missing_coverage(dataset,sequence)
end
- else
- report_missing_coverage(dataset,sequence)
end
- end
- if start then
+ if start then
+ start = getprev(start)
+ end
+ else
start = getprev(start)
end
else
@@ -3716,30 +4520,32 @@ do
while start do
local char, id = ischar(start,font)
if char then
- -- local a = attr and getattr(start,0)
- -- if a then
- -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
- -- else
- -- a = not attribute or getprop(start,a_state) == attribute
- -- end
- local a -- happens often so no assignment is faster
- if attr then
- if getattr(start,0) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ -- local a = attr and getattr(start,0)
+ -- if a then
+ -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
+ -- else
+ -- a = not attribute or getprop(start,a_state) == attribute
+ -- end
+ local a -- happens often so no assignment is faster
+ if attr then
+ if getattr(start,0) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ a = true
+ end
+ elseif not attribute or getprop(start,a_state) == attribute then
a = true
end
- elseif not attribute or getprop(start,a_state) == attribute then
- a = true
- end
- if a then
- local lookupmatch = lookupcache[char]
- if lookupmatch then
+ if a then
local ok
head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1)
if ok then
done = true
end
- end
- if start then
+ if start then
+ start = getnext(start)
+ end
+ else
start = getnext(start)
end
else
@@ -3778,48 +4584,55 @@ do
end
end
end
-
else
+ local merged = steps.merged
while start do
local char, id = ischar(start,font)
if char then
- -- local a = attr and getattr(start,0)
- -- if a then
- -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
- -- else
- -- a = not attribute or getprop(start,a_state) == attribute
- -- end
- local a -- happens often so no assignment is faster
- if attr then
- if getattr(start,0) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ local m = merged[char]
+ if m then
+ -- local a = attr and getattr(start,0)
+ -- if a then
+ -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
+ -- else
+ -- a = not attribute or getprop(start,a_state) == attribute
+ -- end
+ local a -- happens often so no assignment is faster
+ if attr then
+ if getattr(start,0) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ a = true
+ end
+ elseif not attribute or getprop(start,a_state) == attribute then
a = true
end
- elseif not attribute or getprop(start,a_state) == attribute then
- a = true
- end
- if a then
- for i=1,nofsteps do
- local step = steps[i]
- local lookupcache = step.coverage
- if lookupcache then
- local lookupmatch = lookupcache[char]
- if lookupmatch then
- -- we could move all code inline but that makes things even more unreadable
- local ok
- head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
- if ok then
- done = true
- break
- elseif not start then
- -- don't ask why ... shouldn't happen
- break
+ if a then
+ for i=m[1],m[2] do
+ local step = steps[i]
+ -- for i=1,#m do
+ -- local step = m[i]
+ local lookupcache = step.coverage
+ if lookupcache then
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ -- we could move all code inline but that makes things even more unreadable
+ local ok
+ head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
+ if ok then
+ done = true
+ break
+ elseif not start then
+ -- don't ask why ... shouldn't happen
+ break
+ end
end
+ else
+ report_missing_coverage(dataset,sequence)
end
- else
- report_missing_coverage(dataset,sequence)
end
- end
- if start then
+ if start then
+ start = getnext(start)
+ end
+ else
start = getnext(start)
end
else
@@ -3891,14 +4704,14 @@ function otf.plugininitializer(tfmdata,value)
end
end
-function otf.pluginprocessor(head,font)
+function otf.pluginprocessor(head,font,attr,direction) -- n
local s = fontdata[font].shared
local p = s and s.plugin
if p then
if trace_plugins then
report_process("applying plugin %a",p[1])
end
- return p[2](head,font)
+ return p[2](head,font,attr,direction)
else
return head, false
end
diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua
index 54ca690d1..5ee6df505 100644
--- a/tex/context/base/mkiv/font-oup.lua
+++ b/tex/context/base/mkiv/font-oup.lua
@@ -15,6 +15,7 @@ local formatters = string.formatters
local sortedkeys = table.sortedkeys
local sortedhash = table.sortedhash
local tohash = table.tohash
+local setmetatableindex = table.setmetatableindex
local report = logs.reporter("otf reader")
@@ -2256,6 +2257,33 @@ function readers.expand(data)
end
end
end
+
+ -- using a merged combined hash as first test saves some 30% on ebgaramond and
+ -- about 15% on arabtype .. then moving the a test also saves a bit (even when
+ -- often a is not set at all so that one is a bit debatable
+
+ local function mergesteps(t,k)
+ if k == "merged" then
+ local merged = { }
+ for i=1,#t do
+ local step = t[i]
+ local coverage = step.coverage
+ for k, v in next, coverage do
+ local m = merged[k]
+ if m then
+ m[2] = i
+ -- m[#m+1] = step
+ else
+ merged[k] = { i, i }
+ -- merged[k] = { step }
+ end
+ end
+ end
+ t.merged = merged
+ return merged
+ end
+ end
+
local function expandlookups(sequences)
if sequences then
-- we also need to do sublookups
@@ -2263,10 +2291,10 @@ function readers.expand(data)
local sequence = sequences[i]
local steps = sequence.steps
if steps then
+
+ setmetatableindex(steps,mergesteps)
+
local kind = sequence.type
--- if kind == "gsub_reversecontextchain" then
--- inspect(sequence)
--- end
local markclass = sequence.markclass
if markclass then
if not markclasses then
@@ -2276,7 +2304,8 @@ function readers.expand(data)
sequence.markclass = markclasses[markclass]
end
end
- for i=1,sequence.nofsteps do
+ local nofsteps = sequence.nofsteps
+ for i=1,nofsteps do
local step = steps[i]
local baseclasses = step.baseclasses
if baseclasses then
@@ -2371,6 +2400,7 @@ function readers.expand(data)
end
end
end
+
expandlookups(sequences)
expandlookups(sublookups)
end
diff --git a/tex/context/base/mkiv/l-string.lua b/tex/context/base/mkiv/l-string.lua
index e0fb28445..cda837615 100644
--- a/tex/context/base/mkiv/l-string.lua
+++ b/tex/context/base/mkiv/l-string.lua
@@ -18,7 +18,7 @@ local P, S, C, Ct, Cc, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cs
--
-- function string.split(str,pattern)
-- local t = { }
--- if #str > 0 then
+-- if str ~= "" then
-- local n = 1
-- for s in gmatch(str..pattern,"(.-)"..pattern) do
-- t[n] = s
diff --git a/tex/context/base/mkiv/math-fbk.lua b/tex/context/base/mkiv/math-fbk.lua
index c883d57a7..2ce292a19 100644
--- a/tex/context/base/mkiv/math-fbk.lua
+++ b/tex/context/base/mkiv/math-fbk.lua
@@ -423,7 +423,7 @@ end
virtualcharacters[0xFE33E] = virtualcharacters[0x203E] -- convenient
virtualcharacters[0xFE33F] = virtualcharacters[0x203E] -- convenient
--- spacing
+-- spacing (no need for a cache of widths)
local c_zero = byte('0')
local c_period = byte('.')
@@ -432,7 +432,7 @@ local function spacefraction(data,fraction)
local width = fraction * data.target.parameters.space
return {
width = width,
- commands = { right = width }
+ commands = { { "right", width } }
}
end
@@ -440,7 +440,7 @@ local function charfraction(data,char)
local width = data.target.characters[char].width
return {
width = width,
- commands = { right = width }
+ commands = { { "right", width } }
}
end
@@ -448,7 +448,7 @@ local function quadfraction(data,fraction)
local width = fraction * data.target.parameters.quad
return {
width = width,
- commands = { right = width }
+ commands = { { "right", width } }
}
end
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 4a7516ffe..933402892 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index c99f701e7..3334c4ae9 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/util-deb.lua b/tex/context/base/mkiv/util-deb.lua
index 57e015386..b8db0c583 100644
--- a/tex/context/base/mkiv/util-deb.lua
+++ b/tex/context/base/mkiv/util-deb.lua
@@ -145,7 +145,8 @@ function debugger.showstats(printer,threshold)
local functions = 0
local dataset = { }
local length = 0
- local wholetime = 0
+ local realtime = 0
+ local totaltime = 0
local threshold = threshold or 0
for name, sources in next, names do
for source, lines in next, sources do
@@ -162,8 +163,9 @@ function debugger.showstats(printer,threshold)
if real < 0 then
real = 0
end
- wholetime = wholetime + real
+ realtime = realtime + real
end
+ totaltime = totaltime + total
if line < 0 then
line = 0
end
@@ -201,23 +203,22 @@ function debugger.showstats(printer,threshold)
if length > 50 then
length = 50
end
- local fmt = string.formatters["%4.9k %4.9k %3.3k %8i %-" .. length .. "s %4i %s"]
+ local fmt = string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-" .. length .. "s %4i %s"]
for i=1,#dataset do
- local data = dataset[i]
- local real = data[1]
- local total = data[2]
- local count = data[3]
- local name = data[4]
- local source = data[5]
- local line = data[6]
- local percent = real / wholetime
+ local data = dataset[i]
+ local real = data[1]
+ local total = data[2]
+ local count = data[3]
+ local name = data[4]
+ local source = data[5]
+ local line = data[6]
calls = calls + count
functions = functions + 1
name = gsub(name,"%s+"," ")
if #name > length then
name = sub(name,1,length)
end
- printer(fmt(seconds(total),seconds(real),percent,count,name,line,source))
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
end
printer("")
printer(format("functions : %i", functions))
diff --git a/tex/context/interface/mkii/keys-nl.xml b/tex/context/interface/mkii/keys-nl.xml
index 1c6077d1e..e99911bde 100644
--- a/tex/context/interface/mkii/keys-nl.xml
+++ b/tex/context/interface/mkii/keys-nl.xml
@@ -693,6 +693,7 @@
<cd:constant name='bottomoffset' value='onderoffset'/>
<cd:constant name='bottomspace' value='bodemwit'/>
<cd:constant name='bottomstate' value='onderstatus'/>
+ <cd:constant name='break' value='break'/>
<cd:constant name='buffer' value='buffer'/>
<cd:constant name='cache' value='cache'/>
<cd:constant name='calculate' value='bereken'/>
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 03a1906e2..365dc0f01 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 13cb46287..f656c5953 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/modules/mkiv/x-asciimath.lua b/tex/context/modules/mkiv/x-asciimath.lua
index 75f4b06fd..07cf12306 100644
--- a/tex/context/modules/mkiv/x-asciimath.lua
+++ b/tex/context/modules/mkiv/x-asciimath.lua
@@ -1934,7 +1934,7 @@ local uncrapped = {
}
local function convert(str,nowrap)
- if #str > 0 then
+ if str ~= "" then
local unicoded = lpegmatch(u_parser,str) or str
if lpegmatch(p_onechar,unicoded) then
ctx_mathematics(uncrapped[unicoded] or unicoded)
diff --git a/tex/context/modules/mkiv/x-ldx.lua b/tex/context/modules/mkiv/x-ldx.lua
index e88c4c797..775c9a16d 100644
--- a/tex/context/modules/mkiv/x-ldx.lua
+++ b/tex/context/modules/mkiv/x-ldx.lua
@@ -80,7 +80,7 @@ function ldx.load(filename)
end
local str = sub(data, i, #data)
str = gsub(str, "^%s*(.-)%s*$", "%1")
- if #str > 0 then
+ if str ~= "" then
t[#t+1] = { code = str }
end
return t
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index d793cdf04..ed9c29f78 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 : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 06/29/17 09:34:20
+-- merge date : 06/30/17 19:45:43
do -- begin closure to overcome local limits and interference
@@ -7928,19 +7928,6 @@ function constructors.scale(tfmdata,specification)
if changed then
local c=changed[unicode]
if c and c~=unicode then
- while true do
- local cc=changed[c]
- if not cc then
- break
- elseif cc==unicode then
- break
- elseif cc==c then
- c=nil
- break
- else
- c=cc
- end
- end
if c then
description=descriptions[c] or descriptions[unicode] or character
character=characters[c] or character
@@ -17325,6 +17312,7 @@ local formatters=string.formatters
local sortedkeys=table.sortedkeys
local sortedhash=table.sortedhash
local tohash=table.tohash
+local setmetatableindex=table.setmetatableindex
local report=logs.reporter("otf reader")
local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end)
local readers=fonts.handlers.otf.readers
@@ -19332,12 +19320,32 @@ function readers.expand(data)
end
end
end
+ local function mergesteps(t,k)
+ if k=="merged" then
+ local merged={}
+ for i=1,#t do
+ local step=t[i]
+ local coverage=step.coverage
+ for k,v in next,coverage do
+ local m=merged[k]
+ if m then
+ m[2]=i
+ else
+ merged[k]={ i,i }
+ end
+ end
+ end
+ t.merged=merged
+ return merged
+ end
+ end
local function expandlookups(sequences)
if sequences then
for i=1,#sequences do
local sequence=sequences[i]
local steps=sequence.steps
if steps then
+ setmetatableindex(steps,mergesteps)
local kind=sequence.type
local markclass=sequence.markclass
if markclass then
@@ -19348,7 +19356,8 @@ function readers.expand(data)
sequence.markclass=markclasses[markclass]
end
end
- for i=1,sequence.nofsteps do
+ local nofsteps=sequence.nofsteps
+ for i=1,nofsteps do
local step=steps[i]
local baseclasses=step.baseclasses
if baseclasses then
@@ -22389,12 +22398,10 @@ local factor=0
local threshold=0
local checkmarks=false
local sweepnode=nil
-local sweepprev=nil
-local sweepnext=nil
-local sweephead={}
-local notmatchpre={}
-local notmatchpost={}
-local notmatchreplace={}
+local sweephead={}
+local notmatchpre={}
+local notmatchpost={}
+local notmatchreplace={}
local handlers={}
local isspace=injections.isspace
local getthreshold=injections.getthreshold
@@ -24039,8 +24046,8 @@ local function chaindisk(head,start,dataset,sequence,rlmode,ck,skipped)
setdisc(lookaheaddisc,cf,post,new)
end
start=getprev(lookaheaddisc)
- sweephead[cf]=getnext(clast)
- sweephead[new]=getnext(cl)
+ sweephead[cf]=getnext(clast) or false
+ sweephead[new]=getnext(cl) or false
elseif backtrackdisc then
local cf=getnext(backtrackdisc)
local cl=start
@@ -24102,8 +24109,8 @@ local function chaindisk(head,start,dataset,sequence,rlmode,ck,skipped)
setdisc(backtrackdisc,pre,post,replace)
end
start=getprev(backtrackdisc)
- sweephead[post]=getnext(clast)
- sweephead[replace]=getnext(last)
+ sweephead[post]=getnext(clast) or false
+ sweephead[replace]=getnext(last) or false
else
local ok=false
head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
@@ -24135,6 +24142,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
local skipligature=flags[2]
local skipbase=flags[3]
local markclass=sequence.markclass
+ local skipsome=skipmark~=false or skipligature~=false or skipbase~=false or markclass
local skipped=false
local startprev,
startnext=getboth(start)
@@ -24148,10 +24156,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
local size=1
if s==1 then
local char=ischar(current,currentfont)
- if char then
- if not seq[1][char] then
- match=false
- end
+ if char and not seq[1][char] then
+ match=false
end
else
local f=ck[4]
@@ -24169,8 +24175,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if last then
local char,id=ischar(last,currentfont)
if char then
- local class=classes[char]
- if class then
+ if skipsome then
+ local class=classes[char]
if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then
skipped=true
if trace_skips then
@@ -24194,15 +24200,22 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
break
end
else
- if discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- match=false
+ if seq[n][char] then
+ if n<l then
+ last=getnext(last)
end
+ n=n+1
else
- match=false
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ match=false
+ end
+ else
+ match=false
+ end
+ break
end
- break
end
elseif char==false then
if discfound then
@@ -24226,10 +24239,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
while pre do
if seq[n][getchar(pre)] then
n=n+1
- pre=getnext(pre)
if n>l then
break
end
+ pre=getnext(pre)
else
notmatchpre[last]=true
break
@@ -24245,10 +24258,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
while replace do
if seq[n][getchar(replace)] then
n=n+1
- replace=getnext(replace)
if n>l then
break
end
+ replace=getnext(replace)
else
notmatchreplace[last]=true
if notmatchpre[last] then
@@ -24285,8 +24298,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if prev then
local char,id=ischar(prev,currentfont)
if char then
- local class=classes[char]
- if class then
+ if skipsome then
+ local class=classes[char]
if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then
skipped=true
if trace_skips then
@@ -24310,15 +24323,22 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
break
end
else
- if discfound then
- notmatchreplace[discfound]=true
- if notmatchpost[discfound] then
- match=false
+ if seq[n][char] then
+ if n>1 then
+ prev=getprev(prev)
end
+ n=n-1
else
- match=false
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpost[discfound] then
+ match=false
+ end
+ else
+ match=false
+ end
+ break
end
- break
end
elseif char==false then
if discfound then
@@ -24346,10 +24366,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if posttail==post then
break
else
- posttail=getprev(posttail)
if n<1 then
break
end
+ posttail=getprev(posttail)
end
else
notmatchpost[prev]=true
@@ -24369,10 +24389,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if replacetail==replace then
break
else
- replacetail=getprev(replacetail)
if n<1 then
break
end
+ replacetail=getprev(replacetail)
end
else
notmatchreplace[prev]=true
@@ -24419,8 +24439,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if current then
local char,id=ischar(current,currentfont)
if char then
- local class=classes[char]
- if class then
+ if skipsome then
+ local class=classes[char]
if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then
skipped=true
if trace_skips then
@@ -24444,15 +24464,22 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
break
end
else
- if discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- match=false
+ if seq[n][char] then
+ if n<s then
+ current=getnext(current)
end
+ n=n+1
else
- match=false
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ match=false
+ end
+ else
+ match=false
+ end
+ break
end
- break
end
elseif char==false then
if discfound then
@@ -24476,10 +24503,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
while pre do
if seq[n][getchar(pre)] then
n=n+1
- pre=getnext(pre)
if n>s then
break
end
+ pre=getnext(pre)
else
notmatchpre[current]=true
break
@@ -24495,10 +24522,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
while replace do
if seq[n][getchar(replace)] then
n=n+1
- replace=getnext(replace)
if n>s then
break
end
+ replace=getnext(replace)
else
notmatchreplace[current]=true
if not notmatchpre[current] then
@@ -24540,7 +24567,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
end
if done then
- break
+ break
+ else
end
end
end
@@ -24699,13 +24727,12 @@ local function kernrun(disc,k_run,font,attr,...)
done=true
end
if prev then
- local nest=getprev(pre)
setlink(prev,pre)
if k_run(prevmarks,"preinjections",pre,font,attr,...) then
done=true
end
- setprev(pre,nest)
- setnext(prev,disc)
+ setprev(pre)
+ setlink(prev,disc)
end
end
if post then
@@ -24718,7 +24745,7 @@ local function kernrun(disc,k_run,font,attr,...)
done=true
end
setnext(posttail)
- setprev(next,disc)
+ setlink(disc,next)
end
end
if replace then
@@ -24726,13 +24753,12 @@ local function kernrun(disc,k_run,font,attr,...)
done=true
end
if prev then
- local nest=getprev(replace)
setlink(prev,replace)
if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then
done=true
end
- setprev(replace,nest)
- setnext(prev,disc)
+ setprev(replace)
+ setlink(prev,disc)
end
if next then
setlink(replacetail,next)
@@ -24740,7 +24766,7 @@ local function kernrun(disc,k_run,font,attr,...)
done=true
end
setnext(replacetail)
- setprev(next,disc)
+ setlink(disc,next)
end
elseif prev and next then
setlink(prev,next)
@@ -24899,7 +24925,7 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm
local sweep=sweephead[head]
if sweep then
start=sweep
- sweephead[head]=nil
+ sweephead[head]=false
else
start=head
end
@@ -25035,7 +25061,7 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm
local sweep=sweephead[head]
if sweep then
start=sweep
- sweephead[head]=nil
+ sweephead[head]=false
else
start=head
end
@@ -25180,7 +25206,7 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase
if lookupcache then
local lookupmatch=lookupcache[char]
if lookupmatch then
- local h,d,ok=handler(head,n,dataset,sequence,lookupmatch,step,rlmode,i,injection)
+ local h,d,ok=handler(head,n,dataset,sequence,lookupmatch,rlmode,step,i,injection)
if ok then
return true
end
@@ -25293,32 +25319,38 @@ do
elseif typ=="gsub_reversecontextchain" then
local start=find_node_tail(head)
local rlmode=0
+ local merged=steps.merged
while start do
local char=ischar(start,font)
if char then
- local a
- if attr then
- a=getattr(start,0)
- end
- if not a or (a==attr) then
- for i=1,nofsteps do
- local step=steps[i]
- local lookupcache=step.coverage
- if lookupcache then
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
- if ok then
- done=true
- break
+ local m=merged[char]
+ if m then
+ local a
+ if attr then
+ a=getattr(start,0)
+ end
+ if not a or (a==attr) then
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ if lookupcache then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
+ if ok then
+ done=true
+ break
+ end
end
+ else
+ report_missing_coverage(dataset,sequence)
end
- else
- report_missing_coverage(dataset,sequence)
end
- end
- if start then
+ if start then
+ start=getprev(start)
+ end
+ else
start=getprev(start)
end
else
@@ -25340,24 +25372,26 @@ do
while start do
local char,id=ischar(start,font)
if char then
- local a
- if attr then
- if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local a
+ if attr then
+ if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ a=true
+ end
+ elseif not attribute or getprop(start,a_state)==attribute then
a=true
end
- elseif not attribute or getprop(start,a_state)==attribute then
- a=true
- end
- if a then
- local lookupmatch=lookupcache[char]
- if lookupmatch then
+ if a then
local ok
head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1)
if ok then
done=true
end
- end
- if start then
+ if start then
+ start=getnext(start)
+ end
+ else
start=getnext(start)
end
else
@@ -25395,38 +25429,44 @@ do
end
end
else
+ local merged=steps.merged
while start do
local char,id=ischar(start,font)
if char then
- local a
- if attr then
- if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ local m=merged[char]
+ if m then
+ local a
+ if attr then
+ if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ a=true
+ end
+ elseif not attribute or getprop(start,a_state)==attribute then
a=true
end
- elseif not attribute or getprop(start,a_state)==attribute then
- a=true
- end
- if a then
- for i=1,nofsteps do
- local step=steps[i]
- local lookupcache=step.coverage
- if lookupcache then
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
- if ok then
- done=true
- break
- elseif not start then
- break
+ if a then
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ if lookupcache then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
+ if ok then
+ done=true
+ break
+ elseif not start then
+ break
+ end
end
+ else
+ report_missing_coverage(dataset,sequence)
end
- else
- report_missing_coverage(dataset,sequence)
end
- end
- if start then
+ if start then
+ start=getnext(start)
+ end
+ else
start=getnext(start)
end
else
@@ -25485,14 +25525,14 @@ function otf.plugininitializer(tfmdata,value)
tfmdata.shared.plugin=plugins[value]
end
end
-function otf.pluginprocessor(head,font)
+function otf.pluginprocessor(head,font,attr,direction)
local s=fontdata[font].shared
local p=s and s.plugin
if p then
if trace_plugins then
report_process("applying plugin %a",p[1])
end
- return p[2](head,font)
+ return p[2](head,font,attr,direction)
else
return head,false
end
@@ -29020,7 +29060,7 @@ local afm=handlers.afm or {}
handlers.afm=afm
local readers=afm.readers or {}
afm.readers=readers
-afm.version=1.512
+afm.version=1.513
local get_indexes,get_shapes
do
local decrypt