summaryrefslogtreecommitdiff
path: root/texmf-dist/tex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-08 08:56:57 +0900
committerNorbert Preining <norbert@preining.info>2019-09-08 08:56:57 +0900
commitd450c34f28c42ff6fdd5f2a67ac7c499195d3444 (patch)
treefcd2dea86614ceff2f38c7e1af3fad7b33c81f12 /texmf-dist/tex
parent7e3e290bd75fb3998ad9184a934c75c996543582 (diff)
harftex macros 0.4.2
Diffstat (limited to 'texmf-dist/tex')
-rw-r--r--texmf-dist/tex/harftex/base/harf-node.lua292
-rw-r--r--texmf-dist/tex/harftex/base/harfload.sty2
2 files changed, 161 insertions, 133 deletions
diff --git a/texmf-dist/tex/harftex/base/harf-node.lua b/texmf-dist/tex/harftex/base/harf-node.lua
index 730a8735..33fce8e2 100644
--- a/texmf-dist/tex/harftex/base/harf-node.lua
+++ b/texmf-dist/tex/harftex/base/harf-node.lua
@@ -1,84 +1,101 @@
local hb = require("harf-base")
-local direct = node.direct
-local tonode = direct.tonode
-local todirect = direct.todirect
-local traverse = direct.traverse
-local traverseid = direct.traverse_id
-local insertbefore = direct.insert_before
-local insertafter = direct.insert_after
-local protectglyph = direct.protect_glyph
-local newnode = direct.new
-local copynode = direct.copy
-local removenode = direct.remove
-local copynodelist = direct.copy_list
-local isglyph = direct.is_glyph
-
-local getattrs = direct.getattributelist
-local setattrs = direct.setattributelist
-local getchar = direct.getchar
-local setchar = direct.setchar
-local getdir = direct.getdir
-local setdir = direct.setdir
-local getdata = direct.getdata
-local setdata = direct.setdata
-local getfont = direct.getfont
-local setfont = direct.setfont
-local getfield = direct.getfield
-local setfield = direct.setfield
-local getid = direct.getid
-local getkern = direct.getkern
-local setkern = direct.setkern
-local getnext = direct.getnext
-local setnext = direct.setnext
-local getoffsets = direct.getoffsets
-local setoffsets = direct.setoffsets
-local getproperty = direct.getproperty
-local setproperty = direct.setproperty
-local getprev = direct.getprev
-local setprev = direct.setprev
-local getsubtype = direct.getsubtype
-local setsubtype = direct.setsubtype
-local getwidth = direct.getwidth
-local setwidth = direct.setwidth
-
-local getpre = function (n) return getfield(n, "pre") end
-local setpre = function (n, v) setfield(n, "pre", v) end
-local getpost = function (n) return getfield(n, "post") end
-local setpost = function (n, v) setfield(n, "post", v) end
-local getrep = function (n) return getfield(n, "replace") end
-local setrep = function (n, v) setfield(n, "replace", v) end
-
-local discid = node.id("disc")
-local glueid = node.id("glue")
-local glyphid = node.id("glyph")
-local dirid = node.id("dir")
-local kernid = node.id("kern")
-local localparid = node.id("local_par")
-
-local spaceskip = 13
-local directmode = 2
-local fontkern = 0
-local italiccorrection = 3
-local explicitdisc = 1
-local regulardisc = 3
-
-local getscript = hb.unicode.script
-local sc_common = hb.Script.new("Zyyy")
-local sc_inherited = hb.Script.new("Zinh")
-local sc_unknown = hb.Script.new("Zzzz")
-local sc_latn = hb.Script.new("Latn")
-local dir_ltr = hb.Direction.new("ltr")
-local dir_rtl = hb.Direction.new("rtl")
-local lang_invalid = hb.Language.new()
-local fl_unsafe = hb.Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK
-
-local p_startactual = "startactualtext"
-local p_endactual = "endactualtext"
-local p_color = "color"
-local p_string = "string"
-
-local format = string.format
+local assert = assert
+local next = next
+local tonumber = tonumber
+local type = type
+local format = string.format
+local open = io.open
+local tableinsert = table.insert
+local tableremove = table.remove
+local ostmpname = os.tmpname
+local osremove = os.remove
+
+local direct = node.direct
+local tonode = direct.tonode
+local todirect = direct.todirect
+local traverse = direct.traverse
+local traverseid = direct.traverse_id
+local insertbefore = direct.insert_before
+local insertafter = direct.insert_after
+local protectglyph = direct.protect_glyph
+local newnode = direct.new
+local copynode = direct.copy
+local removenode = direct.remove
+local copynodelist = direct.copy_list
+local isglyph = direct.is_glyph
+
+local getattrs = direct.getattributelist
+local setattrs = direct.setattributelist
+local getchar = direct.getchar
+local setchar = direct.setchar
+local getdir = direct.getdir
+local setdir = direct.setdir
+local getdata = direct.getdata
+local setdata = direct.setdata
+local getfont = direct.getfont
+local setfont = direct.setfont
+local getfield = direct.getfield
+local setfield = direct.setfield
+local getid = direct.getid
+local getkern = direct.getkern
+local setkern = direct.setkern
+local getnext = direct.getnext
+local setnext = direct.setnext
+local getoffsets = direct.getoffsets
+local setoffsets = direct.setoffsets
+local getproperty = direct.getproperty
+local setproperty = direct.setproperty
+local getprev = direct.getprev
+local setprev = direct.setprev
+local getsubtype = direct.getsubtype
+local setsubtype = direct.setsubtype
+local getwidth = direct.getwidth
+local setwidth = direct.setwidth
+
+local getpre = function (n) return getfield(n, "pre") end
+local setpre = function (n, v) setfield(n, "pre", v) end
+local getpost = function (n) return getfield(n, "post") end
+local setpost = function (n, v) setfield(n, "post", v) end
+local getrep = function (n) return getfield(n, "replace") end
+local setrep = function (n, v) setfield(n, "replace", v) end
+
+local imgnode = img.node
+
+local disc_t = node.id("disc")
+local glue_t = node.id("glue")
+local glyph_t = node.id("glyph")
+local dir_t = node.id("dir")
+local kern_t = node.id("kern")
+local localpar_t = node.id("local_par")
+local whatsit_t = node.id("whatsit")
+local pdfliteral_t = node.subtype("pdf_literal")
+local pdfcolorstack_t = node.subtype("pdf_colorstack")
+
+local spaceskip = 13
+local directmode = 2
+local fontkern = 0
+local italiccorrection = 3
+local explicitdisc = 1
+local regulardisc = 3
+
+local getscript = hb.unicode.script
+
+local common_s = hb.Script.new("Zyyy")
+local inherited_s = hb.Script.new("Zinh")
+local unknown_s = hb.Script.new("Zzzz")
+local latn_s = hb.Script.new("Latn")
+
+local invalid_l = hb.Language.new()
+
+local dir_ltr = hb.Direction.new("ltr")
+local dir_rtl = hb.Direction.new("rtl")
+local fl_unsafe = hb.Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK
+
+local startactual_p = "startactualtext"
+local endactual_p = "endactualtext"
+local color_p = "color"
+local string_p = "string"
-- Simple table copying function.
local function copytable(old)
@@ -103,7 +120,7 @@ end
-- New kern node of amount `v`, inheriting the properties/attributes of `n`.
local function newkern(v, n)
- local kern = newnode(kernid)
+ local kern = newnode(kern_t)
local props = getproperty(n)
local attrs = getattrs(n)
if props then
@@ -169,10 +186,10 @@ local function itemize(head, direction)
for n in direct.traverse(head) do
local id = getid(n)
local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER
- local script = sc_common
+ local script = common_s
local skip = false
- if id == glyphid then
+ if id == glyph_t then
currfontid = getfont(n)
if getsubtype(n) > 255 then
skip = true
@@ -180,25 +197,25 @@ local function itemize(head, direction)
code = getchar(n)
script = getscript(code)
end
- elseif id == glueid and getsubtype(n) == spaceskip then
+ elseif id == glue_t and getsubtype(n) == spaceskip then
code = 0x0020 -- SPACE
- elseif id == discid
+ elseif id == disc_t
and (getsubtype(n) == explicitdisc -- \-
or getsubtype(n) == regulardisc) -- \discretionary
then
code = 0x00AD -- SOFT HYPHEN
- elseif id == dirid then
+ elseif id == dir_t then
local dir = getdir(n)
if dir:sub(1, 1) == "+" then
-- Push the current direction to the stack.
- table.insert(dirstack, currdir)
+ tableinsert(dirstack, currdir)
currdir = dir:sub(2)
else
assert(currdir == dir:sub(2))
-- Pop the last direction from the stack.
- currdir = table.remove(dirstack)
+ currdir = tableremove(dirstack)
end
- elseif id == localparid then
+ elseif id == localpar_t then
currdir = getdir(n)
end
@@ -219,14 +236,14 @@ local function itemize(head, direction)
-- Resolve common and inherited scripts. Inherited takes the script of the
-- previous character. Common almost the same, but we tray to make paired
-- characters (e.g. parentheses) to take the same script.
- if #props > 0 and (script == sc_common or script == sc_inherited) then
+ if #props > 0 and (script == common_s or script == inherited_s) then
script = props[#props].script
-- Paired punctuation characters
if paired_open[code] then
- table.insert(pairstack, { code, script })
+ tableinsert(pairstack, { code, script })
elseif paired_close[code] then
while #pairstack > 0 do
- local c = table.remove(pairstack)
+ local c = tableremove(pairstack)
if c[1] == paired_close[code] then
script = c[2]
break
@@ -237,7 +254,7 @@ local function itemize(head, direction)
-- If script is not resolved yet, and the font has a "script" option, use
-- it.
- if (script == sc_common or script == sc_inherited) and hbdata then
+ if (script == common_s or script == inherited_s) and hbdata then
local spec = hbdata.spec
local features = spec.features
local options = spec.options
@@ -257,7 +274,7 @@ local function itemize(head, direction)
for i = #props - 1, 1, -1 do
-- If script is not resolved yet, use that of the next character.
- if props[i].script == sc_common or props[i].script == sc_inherited then
+ if props[i].script == common_s or props[i].script == inherited_s then
props[i].script = props[i + 1].script
end
end
@@ -339,7 +356,7 @@ local function unsafetobreak(glyph, nodes)
and glyph.flags & fl_unsafe
-- Discretionary nodes can’t contain glue, so stop at first glue as well.
-- This is incorrect, but I don’t have a better idea.
- and getid(nodes[glyph.cluster + 1]) ~= glueid
+ and getid(nodes[glyph.cluster + 1]) ~= glue_t
end
local shape
@@ -352,7 +369,7 @@ local function makesub(run, start, stop, nodelist)
local stop = stop
local subnodes, subcodes = {}, {}
for i = start, stop do
- if getid(nodes[i]) ~= discid then
+ if getid(nodes[i]) ~= disc_t then
subnodes[#subnodes + 1] = copynode(nodes[i])
subcodes[#subcodes + 1] = codes[i]
end
@@ -398,7 +415,7 @@ shape = function(run)
local hbfont = hbshared.font
local hbface = hbshared.face
- local lang = lang or options.language or lang_invalid
+ local lang = lang or options.language or invalid_l
local shapers = options.shaper and { options.shaper } or {}
local buf = hb.Buffer.new()
@@ -427,7 +444,7 @@ shape = function(run)
local layers = hbface:ot_color_glyph_get_layers(gid)
if layers then
-- Remove this glyph, we will use its layers.
- table.remove(glyphs, i)
+ tableremove(glyphs, i)
for j, layer in next, layers do
-- All glyphs but the last use 0 advance so that the layers
-- overlap.
@@ -439,7 +456,7 @@ shape = function(run)
x_advance = j == #layers and glyph.x_advance or 0
y_advance = j == #layers and glyph.y_advance or 0
end
- table.insert(glyphs, i + j - 1, {
+ tableinsert(glyphs, i + j - 1, {
codepoint = layer.glyph,
cluster = glyph.cluster,
x_advance = x_advance,
@@ -470,7 +487,7 @@ shape = function(run)
local str = ""
for j = 0, nchars - 1 do
local id = getid(nodes[nodeindex + j])
- if id == glyphid or id == glueid then
+ if id == glyph_t or id == glue_t then
local code = codes[nodeindex + j]
hex = hex..to_utf16_hex(code)
str = str..utf8.char(code)
@@ -555,8 +572,8 @@ local function cachedpng(data)
local hash = md5.sumhexa(data)
local path = pngcache[hash]
if not path then
- path = os.tmpname()
- local file = io.open(path, "wb")
+ path = ostmpname()
+ local file = open(path, "wb")
file:write(data)
file:close()
pngcache[hash] = path
@@ -601,7 +618,7 @@ local function tonodes(head, current, run, glyphs, color)
end
if color then
- setprop(n, p_color, color)
+ setprop(n, color_p, color)
end
if glyph.disc then
@@ -617,10 +634,10 @@ local function tonodes(head, current, run, glyphs, color)
head, current = insertafter(head, current, disc)
elseif not glyph.skip then
if glyph.color then
- setprop(n, p_color, color_to_rgba(glyph.color))
+ setprop(n, color_p, color_to_rgba(glyph.color))
end
- if id == glyphid then
+ if id == glyph_t then
local fontglyph = fontglyphs[gid]
local pngblob = fontglyph.png
@@ -635,7 +652,7 @@ local function tonodes(head, current, run, glyphs, color)
local data = pngblob:get_data()
local path = cachedpng(data)
- local image = img.node {
+ local image = imgnode {
filename = path,
width = character.width,
height = character.height,
@@ -657,10 +674,10 @@ local function tonodes(head, current, run, glyphs, color)
elseif haspng and not fonttype then
-- Color bitmap font with no glyph outlines (like Noto
-- Color Emoji) but has no bitmap for current glyph (most likely
- -- `.notdef` glyph). The engine does not know how to embed such
- -- fonts, so we don’t want them to reach the backend as it will cause
- -- a fatal error. We use `nullfont` instead. That is a hack, but I
- -- think it is good enough for now.
+ -- `.notdef` glyph). The engine does not know how to embed such
+ -- fonts, so we don’t want them to reach the backend as it will cause
+ -- a fatal error. We use `nullfont` instead. That is a hack, but I
+ -- think it is good enough for now.
-- We insert the glyph node and move on, no further work is needed.
setfont(n, 0)
head, current = insertafter(head, current, n)
@@ -682,19 +699,21 @@ local function tonodes(head, current, run, glyphs, color)
local x_advance = glyph.x_advance + letterspace
local width = fontglyph.width
if width ~= x_advance then
- -- The engine always uses the glyph width from the font, so we need
- -- to insert a kern node if the x advance is different.
+ -- The engine always uses the glyph width from the font, so we need
+ -- to insert a kern node if the x advance is different.
local kern = newkern((x_advance - width) * scale, n)
head, current = insertkern(head, current, kern, rtl)
end
- -- The engine will use this string when printing a glyph node e.g. in
- -- overfull messages, otherwise it will be trying to print our
- -- invalid pseudo Unicode code points.
+ fontglyph.used = true
+
+ -- The engine will use this string when printing a glyph node e.g. in
+ -- overfull messages, otherwise it will be trying to print our
+ -- invalid pseudo Unicode code points.
-- If the string is empty it means this glyph is part of a larger
-- cluster and we don’t to print anything for it as the first glyph
-- in the cluster will have the string of the whole cluster.
- setprop(n, p_string, glyph.string or "")
+ setprop(n, string_p, glyph.string or "")
-- Handle PDF text extraction:
-- * Find how many characters in this cluster and how many glyphs,
@@ -710,15 +729,15 @@ local function tonodes(head, current, run, glyphs, color)
if nglyphs == 1 and not fontglyph.tounicode then
fontglyph.tounicode = tounicode
elseif tounicode ~= fontglyph.tounicode then
- setprop(n, p_startactual, tounicode)
+ setprop(n, startactual_p, tounicode)
glyphs[i + nglyphs - 1].endactual = true
end
end
if glyph.endactual then
- setprop(n, p_endactual, true)
+ setprop(n, endactual_p, true)
end
end
- elseif id == glueid and getsubtype(n) == spaceskip then
+ elseif id == glue_t and getsubtype(n) == spaceskip then
-- If the glyph advance is different from the font space, then a
-- substitution or positioning was applied to the space glyph changing
-- it from the default, so reset the glue using the new advance.
@@ -731,7 +750,7 @@ local function tonodes(head, current, run, glyphs, color)
setfield(n, "shrink", width / 3)
end
head, current = insertafter(head, current, n)
- elseif id == kernid and getsubtype(n) == italiccorrection then
+ elseif id == kern_t and getsubtype(n) == italiccorrection then
-- If this is an italic correction node and the previous node is a
-- glyph, update its kern value with the glyph’s italic correction.
-- I’d have expected the engine to do this, but apparently it doesn’t.
@@ -747,7 +766,7 @@ local function tonodes(head, current, run, glyphs, color)
end
end
head, current = insertafter(head, current, n)
- elseif id == discid then
+ elseif id == disc_t then
assert(nglyphs == 1)
-- The simple case of a discretionary that is not part of a complex
-- cluster. We only need to make sure kerning before the hyphenation
@@ -757,7 +776,7 @@ local function tonodes(head, current, run, glyphs, color)
-- the other discretionary handling, otherwise the discretionary
-- contents do not interact with the surrounding (e.g. no ligatures or
-- kerning) as it should.
- if current and getid(current) == kernid and getsubtype(current) == fontkern then
+ if current and getid(current) == kern_t and getsubtype(current) == fontkern then
setprev(current, nil)
setnext(current, nil)
setfield(n, "replace", current)
@@ -845,7 +864,7 @@ local function process_nodes(head, groupcode, size, packtype, direction)
-- Check if any fonts are loaded by us and then process the whole node list,
-- we will take care of skipping fonts we did not load later, otherwise
-- return unmodified head.
- for n in traverseid(glyphid, head) do
+ for n in traverseid(glyph_t, head) do
local fontid = getfont(n)
local fontdata = font.getfont(fontid)
local hbdata = fontdata and fontdata.hb
@@ -860,12 +879,20 @@ local function process_nodes(head, groupcode, size, packtype, direction)
end
local function pdfdirect(data)
- local n = newnode("whatsit", "pdf_literal")
+ local n = newnode(whatsit_t, pdfliteral_t)
setfield(n, "mode", directmode)
setdata(n, data)
return n
end
+local function pdfcolor(color)
+ local c = newnode(whatsit_t, pdfcolorstack_t)
+ setfield(c, "stack", 0)
+ setfield(c, "command", color and 1 or 2) -- 1: push, 2: pop
+ setfield(c, "data", color)
+ return c
+end
+
local function post_process(head, currentcolor)
for n in traverse(head) do
local props = getproperty(n)
@@ -873,20 +900,21 @@ local function post_process(head, currentcolor)
local startactual, endactual, color
if harfprops then
- startactual = harfprops[p_startactual]
- endactual = harfprops[p_endactual]
- color = harfprops[p_color]
+ startactual = harfprops[startactual_p]
+ endactual = harfprops[endactual_p]
+ color = harfprops[color_p]
end
if currentcolor and currentcolor ~= color then
-- Pop current color.
- head = insertbefore(head, n, pdfdirect("0 g"))
+ currentcolor = nil
+ head = insertbefore(head, n, pdfcolor(currentcolor))
end
if currentcolor ~= color then
-- Push new color.
- head = insertbefore(head, n, pdfdirect(color))
currentcolor = color
+ head = insertbefore(head, n, pdfcolor(currentcolor))
end
if startactual then
@@ -918,7 +946,7 @@ end
local function run_cleanup()
-- Remove temporary PNG files that we created, if any.
for _, path in next, pngcache do
- os.remove(path)
+ osremove(path)
end
end
@@ -931,8 +959,8 @@ local function set_tounicode()
local glyphs = hbdata.shared.glyphs
for gid = 0, #glyphs do
local glyph = glyphs[gid]
- local tounicode = glyph.tounicode
- if tounicode then
+ if glyph.used then
+ local tounicode = glyph.tounicode or "FFFD"
local character = characters[gid + hb.CH_GID_PREFIX]
newcharacters[gid + hb.CH_GID_PREFIX] = character
character.tounicode = tounicode
@@ -948,7 +976,7 @@ local function get_glyph_string(n)
local n = todirect(n)
local props = getproperty(n)
props = props and props.harf
- return props and props[p_string] or nil
+ return props and props[string_p] or nil
end
return {
diff --git a/texmf-dist/tex/harftex/base/harfload.sty b/texmf-dist/tex/harftex/base/harfload.sty
index 0164983a..32e23400 100644
--- a/texmf-dist/tex/harftex/base/harfload.sty
+++ b/texmf-dist/tex/harftex/base/harfload.sty
@@ -2,7 +2,7 @@
\let\ifharfloadloaded\endinput
\ifdefined\ProvidesPackage
\RequirePackage{luaotfload}
- \ProvidesPackage{harfload}[2019/08/25 v0.4.1 Unicode text layout system]
+ \ProvidesPackage{harfload}[2019/09/07 v0.4.2 Unicode text layout system]
\else
\input luaotfload.sty
\fi