summaryrefslogtreecommitdiff
path: root/tex
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
parentee627840c85edc7b073d0582632dcc4da82a1e83 (diff)
downloadcontext-fe1ea06fcb9c42c23beaf4211ae3b0a2de60895e.tar.gz
2017-08-02 23:05:00
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/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
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin848078 -> 848075 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60777 -> 60775 bytes
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua817
15 files changed, 715 insertions, 1434 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
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 23591e183..8bb1b96fa 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 e3e3d744e..96dbf5240 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 73f68128e..7c929867f 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 : 08/02/17 18:59:29
+-- merge date : 08/02/17 23:00:11
do -- begin closure to overcome local limits and interference
@@ -19160,7 +19160,7 @@ local function mergesteps_1(lookup,strict)
lookup.steps={ first }
return nofsteps-1
end
-local function mergesteps_2(lookup,strict)
+local function mergesteps_2(lookup,strict)
local steps=lookup.steps
local nofsteps=lookup.nofsteps
local first=steps[1]
@@ -19469,8 +19469,29 @@ local function mergesteps(t,k)
return merged
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]
+ 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)
if not data or data.expanded then
@@ -19528,14 +19549,7 @@ function readers.expand(data)
sequence.markclass=markclasses[markclass]
end
end
- local flags=sequence.flags
- if flags then
- flags[5]=flags[1]~=false
- or flags[2]~=false
- or flags[3]~=false
- or sequence.markclass
- or false
- end
+ checkflags(sequence,resources)
for i=1,nofsteps do
local step=steps[i]
local baseclasses=step.baseclasses
@@ -21024,40 +21038,21 @@ function injections.setkern(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
@@ -21072,40 +21067,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
@@ -24057,7 +24033,7 @@ local function setdiscchecked(d,pre,post,replace)
setdisc(d,pre,post,replace)
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)
local size=ck[5]-ck[4]+1
local chainlookups=ck[6]
local done=false
@@ -24079,32 +24055,19 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
end
end
else
- 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
while start do
- if skipped then
+ if skipsome then
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
@@ -24125,7 +24088,7 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
if ok then
done=true
if n and n>1 and i+n>nofchainlookups then
-i=size
+ i=size
break
end
end
@@ -24474,472 +24437,7 @@ local function chaintrac(head,start,dataset,sequence,rlmode,ck,skipped,match)
logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a",
cref(dataset,sequence),rule,match and "matches" or "nomatch",gref(char),first-1,last-first+1,nofseq-last,lookuptype)
end
-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=flags[5]
- local skipped=false
- local startprev,
- startnext=getboth(start)
- for k=1,#contexts do
- local match=true
- local current=start
- local last=start
- local ck=contexts[k]
- local seq=ck[3]
- local s=#seq
- if s==1 then
- local char=ischar(current,currentfont)
- if char and not seq[1][char] then
- match=false
- end
- else
- local f=ck[4]
- local l=ck[5]
- if l>f then
- local discfound
- local n=f+1
- last=startnext
- 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
- 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
- if notmatchpre[last] then
- match=false
- end
- end
- last=getnext(last)
- else
- match=false
- break
- end
- else
- match=false
- break
- end
- end
- end
- 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
- 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
- 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
- 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
- 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
- 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
- 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)
- elseif seq[n][char] then
- if n<s then
- current=getnext(current)
- 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
- current=getnext(current)
- 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
- 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
- if not notmatchpre[current] then
- match=false
- end
- break
- end
- end
- if not match then
- break
- end
- else
- end
- 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
- end
- end
- end
- if diskseen then
- notmatchpre={}
- notmatchpost={}
- notmatchreplace={}
- end
- return head,start,done
-end
-local function optimized_handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
+local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
local sweepnode=sweepnode
local sweeptype=sweeptype
local postreplace
@@ -24957,19 +24455,8 @@ 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
+ local skipsome=sequence.skipsome
local startprev,
startnext=getboth(start)
local done
@@ -24999,29 +24486,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 (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)
@@ -25118,29 +24588,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 (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)
@@ -25253,29 +24706,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 (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)
- elseif seq[n][char] then
- if n<s then
- current=getnext(current)
- 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)
elseif seq[n][char] then
if n<s then
current=getnext(current)
@@ -25394,20 +24830,6 @@ local function optimized_handle_contextchain(head,start,dataset,sequence,context
end
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
@@ -26125,6 +25547,7 @@ do
local handler=handlers[typ]
local steps=sequence.steps
local nofsteps=sequence.nofsteps
+ local skipsome=sequence.skipsome
if not steps then
local h,d,ok=handler(head,head,dataset,sequence,nil,nil,nil,0,font,attr)
if ok then
@@ -26182,30 +25605,34 @@ do
while start do
local char,id=ischar(start,font)
if char 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
+ if skipsome and skipsome[char] then
+ start=getnext(start)
+ else
+ 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 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)
end
- else
- start=getnext(start)
end
elseif char==false or id==glue_code then
start=getnext(start)
@@ -26242,35 +25669,39 @@ do
if char 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
+ if skipsome and skipsome[char] then
+ start=getnext(start)
+ else
+ 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=m[1],m[2] do
- local step=steps[i]
- local lookupcache=step.coverage
- 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
+ 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
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)
@@ -29028,6 +28459,8 @@ local fonts=fonts
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",
@@ -29566,6 +28999,7 @@ local function addfeature(data,feature,specifications)
local steps={}
local sublookups=specification.lookups
local category=nil
+ checkflags(specification,resources)
if sublookups then
local s={}
for i=1,#sublookups do
@@ -29602,7 +29036,7 @@ local function addfeature(data,feature,specifications)
steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
end
end
- setmetatableindex(steps,fonts.helpers.mergesteps)
+ setmetatableindex(steps,mergesteps)
s[i]={
[stepkey]=steps,
nofsteps=nofsteps,
@@ -29661,7 +29095,7 @@ local function addfeature(data,feature,specifications)
askedfeatures[k]=tohash(v)
end
end
- setmetatableindex(steps,fonts.helpers.mergesteps)
+ setmetatableindex(steps,mergesteps)
if featureflags[1] then featureflags[1]="mark" end
if featureflags[2] then featureflags[2]="ligature" end
if featureflags[3] then featureflags[3]="base" end
@@ -29676,6 +29110,7 @@ local function addfeature(data,feature,specifications)
nofsteps=nofsteps,
type=steptype,
}
+ checkflags(sequence,resources)
local first,last=getrange(sequences,category)
inject(specification,sequences,sequence,first,last,category,feature)
local features=fontfeatures[category]