[latex3-commits] [git/LaTeX3-latex3-luaotfload] harfnode-dev: Bugs + new PNG handling (278ee08)
Marcel Fabian Krüger
tex at 2krueger.de
Fri Oct 11 20:41:43 CEST 2019
Repository : https://github.com/latex3/luaotfload
On branch : harfnode-dev
Link : https://github.com/latex3/luaotfload/commit/278ee08e52068e431b7f9a2061a114727dbded17
>---------------------------------------------------------------
commit 278ee08e52068e431b7f9a2061a114727dbded17
Author: Marcel Fabian Krüger <tex at 2krueger.de>
Date: Fri Oct 11 20:41:43 2019 +0200
Bugs + new PNG handling
Use virtual fonts instead of inserting image nodes directly, such that
they behave more like normal glyphs.
>---------------------------------------------------------------
278ee08e52068e431b7f9a2061a114727dbded17
src/luaotfload-harf-define.lua | 1 -
src/luaotfload-harf-plug.lua | 134 ++++++++++++++++++++++++-----------------
2 files changed, 79 insertions(+), 56 deletions(-)
diff --git a/src/luaotfload-harf-define.lua b/src/luaotfload-harf-define.lua
index 317d129..6ca6f22 100644
--- a/src/luaotfload-harf-define.lua
+++ b/src/luaotfload-harf-define.lua
@@ -283,7 +283,6 @@ local function scalefont(data, spec)
index = spec.index,
size = size,
units_per_em = upem,
- type = "real",
embedding = "subset",
tounicode = 1,
nomath = true,
diff --git a/src/luaotfload-harf-plug.lua b/src/luaotfload-harf-plug.lua
index fdc732f..35cd523 100644
--- a/src/luaotfload-harf-plug.lua
+++ b/src/luaotfload-harf-plug.lua
@@ -24,6 +24,7 @@ local copynode = direct.copy
local removenode = direct.remove
local copynodelist = direct.copy_list
local isglyph = direct.is_glyph
+local uses_font = direct.uses_font
local getattrs = direct.getattributelist
local setattrs = direct.setattributelist
@@ -166,7 +167,8 @@ local function itemize(head, fontid, direction)
local runs, codes = {}, {}
local dirstack = {}
local currdir = direction or "TLT"
- local lastdir, lastskip, lastrun
+ local lastdir, lastskip
+ local lastrun = {}
for n, id, subtype in direct.traverse(head) do
local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER
@@ -184,7 +186,11 @@ local function itemize(head, fontid, direction)
-- and (subtype == explicitdisc_t -- \-
-- or subtype == regulardisc_t) -- \discretionary
then
- code = 0x00AD -- SOFT HYPHEN
+ if uses_font(n, fontid) then
+ code = 0x00AD -- SOFT HYPHEN
+ else
+ skip = true
+ end
elseif id == dir_t then
local dir = getdir(n)
if dir:sub(1, 1) == "+" then
@@ -210,6 +216,7 @@ local function itemize(head, fontid, direction)
codes[#codes + 1] = code
if lastdir ~= currdir or lastskip ~= skip then
+ lastrun.after = n
lastrun = {
start = #codes,
len = 1,
@@ -294,7 +301,8 @@ end
-- the output.
shape = function(head, node, run)
local codes = run.codes
- local offset = run.start
+ local offset = run.start - (codes.offset or 0)
+ run.start = offset
local len = run.len
local fontid = run.font
local dir = run.dir
@@ -439,14 +447,17 @@ shape = function(head, node, run)
-- Find the next glyph that is safe to break at.
stopglyph = i + 1
local lastcluster = glyphs[i].cluster
- while unsafetobreak(glyphs[stopglyph])
- or lastcluster == glyphs[stopglyph].cluster
- and getid(stopnode) ~= glue_t do
+ while stopglyph < #glyphs
+ and codes[glyphs[stopglyph].cluster + 1] ~= 0x20
+ and (unsafetobreak(glyphs[stopglyph])
+ or lastcluster == glyphs[stopglyph].cluster) do
lastcluster = glyphs[stopglyph].cluster
stopglyph = stopglyph + 1
end
-- We also want the last char in the previous glyph, so no +1 below.
- stopindex = glyphs[stopglyph].cluster
+
+ stopindex = stopglyph < #glyphs and glyphs[stopglyph].cluster
+ or offset + len - 1
local startnode, stopnode = node, node
for j=cluster, startindex, -1 do
@@ -494,15 +505,15 @@ shape = function(head, node, run)
local precodes, postcodes, repcodes = {}, {}, {}
table.move(subcodes, 1, subindex, 1, repcodes)
for n, id, subtype in traverse(rep) do
- repcodes[#repcodes + 1] = id == glyph_t and getchar(n) or 0xFFFC
+ repcodes[#repcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC
end
table.move(subcodes, subindex + 1, #subcodes, #repcodes + 1, repcodes)
table.move(subcodes, 1, subindex, 1, precodes)
for n, id, subtype in traverse(pre) do
- precodes[#precodes + 1] = id == glyph_t and getchar(n) or 0xFFFC
+ precodes[#precodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC
end
for n, id, subtype in traverse(post) do
- postcodes[#postcodes + 1] = id == glyph_t and getchar(n) or 0xFFFC
+ postcodes[#postcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC
end
table.move(subcodes, subindex + 1, #subcodes, #postcodes + 1, postcodes)
do local newpre = copynodelist(startnode, disc)
@@ -546,6 +557,7 @@ shape = function(head, node, run)
end
node = getnext(node)
end
+ codes.offset = run.len - len + (codes.offset or 0)
return head, glyphs
end
@@ -581,6 +593,10 @@ local function cachedpng(data)
return path
end
+local function get_png_glyph(gid, fontid, characters, haspng)
+ return gid
+end
+
-- Convert glyphs to nodes and collect font characters.
local function tonodes(head, node, run, glyphs, color)
local nodeindex = run.start
@@ -648,49 +664,60 @@ local function tonodes(head, node, run, glyphs, color)
end
if id == glyph_t then
+ local done
local fontglyph = fontglyphs[gid]
-
- local pngblob = fontglyph.png -- FIXME: Rewrite
- if haspng and not pngblob then
- pngblob = hbfont:ot_color_glyph_get_png(gid)
- fontglyph.png = pngblob
- end
local character = characters[char]
- if pngblob then
- -- Color bitmap font, extract the PNG data and insert it in the node
- -- list.
- local data = pngblob:get_data()
- local path = cachedpng(data)
-
- local image = imgnode {
- filename = path,
- width = character.width,
- height = character.height,
- depth = character.depth,
- }
- if fonttype then
- -- Color bitmap font with glyph outlines. Insert negative kerning
- -- as we will insert the glyph node below (to help with text
- -- copying) and want the bitmap and the glyph to take the same
- -- advance width.
- local kern = newkern(-character.width, node)
- head, node = insertkern(head, node, kern, rtl)
+
+ if haspng then
+ local pngglyph = character.pngglyph
+ if pngglyph == nil then
+ pngglyph = fontglyph.png
+ if pngglyph == nil then
+ local pngblob = hbfont:ot_color_glyph_get_png(gid)
+ if pngblob then
+ pngglyph = img.scan{filename = cachedpng(pngblob:get_data())}
+ else
+ pngglyph = false
+ end
+ fontglyph.png = pngglyph
+ end
+ if pngglyph then
+ local pngchar = { }
+ for k,v in next, character do
+ pngchar[k] = v
+ end
+ local i = img.copy(pngglyph)
+ i.width = character.width
+ i.depth = 0
+ i.height = character.height + character.depth
+ pngchar.commands = fonttype and {
+ {"push"}, {"char", gid_offset + gid}, {"pop"},
+ {"down", character.depth}, {"image", i}
+ } or { {"down", character.depth}, {"image", i} }
+ if not nominals[gid] then
+ char = 0x130000 + gid
+ end
+ characters[char] = pngchar
+ pngglyph = char
+ font.addcharacters(fontid, {characters = {[char] = pngchar}})
+ end
+ character.pngglyph = pngglyph
+ end
+ if pngglyph then
+ char = pngglyph
+ elseif 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.
+ -- We insert the glyph node and move on, no further work is needed.
+ setfont(node, 0)
+ done = true
end
end
- if pngblob and not fonttype then
- -- Color bitmap font with no glyph outlines, and has a bitmap for
- -- this glyph. No further work is needed.
- 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.
- -- We insert the glyph node and move on, no further work is needed.
- setfont(node, 0)
- head, current = insertafter(head, current, node)
- else
+ if not done then
local oldcharacter = characters[getchar(node)]
-- If the glyph index of current font character is the same as shaped
-- glyph, keep the node char unchanged. Helps with primitives that
@@ -703,7 +730,7 @@ local function tonodes(head, node, run, glyphs, color)
local yoffset = glyph.y_offset * scale
setoffsets(node, xoffset, yoffset)
- fontglyph.used = true
+ fontglyph.used = fonttype and 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
@@ -794,7 +821,7 @@ local function tonodes(head, node, run, glyphs, color)
nodeindex = nodeindex + 1
end
end
- for j = nodeindex + 1, run.start + #run.codes do
+ while node ~= run.after do
local oldnode = node
head, node = removenode(head, node)
freenode(oldnode)
@@ -828,10 +855,7 @@ local function shape_run(head, current, run)
head, glyphs = shape(head, current, run)
return tonodes(head, current, run, glyphs, color)
else
- for i = 1, len do
- current = getnext(current)
- end
- return head, current
+ return head, run.after
end
end
More information about the latex3-commits
mailing list