summaryrefslogtreecommitdiff
path: root/tex/context/base
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2017-08-02 23:42:35 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2017-08-02 23:42:35 +0200
commitfe1ea06fcb9c42c23beaf4211ae3b0a2de60895e (patch)
treeb14be0ced75829638c0c3be2ca1eb9d53defd35a /tex/context/base
parentee627840c85edc7b073d0582632dcc4da82a1e83 (diff)
downloadcontext-fe1ea06fcb9c42c23beaf4211ae3b0a2de60895e.tar.gz
2017-08-02 23:05:00
Diffstat (limited to 'tex/context/base')
-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/mkiv/buff-ver.mkiv4
-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-otc.lua11
-rw-r--r--tex/context/base/mkiv/font-otj.lua83
-rw-r--r--tex/context/base/mkiv/font-ots.lua1189
-rw-r--r--tex/context/base/mkiv/font-oup.lua36
-rw-r--r--tex/context/base/mkiv/node-nut.lua1
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25788 -> 25786 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin426288 -> 426318 bytes
12 files changed, 589 insertions, 743 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index ad39ff810..ba0e30220 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.08.02 18:59}
+\newcontextversion{2017.08.02 23:00}
%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 5bb3e1b31..1658e1e7d 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.08.02 18:59}
+\edef\contextversion{2017.08.02 23:00}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/buff-ver.mkiv b/tex/context/base/mkiv/buff-ver.mkiv
index 8e76ff139..44fa72932 100644
--- a/tex/context/base/mkiv/buff-ver.mkiv
+++ b/tex/context/base/mkiv/buff-ver.mkiv
@@ -857,11 +857,11 @@
\begingroup
\let\buff_verbatim_type_buffer_indeed\buff_verbatim_type_buffer_indeed_inline
\let\setupcurrenttyping\setupcurrenttype % a terrible hack but it saves code
- \let\currenttype\v!buffer
+ \let\currenttype\empty
\dodoubleempty\buff_verbatim_type_buffer}
\unexpanded\def\buff_verbatim_type_buffer_indeed_inline#1#2% category name
- {\doifsomething{#1}{\edef\currenttype{#1}}% probably this line can go
+ {\edef\currenttype{#1}%
\buff_verbatim_initialize_type_one
\dostarttaggedchained\t!verbatim\currenttype\??type
\clf_typebuffer
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index d5ae4be08..392f1e1fe 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.08.02 18:59}
+\newcontextversion{2017.08.02 23:00}
%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 6c8b58ee3..02ce376f2 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.08.02 18:59}
+\edef\contextversion{2017.08.02 23:00}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua
index 97a7ad72b..0d470c690 100644
--- a/tex/context/base/mkiv/font-otc.lua
+++ b/tex/context/base/mkiv/font-otc.lua
@@ -21,6 +21,9 @@ local otf = fonts.handlers.otf
local registerotffeature = otf.features.register
local setmetatableindex = table.setmetatableindex
+local mergesteps = fonts.helpers.mergesteps
+local checkflags = fonts.helpers.checkflags
+
local normalized = {
substitution = "substitution",
single = "substitution",
@@ -605,6 +608,8 @@ local function addfeature(data,feature,specifications)
local sublookups = specification.lookups
local category = nil
--
+ checkflags(specification,resources)
+ --
if sublookups then
local s = { }
for i=1,#sublookups do
@@ -642,7 +647,7 @@ local function addfeature(data,feature,specifications)
end
end
--
- setmetatableindex(steps,fonts.helpers.mergesteps) -- speedup
+ setmetatableindex(steps,mergesteps) -- speedup
--
s[i] = {
[stepkey] = steps,
@@ -704,7 +709,7 @@ local function addfeature(data,feature,specifications)
end
end
--
- setmetatableindex(steps,fonts.helpers.mergesteps) -- speedup
+ setmetatableindex(steps,mergesteps) -- speedup
--
if featureflags[1] then featureflags[1] = "mark" end
if featureflags[2] then featureflags[2] = "ligature" end
@@ -720,6 +725,8 @@ local function addfeature(data,feature,specifications)
nofsteps = nofsteps,
type = steptype,
}
+ -- new
+ checkflags(sequence,resources)
-- position | prepend | append
local first, last = getrange(sequences,category)
inject(specification,sequences,sequence,first,last,category,feature)
diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua
index 8d95e115b..657f1a2a6 100644
--- a/tex/context/base/mkiv/font-otj.lua
+++ b/tex/context/base/mkiv/font-otj.lua
@@ -356,41 +356,21 @@ function injections.setkern(current,factor,rlmode,x,injection)
if not injection then
injection = "injections"
end
- if rlmode and rlmode < 0 then
- -- was right kern but why ... we need to check this (kai)
- if p then
- local i = rawget(p,injection)
- if i then
- i.leftkern = dx + (i.leftkern or 0)
- else
- p[injection] = {
- leftkern = dx,
- }
- end
+ if p then
+ local i = rawget(p,injection)
+ if i then
+ i.leftkern = dx + (i.leftkern or 0)
else
- properties[current] = {
- [injection] = {
- leftkern = dx,
- },
+ p[injection] = {
+ leftkern = dx,
}
end
else
- if p then
- local i = rawget(p,injection)
- if i then
- i.leftkern = dx + (i.leftkern or 0)
- else
- p[injection] = {
- leftkern = dx,
- }
- end
- else
- properties[current] = {
- [injection] = {
- leftkern = dx,
- },
- }
- end
+ properties[current] = {
+ [injection] = {
+ leftkern = dx,
+ },
+ }
end
return dx, nofregisteredkerns
else
@@ -410,40 +390,21 @@ function injections.setmove(current,factor,rlmode,x,injection)
if not injection then
injection = "injections"
end
- if rlmode and rlmode < 0 then
- if p then
- local i = rawget(p,injection)
- if i then
- i.leftkern = dx + (i.leftkern or 0)
- else
- p[injection] = {
- leftkern = dx,
- }
- end
+ if p then
+ local i = rawget(p,injection)
+ if i then
+ i.leftkern = dx + (i.leftkern or 0)
else
- properties[current] = {
- [injection] = {
- leftkern = dx,
- },
+ p[injection] = {
+ leftkern = dx,
}
end
else
- if p then
- local i = rawget(p,injection)
- if i then
- i.leftkern = dx + (i.leftkern or 0)
- else
- p[injection] = {
- leftkern = dx,
- }
- end
- else
- properties[current] = {
- [injection] = {
- leftkern = dx,
- },
- }
- end
+ properties[current] = {
+ [injection] = {
+ leftkern = dx,
+ },
+ }
end
return dx, nofregisteredkerns
else
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index 98a9184ae..e5641f5c5 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -874,7 +874,7 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje
if marks[nextchar] and sequence.flags[1] then
prev = snext
snext = getnext(snext)
--- elseif sequence.markclass and sequence.markclass[nextchar] then
+-- elseif sequence.markclass and sequence.markclass[nextchar] then -- skipsome
-- prev = snext
-- snext = getnext(snext)
else
@@ -1489,7 +1489,7 @@ function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlm
if marks[nextchar] and sequence.flags[1] then
prev = snext
snext = getnext(snext)
--- elseif sequence.markclass and sequence.markclass[nextchar] then
+-- elseif sequence.markclass and sequence.markclass[nextchar] then - skipsome
-- prev = snext
-- snext = getnext(snext)
else
@@ -1873,7 +1873,7 @@ end
local noflags = { false, false, false, false }
-local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
+local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipsome) -- skipped)
local size = ck[5] - ck[4] + 1
local chainlookups = ck[6]
@@ -1922,33 +1922,20 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
-- It's very unlikely that we will have skip classes here but still ... we seldom
-- enter this branch anyway.
- local skipmark
- local skipligature
- local skipbase
- local markclass
- if skipped then
- local flags = sequence.flags or noflags
- skipmark = flags[1]
- skipligature = flags[2]
- skipbase = flags[3]
- markclass = sequence.markclass
+ if skipsome then
+ skipsome = sequence.skipsome
end
local i = 1
local laststart = start
local nofchainlookups = #chainlookups -- useful?
while start do
- if skipped then -- hm, so we know we skip some
+ if skipsome then -- hm, so we know we skip some
while start do
- local char, id = ischar(start,currentfont)
+ local char = ischar(start,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
- start = getnext(start)
- else
- break
- end
+ if skipsome[char] then
+ start = getnext(start)
else
break
end
@@ -1971,7 +1958,7 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
done = true
if n and n > 1 and i + n > nofchainlookups then
-- this is a safeguard, we just ignore the rest of the lookups
-i = size -- prevents an advance
+ i = size -- prevents an advance
break
end
end
@@ -2354,505 +2341,448 @@ end
-- tests because they have many steps with one context (having multiple contexts makes more sense)
-- also because we (can) reduce them.
-local function traditional_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 markclass = sequence.markclass
- local skipmark = flags[1]
- local skipligature = flags[2]
- local skipbase = flags[3]
- -- local skipsome = skipmark ~= false or skipligature ~= false or skipbase ~= false or markclass
- local skipsome = flags[5]
- 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
- -- 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 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)
- -- 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
- if l > f then
- -- before/current/after | before/current | current/after
- local discfound -- = nil
- local n = f + 1
- 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
- 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
- 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
- if 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
- 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
- if n > l then
- break
- end
- pre = getnext(pre)
- 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
- if n > l then
- break
- end
- replace = getnext(replace)
- 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
- if startprev then
- local prev = startprev
- if prev == checkdisc and (sweeptype == "pre" or sweeptype == "replace") then
- prev = getprev(sweepnode)
- 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
- 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
- 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
- if 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
- 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
- if n < 1 then
- break
- end
- posttail = getprev(posttail)
- 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
- if n < 1 then
- break
- end
- replacetail = getprev(replacetail)
- 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)
- elseif id == glue_code then
- local sn = seq[n]
- if (sn[32] and spaces[prev]) or sn[0xFFFC] then
- n = n - 1
- prev = getprev(prev)
- else
- match = false
- break
- end
- elseif seq[n][0xFFFC] 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)
- 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
- 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
- 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
- if 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
- 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
- if n > s then
- break
- end
- pre = getnext(pre)
- 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
- if n > s then
- break
- end
- replace = getnext(replace)
- 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)
- elseif id == glue_code then
- local sn = seq[n]
- if (sn[32] and spaces[current]) or sn[0xFFFC] then
- n = n + 1
- current = getnext(current)
- else
- match = false
- break
- end
- elseif seq[n][0xFFFC] 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
+-- 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 skipsome = sequence.skipsome
+-- 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
+-- -- 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 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)
+-- -- 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
+-- if l > f then
+-- -- before/current/after | before/current | current/after
+-- local discfound -- = nil
+-- local n = f + 1
+-- 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
+-- if skipsome and skipsome[char] then
+-- skipped = true
+-- if trace_skips then
+-- show_skip(dataset,sequence,char,ck,classes[char])
+-- end
+-- last = getnext(last)
+-- else
+-- if 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
+-- 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
+-- if n > l then
+-- break
+-- end
+-- pre = getnext(pre)
+-- 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
+-- if n > l then
+-- break
+-- end
+-- replace = getnext(replace)
+-- 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
+-- if startprev then
+-- local prev = startprev
+-- if prev == checkdisc and (sweeptype == "pre" or sweeptype == "replace") then
+-- prev = getprev(sweepnode)
+-- 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
+-- if skipsome and skipsome[char] then
+-- skipped = true
+-- if trace_skips then
+-- show_skip(dataset,sequence,char,ck,classes[char])
+-- end
+-- prev = getprev(prev)
+-- else
+-- if 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
+-- 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
+-- if n < 1 then
+-- break
+-- end
+-- posttail = getprev(posttail)
+-- 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
+-- if n < 1 then
+-- break
+-- end
+-- replacetail = getprev(replacetail)
+-- 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)
+-- elseif id == glue_code then
+-- local sn = seq[n]
+-- if (sn[32] and spaces[prev]) or sn[0xFFFC] then
+-- n = n - 1
+-- prev = getprev(prev)
+-- else
+-- match = false
+-- break
+-- end
+-- elseif seq[n][0xFFFC] 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)
+-- 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
+-- if skipsome and skipsome[char] then
+-- skipped = true
+-- if trace_skips then
+-- show_skip(dataset,sequence,char,ck,classes[char])
+-- end
+-- current = getnext(current) -- was absent
+-- else
+-- if 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
+-- 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
+-- if n > s then
+-- break
+-- end
+-- pre = getnext(pre)
+-- 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
+-- if n > s then
+-- break
+-- end
+-- replace = getnext(replace)
+-- 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)
+-- elseif id == glue_code then
+-- local sn = seq[n]
+-- if (sn[32] and spaces[current]) or sn[0xFFFC] then
+-- n = n + 1
+-- current = getnext(current)
+-- else
+-- match = false
+-- break
+-- end
+-- elseif seq[n][0xFFFC] 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
--- only a bit faster but probably also a bit cleaner ... so ...
+-- Instead of a "match" boolean variable and check for that I decided to use a "goto" with
+-- "labels" instead. This is one of the cases where it makes th ecode more readable and we might
+-- even gain a bit performance.
-local function optimized_handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
+local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
-- optimizing for rlmode gains nothing
local sweepnode = sweepnode
local sweeptype = sweeptype
@@ -2871,19 +2801,10 @@ local function optimized_handle_contextchain(head,start,dataset,sequence,context
checkdisc = getprev(head)
end
local currentfont = currentfont
- local flags = sequence.flags or noflags
- local skipsome = flags[5]
- local skipmark
- local skipligature
- local skipbase
- local markclass
- if skipsome then
- skipmark = flags[1]
- skipligature = flags[2]
- skipbase = flags[3]
- markclass = sequence.markclass
- end
+
local skipped -- = false
+ local skipsome = sequence.skipsome
+
local startprev,
startnext = getboth(start)
local done -- = false
@@ -2921,30 +2842,12 @@ local function optimized_handle_contextchain(head,start,dataset,sequence,context
if last then
local char, id = ischar(last,currentfont)
if char 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
- if class == skipmark or (markclass and class == "mark" and not markclass[char]) or class == skipligature or class == skipbase 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
- elseif discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
+ if skipsome and skipsome[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
end
+ last = getnext(last)
elseif seq[n][char] then
if n < l then
last = getnext(last)
@@ -3046,30 +2949,12 @@ local function optimized_handle_contextchain(head,start,dataset,sequence,context
if prev then
local char, id = ischar(prev,currentfont)
if char 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
- if class == skipmark or (markclass and class == "mark" and not markclass[char]) or class == skipligature or class == skipbase 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
- elseif discfound then
- notmatchreplace[discfound] = true
- if notmatchpost[discfound] then
- goto next
- else
- break
- end
- else
- goto next
+ if skipsome and skipsome[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
end
+ prev = getprev(prev)
elseif seq[n][char] then
if n > 1 then
prev = getprev(prev)
@@ -3190,30 +3075,12 @@ local function optimized_handle_contextchain(head,start,dataset,sequence,context
if current then
local char, id = ischar(current,currentfont)
if char 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
- if class == skipmark or (markclass and class == "mark" and not markclass[char]) or class == skipligature or class == skipbase 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
- elseif discfound then
- notmatchreplace[discfound] = true
- if notmatchpre[discfound] then
- break
- else
- goto next
- end
- else
- goto next
+ if skipsome and skipsome[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
end
+ current = getnext(current) -- was absent
elseif seq[n][char] then
if n < s then -- new test
current = getnext(current) -- was absent
@@ -3346,26 +3213,6 @@ local function optimized_handle_contextchain(head,start,dataset,sequence,context
return head, start, done
end
-------------------------------
-
-local handle_contextchain = traditional_handle_contextchain
-
-directives.register("otf.optimizechains",function(v)
- if v then
- report_chain()
- report_chain("using experimental optimized code")
- report_chain()
- end
- handle_contextchain = v and optimized_handle_contextchain or traditional_handle_contextchain
- handlers.gsub_context = handle_contextchain
- handlers.gsub_contextchain = handle_contextchain
- handlers.gsub_reversecontextchain = handle_contextchain
- handlers.gpos_contextchain = handle_contextchain
- handlers.gpos_context = handle_contextchain
-end)
-
-------------------------------
-
handlers.gsub_context = handle_contextchain
handlers.gsub_contextchain = handle_contextchain
handlers.gsub_reversecontextchain = handle_contextchain
@@ -4567,6 +4414,8 @@ do
local handler = handlers[typ] -- store in dataset
local steps = sequence.steps
local nofsteps = sequence.nofsteps
+ local skipsome = sequence.skipsome
+
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)
@@ -4633,30 +4482,34 @@ do
while start do
local char, id = ischar(start,font)
if char then
- local lookupmatch = lookupcache[char]
- if lookupmatch then
- 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
+ if skipsome and skipsome[char] then
+ start = getnext(start)
+ else
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ 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 ok
- head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1)
- if ok then
- done = true
- end
- if start then
+ if a then
+ local ok
+ head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1)
+ if ok then
+ done = true
+ end
+ if start then
+ start = getnext(start)
+ end
+ else
start = getnext(start)
end
else
- start = getnext(start)
+ start = getnext(start)
end
- else
- start = getnext(start)
end
elseif char == false or id == glue_code then
-- a different font|state or glue (happens often)
@@ -4694,39 +4547,43 @@ do
if char then
local m = merged[char]
if m then
- 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
+ if skipsome and skipsome[char] then
+ start = getnext(start)
+ else
+ 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=m[1],m[2] do
- local step = steps[i]
- -- for i=1,#m do
- -- local step = m[i]
- local lookupcache = step.coverage
- 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
+ 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
end
- end
- if start then
+ if start then
+ start = getnext(start)
+ end
+ else
start = getnext(start)
end
- else
- start = getnext(start)
end
else
start = getnext(start)
diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua
index ce1dca724..3b86cde72 100644
--- a/tex/context/base/mkiv/font-oup.lua
+++ b/tex/context/base/mkiv/font-oup.lua
@@ -2146,6 +2146,9 @@ local function mergesteps_1(lookup,strict)
end
local function mergesteps_2(lookup,strict) -- pairs
+ -- this can be tricky as we can have a match on a mark with no marks skip flag
+ -- in which case with multiple steps a hit can prevent a next step while in the
+ -- merged case we can hit differently (a messy font then anyway)
local steps = lookup.steps
local nofsteps = lookup.nofsteps
local first = steps[1]
@@ -2494,8 +2497,30 @@ local function mergesteps(t,k)
end
end
+local function checkflags(sequence,resources)
+ if not sequence.skipsome then
+ local flags = sequence.flags
+ if flags then
+ local skipmark = flags[1]
+ local skipligature = flags[2]
+ local skipbase = flags[3]
+ local markclass = sequence.markclass
+ local skipsome = skipmark or skipligature or skipbase or markclass or false
+ if skipsome then
+ sequence.skipsome = setmetatableindex(function(t,k)
+ local c = resources.classes[k] -- delayed table
+ local v = c == skipmark or (markclass and c == "mark" and not markclass[k]) or c == skipligature or c == skipbase
+ t[k] = v or false
+ return v
+ end)
+ end
+ end
+ end
+end
+
if fonts.helpers then
fonts.helpers.mergesteps = mergesteps
+ fonts.helpers.checkflags = checkflags
end
function readers.expand(data)
@@ -2565,14 +2590,9 @@ function readers.expand(data)
sequence.markclass = markclasses[markclass]
end
end
- local flags = sequence.flags
- if flags then
- flags[5] = flags[1] ~= false -- otherwise "mark"
- or flags[2] ~= false -- otherwise "base"
- or flags[3] ~= false -- otherwise "ligature"
- or sequence.markclass
- or false
- end
+
+ checkflags(sequence,resources)
+
for i=1,nofsteps do
local step = steps[i]
local baseclasses = step.baseclasses
diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua
index bbb629cd9..651717c68 100644
--- a/tex/context/base/mkiv/node-nut.lua
+++ b/tex/context/base/mkiv/node-nut.lua
@@ -950,6 +950,7 @@ end
if LUATEXFUNCTIONALITY < 6384 then
local getfield = nuts.getfield
+ local setfield = nuts.setfield
function nuts.getboxglue(n,glue_set,glue_order,glue_sign)
return
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index c210fae43..68c55f340 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 cebe52549..033f44b3d 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ