diff options
author | Norbert Preining <norbert@preining.info> | 2022-12-04 03:01:36 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-12-04 03:01:36 +0000 |
commit | b153d9b098596910fb2be9311f13c4415233c2a2 (patch) | |
tree | f0f44c9b4caa5756e6957885e8691c0268920a56 /macros/optex/base/optex.lua | |
parent | 34896a353fe22e8ac88ef0b4e39f4fa878e2b0b6 (diff) |
CTAN sync 202212040301
Diffstat (limited to 'macros/optex/base/optex.lua')
-rw-r--r-- | macros/optex/base/optex.lua | 107 |
1 files changed, 73 insertions, 34 deletions
diff --git a/macros/optex/base/optex.lua b/macros/optex/base/optex.lua index 3bec088b60..40915fd6d4 100644 --- a/macros/optex/base/optex.lua +++ b/macros/optex/base/optex.lua @@ -8,7 +8,8 @@ local fmt = string.format -- -- Define namespace where some \OpTeX/ functions will be added. -optex = optex or {} +local optex = _ENV.optex or {} +_ENV.optex = optex -- Error function used by following functions for critical errors. local function err(message) @@ -17,12 +18,14 @@ end -- -- For a `\chardef`'d, `\countdef`'d, etc., csname return corresponding register -- number. The responsibility of providing a `\XXdef`'d name is on the caller. -function registernumber(name) +local function registernumber(name) return token.create(name).index end +_ENV.registernumber = registernumber +optex.registernumber = registernumber -- -- MD5 hash of given file. -function mdfive(file) +function optex.mdfive(file) local fh = io.open(file, "rb") if fh then local data = fh:read("*a") @@ -32,7 +35,8 @@ function mdfive(file) end -- -- \medskip\secc[lua-alloc] Allocators^^M -alloc = alloc or {} +local alloc = _ENV.alloc or {} +_ENV.alloc = alloc -- -- An attribute allocator in Lua that cooperates with normal \OpTeX/ allocator. local attributes = {} @@ -51,17 +55,17 @@ end -- Allocator for Lua functions ("pseudoprimitives"). It passes variadic -- arguments (\"`...`") like `"global"` to `token.set_lua`. local function_table = lua.get_functions_table() -function define_lua_command(csname, fn, ...) +local function define_lua_command(csname, fn, ...) local luafnalloc = #function_table + 1 token.set_lua(csname, luafnalloc, ...) -- WARNING: needs LuaTeX 1.08 (2019) or newer function_table[luafnalloc] = fn end --- --- `provides_module` is needed by older version of luaotfload -provides_module = function() end +_ENV.define_lua_command = define_lua_command +optex.define_lua_command = define_lua_command -- -- \medskip\secc[callbacks] Callbacks^^M -callback = callback or {} +local callback = _ENV.callback or {} +_ENV.callback = callback -- -- Save `callback.register` function for internal use. local callback_register = callback.register @@ -388,17 +392,18 @@ end) -- -- Compatibility with \LaTeX/ through luatexbase namespace. Needed for -- luaotfload. -luatexbase = { +_ENV.luatexbase = { registernumber = registernumber, attributes = attributes, - provides_module = provides_module, + -- `provides_module` is needed by older version of luaotfload + provides_module = function() end, new_attribute = alloc.new_attribute, callback_descriptions = callback.callback_descriptions, create_callback = callback.create_callback, add_to_callback = callback.add_to_callback, remove_from_callback = callback.remove_from_callback, call_callback = callback.call_callback, - callbacktypes = {} + callbacktypes = {}, } -- -- `\tracingmacros` callback registered. @@ -441,6 +446,7 @@ local pdfdict_mt = { local function pdf_dict(t) return setmetatable(t or {}, pdfdict_mt) end +optex.pdf_dict = pdf_dict -- local resource_dict_objects = {} local page_resources = {} @@ -653,34 +659,67 @@ callback.add_to_callback("pre_shipout_filter", function(list) return tonode(list) end, "_colors") -- --- We also hook into `luaotfload`'s handling of color. Instead of the default --- behavior (inserting colorstack whatsits) we set our own attribute. The hook --- has to be registered {\em after} `luaotfload` is loaded. -function optex_hook_into_luaotfload() - if not luaotfload.set_colorhandler then - return -- old luaotfload, colored fonts will be broken +-- We also hook into `luaotfload`'s handling of color and transparency. Instead +-- of the default behavior (inserting colorstack whatsits) we set our own +-- attribute. On top of that, we take care of transparency resources ourselves. +-- +-- The hook has to be registered {\em after} `luaotfload` is loaded. +local setattribute = direct.set_attribute +local token_setmacro = token.set_macro +local color_count = registernumber("_colorcnt") +local tex_getcount, tex_setcount = tex.getcount, tex.setcount +-- +local function set_node_color(n, color) -- "1 0 0 rg" or "0 g", etc. + local attr = tonumber(token_getmacro("_color::"..color)) + if not attr then + attr = tex_getcount(color_count) + tex_setcount(color_count, attr + 1) + local strattr = tostring(attr) + token_setmacro("_color::"..color, strattr) + token_setmacro("_color:"..strattr, color) + token_setmacro("_color-s:"..strattr, string.upper(color)) end - local setattribute = direct.set_attribute - local token_setmacro = token.set_macro - local color_count = registernumber("_colorcnt") - local tex_getcount, tex_setcount = tex.getcount, tex.setcount - luaotfload.set_colorhandler(function(head, n, rgbcolor) -- rgbcolor = "1 0 0 rg" - local attr = tonumber(token_getmacro("_color::"..rgbcolor)) - if not attr then - attr = tex_getcount(color_count) - tex_setcount(color_count, attr + 1) - local strattr = tostring(attr) - token_setmacro("_color::"..rgbcolor, strattr) - token_setmacro("_color:"..strattr, rgbcolor) - -- no stroke color set - end - setattribute(n, color_attribute, attr) + setattribute(todirect(n), color_attribute, attr) +end +optex.set_node_color = set_node_color +-- +function optex.hook_into_luaotfload() + -- color support for luaotfload v3.13+, otherwise broken + pcall(luaotfload.set_colorhandler, function(head, n, rgbcolor) -- rgbcolor = "1 0 0 rg" + set_node_color(n, rgbcolor) return head, n end) + + -- transparency support for luaotfload v3.22+, otherwise broken + pcall(function() + luatexbase.add_to_callback("luaotfload.parse_transparent", function(input) -- from "00" to "FF" + -- in luaotfload: 0 = transparent, 255 = opaque + -- in optex: 0 = opaque, 255 = transparent + local alpha = tonumber(input, 16) + if not alpha then + tex.error("Invalid transparency specification passed to font") + return nil + elseif alpha == 255 then + return nil -- this allows luaotfload to skip calling us for opaque style + end + local transp = 255 - alpha + local transpv = fmt("%.3f", alpha / 255) + pdf.add_page_resource("ExtGState", fmt("tr%d", transp), pdf_dict{ca = transpv, CA = transpv}) + pdf.add_page_resource("ExtGState", "tr0", pdf_dict{ca = 1, CA = 1}) + return transp -- will be passed to the below function + end, "optex") + + luaotfload.set_transparenthandler(function(head, n, transp) + setattribute(n, transp_attribute, transp) + return head, n + end) + end) end -- History: - -- 2022-03-07 transparency in the colorize() function, current_tr added + -- 2022-08-25 expose some useful functions in `optex` namespace + -- 2022-08-24 luaotfload transparency with attributes added + -- 2022-03-07 transparency in the colorize() function, current_tr added -- 2022-03-05 resources management added -- 2021-07-16 support for colors via attributes added -- 2020-11-11 optex.lua released |