Hi Luigi, I've attached a series of font-related patches. Patch 1: Even if you set "tounicode = 1" at the top level of a font, "tounicode = <something>" for each character, and run "pdf.setgentounicode(1)", LuaTeX will only write out a /ToUnicode entry if the document uses "\pdfextension glyphtounicode" somewhere. A minimal(-ish) example: % \pdfextension glyphtounicode{fake!}{0000} \newcount\fontid \directlua{ local height = tex.sp("8bp") local width = tex.sp("36bp") pdf.setgentounicode(1) local inner = font.define { name = "fake-font-inner", parameters = {}, properties = {}, encodingbytes = 0, psname = "none", tounicode = 1, characters = { [1] = { width = width, height = height, depth = 0, tounicode = { 0x1f986 }, } } } tex.count.fontid = font.define { name = "fake-font-virtual", parameters = {}, properties = {}, characters = { [string.byte"x"] = { width = width, height = height, depth = 0, commands = { { "slot", 1, 1 } } } }, type = "virtual", fonts = {{ id = inner }}, } callback.register( "provide_charproc_data", function (mode, font_id, slot) if mode == 2 then return pdf.immediateobj("stream", "36 0 d0 0 0 36 8 re f"), 36 elseif mode == 3 then return 1 / 10 end end ) } x{\setfontid\fontid x}x \bye You would expect that copying the black box would give you a duck, but this only happens if the first line is uncommented. The first patch should fix this. Patch 2: Defining a Type 3 font with a character index greater than 256 can cause a segfault. Using an index >256 is impossible with a T3 font, but you shouldn't be able to cause a segfault from Lua code. Minimal example: \directlua{ local height = tex.sp("8bp") local width = tex.sp("36bp") local id = font.define { name = "fake-font-inner", parameters = {}, properties = {}, encodingbytes = 0, psname = "none", tounicode = 1, characters = { [0x1f986] = { width = width, height = height, depth = 0, } } } callback.register( "provide_charproc_data", function (mode, font_id, slot) if mode == 2 then return pdf.immediateobj("stream", "36 0 d0 0 0 36 8 re f"), 36 elseif mode == 3 then return 1 / 10 end end ) local glyph = node.new("glyph") glyph.font = id glyph.char = 0x1f986 tex.forcehmode() node.write(glyph) } \bye The second patch catches this when the font is initialized, skips the too-large character, and issues a warning. Patch 3: The third patch adds the "provide_charproc_data" callback to the manual. Thanks, -- Max
On Thu, 6 Jul 2023 at 08:04, Max Chernoff
Hi Luigi,
I've attached a series of font-related patches.
Patch 1:
Even if you set "tounicode = 1" at the top level of a font, "tounicode = <something>" for each character, and run "pdf.setgentounicode(1)", LuaTeX will only write out a /ToUnicode entry if the document uses "\pdfextension glyphtounicode" somewhere.
A minimal(-ish) example:
% \pdfextension glyphtounicode{fake!}{0000}
\newcount\fontid \directlua{ local height = tex.sp("8bp") local width = tex.sp("36bp")
pdf.setgentounicode(1)
local inner = font.define { name = "fake-font-inner", parameters = {}, properties = {}, encodingbytes = 0, psname = "none", tounicode = 1, characters = { [1] = { width = width, height = height, depth = 0, tounicode = { 0x1f986 }, } } }
tex.count.fontid = font.define { name = "fake-font-virtual", parameters = {}, properties = {}, characters = { [string.byte"x"] = { width = width, height = height, depth = 0, commands = { { "slot", 1, 1 } }
} }, type = "virtual", fonts = {{ id = inner }}, }
callback.register( "provide_charproc_data", function (mode, font_id, slot) if mode == 2 then return pdf.immediateobj("stream", "36 0 d0 0 0 36 8 re f"), 36 elseif mode == 3 then return 1 / 10 end end ) }
x{\setfontid\fontid x}x
\bye
You would expect that copying the black box would give you a duck, but this only happens if the first line is uncommented. The first patch should fix this.
Patch 2:
Defining a Type 3 font with a character index greater than 256 can cause a segfault. Using an index >256 is impossible with a T3 font, but you shouldn't be able to cause a segfault from Lua code.
Minimal example:
\directlua{ local height = tex.sp("8bp") local width = tex.sp("36bp")
local id = font.define { name = "fake-font-inner", parameters = {}, properties = {}, encodingbytes = 0, psname = "none", tounicode = 1, characters = { [0x1f986] = { width = width, height = height, depth = 0, } } }
callback.register( "provide_charproc_data", function (mode, font_id, slot) if mode == 2 then return pdf.immediateobj("stream", "36 0 d0 0 0 36 8 re f"), 36 elseif mode == 3 then return 1 / 10 end end )
local glyph = node.new("glyph") glyph.font = id glyph.char = 0x1f986
tex.forcehmode() node.write(glyph) } \bye
The second patch catches this when the font is initialized, skips the too-large character, and issues a warning.
Patch 3:
The third patch adds the "provide_charproc_data" callback to the manual.
Thanks, -- Max
ok, I will check them during this weekend. -- luigi
On 7/5/2023 9:29 AM, Max Chernoff wrote:
\newcount\fontid
you overload a primitive Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
On Thu, 6 Jul 2023 at 08:04, Max Chernoff
Hi Luigi,
I've attached a series of font-related patches.
Patch 1:
Even if you set "tounicode = 1" at the top level of a font, "tounicode = <something>" for each character, and run "pdf.setgentounicode(1)", LuaTeX will only write out a /ToUnicode entry if the document uses "\pdfextension glyphtounicode" somewhere.
A minimal(-ish) example:
% \pdfextension glyphtounicode{fake!}{0000}
\newcount\fontid \directlua{ local height = tex.sp("8bp") local width = tex.sp("36bp")
pdf.setgentounicode(1)
local inner = font.define { name = "fake-font-inner", parameters = {}, properties = {}, encodingbytes = 0, psname = "none", tounicode = 1, characters = { [1] = { width = width, height = height, depth = 0, tounicode = { 0x1f986 }, } } }
tex.count.fontid = font.define { name = "fake-font-virtual", parameters = {}, properties = {}, characters = { [string.byte"x"] = { width = width, height = height, depth = 0, commands = { { "slot", 1, 1 } }
} }, type = "virtual", fonts = {{ id = inner }}, }
callback.register( "provide_charproc_data", function (mode, font_id, slot) if mode == 2 then return pdf.immediateobj("stream", "36 0 d0 0 0 36 8 re f"), 36 elseif mode == 3 then return 1 / 10 end end ) }
x{\setfontid\fontid x}x
\bye
You would expect that copying the black box would give you a duck, but this only happens if the first line is uncommented. The first patch should fix this.
(sorry for the long delay) Iiuc, the problem is that in this case glyph_unicode_tree is NULL ( \pdfextension glyphtounicode{fake!}{0000} create a new glyph_unicode_tree if is the case, by mean of def_tounicode). So perhaps it's better if we export a new function glyph_unicode_new(void) at the lua level that allocate ,if the case, a new glyph_unicode_tree, leaving do_write_tounicode as is now. -- luigi
participants (3)
-
Hans Hagen
-
luigi scarso
-
Max Chernoff