summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua')
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua51
1 files changed, 34 insertions, 17 deletions
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
index 1577aa7004..634da68786 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
@@ -4,8 +4,8 @@
-----------------------------------------------------------------------
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-plug",
- version = "3.18", --TAGVERSION
- date = "2021-05-21", --TAGDATE
+ version = "3.19", --TAGVERSION
+ date = "2022-02-24", --TAGDATE
description = "luaotfload submodule / HarfBuzz shaping",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
@@ -110,6 +110,11 @@ local endactual_p = "luaotfload_endactualtext"
local empty_table = {}
+local function is_empty_disc(n)
+ local pre, post, rep = getdisc(n)
+ return not pre and not post and not rep
+end
+
-- "Copy" properties as done by LuaTeX: Make old properties metatable
local function copytable(old)
local new = {}
@@ -174,6 +179,7 @@ local function itemize(head, fontid, direction)
local hbdata = fontdata and fontdata.hb
local spec = fontdata and fontdata.specification
local options = spec and spec.features.raw
+ local obj_repl = hbdata and hbdata.obj_repl
local runs, codes = {}, {}
local dirstack = {}
@@ -187,7 +193,7 @@ local function itemize(head, fontid, direction)
for n, id, subtype in traverse(head) do
if in_disc == n then in_disc = nil end
local disc
- local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER
+ local code = obj_repl -- OBJECT REPLACEMENT CHARACTER, substitute invalid surrogate if otherwise colliding with font glyph
local skip = lastskip
local props = properties[n]
@@ -205,7 +211,7 @@ local function itemize(head, fontid, direction)
elseif id == glue_t and subtype == spaceskip_t then
code = 0x0020 -- SPACE
elseif id == disc_t then
- if uses_font(n, fontid) then
+ if uses_font(n, fontid) or not lastskip and is_empty_disc(n) then
local _, _, rep, _, _, rep_tail = getdisc(n, true)
setfield(n, 'replace', nil)
local prev, next = getboth(n)
@@ -347,6 +353,7 @@ function shape(head, firstnode, run)
local options = spec.features.raw
local hbshared = hbdata.shared
local hbfont = hbshared.font
+ local obj_repl = hbdata.obj_repl
local lang = spec.language
local script = spec.script
@@ -430,7 +437,9 @@ function shape(head, firstnode, run)
end
-- Is this a safe breakpoint?
- if discs and ((not glyph) or codes[cluster] == 0x20 or codes[cluster+1] == 0x20 or codes[cluster+1] == 0xFFFC
+ if discs and ((not glyph)
+ or codes[cluster] == 0x20 or codes[cluster+1] == 0x20
+ or codes[cluster] == obj_repl or codes[cluster+1] == obj_repl
or not unsafetobreak(glyph)) then
-- Should we change the discretionary state?
local anchor_cluster, after_cluster = offset + discs.anchor_cluster, offset + discs.after_cluster
@@ -478,20 +487,20 @@ function shape(head, firstnode, run)
local precodes, postcodes, repcodes = {}, {}
table.move(codes, disc_cluster + 1, anchor_cluster, 1, precodes)
for n in traverse(pre) do
- precodes[#precodes + 1] = is_char(n, fontid) or 0xFFFC
+ precodes[#precodes + 1] = is_char(n, fontid) or obj_repl
end
for n in traverse(post) do
- postcodes[#postcodes + 1] = is_char(n, fontid) or 0xFFFC
+ postcodes[#postcodes + 1] = is_char(n, fontid) or obj_repl
end
table.move(codes, after_cluster + 1, cluster, #postcodes + 1, postcodes)
if saved_after then
repcodes = table.move(codes, disc_cluster + 1, cluster, 1, {})
table.move(codes, cluster + 1, #codes + cluster - disc_cluster, disc_cluster + 3)
- codes[disc_cluster + 1], codes[disc_cluster + 2] = 0xFFFC, 0xFFFC
+ codes[disc_cluster + 1], codes[disc_cluster + 2] = obj_repl, obj_repl
else
table.move(codes, cluster + 1, #codes + cluster - disc_cluster, disc_cluster + 2)
- codes[disc_cluster + 1] = 0xFFFC
+ codes[disc_cluster + 1] = obj_repl
end
do
@@ -535,7 +544,7 @@ function shape(head, firstnode, run)
post = makesub(run, postcodes, post),
cluster = disc_cluster,
nextcluster = disc_cluster + 1,
- codepoint = 0xFFFC,
+ codepoint = obj_repl,
}
if saved_after then
local next_disc = discs.next
@@ -550,10 +559,10 @@ function shape(head, firstnode, run)
local saved_anchor, saved_after = saved_anchor + saved_offset, saved_after + saved_offset
table.move(postcodes, 1, saved_anchor, 1, next_precodes)
for n in traverse(next_pre) do
- next_precodes[#next_precodes + 1] = is_char(n, fontid) or 0xFFFC
+ next_precodes[#next_precodes + 1] = is_char(n, fontid) or obj_repl
end
for n in traverse(next_post) do
- next_postcodes[#next_postcodes + 1] = is_char(n, fontid) or 0xFFFC
+ next_postcodes[#next_postcodes + 1] = is_char(n, fontid) or obj_repl
end
table.move(postcodes, saved_after + 1, #postcodes, #next_postcodes + 1, next_postcodes)
@@ -576,7 +585,7 @@ function shape(head, firstnode, run)
local saved_anchor = saved_anchor - disc_cluster
table.move(repcodes, 1, saved_anchor, 1, next_repcodes)
for n in traverse(next_rep) do
- next_repcodes[#next_repcodes + 1] = is_char(n, fontid) or 0xFFFC
+ next_repcodes[#next_repcodes + 1] = is_char(n, fontid) or obj_repl
end
local rep = glyphs[disc_glyph].replace.head
@@ -599,7 +608,7 @@ function shape(head, firstnode, run)
post = makesub(run, next_postcodes, next_post),
cluster = disc_cluster,
nextcluster = disc_cluster + 1,
- codepoint = 0xFFFC,
+ codepoint = obj_repl,
}
end
i = disc_glyph + 1
@@ -772,9 +781,15 @@ local function tonodes(head, node, run, glyphs)
nodeindex = glyph.cluster + 1
elseif nextcluster + 1 == nodeindex then -- Oops, we went too far
nodeindex = nodeindex - 1
- local new = inherit(glyph_t, getprev(node), lastprops)
- setfont(new, fontid)
- head, node = insertbefore(head, node, new)
+ if node then
+ local new = inherit(glyph_t, getprev(node), lastprops)
+ head, node = insertbefore(head, node, new)
+ else
+ node = tail(head)
+ local new = inherit(glyph_t, node, lastprops)
+ head, node = insertafter(head, node, new)
+ end
+ setfont(node, fontid)
end
local gid = glyph.codepoint
local char = nominals[gid] or gid_offset + gid
@@ -1134,6 +1149,8 @@ local function get_glyph_info(n)
local c = getchar(n)
if c == 0 then
return '^^@'
+ elseif c < 0 then -- These are left and right boundaries in ligature lists
+ return ''
elseif c < 0x110000 then
return utfchar(c)
else