summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-02-26 03:00:34 +0000
committerNorbert Preining <norbert@preining.info>2022-02-26 03:00:34 +0000
commit740a11f29a3551babe3d7edbb57ac3baa2280a3f (patch)
tree5d6d449e762f5ab95042e3517d03c5ac3ddaf7c3 /macros/luatex/generic/luaotfload/fontloader-font-ots.lua
parent157cc9e776520d0b7d488317a69a10d4ae4d493b (diff)
CTAN sync 202202260300
Diffstat (limited to 'macros/luatex/generic/luaotfload/fontloader-font-ots.lua')
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ots.lua121
1 files changed, 82 insertions, 39 deletions
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
index 30d79c4077..7de108d4c8 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
@@ -163,6 +163,8 @@ local trace_testruns = false registertracker("otf.testruns", function
local forcediscretionaries = false
local forcepairadvance = false -- for testing
+local repeatablemultiples = context or false
+
directives.register("otf.forcediscretionaries",function(v)
forcediscretionaries = v
end)
@@ -648,16 +650,52 @@ local function multiple_glyphs(head,start,multiple,skiphash,what,stop) -- what t
insertnodeafter(head,start,n)
start = n
end
- if what == true then
- -- we're ok
- elseif what > 1 then
- local m = multiple[nofmultiples]
- for i=2,what do
- local n = copy_node(start) -- ignore components
- resetinjection(n)
- setchar(n,m)
- insertnodeafter(head,start,n)
- start = n
+ if what ~= true and repeatablemultiples then
+ -- This is just some experimental code; we might introduce gsub_extensible
+ -- some day instead. Beware: when we have a feature that mixes alternates and
+ -- multiples we need to make sure we don't handle the alternate string values
+ -- here. This might eventually become an lmtx only feature.
+ local kind = type(what)
+ local m, f, l
+ if kind == "string" then
+ local what, n = string.match(what,"^repeat(.-)[:=](%d+)$")
+ if what == "middle" then
+ m = tonumber(n)
+ elseif what == "first" then
+ f = tonumber(n)
+ elseif what == "last" then
+ l = tonumber(n)
+ end
+ elseif kind == "table" then
+ -- won't happen because currently we don't split these values
+ m = what.middle
+ f = what.first
+ l = what.last
+ end
+ if f or m or l then
+ if m and m > 1 and nofmultiples == 3 then
+ local middle = getnext(first)
+ for i=2,m do
+ local n = copynode(middle) -- ignore components
+ resetinjection(n)
+ insertnodeafter(head,first,n)
+ end
+ end
+ if f and f > 1 then
+ for i=2,f do
+ local n = copynode(first) -- ignore components
+ resetinjection(n)
+ insertnodeafter(head,first,n)
+ end
+ end
+ if l and l > 1 then
+ for i=2,l do
+ local n = copynode(start) -- ignore components
+ resetinjection(n)
+ insertnodeafter(head,start,n)
+ start = n
+ end
+ end
end
end
end
@@ -763,7 +801,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
while current do
local char = ischar(current,currentfont)
if char then
- local lg = ligature[char]
+ local lg = not tonumber(ligature) and ligature[char]
if lg then
stop = current
ligature = lg
@@ -776,14 +814,14 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
end
end
if stop then
- local lig = ligature.ligature
- if lig then
+ local ligature = tonumber(ligature) or ligature.ligature
+ if ligature then
if trace_ligatures then
local stopchar = getchar(stop)
- head, start = markstoligature(head,start,stop,lig)
+ head, start = markstoligature(head,start,stop,ligature)
logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
else
- head, start = markstoligature(head,start,stop,lig)
+ head, start = markstoligature(head,start,stop,ligature)
end
return head, start, true, false
else
@@ -799,7 +837,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
if skiphash and skiphash[char] then
current = getnext(current)
else
- local lg = ligature[char]
+ local lg = not tonumber(ligature) and ligature[char]
if lg then
if marks[char] then
hasmarks = true
@@ -833,20 +871,20 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
local match
if replace then
local char = ischar(replace,currentfont)
- if char and ligature[char] then
+ if char and (not tonumber(ligature) and ligature[char]) then
match = true
end
end
if not match and pre then
local char = ischar(pre,currentfont)
- if char and ligature[char] then
+ if char and (not tonumber(ligature) and ligature[char]) then
match = true
end
end
if not match and not pre or not replace then
local n = getnext(discfound)
local char = ischar(n,currentfont)
- if char and ligature[char] then
+ if char and (not tonumber(ligature) and ligature[char]) then
match = true
end
end
@@ -890,24 +928,26 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
return head, start, true, true
end
end
- local lig = ligature.ligature
- if lig then
+ local ligature = tonumber(ligature) or ligature.ligature
+ if ligature then
if stop then
if trace_ligatures then
local stopchar = getchar(stop)
- -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
- logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
+ -- head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,false,hasmarks)
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(ligature))
+ -- we can have a rare case of multiple disc in a lig but that makes no sense language wise but if really
+ -- needed we could backtrack if we're in a disc node
else
- -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ -- head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,false,hasmarks)
end
else
-- weird but happens (in some arabic font)
resetinjection(start)
- setchar(start,lig)
+ setchar(start,ligature)
if trace_ligatures then
- logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
+ logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(ligature))
end
end
return head, start, true, false
@@ -1050,7 +1090,7 @@ function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,
end
return head, start, true
elseif trace_bugs then
- -- onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
+ -- onetimemessage(currentfont,basechar,"no base anchors")
logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar))
end
elseif trace_bugs then
@@ -1116,7 +1156,7 @@ function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlm
end
elseif trace_bugs then
-- logwarning("%s: char %s is missing in font",pref(dataset,sequence),gref(basechar))
- onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
+ onetimemessage(currentfont,basechar,"no base anchors")
end
elseif trace_bugs then
logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1)
@@ -1484,7 +1524,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
current = getnext(current)
-- end
else
- local lg = ligatures[schar]
+ local lg = not tonumber(ligatures) and ligatures[schar]
if lg then
ligatures = lg
last = current
@@ -1503,7 +1543,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
end
end
end
- local ligature = ligatures.ligature
+ local ligature = tonumber(ligatures) or ligatures.ligature
if ligature then
if chainindex then
stop = last
@@ -1856,7 +1896,7 @@ function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,
end
end
elseif trace_bugs then
- onetimemessage(currentfont,startchar,"no entry anchors",report_fonts)
+ onetimemessage(currentfont,startchar,"no entry anchors")
end
break
end
@@ -1978,7 +2018,9 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
local chainproc = chainprocs[chainkind]
if chainproc then
local ok
- head, start, ok = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash)
+ -- HH: chainindex 1 added here (for KAI to check too), there are weird ligatures e.g.
+ -- char + mark -> char where mark has to disappear
+ head, start, ok = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,1)
if ok then
done = true
end
@@ -2471,6 +2513,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
local ck = contexts[k]
local seq = ck[3]
local f = ck[4] -- first current
+local last = start
if not startchar or not seq[f][startchar] then
-- report("no hit in %a at %i of %i contexts",sequence.type,k,nofcontexts)
goto next
@@ -2481,7 +2524,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
else
local l = ck[5] -- last current
local current = start
- local last = start
+-- local last = start
-- current match
@@ -3409,7 +3452,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
while s do
local char = ischar(s,font)
if char then
- local lg = lookupmatch[char]
+ local lg = not tonumber(lookupmatch) and lookupmatch[char]
if lg then
if sstop then
d = 1
@@ -3439,7 +3482,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
break
end
end
- if l and l.ligature then -- so we test for ligature
+ if l and (tonumber(l) or l.ligature) then -- so we test for ligature
lastd = d
end
-- why not: if not l then break elseif l.ligature then return d end
@@ -3580,7 +3623,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
while s do
local char = ischar(s)
if char then
- local lg = lookupmatch[char]
+ local lg = not tonumber(lookupmatch) and lookupmatch[char]
if lg then
if sstop then
d = 1
@@ -3610,7 +3653,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
break
end
end
- if l and l.ligature then
+ if l and (tonumber(l) or l.ligature) then
lastd = d
end
end