summaryrefslogtreecommitdiff
path: root/texmf-dist/tex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-24 09:16:53 +0900
committerNorbert Preining <norbert@preining.info>2019-09-24 09:16:53 +0900
commit844efbe3820e6c5b5a61c8a40abd5da1e91e6349 (patch)
tree1e387fa7bbf46d0ed985d8b2b68124d2e664787f /texmf-dist/tex
parente0ad882887b423e68512065b625c57995b312ec0 (diff)
harf 1.0.0
Diffstat (limited to 'texmf-dist/tex')
-rw-r--r--texmf-dist/tex/harftex/base/harf-base.lua9
-rw-r--r--texmf-dist/tex/harftex/base/harf-load.lua122
-rw-r--r--texmf-dist/tex/harftex/base/harf-luaotfload.lua66
-rw-r--r--texmf-dist/tex/harftex/base/harf-node.lua48
-rw-r--r--texmf-dist/tex/harftex/base/harf.lua9
-rw-r--r--texmf-dist/tex/harftex/base/harfload.sty2
6 files changed, 102 insertions, 154 deletions
diff --git a/texmf-dist/tex/harftex/base/harf-base.lua b/texmf-dist/tex/harftex/base/harf-base.lua
index e0d2299c..21f46d75 100644
--- a/texmf-dist/tex/harftex/base/harf-base.lua
+++ b/texmf-dist/tex/harftex/base/harf-base.lua
@@ -1,3 +1,12 @@
+local module = {
+ name = "harf-base",
+ description = "Harf base/shared code",
+ version = "0.4.2",
+ date = "2019-09-07",
+ license = "GPL v2.0"
+}
+luatexbase.provides_module(module)
+
local hb = require("luaharfbuzz")
-- The engine’s TFM structure indexes glyphs by character codes, which means
diff --git a/texmf-dist/tex/harftex/base/harf-load.lua b/texmf-dist/tex/harftex/base/harf-load.lua
index 0543c94c..8367ced0 100644
--- a/texmf-dist/tex/harftex/base/harf-load.lua
+++ b/texmf-dist/tex/harftex/base/harf-load.lua
@@ -1,3 +1,12 @@
+local module = {
+ name = "harf-load",
+ description = "Harf font loading",
+ version = "0.4.2",
+ date = "2019-09-07",
+ license = "GPL v2.0"
+}
+luatexbase.provides_module(module)
+
local hb = require("harf-base")
local hbfonts = hb.fonts
@@ -9,73 +18,20 @@ local os2tag = hb.Tag.new("OS/2")
local posttag = hb.Tag.new("post")
local glyftag = hb.Tag.new("glyf")
-local function trim(str)
- return str:gsub("^%s*(.-)%s*$", "%1")
-end
-
-local function split(str, sep)
- if str then
- local result = string.explode(str, sep.."+")
- for i, s in next, result do
- result[i] = trim(result[i])
- end
- return result
- end
-end
-
-local function parse(str, size)
- local name, options = str:match("%s*(.*)%s*:%s*(.*)%s*")
- local spec = {
- specification = str,
- size = size,
- variants = {}, features = {}, options = {},
- }
-
- name = trim(name or str)
-
- local filename = name:match("%[(.*)%]")
- if filename then
- -- [file]
- -- [file:index]
- filename = string.explode(filename, ":+")
- spec.file = filename[1]
- spec.index = tonumber(filename[2]) or 0
- else
- -- name
- -- name/variants
- local fontname, variants = name:match("(.-)%s*/%s*(.*)")
- spec.name = fontname or name
- spec.variants = split(variants, "/")
- end
- if options then
- options = split(options, ";+")
- for _, opt in next, options do
- if opt:find("[+-]") == 1 then
- local feature = hb.Feature.new(opt)
- spec.features[#spec.features + 1] = feature
- elseif opt ~= "" then
- local key, val = opt:match("(.*)%s*=%s*(.*)")
- if key == "language" then val = hb.Language.new(val) end
- spec.options[key or opt] = val or true
- end
- end
- end
- return spec
-end
-
local function loadfont(spec)
- local path, index = spec.path, spec.index
+ local path = spec.resolved or spec.name
if not path then
return nil
end
+ local index = spec.sub and spec.sub or 1
local key = string.format("%s:%d", path, index)
local data = hbfonts[key]
if data then
return data
end
- local hbface = hb.Face.new(path, index)
+ local hbface = hb.Face.new(path, index - 1)
local tags = hbface and hbface:get_table_tags()
-- If the face has no table tags then it isn’t a valid SFNT font that
-- HarfBuzz can handle.
@@ -237,7 +193,6 @@ 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
@@ -247,6 +202,32 @@ local function scalefont(data, spec)
size = -655.36 * size
end
+ -- Extract features (that we pass to HarfBuzz) from the rest of the options.
+ -- Mostly a heuristic.
+ local features = {}
+ local options = {}
+ local rawfeatures = spec.features and spec.features.raw or {}
+ for key, val in next, rawfeatures do
+ if key == "language" then val = hb.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.
+ if val == true or val == false then
+ val = (val and '+' or '-')..key
+ features[#features + 1] = hb.Feature.new(val)
+ elseif tonumber(val) then
+ val = '+'..key..'='..tonumber(val) - 1
+ features[#features + 1] = hb.Feature.new(val)
+ else
+ options[key] = val
+ end
+ else
+ options[key] = val
+ end
+ end
+
-- We shape in font units (at UPEM) and then scale output with the desired
-- sfont size.
local scale = size / upem
@@ -331,11 +312,11 @@ local function scalefont(data, spec)
return {
name = spec.specification,
- filename = spec.path,
+ filename = spec.resolved or spec.name,
designsize = size,
psname = sanitize(data.psname),
fullname = data.fullname,
- index = spec.index,
+ index = (spec.sub and spec.sub or 1) - 1,
size = size,
units_per_em = upem,
type = "real",
@@ -361,7 +342,8 @@ local function scalefont(data, spec)
},
hb = {
scale = scale,
- spec = spec,
+ features = features,
+ options = options,
palette = palette,
shared = data,
letterspace = letterspace,
@@ -371,25 +353,9 @@ local function scalefont(data, spec)
}
end
-local function define_font(name, size)
- local spec = type(name) == "string" and parse(name, size) or name
- if spec.file then
- spec.path = kpse.find_file(spec.file, "truetype fonts") or
- kpse.find_file(spec.file, "opentype fonts")
- else
- -- XXX support font names
- end
-
- if spec.specification == "" then return nil end
-
- local tfmdata = nil
+local function define_font(spec, size)
local hbdata = loadfont(spec)
- if hbdata then
- tfmdata = scalefont(hbdata, spec)
- else
- tfmdata = font.read_tfm(spec.specification, spec.size)
- end
- return tfmdata
+ return hbdata and scalefont(hbdata, spec)
end
return define_font
diff --git a/texmf-dist/tex/harftex/base/harf-luaotfload.lua b/texmf-dist/tex/harftex/base/harf-luaotfload.lua
index 8a373275..10099c68 100644
--- a/texmf-dist/tex/harftex/base/harf-luaotfload.lua
+++ b/texmf-dist/tex/harftex/base/harf-luaotfload.lua
@@ -1,26 +1,19 @@
+local module = {
+ name = "harf-luaotfload",
+ description = "Harf luaotfload integration",
+ version = "0.4.2",
+ date = "2019-09-07",
+ license = "GPL v2.0"
+}
+luatexbase.provides_module(module)
+
if not pcall(require, "luaharfbuzz") then
luatexbase.module_error("harf", "'luaharfbuzz' module is required.")
end
local harf = require("harf")
-local define_font = harf.callbacks.define_font
-
--- Change luaotfload’s default of preferring system fonts.
-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 define_font = harf.callbacks.define_font
local readers = {
opentype = fonts.readers.opentype,
@@ -30,46 +23,13 @@ local readers = {
}
local function harf_reader(spec)
- local features = {}
- local options = {}
- local rawfeatures = spec.features and spec.features.raw or {}
-
- local mode = rawfeatures.mode
+ local features = spec.features and spec.features.raw
+ local mode = features and features.mode
if mode and mode ~= "harf" then
return readers[spec.forced](spec)
end
- -- Rewrite luaotfload specification to look like what we expect.
- local specification = {
- features = features,
- options = options,
- path = spec.resolved or spec.name,
- index = spec.sub and spec.sub - 1 or 0,
- size = spec.size,
- specification = spec.specification,
- }
-
- 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.
- if val == true or val == false then
- val = (val and '+' or '-')..key
- features[#features + 1] = harf.Feature.new(val)
- elseif tonumber(val) then
- val = '+'..key..'='..tonumber(val) - 1
- features[#features + 1] = harf.Feature.new(val)
- else
- options[key] = val
- end
- else
- options[key] = val
- end
- end
- return define_font(specification)
+ return define_font(spec)
end
-- Register font readers. We override the default ones to always use HarfBuzz
diff --git a/texmf-dist/tex/harftex/base/harf-node.lua b/texmf-dist/tex/harftex/base/harf-node.lua
index 33fce8e2..466db2ac 100644
--- a/texmf-dist/tex/harftex/base/harf-node.lua
+++ b/texmf-dist/tex/harftex/base/harf-node.lua
@@ -1,3 +1,12 @@
+local module = {
+ name = "harf-node",
+ description = "Harf text shaping",
+ version = "0.4.2",
+ date = "2019-09-07",
+ license = "GPL v2.0"
+}
+luatexbase.provides_module(module)
+
local hb = require("harf-base")
local assert = assert
@@ -72,12 +81,11 @@ local whatsit_t = node.id("whatsit")
local pdfliteral_t = node.subtype("pdf_literal")
local pdfcolorstack_t = node.subtype("pdf_colorstack")
-local spaceskip = 13
-local directmode = 2
-local fontkern = 0
-local italiccorrection = 3
-local explicitdisc = 1
-local regulardisc = 3
+local explicitdisc_t = 1
+local fontkern_t = 0
+local italiccorr_t = 3
+local regulardisc_t = 3
+local spaceskip_t = 13
local getscript = hb.unicode.script
@@ -197,11 +205,11 @@ local function itemize(head, direction)
code = getchar(n)
script = getscript(code)
end
- elseif id == glue_t and getsubtype(n) == spaceskip then
+ elseif id == glue_t and getsubtype(n) == spaceskip_t then
code = 0x0020 -- SPACE
elseif id == disc_t
- and (getsubtype(n) == explicitdisc -- \-
- or getsubtype(n) == regulardisc) -- \discretionary
+ and (getsubtype(n) == explicitdisc_t -- \-
+ or getsubtype(n) == regulardisc_t) -- \discretionary
then
code = 0x00AD -- SOFT HYPHEN
elseif id == dir_t then
@@ -221,8 +229,7 @@ local function itemize(head, direction)
local fontdata = currfontid and font.getfont(currfontid)
local hbdata = fontdata and fontdata.hb
- local spec = hbdata and hbdata.spec
- local options = spec and spec.options
+ local options = hbdata and hbdata.options
local texlig = options and options.texlig
if texlig then
local replacement = trep[code]
@@ -255,9 +262,7 @@ local function itemize(head, direction)
-- If script is not resolved yet, and the font has a "script" option, use
-- it.
if (script == common_s or script == inherited_s) and hbdata then
- local spec = hbdata.spec
- local features = spec.features
- local options = spec.options
+ local options = hbdata.options
script = options.script and hb.Script.new(options.script) or script
end
@@ -407,10 +412,9 @@ shape = function(run)
local fontdata = font.getfont(fontid)
local hbdata = fontdata.hb
+ local features = hbdata.features
+ local options = hbdata.options
local palette = hbdata.palette
- local spec = hbdata.spec
- local features = spec.features
- local options = spec.options
local hbshared = hbdata.shared
local hbfont = hbshared.font
local hbface = hbshared.face
@@ -737,7 +741,7 @@ local function tonodes(head, current, run, glyphs, color)
setprop(n, endactual_p, true)
end
end
- elseif id == glue_t and getsubtype(n) == spaceskip then
+ elseif id == glue_t and getsubtype(n) == spaceskip_t then
-- If the glyph advance is different from the font space, then a
-- substitution or positioning was applied to the space glyph changing
-- it from the default, so reset the glue using the new advance.
@@ -750,7 +754,7 @@ local function tonodes(head, current, run, glyphs, color)
setfield(n, "shrink", width / 3)
end
head, current = insertafter(head, current, n)
- elseif id == kern_t and getsubtype(n) == italiccorrection then
+ elseif id == kern_t and getsubtype(n) == italiccorr_t then
-- If this is an italic correction node and the previous node is a
-- glyph, update its kern value with the glyph’s italic correction.
-- I’d have expected the engine to do this, but apparently it doesn’t.
@@ -776,7 +780,7 @@ local function tonodes(head, current, run, glyphs, color)
-- the other discretionary handling, otherwise the discretionary
-- contents do not interact with the surrounding (e.g. no ligatures or
-- kerning) as it should.
- if current and getid(current) == kern_t and getsubtype(current) == fontkern then
+ if current and getid(current) == kern_t and getsubtype(current) == fontkern_t then
setprev(current, nil)
setnext(current, nil)
setfield(n, "replace", current)
@@ -829,7 +833,7 @@ local function shape_run(head, current, run)
-- shaping.
local fontid = run.font
local fontdata = font.getfont(fontid)
- local options = fontdata.hb.spec.options
+ local options = fontdata.hb.options
local color = options and options.color and hex_to_rgba(options.color)
local glyphs = shape(run)
@@ -880,7 +884,7 @@ end
local function pdfdirect(data)
local n = newnode(whatsit_t, pdfliteral_t)
- setfield(n, "mode", directmode)
+ setfield(n, "mode", 2) -- direct
setdata(n, data)
return n
end
diff --git a/texmf-dist/tex/harftex/base/harf.lua b/texmf-dist/tex/harftex/base/harf.lua
index 082a5130..500cca00 100644
--- a/texmf-dist/tex/harftex/base/harf.lua
+++ b/texmf-dist/tex/harftex/base/harf.lua
@@ -1,3 +1,12 @@
+local module = {
+ name = "harf",
+ description = "Harf",
+ version = "0.4.2",
+ date = "2019-09-07",
+ license = "GPL v2.0"
+}
+luatexbase.provides_module(module)
+
local harf = require("harf-base")
local define_font = require("harf-load")
diff --git a/texmf-dist/tex/harftex/base/harfload.sty b/texmf-dist/tex/harftex/base/harfload.sty
index 32e23400..da30889d 100644
--- a/texmf-dist/tex/harftex/base/harfload.sty
+++ b/texmf-dist/tex/harftex/base/harfload.sty
@@ -2,7 +2,7 @@
\let\ifharfloadloaded\endinput
\ifdefined\ProvidesPackage
\RequirePackage{luaotfload}
- \ProvidesPackage{harfload}[2019/09/07 v0.4.2 Unicode text layout system]
+ \ProvidesPackage{harfload}[2019/09/21 v1.0.0 Unicode text layout system]
\else
\input luaotfload.sty
\fi