summaryrefslogtreecommitdiff
path: root/macros/optex/base/optex.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-12-04 03:01:36 +0000
committerNorbert Preining <norbert@preining.info>2022-12-04 03:01:36 +0000
commitb153d9b098596910fb2be9311f13c4415233c2a2 (patch)
treef0f44c9b4caa5756e6957885e8691c0268920a56 /macros/optex/base/optex.lua
parent34896a353fe22e8ac88ef0b4e39f4fa878e2b0b6 (diff)
CTAN sync 202212040301
Diffstat (limited to 'macros/optex/base/optex.lua')
-rw-r--r--macros/optex/base/optex.lua107
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