I am trying to debug a much larger problem, but the smoking gun is some (apparently) strange behavior with LuaTeX’s fontloader library.
Minimal Example
Here is file backmap.tex
:
\directlua { tex.enableprimitives('',tex.extraprimitives()) }
\directlua { dofile('define_font.lua') }
\font\noto={../../fonts/amiri-regular.ttf}
\bye
Here is file define_font.lua
:
function read_font (name, size, fontid)
-- Load file using fontloader.open
local f = fontloader.open (name)
local fonttable = fontloader.to_table(f)
fontloader.close(f)
for char, glyph in pairs(fonttable.map.map) do
if char == 0x0020 -- SPACE
or char == 0x110300 -- Some ‘character’ in Amiri font
or char == 0x06A9 then -- ARABIC LETTER KEHEH
local backmap = fonttable.map.backmap[glyph]
texio.write_nl(string.format("\n\nGLYPH: 0x%x, CHAR: 0x%x, BACKMAP: 0x%x", glyph, char, backmap))
if char ~= backmap then
texio.write_nl("char and backmap value DIFFERENT")
texio.write_nl(string.format("fonttable.map.map[0x%x]: 0x%x", char, fonttable.map.map[char]))
texio.write_nl(string.format("fonttable.map.map[0x%x]: 0x%x", char, fonttable.map.map[backmap]))
else
texio.write_nl("char and backmap value SAME")
end
end
end
return { }
end
-- Register OpenType font loader in define_font callback.
callback.register('define_font', read_font, "font loader")
And here is the output of running luatex --fmt=plain backmap.tex
:
This is LuaTeX, Version beta-0.87.1 (TeX Live 2016/dev)
(./backmap.tex
GLYPH: 0x3, CHAR: 0x20, BACKMAP: 0xa0
char and backmap value DIFFERENT
fonttable.map.map[0x20]: 0x3
fonttable.map.map[0xa0]: 0x3
GLYPH: 0x206, CHAR: 0x6a9, BACKMAP: 0x6a9
char and backmap value SAME
GLYPH: 0x987, CHAR: 0x110300, BACKMAP: 0x110300
char and backmap value SAME
! error (font): lua-loaded font '51' has no name!
! ==> Fatal error occurred, bad output DVI file produced!
No pages of output.
(
Explanation
I am trying to read all the characters and glyphs from fonttable.map.map
, and then comparing the values of the char
to the corresponding value of fonttable.map.backmap[glyph]
.
My expectation is that the fonttable.map.backmap
table should map the glyph back to the same character, that maps to that specific glyph. But as you can see from the output above, the backmap for the glyph corresponding to U+0020 (SPACE), instead maps to U+00A0 (NO-BREAK SPACE).
The reason this is causing me problems is that I am using an external shaping engine (Harfbuzz) to get glyphs for characters in a paragraph, and then trying to check the backmap to see if a glyph maps back to U+0020 (SPACE) character, and then intercept it to add a glue node instead.
My questions:
- Is it valid for a font to be that way, i.e. backmap does not match glyph back to the same character?
- Any suggestions for how I can intercept spaces in general? Should I look for any kind of space and substitute it for glue instead?