diff options
Diffstat (limited to 'macros/luatex/generic/luaotfload/luaotfload-colors.lua')
-rw-r--r-- | macros/luatex/generic/luaotfload/luaotfload-colors.lua | 80 |
1 files changed, 69 insertions, 11 deletions
diff --git a/macros/luatex/generic/luaotfload/luaotfload-colors.lua b/macros/luatex/generic/luaotfload/luaotfload-colors.lua index ddc564b05b..2569eb1b48 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-colors.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-colors.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-colors", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle", @@ -40,9 +40,13 @@ local insert_node_after = nodedirect.insert_after local todirect = nodedirect.todirect local tonode = nodedirect.tonode local setfield = nodedirect.setfield +local setdisc = nodedirect.setdisc +local setreplace = nodedirect.setreplace local getid = nodedirect.getid local getfont = nodedirect.getfont +local getchar = nodedirect.getchar local getlist = nodedirect.getlist +local getdisc = nodedirect.getdisc local getsubtype = nodedirect.getsubtype local getnext = nodedirect.getnext local nodetail = nodedirect.tail @@ -198,9 +202,14 @@ color_whatsit = function (head, curr, color, push, tail) end -- number -> string | nil -local get_font_color = function (font_id) +local get_glyph_color = function (font_id, char) local tfmdata = identifiers[font_id] local font_color = tfmdata and tfmdata.properties and tfmdata.properties.color + if type(font_color) == "table" then + local char_tbl = tfmdata.characters[char] + char = char_tbl and (char_tbl.index or char) + return char and font_color[char] or font_color.default + end return font_color end @@ -231,25 +240,30 @@ node_colorize = function (head, toplevel, current_color) setfield(n, "head", n_list) end + elseif n_id == disc_t then + local n_pre, n_post, n_replace = getdisc(n) + n_replace, current_color = node_colorize(n_replace, false, current_color) + setdisc(n, n_pre, n_post, n_replace) + elseif n_id == glyph_t then --- colorization is restricted to those fonts --- that received the “color” property upon --- loading (see ``setcolor()`` above) - local font_color = get_font_color(getfont(n)) - if font_color ~= current_color then + local glyph_color = get_glyph_color(getfont(n), getchar(n)) + if glyph_color ~= current_color then if current_color then head, n, current_color = color_whatsit(head, n, current_color, false) end - if font_color then - head, n, current_color = color_whatsit(head, n, font_color, true) + if glyph_color then + head, n, current_color = color_whatsit(head, n, glyph_color, true) end end if current_color and color_callback == "pre_linebreak_filter" then local nn = getnext(n) while nn and getid(nn) == glyph_t do - local font_color = get_font_color(getfont(nn)) - if font_color == current_color then + local glyph_color = get_glyph_color(getfont(nn), getchar(nn)) + if glyph_color == current_color then n = nn else break @@ -381,8 +395,41 @@ end --- hexadecimal, with an optional fourth transparency --- value) --- -local setcolor = function (tfmdata, value) - local sanitized = sanitize_color_expression(value) +local glyph_color_tables = { } +-- Currently this either sets a common color for the whole font or +-- builds a GID lookup table. This might change later to replace the +-- lookup table with color information in the character hash. The +-- problem with that approach right now are differences between harf +-- and node and difficulties with getting the mapped unicode value for +-- a GID. +local function setcolor (tfmdata, value) + local sanitized + local color_table = glyph_color_tables[tonumber(value) or value] + if color_table then + sanitized = {} + local unicodes = tfmdata.resources.unicodes + local gid_mapping = {} + local descriptions = tfmdata.descriptions or tfmdata.characters + for color, glyphs in next, color_table do + for _, glyph in ipairs(glyphs) do + local gid = glyph == "default" and "default" or tonumber(glyph) + if not gid then + local unicode = unicodes[glyph] + local desc = unicode and descriptions[unicode] + gid = desc and (desc.index or unicode) + end + if gid then + sanitized[gid] = sanitize_color_expression(color) + else + -- TODO: ??? Error out, warn or just ignore? Ignore + -- makes sense because we have to ignore for GIDs + -- anyway. + end + end + end + else + sanitized = sanitize_color_expression(value) + end local properties = tfmdata.properties if sanitized then @@ -391,6 +438,17 @@ local setcolor = function (tfmdata, value) end end +function luaotfload.add_colorscheme(name, colortable) + if fonts == nil then + fonts = name + name = #glyph_color_tables + 1 + else + name = name:lower() + end + glyph_color_tables[name] = colortable + return name +end + return function () logreport = luaotfload.log.report if not fonts then |