summaryrefslogtreecommitdiff
path: root/luaotfload-colors.lua
diff options
context:
space:
mode:
authorPhilipp Gesang <phg42.2a@gmail.com>2013-05-04 15:56:16 +0200
committerPhilipp Gesang <phg42.2a@gmail.com>2013-05-04 15:56:16 +0200
commitcb31932c3cdc8f5caa42bb179e1b7444508513a4 (patch)
treedfa10d6ab78f87f966154f8be944abcdfe7f9074 /luaotfload-colors.lua
parent7182e2279ca9acc02195074849eeb9d1e8943fcc (diff)
downloadluaotfload-cb31932c3cdc8f5caa42bb179e1b7444508513a4.tar.gz
move rgba converter to lpeg; also some caching
Diffstat (limited to 'luaotfload-colors.lua')
-rw-r--r--luaotfload-colors.lua105
1 files changed, 59 insertions, 46 deletions
diff --git a/luaotfload-colors.lua b/luaotfload-colors.lua
index 5be0a1f..4121441 100644
--- a/luaotfload-colors.lua
+++ b/luaotfload-colors.lua
@@ -24,6 +24,21 @@ local registerotffeature = otffeatures.register
local add_color_callback --[[ this used to be a global‽ ]]
--[[doc--
+This converts a single octet into a decimal with three digits of
+precision. The optional second argument limits precision to a single
+digit.
+--doc]]--
+
+--- string -> bool? -> string
+local hex_to_dec = function (hex,one) --- one isn’t actually used anywhere ...
+ if one then
+ return stringformat("%.1g", tonumber(hex, 16)/255)
+ else
+ return stringformat("%.3g", tonumber(hex, 16)/255)
+ end
+end
+
+--[[doc--
Color string validator / parser.
--doc]]--
@@ -38,10 +53,10 @@ local p_rgb = octet * octet * octet
local p_rgba = p_rgb * octet
local valid_digits = C(p_rgba + p_rgb) -- matches eight or six hex digits
-local p_Crgb = Cg(octet, "red") --- for captures
- * Cg(octet, "green")
- * Cg(octet, "blue")
-local p_Crgba = p_Crgb * Cg(octet, "alpha")
+local p_Crgb = Cg(octet/hex_to_dec, "red") --- for captures
+ * Cg(octet/hex_to_dec, "green")
+ * Cg(octet/hex_to_dec, "blue")
+local p_Crgba = p_Crgb * Cg(octet/hex_to_dec, "alpha")
local extract_color = Ct(p_Crgba + p_Crgb)
--- string -> (string | nil)
@@ -66,12 +81,12 @@ end
--- hexadecimal, with an optional fourth transparency
--- value)
---
-local function setcolor (tfmdata, value)
+local setcolor = function (tfmdata, value)
local sanitized = sanitize_color_expression(value)
local properties = tfmdata.properties
if sanitized then
- tfmdata.properties.color = sanitized
+ properties.color = sanitized
add_color_callback()
end
end
@@ -86,64 +101,62 @@ registerotffeature {
}
---[[doc--
-This converts a single octet into a decimal with three digits of
-precision. The optional second argument limits precision to a single
-digit.
---doc]]--
-
---- string -> bool? -> float
-local function hex_to_dec(hex,one)
- if one then
- return stringformat("%.1g", tonumber(hex, 16)/255)
- else
- return stringformat("%.3g", tonumber(hex, 16)/255)
- end
-end
-
--- something is carried around in ``res``
--- for later use by color_handler() --- but what?
local res --- <- state of what?
--- float -> unit
-local function pageresources(a)
+local function pageresources(alpha)
local res2
if not res then
res = "/TransGs1<</ca 1/CA 1>>"
end
- res2 = stringformat("/TransGs%s<</ca %s/CA %s>>", a, a, a)
+ res2 = stringformat("/TransGs%s<</ca %s/CA %s>>",
+ alpha, alpha, alpha)
res = stringformat("%s%s",
res,
stringfind(res, res2) and "" or res2)
end
+--- we store results of below color handler as tuples of
+--- push/pop strings
+local color_cache = { } --- (string, (string * string)) hash_t
+
--- string -> (string * string)
-local function hex_to_rgba(hex)
- local r, g, b, a, push, pop, res3
- if hex then
- --- TODO lpeg this mess
- if #hex == 6 then
- _, _, r, g, b = stringfind(hex, '(..)(..)(..)')
- elseif #hex == 8 then
- _, _, r, g, b, a = stringfind(hex, '(..)(..)(..)(..)')
- a = hex_to_dec(a,true)
- pageresources(a)
- end
- else
- return nil
+local hex_to_rgba = function (digits)
+ if not digits then
+ return
end
- r = hex_to_dec(r)
- g = hex_to_dec(g)
- b = hex_to_dec(b)
- if a then
- push = stringformat('/TransGs%g gs %s %s %s rg', a, r, g, b)
- pop = '0 g /TransGs1 gs'
- else
- push = stringformat('%s %s %s rg', r, g, b)
- pop = '0 g'
+
+ --- this is called like a thousand times, so some
+ --- memoizing is in order.
+ local cached = color_cache[digits]
+ if not cached then
+ local push, pop
+ local rgb = lpegmatch(extract_color, digits)
+ if rgb.alpha then
+ pageresources(rgb.alpha)
+ push = stringformat(
+ "/TransGs%g gs %s %s %s rg",
+ rgb.alpha,
+ rgb.red,
+ rgb.green,
+ rgb.blue)
+ pop = "0 g /TransGs1 gs"
+ else
+ push = stringformat(
+ "%s %s %s rg",
+ rgb.red,
+ rgb.green,
+ rgb.blue)
+ pop = "0 g"
+ end
+ color_cache[digits] = { push, pop }
+ return push, pop
end
- return push, pop
+
+ return cached[1], cached[2]
end
--- Luatex internal types