summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-05-03 03:02:51 +0000
committerNorbert Preining <norbert@preining.info>2020-05-03 03:02:51 +0000
commitd78de17ddf0443233483fd98f40802cae5aa87c5 (patch)
tree1b7128cc505808a09c18e158288d6c3cdcf5c2fb /macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
parent8626a9c3cb5dc8d02d779d5b5b1e3933d5626f43 (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.lua147
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')