summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luaotfload/luaotfload-colors.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/generic/luaotfload/luaotfload-colors.lua')
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-colors.lua80
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