[latex3-commits] [git/LaTeX3-latex3-luaotfload] harf-dev: More plugin like (ed59eca)
Marcel Fabian Krüger
tex at 2krueger.de
Tue Sep 17 15:00:18 CEST 2019
Repository : https://github.com/latex3/luaotfload
On branch : harf-dev
Link : https://github.com/latex3/luaotfload/commit/ed59eca50c52d61588bf1961ff79b891993e28dc
>---------------------------------------------------------------
commit ed59eca50c52d61588bf1961ff79b891993e28dc
Author: Marcel Fabian Krüger <tex at 2krueger.de>
Date: Tue Sep 17 12:48:07 2019 +0200
More plugin like
>---------------------------------------------------------------
ed59eca50c52d61588bf1961ff79b891993e28dc
src/harf/harf-luaotfload.lua | 3 +
src/harf/harf-node.lua | 146 ++++++++++---------------------------------
2 files changed, 36 insertions(+), 113 deletions(-)
diff --git a/src/harf/harf-luaotfload.lua b/src/harf/harf-luaotfload.lua
index 703162b..f5d87e7 100644
--- a/src/harf/harf-luaotfload.lua
+++ b/src/harf/harf-luaotfload.lua
@@ -38,6 +38,9 @@ fonts.readers.harf = function(spec)
if rawfeatures.language then
spec.language = harf.Language.new(rawfeatures.language)
end
+ if rawfeatures.script then
+ spec.script = harf.Script.new(rawfeatures.script)
+ end
for key, val in next, rawfeatures do
if key:len() == 4 then
-- 4-letter options are likely font features, but not always, so we do
diff --git a/src/harf/harf-node.lua b/src/harf/harf-node.lua
index d7f0ee2..abdc9b3 100644
--- a/src/harf/harf-node.lua
+++ b/src/harf/harf-node.lua
@@ -4,7 +4,6 @@ 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
@@ -41,6 +40,7 @@ local getsubtype = direct.getsubtype
local setsubtype = direct.setsubtype
local getwidth = direct.getwidth
local setwidth = direct.setwidth
+local uses_font = direct.uses_font
local getpre = function (n) return getfield(n, "pre") end
local setpre = function (n, v) setfield(n, "pre", v) end
@@ -63,15 +63,16 @@ 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 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 script_invalid = hb.Script.new()
+local fl_unsafe = hb.Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK
local p_startactual = "startactualtext"
local p_endactual = "endactualtext"
@@ -158,30 +159,30 @@ local process
local trep = hb.texrep
-local function itemize(head, direction)
- -- Collect character properties (font, direction, script) and resolve common
- -- and inherited scripts. Pre-requisite for itemization into smaller runs.
+local function itemize(head, fontid, direction)
+ local fontdata = font.getfont(fontid)
+ local hbdata = fontdata and fontdata.hb
+ local spec = fontdata and fontdata.specification
+ local options = spec and spec.features.raw
+ local texlig = options and options.tlig
+
local props, nodes, codes = {}, {}, {}
- local dirstack, pairstack = {}, {}
+ local dirstack = {}
local currdir = direction or "TLT"
- local currfontid = nil
for n, id, subtype in direct.traverse(head) do
local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER
- local script = sc_common
local skip = false
if id == glyphid then
- currfontid = getfont(n)
- if subtype > 255 then
+ if subtype > 255 or not uses_font(n, fontid) then
skip = true
else
code = getchar(n)
- script = getscript(code)
end
elseif id == glueid and subtype == spaceskip then
code = 0x0020 -- SPACE
- elseif id == discid
+ elseif id == discid -- FIXME
and (subtype == explicitdisc -- \-
or subtype == regulardisc) -- \discretionary
then
@@ -201,84 +202,37 @@ local function itemize(head, direction)
currdir = getdir(n)
end
- local fontdata = currfontid and font.getfont(currfontid)
- local hbdata = fontdata and fontdata.hb
- local spec = fontdata and fontdata.specification
- local options = spec and spec.features.raw
- local texlig = options and options.tlig
- if texlig then
+ if not skip and texlig then
local replacement = trep[code]
if replacement then
code = replacement
end
end
- if not hbdata then skip = true end
-
- -- 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
- script = props[#props].script
- -- Paired punctuation characters
- if paired_open[code] then
- table.insert(pairstack, { code, script })
- elseif paired_close[code] then
- while #pairstack > 0 do
- local c = table.remove(pairstack)
- if c[1] == paired_close[code] then
- script = c[2]
- break
- end
- end
- end
- end
-
- -- 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
- script = options.script and hb.Script.new(options.script) or script
- end
-
codes[#codes + 1] = code
nodes[#nodes + 1] = n
props[#props + 1] = {
- font = currfontid,
-- XXX handle RTT and LTL.
dir = currdir == "TRT" and dir_rtl or dir_ltr,
- script = script,
skip = skip,
}
end
- 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
- props[i].script = props[i + 1].script
- end
- end
-
- -- Split into a list of runs, each has the same font, direction and script.
- -- TODO: itemize by language as well.
+ -- Split into a list of runs, each has the same font and direction
local runs = {}
- local currfontid, currdir, currscript, currskip = nil, nil, nil, nil
+ local currdir, currskip
for i, prop in next, props do
- local fontid = prop.font
local dir = prop.dir
- local script = prop.script
local skip = prop.skip
-- Start a new run if there is a change in properties.
- if fontid ~= currfontid or
- dir ~= currdir or
- script ~= currscript or
+ if dir ~= currdir or
skip ~= currskip then
runs[#runs + 1] = {
start = i,
len = 0,
font = fontid,
dir = dir,
- script = script,
skip = skip,
nodes = nodes,
codes = codes,
@@ -287,7 +241,6 @@ local function itemize(head, direction)
runs[#runs].len = runs[#runs].len + 1
- currfontid = fontid
currdir = dir
currscript = script
currskip = skip
@@ -380,8 +333,6 @@ shape = function(run)
local len = run.len
local fontid = run.font
local dir = run.dir
- local script = run.script
- local lang = run.lang
local fordisc = run.fordisc
local fontdata = font.getfont(fontid)
@@ -394,7 +345,8 @@ shape = function(run)
local hbfont = hbshared.font
local hbface = hbshared.face
- local lang = lang or options.language or lang_invalid
+ local lang = options.language or lang_invalid
+ local script = options.script or script_invalid
local shapers = options.shaper and { options.shaper } or {}
local buf = hb.Buffer.new()
@@ -760,9 +712,9 @@ local function tonodes(head, current, run, glyphs, color)
head, current = removenode(head, current)
end
local pre, post, rep = getpre(n), getpost(n), getrep(n)
- setfield(n, "pre", process(pre, direction))
- setfield(n, "post", process(post, direction))
- setfield(n, "replace", process(rep, direction))
+ setfield(n, "pre", process(pre, fontid, direction))
+ setfield(n, "post", process(post, fontid, direction))
+ setfield(n, "replace", process(rep, fontid, direction))
head, current = insertafter(head, current, n)
else
@@ -774,18 +726,6 @@ local function tonodes(head, current, run, glyphs, color)
return head, current
end
-local function validate_color(s)
- local r = tonumber(s:sub(1, 2), 16)
- local g = tonumber(s:sub(3, 4), 16)
- local b = tonumber(s:sub(5, 6), 16)
- if not (r and g and b) then return end
- if #s == 8 then
- local a = tonumber(s:sub(7, 8), 16)
- if not a then return end
- end
- return s
-end
-
local hex_to_rgba do
local hex = lpeg.R'09' + lpeg.R'AF' + lpeg.R'af'
local twohex = hex * hex / function(s) return tonumber(s, 16) / 255 end
@@ -822,9 +762,9 @@ local function shape_run(head, current, run)
return head, current
end
-process = function(head, direction)
+process = function(head, font, direction)
local newhead, current = nil, nil
- local runs = itemize(head, direction)
+ local runs = itemize(head, font, direction)
for _, run in next, runs do
newhead, current = shape_run(newhead, current, run)
@@ -833,26 +773,6 @@ process = function(head, direction)
return newhead or head
end
-local function process_nodes(head, font, _, direction)
- local head = todirect(head)
-
- -- 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
- local fontid = getfont(n)
- local fontdata = font.getfont(fontid)
- local hbdata = fontdata and fontdata.hb
- if hbdata then
- head = process(head, direction)
- break
- end
- end
-
- -- Nothing to do; no glyphs or no HarfBuzz fonts.
- return tonode(head)
-end
-
local function pdfdirect(data)
local n = newnode("whatsit", "pdf_literal")
setfield(n, "mode", directmode)
@@ -940,7 +860,7 @@ local function get_glyph_string(n)
return props and props[p_string] or nil
end
-fonts.handlers.otf.registerplugin('harf', process_nodes)
+fonts.handlers.otf.registerplugin('harf', process)
return {
-- process = process_nodes,
More information about the latex3-commits
mailing list