summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2019-09-18 21:58:28 +0000
committerKarl Berry <karl@freefriends.org>2019-09-18 21:58:28 +0000
commit9ac243d09b484e3096e35a521df4328ceba78a8e (patch)
treea734f5ad7c2adc762deb9b1e4ebfaa6e8c9fd14f /Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua
parent57d8e344d4a807272cc4f5ee6c04af89ff866756 (diff)
luaotfload (18sep19)
git-svn-id: svn://tug.org/texlive/trunk@52120 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua113
1 files changed, 102 insertions, 11 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua
index 196ea928bbb..0cc972a0e3e 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-notdef",
- version = "2.991", --TAGVERSION
- date = "2019-08-11", --TAGDATE
+ version = "3.00", --TAGVERSION
+ date = "2019-09-13", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
author = "Marcel Krüger"
@@ -16,14 +16,69 @@ if luatexbase and luatexbase.provides_module then
luatexbase.provides_module (ProvidesLuaModule)
end
-local nodenew = node.direct.new
+local flush_node = node.direct.flush_node
local getfont = font.getfont
-local setfont = node.direct.setfont
+local getnext = node.direct.getnext
local getwhd = node.direct.getwhd
+local insert = table.insert
local insert_after = node.direct.insert_after
-local traverse_char = node.direct.traverse_char
+local kern_id = node.id'kern'
+local nodenew = node.direct.new
+local otfregister = fonts.constructors.features.otf.register
local protect_glyph = node.direct.protect_glyph
-local otffeatures = fonts.constructors.newfeatures "otf"
+local remove = node.direct.remove
+local setfont = node.direct.setfont
+local traverse_char = node.direct.traverse_char
+
+-- According to DerivedCoreProperties.txt, Default_Ignorable_Code_Point
+-- is generated from:
+-- Other_Default_Ignorable_Code_Point
+-- + Cf (Format characters)
+-- + Variation_Selector
+-- - White_Space
+-- - FFF9..FFFB (Interlinear annotation format characters)
+-- - 13430..13438 (Egyptian hieroglyph format characters)
+-- - Prepended_Concatenation_Mark (Exceptional format characters that should be visible)
+-- Based on HarfBuzz, we add the exclusion
+-- - Lo (Letter, Other)
+-- This affects Hangul fillers.
+local ignorable_codepoints do
+ local sep = lpeg.P' '^0 * ';' * lpeg.P' '^0
+ local codepoint = lpeg.S'0123456789ABCDEF'^4/function(c)return tonumber(c, 16)end
+ local codepoint_range = codepoint * ('..' * codepoint + lpeg.Cc(false))
+ local function multirawset(table, key1, key2, value)
+ for key = key1,(key2 or key1) do
+ rawset(table, key, value)
+ end
+ return table
+ end
+ local entry = lpeg.Cg(codepoint * ';' * (1-lpeg.P';')^0 * ';Cf;' * lpeg.Cc(true))^-1 * (1-lpeg.P'\n')^0 * '\n'
+ local file = lpeg.Cf(
+ lpeg.Ct''
+ * entry^0
+ , rawset)
+ local f = io.open(kpse.find_file"UnicodeData.txt")
+ ignorable_codepoints = file:match(f:read'*a')
+ f:close()
+ entry = lpeg.Cg(codepoint_range * sep * ('Other_Default_Ignorable_Code_Point' * lpeg.Cc(true)
+ + 'Variation_Selector' * lpeg.Cc(true)
+ + 'White_Space' * lpeg.Cc(nil)
+ + 'Prepended_Concatenation_Mark' * lpeg.Cc(nil)
+ ) * ' # ' * (1-lpeg.P'Lo'))^-1 * (1-lpeg.P'\n')^0 * '\n'
+ file = lpeg.Cf(
+ lpeg.Carg(1)
+ * entry^0
+ , multirawset)
+ f = io.open(kpse.find_file"PropList.txt")
+ ignorable_codepoints = file:match(f:read'*a', 1, ignorable_codepoints)
+ f:close()
+ for i = 0xFFF9,0xFFFB do
+ ignorable_codepoints[i] = nil
+ end
+ for i = 0x13430,0x13438 do
+ ignorable_codepoints[i] = nil
+ end
+end
local function setnotdef(tfmdata, factor)
local desc = tfmdata.shared.rawdata.descriptions
@@ -35,7 +90,6 @@ local function setnotdef(tfmdata, factor)
tfmdata.notdefcode = 0xF0000
return
end
- print')'
-- If this didn't happen, it might be mapped to one of the
-- replacement characters:
for code = 0xFFFC,0xFFFF do
@@ -45,7 +99,6 @@ local function setnotdef(tfmdata, factor)
return
end
end
- print')))'
-- Oh no, we couldn't find it. Maybe we can find it by name?
local code = tfmdata.resources.unicodes[".notdef"]
-- Better safe than sorry
@@ -54,7 +107,6 @@ local function setnotdef(tfmdata, factor)
tfmdata.notdefcode = code
return
end
- print'))))'
-- So the font didn't do the obvious things and then it lied to us.
-- At this point we should think about sending an automated complain
-- to the font author, but we probably can't trust the contact
@@ -81,7 +133,7 @@ local function donotdef(head, font, _, _, _)
if not notdef then return end
for cur, cid, fid in traverse_char(head) do if fid == font then
local w, h, d = getwhd(cur)
- if w == 0 and h == 0 and d == 0 and not chars[cid] then
+ if w == 0 and h == 0 and d == 0 and not chars[cid] and not ignorable_codepoints[cid] then
local notdefnode = nodenew(glyph_id, 256)
setfont(notdefnode, font, notdef)
insert_after(cur, cur, notdefnode)
@@ -90,7 +142,7 @@ local function donotdef(head, font, _, _, _)
end end
end
-otffeatures.register {
+otfregister {
name = "notdef",
description = "Add notdef glyphs",
default = 1,
@@ -102,4 +154,43 @@ otffeatures.register {
}
}
+function fonts.handlers.otf.handlers.gsub_remove(head,char,dataset,sequence,replacement)
+ local next
+ head, next = remove(head, char)
+ flush_node(char)
+ if not head and not next then -- Avoid a double free if we were alone
+ head = nodenew(kern_id)
+ end
+ return head, next, true, true
+end
+
+local sequence = {
+ features = {invisible = {["*"] = {["*"] = true}}},
+ flags = {false, false, false, false},
+ name = "invisible",
+ order = {"invisible"},
+ nofsteps = 1,
+ steps = {{
+ coverage = ignorable_codepoints,
+ index = 1,
+ }},
+ type = "gsub_remove",
+}
+local function invisibleinitialiser(tfmdata, value)
+ local resources = tfmdata.resources
+ local sequences = resources and resources.sequences
+ if sequences then
+ -- Now we get to the interesting part: At which point should our new sequence be inserted? Let's do it at the end, then they are still seen by all features.
+ insert(sequences, sequence)
+ end
+end
+otfregister {
+ name = 'invisible',
+ description = 'Remove invisible control characters',
+ default = true,
+ initializers = {
+ node = invisibleinitialiser,
+ },
+}
+
--- vim:sw=2:ts=2:expandtab:tw=71