summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luaotfload/luaotfload-szss.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-05-03 03:02:51 +0000
committerNorbert Preining <norbert@preining.info>2020-05-03 03:02:51 +0000
commitd78de17ddf0443233483fd98f40802cae5aa87c5 (patch)
tree1b7128cc505808a09c18e158288d6c3cdcf5c2fb /macros/luatex/generic/luaotfload/luaotfload-szss.lua
parent8626a9c3cb5dc8d02d779d5b5b1e3933d5626f43 (diff)
CTAN sync 202005030302
Diffstat (limited to 'macros/luatex/generic/luaotfload/luaotfload-szss.lua')
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-szss.lua226
1 files changed, 226 insertions, 0 deletions
diff --git a/macros/luatex/generic/luaotfload/luaotfload-szss.lua b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
new file mode 100644
index 0000000000..23b479f33e
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
@@ -0,0 +1,226 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-szss.lua
+-- DESCRIPTION: part of luaotfload / szss
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-szss",
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
+ description = "luaotfload submodule / color",
+ license = "GPL v2.0",
+ author = "Marcel Krüger"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+local direct = node.direct
+local otfregister = fonts.constructors.features.otf.register
+
+local copy = direct.copy
+local getdisc = direct.getdisc
+local getnext = direct.getnext
+local insert_after = direct.insert_after
+local is_char = direct.is_char
+local setchar = direct.setchar
+local setdisc = direct.setdisc
+
+local disc_t = node.id'disc'
+
+local szsstable = setmetatable({}, { __index = function(t, i)
+ local v = font.getfont(i)
+ v = v and v.properties
+ v = v and v.transform_sz or false
+ t[i] = v
+ return v
+end})
+
+local function szssinitializer(tfmdata, value, features)
+ if value == 'auto' then
+ value = not tfmdata.characters[0x1E9E]
+ end
+ local properties = tfmdata.properties
+ properties.transform_sz = value
+end
+
+local function szssprocessor(head,font) -- ,attr,direction)
+ if not szsstable[font] then return end
+ local n = head
+ while n do
+ local c, id = is_char(n, font)
+ if c == 0x1E9E then
+ setchar(n, 0x53)
+ head, n = insert_after(head, n, copy(n))
+ elseif id == disc_t then
+ local pre, post, replace = getdisc(n)
+ pre = szssprocessor(pre, font)
+ post = szssprocessor(post, font)
+ replace = szssprocessor(replace, font)
+ setdisc(n, pre, post, replace)
+ end
+ n = getnext(n)
+ end
+ return head
+end
+
+otfregister {
+ name = 'szss',
+ description = 'Replace capital ß with SS',
+ default = 'auto',
+ initializers = {
+ node = szssinitializer,
+ plug = szssinitializer,
+ },
+ processors = {
+ position = 1,
+ node = szssprocessor,
+ plug = szssprocessor,
+ },
+}
+
+-- harf-only features (for node they are implemented in the fontloader
+
+otfregister {
+ name = 'extend',
+ description = 'Fake extend',
+ default = false,
+ manipulators = {
+ plug = function(tfmdata, _, value)
+ value = tonumber(value)
+ if not value then
+ error[[Invalid extend value]]
+ end
+ tfmdata.extend = value * 1000
+ tfmdata.hb.hscale = tfmdata.units_per_em * value
+ local parameters = tfmdata.parameters
+ parameters.slant = parameters.slant * value
+ parameters.space = parameters.space * value
+ parameters.space_stretch = parameters.space_stretch * value
+ parameters.space_shrink = parameters.space_shrink * value
+ parameters.quad = parameters.quad * value
+ parameters.extra_space = parameters.extra_space * value
+ local done = {}
+ for _, char in next, tfmdata.characters do
+ if char.width and not done[char] then
+ char.width = char.width * value
+ done[char] = true
+ end
+ end
+ end,
+ },
+}
+
+otfregister {
+ name = 'slant',
+ description = 'Fake slant',
+ default = false,
+ manipulators = {
+ plug = function(tfmdata, _, value)
+ value = tonumber(value)
+ if not value then
+ error[[Invalid slant value]]
+ end
+ tfmdata.slant = value * 1000
+ local parameters = tfmdata.parameters
+ parameters.slant = parameters.slant + value * 65536
+ end,
+ },
+}
+
+otfregister {
+ name = 'squeeze',
+ description = 'Fake squeeze',
+ default = false,
+ manipulators = {
+ plug = function(tfmdata, _, value)
+ value = tonumber(value)
+ if not value then
+ error[[Invalid squeeze value]]
+ end
+ tfmdata.squeeze = value * 1000
+ tfmdata.hb.vscale = tfmdata.units_per_em * value
+ local parameters = tfmdata.parameters
+ parameters.slant = parameters.slant / value
+ parameters.x_height = parameters.x_height * value
+ parameters[8] = parameters[8] * value
+ local done = {}
+ for _, char in next, tfmdata.characters do
+ if not done[char] then
+ if char.height then
+ char.height = char.height * value
+ end
+ if char.depth then
+ char.depth = char.depth * value
+ end
+ done[char] = true
+ end
+ end
+ end,
+ },
+}
+
+-- Legacy TeX Input Method Disguised as Font Ligatures hack.
+--
+-- Single replacements, keyed by character to replace. Handled separately
+-- because TeX ligaturing mechanism does not support one-to-one replacements.
+local trep = {
+ [0x0022] = 0x201D, -- ["]
+ [0x0027] = 0x2019, -- [']
+ [0x0060] = 0x2018, -- [`]
+}
+
+-- Ligatures. The value is a character "ligature" table as described in the
+-- manual.
+local tlig ={
+ [0x2013] = { [0x002D] = { char = 0x2014 } }, -- [---]
+ [0x002D] = { [0x002D] = { char = 0x2013 } }, -- [--]
+ [0x0060] = { [0x0060] = { char = 0x201C } }, -- [``]
+ [0x0027] = { [0x0027] = { char = 0x201D } }, -- ['']
+ [0x0021] = { [0x0060] = { char = 0x00A1 } }, -- [!`]
+ [0x003F] = { [0x0060] = { char = 0x00BF } }, -- [?`]
+ [0x002C] = { [0x002C] = { char = 0x201E } }, -- [,,]
+ [0x003C] = { [0x003C] = { char = 0x00AB } }, -- [<<]
+ [0x003E] = { [0x003E] = { char = 0x00BB } }, -- [>>]
+}
+
+local function tligprocessor(head, font)
+ local n = head
+ while n do
+ local c, id = is_char(n, font)
+ local rep = trep[c]
+ if rep then
+ setchar(n, rep)
+ elseif id == disc_t then
+ local pre, post, replace = getdisc(n)
+ tligprocessor(pre, font)
+ tligprocessor(post, font)
+ tligprocessor(replace, font)
+ end
+ n = getnext(n)
+ end
+end
+
+otfregister {
+ name = 'tlig',
+ description = 'Traditional TeX ligatures',
+ default = false,
+ manipulators = {
+ plug = function(tfmdata, _, value)
+ local characters = tfmdata.characters
+ for codepoint, ligatures in next, tlig do
+ local char = characters[codepoint]
+ if char then
+ char.ligatures = ligatures
+ end
+ end
+ end,
+ },
+ processors = {
+ position=1,
+ plug = tligprocessor,
+ },
+}
+
+--- vim:sw=2:ts=2:expandtab:tw=71