diff options
author | Norbert Preining <norbert@preining.info> | 2020-05-03 03:02:51 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2020-05-03 03:02:51 +0000 |
commit | d78de17ddf0443233483fd98f40802cae5aa87c5 (patch) | |
tree | 1b7128cc505808a09c18e158288d6c3cdcf5c2fb /macros/luatex/generic/luaotfload/luaotfload-harf-define.lua | |
parent | 8626a9c3cb5dc8d02d779d5b5b1e3933d5626f43 (diff) |
CTAN sync 202005030302
Diffstat (limited to 'macros/luatex/generic/luaotfload/luaotfload-harf-define.lua')
-rw-r--r-- | macros/luatex/generic/luaotfload/luaotfload-harf-define.lua | 147 |
1 files changed, 64 insertions, 83 deletions
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua index 555180435a..80895d0f4f 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua @@ -5,8 +5,8 @@ do -- block to avoid to many local variables error local ProvidesLuaModule = { name = "luaotfload-harf-define", - version = "3.12", --TAGVERSION - date = "2020-02-02", --TAGDATE + version = "3.13", --TAGVERSION + date = "2020-05-01", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Marcel Krüger", @@ -18,6 +18,7 @@ do -- block to avoid to many local variables error end end +local unpack = string.unpack local stringlower = string.lower local stringupper = string.upper local gsub = string.gsub @@ -25,6 +26,11 @@ local gsub = string.gsub local hb = luaotfload.harfbuzz local scriptlang_to_harfbuzz = require'luaotfload-scripts'.to_harfbuzz +local harf_settings = luaotfload.harf or {} +luaotfload.harf = harf_settings + +harf_settings.default_buf_flags = hb.Buffer.FLAGS_DEFAULT or 0 + local hbfonts = {} local cfftag = hb.Tag.new("CFF ") @@ -32,12 +38,44 @@ local cff2tag = hb.Tag.new("CFF2") local os2tag = hb.Tag.new("OS/2") local posttag = hb.Tag.new("post") local glyftag = hb.Tag.new("glyf") +local gpostag = hb.Tag.new("GPOS") local invalid_l = hb.Language.new() local invalid_s = hb.Script.new() +local floor = math.floor +local function round(x) + return floor(x + 0.5) +end + +local get_designsize do + -- local lpeg = lpeg or require'lpeg' + -- local size_patt = 'size' * lpeg.C(2)/function(s) + -- local first, second = string.byte(s) + -- return (first << 8) | second + -- end + local factor = 6578.176 -- =803/125*2^10=7227/7200/10*2^16 + function get_designsize(face) + local buf = face:get_table(gpostag):get_data() + if #buf == 0 then return 655360 end + local major, feature_off = unpack(">HxxxxH", buf) + assert(major == 1, "Unsupported major version of GPOS table") + local feature_count = unpack(">H", buf, feature_off + 1) + for off = feature_off + 3, feature_off + 6*feature_count, 6 do + local tag = buf:sub(off, off + 3) + if tag == 'size' then + local off = feature_off + 1 + unpack(">H", buf, off + 4) + local off = off + unpack(">H", buf, off) + local design_size = unpack(">H", buf, off) -- unpack(">HHHHH", buf, off)) + return round(design_size * factor) + end + end + return 655360 + end +end + local containers = luaotfload.fontloader.containers -local hbcacheversion = 1.0 +local hbcacheversion = 1.1 local facecache = containers.define("fonts", "hb", hbcacheversion, true) local function loadfont(spec) @@ -92,8 +130,8 @@ local function loadfont(spec) local post = hbface:get_table(posttag) local length = post:get_length() local data = post:get_data() - if length >= 32 and string.unpack(">i4", data) <= 0x00030000 then - local italicangle = string.unpack(">i4", data, 5) / 2^16 + if length >= 32 and unpack(">i4", data) <= 0x00030000 then + local italicangle = unpack(">i4", data, 5) / 2^16 if italicangle ~= 0 then slant = -math.tan(italicangle * math.pi / 180) * 65536.0 end @@ -111,6 +149,7 @@ local function loadfont(spec) -- too slow. local glyphcount = hbface:get_glyph_count() local glyphs = {} + local autoitalic = slant ~= 0 and 20 or nil -- the magic 20 is taken from ConTeXt where it came from Dohyun Kim. We keep it to be metric compatible as far as possible for gid = 0, glyphcount - 1 do local width = hbfont:get_glyph_h_advance(gid) local height, depth, italic = nil, nil, nil @@ -118,8 +157,9 @@ local function loadfont(spec) if extents then height = extents.y_bearing depth = extents.y_bearing + extents.height - if extents.x_bearing < 0 then - italic = -extents.x_bearing + local right_bearing = extents.x_bearing + extents.width - width + if autoitalic and right_bearing > -autoitalic then + italic = right_bearing + autoitalic end end glyphs[gid] = { @@ -146,10 +186,10 @@ local function loadfont(spec) local os2 = hbface:get_table(os2tag) local length = os2:get_length() local data = os2:get_data() - if length >= 96 and string.unpack(">H", data) > 1 then + if length >= 96 and unpack(">H", data) > 1 then -- We don’t need much of the table, so we read from hard-coded offsets. - xheight = string.unpack(">H", data, 87) - capheight = string.unpack(">H", data, 89) + xheight = unpack(">H", data, 87) + capheight = unpack(">H", data, 89) end end @@ -174,6 +214,7 @@ local function loadfont(spec) cached = { date = date, size = size, + designsize = get_designsize(hbface), gid_offset = 0x120000, upem = upem, fonttype = fonttype, @@ -214,20 +255,6 @@ local function sanitize(psname) return psname:gsub('[][\0-\32\127-\255(){}<>/%%]', '-') end --- 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 } }, -- [>>] -} - local function scalefont(data, spec) if not data then return data, spec end local size = spec.size @@ -241,7 +268,7 @@ local function scalefont(data, spec) local gid_offset = data.gid_offset if size < 0 then - size = -655.36 * size + size = round(size * data.designsize / -1000) end -- We shape in font units (at UPEM) and then scale output with the desired @@ -280,57 +307,11 @@ local function scalefont(data, spec) end end - local letterspace = 0 - if features.letterspace then - letterspace = tonumber(features.letterspace) / 100 * upem - elseif features.kernfactor then - letterspace = tonumber(features.kernfactor) * upem - end - space = space + letterspace - - local slantfactor = nil - if features.slant then - slantfactor = tonumber(features.slant) * 1000 - end - - local mode = nil - local width = nil - if features.embolden then - mode = 2 - -- The multiplication by 7200.0/7227 is to undo the opposite conversion - -- the engine is doing and make the final number written in the PDF file - -- match XeTeX’s. - width = (size * tonumber(features.embolden) / 6553.6) * (7200.0/7227) - end - - local hscale = upem - local extendfactor = nil - if features.extend then - extendfactor = tonumber(features.extend) * 1000 - hscale = hscale * tonumber(features.extend) - end - - local vscale = upem - local squeezefactor = nil - if features.squeeze then - squeezefactor = tonumber(features.squeeze) * 1000 - vscale = vscale * tonumber(features.squeeze) - end - - if features.tlig then - for char in next, characters do - local ligatures = tlig[char] - if ligatures then - characters[char].ligatures = ligatures - end - end - end - local tfmdata = { name = spec.specification, filename = 'harfloaded:' .. spec.resolved, subfont = spec.sub or 1, - designsize = size, + designsize = data.designsize, psname = sanitize(data.psname), fullname = data.fullname, index = spec.index, @@ -340,10 +321,6 @@ local function scalefont(data, spec) tounicode = 1, nomath = true, format = data.fonttype, - slant = slantfactor, - mode = mode, - width = width, - extend = extendfactor, squeeze = squeezefactor, characters = characters, parameters = { @@ -358,15 +335,16 @@ local function scalefont(data, spec) }, hb = { scale = scale, - spec = spec, palette = palette, shared = data, - letterspace = letterspace, - hscale = hscale, - vscale = vscale, + hscale = upem, + vscale = upem, + buf_flags = harf_settings.default_buf_flags, }, specification = spec, - shared = {}, + shared = { + features = features, + }, properties = {}, resources = { unicodes = data.name_to_char, @@ -421,10 +399,13 @@ fonts.readers.harf = function(spec) return scalefont(loadfont(spec), spec) end +local find_file = kpse.find_file luatexbase.add_to_callback('find_opentype_file', function(name) - return name:gsub('^harfloaded:', '') + return find_file(name, 'opentype fonts') + or name:gsub('^harfloaded:', '') end, 'luaotfload.harf.strip_prefix') luatexbase.add_to_callback('find_truetype_file', function(name) - return name:gsub('^harfloaded:', '') + return find_file(name, 'truetype fonts') + or name:gsub('^harfloaded:', '') end, 'luaotfload.harf.strip_prefix') |