diff options
author | Norbert Preining <norbert@preining.info> | 2019-08-11 06:34:40 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-08-11 06:34:40 +0900 |
commit | a5cb56c0c5954d2905f84600b1e26e7183207ba8 (patch) | |
tree | d91135771b889a12f9e57df88862075e4706a251 /texmf-dist/tex | |
parent | dd4d64777acfa6fb12822ac3b40810c0e6b52a04 (diff) |
harftex 0.4.0
Diffstat (limited to 'texmf-dist/tex')
-rw-r--r-- | texmf-dist/tex/harftex/base/harf-base.lua (renamed from texmf-dist/tex/generic/harftex/harf-base.lua) | 14 | ||||
-rw-r--r-- | texmf-dist/tex/harftex/base/harf-load.lua (renamed from texmf-dist/tex/generic/harftex/harf-load.lua) | 36 | ||||
-rw-r--r-- | texmf-dist/tex/harftex/base/harf-luaotfload.lua (renamed from texmf-dist/tex/generic/harftex/harf-luaotfload.lua) | 12 | ||||
-rw-r--r-- | texmf-dist/tex/harftex/base/harf-node.lua (renamed from texmf-dist/tex/generic/harftex/harf-node.lua) | 140 | ||||
-rw-r--r-- | texmf-dist/tex/harftex/base/harf-plain.lua (renamed from texmf-dist/tex/generic/harftex/harf-plain.lua) | 0 | ||||
-rw-r--r-- | texmf-dist/tex/harftex/base/harf.lua (renamed from texmf-dist/tex/generic/harftex/harf.lua) | 2 | ||||
-rw-r--r-- | texmf-dist/tex/harftex/base/harfload.sty (renamed from texmf-dist/tex/generic/harftex/harfload.sty) | 2 |
7 files changed, 120 insertions, 86 deletions
diff --git a/texmf-dist/tex/generic/harftex/harf-base.lua b/texmf-dist/tex/harftex/base/harf-base.lua index 37970b29..e0d2299c 100644 --- a/texmf-dist/tex/generic/harftex/harf-base.lua +++ b/texmf-dist/tex/harftex/base/harf-base.lua @@ -1,15 +1,15 @@ local hb = require("luaharfbuzz") --- LuaTeX’s TFM structure indexes glyphs by character codes, so we fake it by --- adding the maximum possible Unicode code point to the glyph id. This way --- we have a simple mapping for all glyphs without interfering with any valid --- Unicode code point. +-- The engine’s TFM structure indexes glyphs by character codes, which means +-- all our glyphs need character codes. We fake them by adding the maximum +-- possible Unicode code point to the glyph id. This way we have a simple +-- mapping for all glyphs without interfering with any valid Unicode code +-- point. -- --- LuaTeX use the first 256 characters above maximum Unicode character for --- escaping raw bytes, so skip that as well. +-- The engine uses the first 256 code points outside valid Unicode code space +-- for escaping raw bytes, so we skip them in our prefix. hb.CH_GID_PREFIX = 0x110000 + 256 - -- Legacy TeX Input Method Disguised as Font Ligatures hack. -- -- Single replacements, keyed by character to replace. Handled separately diff --git a/texmf-dist/tex/generic/harftex/harf-load.lua b/texmf-dist/tex/harftex/base/harf-load.lua index 9ab05783..0543c94c 100644 --- a/texmf-dist/tex/generic/harftex/harf-load.lua +++ b/texmf-dist/tex/harftex/base/harf-load.lua @@ -83,8 +83,8 @@ local function loadfont(spec) local hbfont = hb.Font.new(hbface) local upem = hbface:get_upem() - -- All LuaTeX seem to care about in font type is whether it has CFF table - -- or not, so we check for that here. + -- The engine seems to use the font type to tell whether there is a CFF + -- table or not, so we check for that here. local fonttype = nil local hasos2 = false local haspost = false @@ -121,20 +121,10 @@ local function loadfont(spec) end end - -- Load CPAL palettes if avialable in the font. - local palettes = nil - if hbface:ot_color_has_palettes() and hbface:ot_color_has_layers() then - local count = hbface:ot_color_palette_get_count() - palettes = {} - for i = 1, count do - palettes[#palettes + 1] = hbface:ot_color_palette_get_colors(i) - end - end - -- Load glyph metrics for all glyphs in the font. We used to do this on -- demand to make loading fonts faster, but hit many limitations inside - -- LuaTeX (mainly with shared backend fonts, where LuaTeX would assume all - -- fonts it decides to share load the same set of glyphs). + -- the engine (mainly with shared backend fonts, where the engine would + -- assume all fonts it decides to share load the same set of glyphs). -- -- Getting glyph advances is fast enough, but glyph extents are slower -- especially in CFF fonts. We might want to have an option to ignore exact @@ -210,7 +200,6 @@ local function loadfont(spec) unicodes = characters, psname = hbface:get_name(hb.ot.NAME_ID_POSTSCRIPT_NAME), fullname = hbface:get_name(hb.ot.NAME_ID_FULL_NAME), - palettes = palettes, haspng = hbface:ot_color_has_png(), loaded = {}, -- Cached loaded glyph data. } @@ -249,6 +238,7 @@ local tlig = hb.texlig local function scalefont(data, spec) local size = spec.size local options = spec.options + local hbface = data.face local hbfont = data.font local upem = data.upem local space = data.space @@ -282,8 +272,16 @@ local function scalefont(data, spec) -- Select font palette, we support `palette=index` option, and load the first -- one otherwise. - local palettes = data.palettes - local palette = palettes and palettes[tonumber(options.palette) or 1] + local paletteidx = tonumber(options.palette) or 1 + + -- Load CPAL palette from the font. + local palette = nil + if hbface:ot_color_has_palettes() and hbface:ot_color_has_layers() then + local count = hbface:ot_color_palette_get_count() + if paletteidx <= count then + palette = hbface:ot_color_palette_get_colors(paletteidx) + end + end local letterspace = 0 if options.letterspace then @@ -303,8 +301,8 @@ local function scalefont(data, spec) if options.embolden then mode = 2 -- The multiplication by 7200.0/7227 is to undo the opposite conversion - -- LuaTeX is doing and make the final number written in the PDF file match - -- XeTeX's. + -- the engine is doing and make the final number written in the PDF file + -- match XeTeX’s. width = (size * tonumber(options.embolden) / 6553.6) * (7200.0/7227) end diff --git a/texmf-dist/tex/generic/harftex/harf-luaotfload.lua b/texmf-dist/tex/harftex/base/harf-luaotfload.lua index fbe3181b..8a373275 100644 --- a/texmf-dist/tex/generic/harftex/harf-luaotfload.lua +++ b/texmf-dist/tex/harftex/base/harf-luaotfload.lua @@ -11,6 +11,17 @@ fonts.names.set_location_precedence { "local", "texmf", "system" } +local callback_warning = true +if callback_warning then + local callbacks = callback.list() + if callbacks["get_glyph_string"] == nil then + luatexbase.module_warning("harf", + "'get_glyph_string' callback is missing, " .. + "log messages might show garbage.") + end + callback_warning = false +end + local readers = { opentype = fonts.readers.opentype, otf = fonts.readers.otf, @@ -205,7 +216,6 @@ end -- luatexbase does not know how to handle `wrapup_run` callback, teach it. luatexbase.callbacktypes.wrapup_run = 1 -- simple -luatexbase.callbacktypes.get_char_tounicode = 1 -- simple luatexbase.callbacktypes.get_glyph_string = 1 -- simple local base_callback_descriptions = luatexbase.callback_descriptions diff --git a/texmf-dist/tex/generic/harftex/harf-node.lua b/texmf-dist/tex/harftex/base/harf-node.lua index dfdea058..24f66990 100644 --- a/texmf-dist/tex/generic/harftex/harf-node.lua +++ b/texmf-dist/tex/harftex/base/harf-node.lua @@ -101,16 +101,29 @@ local function setprop(n, prop, value) props.harf[prop] = value end --- Copy node properties and attributes. -local function copyprops(src, dst) - local props = getproperty(src) - local attrs = getattrs(src) +-- New kern node of amount `v`, inheriting the properties/attributes of `n`. +local function newkern(v, n) + local kern = newnode(kernid) + local props = getproperty(n) + local attrs = getattrs(n) if props then - setproperty(dst, copytable(props)) + setproperty(kern, copytable(props)) end if attrs then - setattrs(dst, copynodelist(attrs)) + setattrs(kern, copynodelist(attrs)) end + + setkern(kern, v) + return kern +end + +local function insertkern(head, current, kern, rtl) + if rtl then + head = insertbefore(head, current, kern) + else + head, current = insertafter(head, current, kern) + end + return head, current end -- Convert list of integers to UTF-16 hex string used in PDF. @@ -170,8 +183,9 @@ local function itemize(head, direction) elseif id == glueid and getsubtype(n) == spaceskip then code = 0x0020 -- SPACE elseif id == discid - and (getsubtype(n) == explicitdisc - or getsubtype(n) == regulardisc) then + and (getsubtype(n) == explicitdisc -- \- + or getsubtype(n) == regulardisc) -- \discretionary + then code = 0x00AD -- SOFT HYPHEN elseif id == dirid then local dir = getdir(n) @@ -318,13 +332,13 @@ local function chars_in_glyph(i, glyphs, stop) return nchars, nglyphs end --- Check if it is safe to break before this glyph. +-- Check if it is not safe to break before this glyph. local function unsafetobreak(glyph, nodes) return glyph and glyph.flags and glyph.flags & fl_unsafe - -- LuaTeX’s discretionary nodes can’t contain glue, so stop at first glue - -- as well. This is incorrect, but I don’t have a better idea. + -- 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 end @@ -399,7 +413,8 @@ shape = function(run) hbfont:set_scale(hscale, vscale) if hb.shape_full(hbfont, buf, features, shapers) then - -- LuaTeX wants the glyphs in logical order, so reverse RTL buffers. + -- The engine wants the glyphs in logical order, but HarfBuzz outputs them + -- in visual order, so we reverse RTL buffers. if dir:is_backward() then buf:reverse() end local glyphs = buf:get_glyphs() @@ -534,7 +549,7 @@ local function color_to_rgba(color) end -- Cache of color glyph PNG data for bookkeeping, only because I couldn’t --- figure how to make LuaTeX load the image from the binary data directly. +-- figure how to make the engine load the image from the binary data directly. local pngcache = {} local function cachedpng(data) local hash = md5.sumhexa(data) @@ -627,24 +642,36 @@ local function tonodes(head, current, run, glyphs, color) depth = character.depth, } head, current = insertafter(head, current, todirect(image)) + 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, n) + head, current = insertkern(head, current, kern, rtl) + 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(n, 0) + head, current = insertafter(head, current, n) else - if haspng and not fonttype then - -- If this is a color bitmap font with no glyph outlines (like Noto - -- Color Emoji) and we end up here then the glyph is not supported - -- by the font. LuaTeX does not now 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. - setfont(n, 0) - else - local oldcharacter = characters[getchar(n)] - -- If the glyph index of current font chars is the same as shaped - -- glyph, keep the node char unchanged. Helps with primitives that - -- take characters as input but actually work on glyphs, like - -- `\rpcode`. - if not oldcharacter or character.index ~= oldcharacter.index then - setchar(n, char) - end + local oldcharacter = characters[getchar(n)] + -- If the glyph index of current font character is the same as shaped + -- glyph, keep the node char unchanged. Helps with primitives that + -- take characters as input but actually work on glyphs, like + -- `\rpcode`. + if not oldcharacter or character.index ~= oldcharacter.index then + setchar(n, char) end local xoffset = (rtl and -glyph.x_offset or glyph.x_offset) * scale local yoffset = glyph.y_offset * scale @@ -655,21 +682,15 @@ local function tonodes(head, current, run, glyphs, color) local x_advance = glyph.x_advance + letterspace local width = fontglyph.width if width ~= x_advance then - -- LuaTeX always uses the glyph width from the font, so we need to - -- insert a kern node if the x advance is different. - local kern = newnode(kernid) - setkern(kern, (x_advance - width) * scale) - copyprops(n, kern) - if rtl then - head = insertbefore(head, current, kern) - else - head, current = insertafter(head, current, kern) - end + -- 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 - -- HarfTeX 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. + -- 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. @@ -901,20 +922,25 @@ local function run_cleanup() end end -local function get_tounicode(fontid, c) - local fontdata = font.getfont(fontid) - local hbdata = fontdata.hb - if hbdata then - local hbshared = hbdata.shared - local fontglyphs = hbshared.glyphs - local hbfont = hbshared.font - - local gid = c - hb.CH_GID_PREFIX - if c < hb.CH_GID_PREFIX then - gid = hbfont:get_nominal_glyph(c) +local function set_tounicode() + for fontid, fontdata in font.each() do + local hbdata = fontdata.hb + if hbdata and fontid == pdf.getfontname(fontid) then + local characters = fontdata.characters + local newcharacters = {} + local glyphs = hbdata.shared.glyphs + for gid = 0, #glyphs do + local glyph = glyphs[gid] + local tounicode = glyph.tounicode + if tounicode then + local character = characters[gid + hb.CH_GID_PREFIX] + newcharacters[gid + hb.CH_GID_PREFIX] = character + character.tounicode = tounicode + character.used = true + end + end + font.addcharacters(fontid, { characters = newcharacters }) end - - return fontglyphs[gid].tounicode end end @@ -929,6 +955,6 @@ return { process = process_nodes, post_process = post_process_nodes, cleanup = run_cleanup, - get_tounicode = get_tounicode, + set_tounicode = set_tounicode, get_glyph_string = get_glyph_string, } diff --git a/texmf-dist/tex/generic/harftex/harf-plain.lua b/texmf-dist/tex/harftex/base/harf-plain.lua index a79a174c..a79a174c 100644 --- a/texmf-dist/tex/generic/harftex/harf-plain.lua +++ b/texmf-dist/tex/harftex/base/harf-plain.lua diff --git a/texmf-dist/tex/generic/harftex/harf.lua b/texmf-dist/tex/harftex/base/harf.lua index 08d57d64..082a5130 100644 --- a/texmf-dist/tex/generic/harftex/harf.lua +++ b/texmf-dist/tex/harftex/base/harf.lua @@ -9,7 +9,7 @@ harf.callbacks = { hpack_filter = harf_node.process, pre_output_filter = harf_node.post_process, wrapup_run = harf_node.cleanup, - get_char_tounicode = harf_node.get_tounicode, + finish_pdffile = harf_node.set_tounicode, get_glyph_string = harf_node.get_glyph_string, } diff --git a/texmf-dist/tex/generic/harftex/harfload.sty b/texmf-dist/tex/harftex/base/harfload.sty index 9675b10d..23674b8c 100644 --- a/texmf-dist/tex/generic/harftex/harfload.sty +++ b/texmf-dist/tex/harftex/base/harfload.sty @@ -2,7 +2,7 @@ \let\ifharfloadloaded\endinput \ifdefined\ProvidesPackage \RequirePackage{luaotfload} - \ProvidesPackage{harfload}[2019/06/30 v0.3.1 Unicode text layout system] + \ProvidesPackage{harfload}[2019/08/10 v0.4.0 Unicode text layout system] \else \input luaotfload.sty \fi |