[latex3-commits] [git/LaTeX3-latex3-luaotfload] bidi-dev: Lots of compliance fixes (ac681a2)
Marcel Fabian Krüger
tex at 2krueger.de
Wed Aug 14 17:49:33 CEST 2019
Repository : https://github.com/latex3/luaotfload
On branch : bidi-dev
Link : https://github.com/latex3/luaotfload/commit/ac681a204f744c4c82bd081512d3a84e8fce4265
>---------------------------------------------------------------
commit ac681a204f744c4c82bd081512d3a84e8fce4265
Author: Marcel Fabian Krüger <tex at 2krueger.de>
Date: Wed Aug 14 15:01:37 2019 +0200
Lots of compliance fixes
>---------------------------------------------------------------
ac681a204f744c4c82bd081512d3a84e8fce4265
src/luaotfload-bidi.lua | 89 ++++++++++++++-----------
texmf/tex/luatex/luaotfload/luaotfload-bidi.lua | 89 ++++++++++++++-----------
2 files changed, 100 insertions(+), 78 deletions(-)
diff --git a/src/luaotfload-bidi.lua b/src/luaotfload-bidi.lua
index 02d3659..8e58995 100644
--- a/src/luaotfload-bidi.lua
+++ b/src/luaotfload-bidi.lua
@@ -94,7 +94,7 @@ local bidi_brackets_canonical = {
[0x232A] = 0x3009,
}
for k, v in pairs(bidi_brackets) do
- bidi_brackets_canonical[k] = k
+ bidi_brackets_canonical[k] = bidi_brackets_canonical[k] or k
end
local opentype_mirroring do
@@ -145,12 +145,12 @@ local NI = {
PDI = true,
}
-local function adjust_nsm(pre, dir, node_origclass)
+local function adjust_nsm(pre, stop, dir, node_class, node_origclass)
local follow = getnext(pre)
local follow_origclass = node_origclass[follow]
while follow ~= stop and (not follow_origclass or follow_origclass == "NSM") do
if follow_origclass then
- follow_class = dir
+ node_class[follow] = dir
end
follow = getnext(follow)
follow_origclass = node_origclass[follow]
@@ -181,7 +181,7 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
curclass = "AN"
node_class[cur] = curclass
elseif prevstrong == "L" then
- node_class[cur] = curclass
+ node_class[cur] = "L"
-- HACK: No curclass change. Therefore prevclass is still EN,
-- such that this W7 change does not affect the ES/ET changes
-- in W4-W5
@@ -189,19 +189,14 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
elseif curclass == "ES" then
if prevclass == "EN" then
local follow = getnext(cur)
- local followclass = node_class[cur]
+ local followclass = node_class[follow]
while follow ~= stop and not followclass do
follow = getnext(follow)
followclass = node_class[follow]
end
if follow ~= stop and followclass == "EN" then
- if prevstrong == "AL" then
- curclass = "AN"
- node_class[cur] = curclass
- elseif prevstrong == "L" then
- node_class[cur] = "L"
- curclass = "EN" -- (sic), see above
- end
+ curclass = "EN"
+ node_class[cur] = prevstrong == "L" and "L" or curclass
end
end
elseif curclass == "CS" then
@@ -212,17 +207,23 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
follow = getnext(follow)
followclass = node_class[follow]
end
- if follow ~= stop and followclass == prevclass then
+ if follow ~= stop then
if followclass == "EN" then
if prevstrong == "AL" then
curclass = "AN"
node_class[cur] = curclass
- elseif prevstrong == "L" then
- node_class[cur] = "L"
- curclass = "EN" -- (sic), see above
+ elseif prevclass == "EN" then
+ curclass = "EN"
+ node_class[cur] = prevstrong == "L" and "L" or curclass
+ else
+ curclass = "ON"
+ node_class[cur] = curclass
end
+ elseif followclass == "AN" and prevclass == "AN" then
+ curclass = "AN"
+ node_class[cur] = curclass
else
- curclass = prevclass
+ curclass = "ON"
node_class[cur] = curclass
end
else
@@ -268,15 +269,16 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
end
cur = head
local last_e, last_s = 0, 0
- prevstrong = sos
local stack = {}
+ local need_context = {}
while cur ~= stop do
- if getid(cur) == glyph_id and bidi_fonts[getfont(cur)] then
- local cp = getchar(cur) -- FIXME: canonical equivalents
+ local curclass = node_class[cur]
+ if curclass == "ON" and getid(cur) == glyph_id and bidi_fonts[getfont(cur)] then
+ local cp = bidi_brackets_canonical[getchar(cur)]
local bracket = bidi_brackets[cp]
if bracket then
if bracket.type == 'o' then
- local info = {cur, bracket.other, prevstrong == opposite}
+ local info = {cur, bracket.other}
stack[#stack + 1] = info
else -- if cp.type == 'c'
for i = #stack,1,-1 do
@@ -288,15 +290,16 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
if last_e >= i then
local beg = entry[1]
node_class[beg], node_class[cur] = direction, direction
- adjust_nsm(beg, direction, node_origclass)
- adjust_nsm(cur, direction, node_origclass)
+ adjust_nsm(beg, stop, direction, node_class, node_origclass)
+ adjust_nsm(cur, stop, direction, node_class, node_origclass)
last_s, last_e = i-1, i-1
elseif last_s >= i then
+ need_context[entry[1]] = cur
if entry[3] then
local beg = entry[1]
node_class[beg], node_class[cur] = opposite, opposite
- adjust_nsm(beg, opposite, node_origclass)
- adjust_nsm(cur, opposite, node_origclass)
+ adjust_nsm(beg, stop, opposite, node_class, node_origclass)
+ adjust_nsm(cur, stop, opposite, node_class, node_origclass)
end
last_s = i-1
end
@@ -304,13 +307,13 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
end
end
end
- else
- local curclass = node_class[cur]
- if Strong[curclass] == direction then
- last_e, last_s, prevstrong = #stack, #stack, direction
- elseif Strong[curclass] == opposite then
- last_s, prevstrong = #stack, opposite
- end
+ end
+ else
+ local strong = Strong[curclass]
+ if strong == direction then
+ last_e, last_s = #stack, #stack
+ elseif strong == opposite then
+ last_s = #stack
end
end
cur = getnext(cur)
@@ -335,12 +338,19 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
prevstrong = strong
node_level[cur] = newlevels[curclass]
cur = getnext(cur)
+ elseif need_context[cur] then
+ local final = need_context[cur]
+ node_class[cur], node_class[final] = prevstrong, prevstrong
+ adjust_nsm(final, stop, prevstrong, node_class, node_origclass)
+ adjust_nsm(cur, stop, prevstrong, node_class, node_origclass)
+ node_level[cur] = newlevels[prevstrong]
+ cur = getnext(cur)
else
local follow = getnext(cur)
- local followclass = node_class[follow]
- while follow ~= stop and not Strong[followclass] do
+ local followclass = need_context[follow] and prevstrong or Strong[node_class[follow]]
+ while follow ~= stop and not followclass do
follow = getnext(follow)
- followclass = Strong[node_class[follow]]
+ followclass = need_context[follow] and prevstrong or Strong[node_class[follow]]
end
if follow == stop then
followclass = eos
@@ -351,14 +361,14 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
while follow ~= stop and not Strong[followclass] do
node_class[follow], node_level[follow] = followclass and outerdir, followclass and newlevels[outerdir]
follow = getnext(follow)
- followclass = node_class[follow]
+ followclass = need_context[follow] and prevstrong or node_class[follow]
end
cur = follow
end
end
fulltime1 = fulltime1 + gettime() - starttime
end
-local node_class, node_origclass, node_level = {}, {}, {} -- Making these local was significantly
+node_class, node_origclass, node_level = {}, {}, {} -- Making these local was significantly
-- slower necause they are sparse arrays with medium sized integer
-- keys, requiring relativly big allocations
function dobidi(head, a, b, c, par_direction)
@@ -387,10 +397,10 @@ function dobidi(head, a, b, c, par_direction)
class = bidi_classes[getchar(cur)]
if class == "RLE" then
class, curlevel = nil, level
- push(0)
+ push(1)
elseif class == "LRE" then
class, curlevel = nil, level
- push(1)
+ push(0)
elseif class == "RLO" then
class, curlevel = nil, level
push(1, "R")
@@ -430,6 +440,7 @@ function dobidi(head, a, b, c, par_direction)
-- Unmatched reset. LuaTeX inserts them sometimes, just
-- dropping them normally works fine. But deleting is
-- difficult here because the loop needs the next pointer.
+ -- Technically they should stay
if old_dir then nodeflush(old_dir) end
head = remove(head, cur)
old_dir = cur
diff --git a/texmf/tex/luatex/luaotfload/luaotfload-bidi.lua b/texmf/tex/luatex/luaotfload/luaotfload-bidi.lua
index 02d3659..8e58995 100644
--- a/texmf/tex/luatex/luaotfload/luaotfload-bidi.lua
+++ b/texmf/tex/luatex/luaotfload/luaotfload-bidi.lua
@@ -94,7 +94,7 @@ local bidi_brackets_canonical = {
[0x232A] = 0x3009,
}
for k, v in pairs(bidi_brackets) do
- bidi_brackets_canonical[k] = k
+ bidi_brackets_canonical[k] = bidi_brackets_canonical[k] or k
end
local opentype_mirroring do
@@ -145,12 +145,12 @@ local NI = {
PDI = true,
}
-local function adjust_nsm(pre, dir, node_origclass)
+local function adjust_nsm(pre, stop, dir, node_class, node_origclass)
local follow = getnext(pre)
local follow_origclass = node_origclass[follow]
while follow ~= stop and (not follow_origclass or follow_origclass == "NSM") do
if follow_origclass then
- follow_class = dir
+ node_class[follow] = dir
end
follow = getnext(follow)
follow_origclass = node_origclass[follow]
@@ -181,7 +181,7 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
curclass = "AN"
node_class[cur] = curclass
elseif prevstrong == "L" then
- node_class[cur] = curclass
+ node_class[cur] = "L"
-- HACK: No curclass change. Therefore prevclass is still EN,
-- such that this W7 change does not affect the ES/ET changes
-- in W4-W5
@@ -189,19 +189,14 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
elseif curclass == "ES" then
if prevclass == "EN" then
local follow = getnext(cur)
- local followclass = node_class[cur]
+ local followclass = node_class[follow]
while follow ~= stop and not followclass do
follow = getnext(follow)
followclass = node_class[follow]
end
if follow ~= stop and followclass == "EN" then
- if prevstrong == "AL" then
- curclass = "AN"
- node_class[cur] = curclass
- elseif prevstrong == "L" then
- node_class[cur] = "L"
- curclass = "EN" -- (sic), see above
- end
+ curclass = "EN"
+ node_class[cur] = prevstrong == "L" and "L" or curclass
end
end
elseif curclass == "CS" then
@@ -212,17 +207,23 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
follow = getnext(follow)
followclass = node_class[follow]
end
- if follow ~= stop and followclass == prevclass then
+ if follow ~= stop then
if followclass == "EN" then
if prevstrong == "AL" then
curclass = "AN"
node_class[cur] = curclass
- elseif prevstrong == "L" then
- node_class[cur] = "L"
- curclass = "EN" -- (sic), see above
+ elseif prevclass == "EN" then
+ curclass = "EN"
+ node_class[cur] = prevstrong == "L" and "L" or curclass
+ else
+ curclass = "ON"
+ node_class[cur] = curclass
end
+ elseif followclass == "AN" and prevclass == "AN" then
+ curclass = "AN"
+ node_class[cur] = curclass
else
- curclass = prevclass
+ curclass = "ON"
node_class[cur] = curclass
end
else
@@ -268,15 +269,16 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
end
cur = head
local last_e, last_s = 0, 0
- prevstrong = sos
local stack = {}
+ local need_context = {}
while cur ~= stop do
- if getid(cur) == glyph_id and bidi_fonts[getfont(cur)] then
- local cp = getchar(cur) -- FIXME: canonical equivalents
+ local curclass = node_class[cur]
+ if curclass == "ON" and getid(cur) == glyph_id and bidi_fonts[getfont(cur)] then
+ local cp = bidi_brackets_canonical[getchar(cur)]
local bracket = bidi_brackets[cp]
if bracket then
if bracket.type == 'o' then
- local info = {cur, bracket.other, prevstrong == opposite}
+ local info = {cur, bracket.other}
stack[#stack + 1] = info
else -- if cp.type == 'c'
for i = #stack,1,-1 do
@@ -288,15 +290,16 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
if last_e >= i then
local beg = entry[1]
node_class[beg], node_class[cur] = direction, direction
- adjust_nsm(beg, direction, node_origclass)
- adjust_nsm(cur, direction, node_origclass)
+ adjust_nsm(beg, stop, direction, node_class, node_origclass)
+ adjust_nsm(cur, stop, direction, node_class, node_origclass)
last_s, last_e = i-1, i-1
elseif last_s >= i then
+ need_context[entry[1]] = cur
if entry[3] then
local beg = entry[1]
node_class[beg], node_class[cur] = opposite, opposite
- adjust_nsm(beg, opposite, node_origclass)
- adjust_nsm(cur, opposite, node_origclass)
+ adjust_nsm(beg, stop, opposite, node_class, node_origclass)
+ adjust_nsm(cur, stop, opposite, node_class, node_origclass)
end
last_s = i-1
end
@@ -304,13 +307,13 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
end
end
end
- else
- local curclass = node_class[cur]
- if Strong[curclass] == direction then
- last_e, last_s, prevstrong = #stack, #stack, direction
- elseif Strong[curclass] == opposite then
- last_s, prevstrong = #stack, opposite
- end
+ end
+ else
+ local strong = Strong[curclass]
+ if strong == direction then
+ last_e, last_s = #stack, #stack
+ elseif strong == opposite then
+ last_s = #stack
end
end
cur = getnext(cur)
@@ -335,12 +338,19 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
prevstrong = strong
node_level[cur] = newlevels[curclass]
cur = getnext(cur)
+ elseif need_context[cur] then
+ local final = need_context[cur]
+ node_class[cur], node_class[final] = prevstrong, prevstrong
+ adjust_nsm(final, stop, prevstrong, node_class, node_origclass)
+ adjust_nsm(cur, stop, prevstrong, node_class, node_origclass)
+ node_level[cur] = newlevels[prevstrong]
+ cur = getnext(cur)
else
local follow = getnext(cur)
- local followclass = node_class[follow]
- while follow ~= stop and not Strong[followclass] do
+ local followclass = need_context[follow] and prevstrong or Strong[node_class[follow]]
+ while follow ~= stop and not followclass do
follow = getnext(follow)
- followclass = Strong[node_class[follow]]
+ followclass = need_context[follow] and prevstrong or Strong[node_class[follow]]
end
if follow == stop then
followclass = eos
@@ -351,14 +361,14 @@ function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origcl
while follow ~= stop and not Strong[followclass] do
node_class[follow], node_level[follow] = followclass and outerdir, followclass and newlevels[outerdir]
follow = getnext(follow)
- followclass = node_class[follow]
+ followclass = need_context[follow] and prevstrong or node_class[follow]
end
cur = follow
end
end
fulltime1 = fulltime1 + gettime() - starttime
end
-local node_class, node_origclass, node_level = {}, {}, {} -- Making these local was significantly
+node_class, node_origclass, node_level = {}, {}, {} -- Making these local was significantly
-- slower necause they are sparse arrays with medium sized integer
-- keys, requiring relativly big allocations
function dobidi(head, a, b, c, par_direction)
@@ -387,10 +397,10 @@ function dobidi(head, a, b, c, par_direction)
class = bidi_classes[getchar(cur)]
if class == "RLE" then
class, curlevel = nil, level
- push(0)
+ push(1)
elseif class == "LRE" then
class, curlevel = nil, level
- push(1)
+ push(0)
elseif class == "RLO" then
class, curlevel = nil, level
push(1, "R")
@@ -430,6 +440,7 @@ function dobidi(head, a, b, c, par_direction)
-- Unmatched reset. LuaTeX inserts them sometimes, just
-- dropping them normally works fine. But deleting is
-- difficult here because the loop needs the next pointer.
+ -- Technically they should stay
if old_dir then nodeflush(old_dir) end
head = remove(head, cur)
old_dir = cur
More information about the latex3-commits
mailing list