From d71e668b76f31ca580a89b747717a7440aec99a5 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 25 Jun 2019 12:22:32 +0900 Subject: harftex binary and support file updates --- texmf-dist/tex/generic/harftex/harf-base.lua | 28 ++++++++ texmf-dist/tex/generic/harftex/harf-load.lua | 75 +++++++++++++++++++++- texmf-dist/tex/generic/harftex/harf-luaotfload.lua | 1 + texmf-dist/tex/generic/harftex/harf-node.lua | 24 ++++++- texmf-dist/tex/generic/harftex/harfload.sty | 9 +-- 5 files changed, 125 insertions(+), 12 deletions(-) (limited to 'texmf-dist') diff --git a/texmf-dist/tex/generic/harftex/harf-base.lua b/texmf-dist/tex/generic/harftex/harf-base.lua index 4b5931fd..37970b29 100644 --- a/texmf-dist/tex/generic/harftex/harf-base.lua +++ b/texmf-dist/tex/generic/harftex/harf-base.lua @@ -9,4 +9,32 @@ local hb = require("luaharfbuzz") -- escaping raw bytes, so skip that as well. hb.CH_GID_PREFIX = 0x110000 + 256 + +-- Legacy TeX Input Method Disguised as Font Ligatures hack. +-- +-- Single replacements, keyed by character to replace. Handled separately +-- because TeX ligaturing mechanism does not support one-to-one replacements. +local trep = { + [0x0022] = 0x201D, -- ["] + [0x0027] = 0x2019, -- ['] + [0x0060] = 0x2018, -- [`] +} + +-- Ligatures. The value is a character "ligature" table as described in the +-- manual. +local tlig ={ + [0x2013] = { [0x002D] = { char = 0x2014 } }, -- [---] + [0x002D] = { [0x002D] = { char = 0x2013 } }, -- [--] + [0x0060] = { [0x0060] = { char = 0x201C } }, -- [``] + [0x0027] = { [0x0027] = { char = 0x201D } }, -- [''] + [0x0021] = { [0x0060] = { char = 0x00A1 } }, -- [!`] + [0x003F] = { [0x0060] = { char = 0x00BF } }, -- [?`] + [0x002C] = { [0x002C] = { char = 0x201E } }, -- [,,] + [0x003C] = { [0x003C] = { char = 0x00AB } }, -- [<<] + [0x003E] = { [0x003E] = { char = 0x00BB } }, -- [>>] +} + +hb.texrep = trep +hb.texlig = tlig + return hb diff --git a/texmf-dist/tex/generic/harftex/harf-load.lua b/texmf-dist/tex/generic/harftex/harf-load.lua index c467cedd..06af2706 100644 --- a/texmf-dist/tex/generic/harftex/harf-load.lua +++ b/texmf-dist/tex/generic/harftex/harf-load.lua @@ -205,6 +205,32 @@ local function loadfont(spec) end end +-- Drop illegal characters from PS Name, per the spec +-- https://docs.microsoft.com/en-us/typography/opentype/spec/name#nid6 +local function sanitize(psname) + local new = psname:gsub(".", function(c) + local b = c:byte() + if (b < 33 or b > 126) + or c == "[" + or c == "]" + or c == "(" + or c == ")" + or c == "{" + or c == "}" + or c == "<" + or c == ">" + or c == "/" + or c == "%" + then + return "-" + end + return c + end) + return new +end + +local tlig = hb.texlig + local function scalefont(data, spec) local size = spec.size local options = spec.options @@ -248,22 +274,63 @@ local function scalefont(data, spec) local letterspace = tonumber(options.letterspace or 0) / 100 * upem space = space + letterspace - local slantfactor = tonumber(options.slant or 0) + local slantfactor = nil + if options.slant then + slantfactor = tonumber(options.slant) * 1000 + end + + local mode = nil + local width = nil + 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. + width = (size * tonumber(options.embolden) / 6553.6) * (7200.0/7227) + end + + local hscale = upem + local extendfactor = nil + if options.extend then + extendfactor = tonumber(options.extend) * 1000 + hscale = hscale * tonumber(options.extend) + end + + local vscale = upem + local squeezefactor = nil + if options.squeeze then + squeezefactor = tonumber(options.squeeze) * 1000 + vscale = vscale * tonumber(options.squeeze) + end + + if options.texlig then + for char in next, characters do + local ligatures = tlig[char] + if ligatures then + characters[char].ligatures = ligatures + end + end + end return { name = spec.specification, filename = spec.path, designsize = size, - psname = data.psname, + psname = sanitize(data.psname), fullname = data.fullname, index = spec.index, size = size, + units_per_em = upem, type = "real", embedding = "subset", tounicode = 1, nomath = true, format = data.fonttype, - slant = slantfactor * 1000, + slant = slantfactor, + mode = mode, + width = width, + extend = extendfactor, + squeeze = squeezefactor, characters = characters, parameters = { slant = data.slant, @@ -281,6 +348,8 @@ local function scalefont(data, spec) palette = palette, shared = data, letterspace = letterspace, + hscale = hscale, + vscale = vscale, }, } end diff --git a/texmf-dist/tex/generic/harftex/harf-luaotfload.lua b/texmf-dist/tex/generic/harftex/harf-luaotfload.lua index 45a007f5..fbe3181b 100644 --- a/texmf-dist/tex/generic/harftex/harf-luaotfload.lua +++ b/texmf-dist/tex/generic/harftex/harf-luaotfload.lua @@ -41,6 +41,7 @@ local function harf_reader(spec) for key, val in next, rawfeatures do if key == "language" then val = harf.Language.new(val) end if key == "colr" then key = "palette" end + if key == "tlig" then key = "texlig" end if key:len() == 4 then -- 4-letter options are likely font features, but not always, so we do -- some checks below. We put non feature options in the `options` dict. diff --git a/texmf-dist/tex/generic/harftex/harf-node.lua b/texmf-dist/tex/generic/harftex/harf-node.lua index fb4bfabe..dfdea058 100644 --- a/texmf-dist/tex/generic/harftex/harf-node.lua +++ b/texmf-dist/tex/generic/harftex/harf-node.lua @@ -60,6 +60,8 @@ local spaceskip = 13 local directmode = 2 local fontkern = 0 local italiccorrection = 3 +local explicitdisc = 1 +local regulardisc = 3 local getscript = hb.unicode.script local sc_common = hb.Script.new("Zyyy") @@ -141,6 +143,8 @@ local paired_close = { 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. @@ -165,7 +169,9 @@ local function itemize(head, direction) end elseif id == glueid and getsubtype(n) == spaceskip then code = 0x0020 -- SPACE - elseif id == discid then + elseif id == discid + and (getsubtype(n) == explicitdisc + or getsubtype(n) == regulardisc) then code = 0x00AD -- SOFT HYPHEN elseif id == dirid then local dir = getdir(n) @@ -183,7 +189,17 @@ local function itemize(head, direction) end local fontdata = currfontid and font.getfont(currfontid) - local hbdata = fontdata and fontdata.hb + local hbdata = fontdata and fontdata.hb + local spec = hbdata and hbdata.spec + local options = spec and spec.options + local texlig = options and options.texlig + if 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 @@ -378,6 +394,10 @@ shape = function(run) buf:set_cluster_level(buf.CLUSTER_LEVEL_MONOTONE_CHARACTERS) buf:add_codepoints(codes, offset - 1, len) + local hscale = hbdata.hscale + local vscale = hbdata.vscale + 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. if dir:is_backward() then buf:reverse() end diff --git a/texmf-dist/tex/generic/harftex/harfload.sty b/texmf-dist/tex/generic/harftex/harfload.sty index ae85ab31..4f8cf4df 100644 --- a/texmf-dist/tex/generic/harftex/harfload.sty +++ b/texmf-dist/tex/generic/harftex/harfload.sty @@ -2,13 +2,8 @@ \let\ifharfloadloaded\endinput \ifdefined\ProvidesPackage \RequirePackage{luaotfload} - \ProvidesPackage{harfload}[2019/04/26 v0.1.0 Unicode text layout system] + \ProvidesPackage{harfload}[2019/06/24 v0.3.0 Unicode text layout system] \else \input luaotfload.sty \fi -\directlua{ - if not xpcall(function() require('harf-luaotfload.lua') end, - texio.write_nl) then - texio.write_nl('Error in harfload - loading aborted') - end -} +\directlua{require('harf-luaotfload')} -- cgit v1.2.3