summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luatexja/src/ltj-jfont.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-09-20 03:03:26 +0000
committerNorbert Preining <norbert@preining.info>2020-09-20 03:03:26 +0000
commit1f457376b478257b88d4a857f5ec1b6155442dd7 (patch)
tree2a06a60551dea362cf8cb0cb0ba66c78608717c4 /macros/luatex/generic/luatexja/src/ltj-jfont.lua
parentac690ca29ad5bf8a5203a65fd6252f7b564f4727 (diff)
CTAN sync 202009200303
Diffstat (limited to 'macros/luatex/generic/luatexja/src/ltj-jfont.lua')
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-jfont.lua144
1 files changed, 91 insertions, 53 deletions
diff --git a/macros/luatex/generic/luatexja/src/ltj-jfont.lua b/macros/luatex/generic/luatexja/src/ltj-jfont.lua
index d1751af465..d95b34a511 100644
--- a/macros/luatex/generic/luatexja/src/ltj-jfont.lua
+++ b/macros/luatex/generic/luatexja/src/ltj-jfont.lua
@@ -3,7 +3,7 @@
--
luatexbase.provides_module({
name = 'luatexja.jfont',
- date = '2020-07-30',
+ date = '2020-09-16',
description = 'Loader for Japanese fonts',
})
@@ -42,7 +42,7 @@ local font_metric_table = ltju.font_metric_table -- [font number] -> jfm_name, j
luatexbase.create_callback("luatexja.load_jfm", "data", function (ft, jn) return ft end)
-local jfm_file_name, jfm_var, jfm_ksp
+local jfm_spec, jfm_name, jfm_var, jfm_ksp
local defjfm_res
local jfm_dir, is_def_jfont, vert_activated, auto_enable_vrt2
@@ -177,7 +177,7 @@ function luatexja.jfont.define_jfm(to)
t.chars.nox_alchar = t.chars.jcharbdd
t.chars.glue = t.chars.jcharbdd
end
- t = luatexbase.call_callback("luatexja.load_jfm", t, jfm_file_name)
+ t = luatexbase.call_callback("luatexja.load_jfm", t, jfm_spec, luatexja.jfont.jfm_feature)
t.size_cache = {}
defjfm_res = t
end
@@ -279,25 +279,21 @@ end
-- LOADING JAPANESE FONTS
------------------------------------------------------------------------
-local load_jfont_metric
+local load_jfont_metric, check_callback_order
do
local cstemp
local global_flag -- true if \globaljfont, false if \jfont
load_jfont_metric = function()
- if jfm_file_name=='' then
- ltjb.package_error('luatexja',
- 'no JFM specified',
+ if jfm_name=='' then
+ ltjb.package_error('luatexja', 'no JFM specified',
'To load and define a Japanese font, a JFM must be specified.'..
"The JFM 'ujis' will be used for now.")
- jfm_file_name = 'ujis'
+ jfm_name, jfm_spec = 'ujis', 'ujis'
end
- for j,v in ipairs(metrics) do
- if v.name==jfm_file_name then return j end
- end
- luatexja.load_lua('jfm-' .. jfm_file_name .. '.lua')
+ for j,v in ipairs(metrics) do if v.name==jfm_spec then return j end end
+ luatexja.load_lua('jfm-' .. jfm_name .. '.lua')
if defjfm_res then
- defjfm_res.name = jfm_file_name
- table.insert(metrics, defjfm_res)
+ defjfm_res.name = jfm_spec; table.insert(metrics, defjfm_res)
return #metrics
else
return nil
@@ -323,8 +319,7 @@ do
local fn = font.id(cstemp)
local f = font_getfont(fn)
if not j then
- ltjb.package_error('luatexja',
- "bad JFM `" .. jfm_file_name .. "'",
+ ltjb.package_error('luatexja', "bad JFM `" .. jfm_name .. "'",
'The JFM file you specified is not valid JFM file.\n'..
'So defining Japanese font is cancelled.')
tex.sprint(cat_lp, global_flag, '\\expandafter\\let\\csname ',
@@ -333,7 +328,7 @@ do
return
end
if not f then return end
- update_jfm_cache(j, f.size)
+ update_jfm_cache(j, f.size); check_callback_order()
local sz = metrics[j].size_cache[f.size]
local fmtable = { jfm = j, size = f.size, var = jfm_var,
with_kanjiskip = jfm_ksp,
@@ -352,11 +347,30 @@ do
tex.sprint(cat_lp, global_flag, '\\protected\\expandafter\\def\\csname ',
(cstemp==' ') and '\\space' or cstemp, '\\endcsname{\\ltj@cur'..
(jfm_dir == 'yoko' and 'j' or 't') .. 'fnt', fn, '\\relax}')
- jfm_file_name = nil
+ jfm_spec = nil
end
end
do
+ local ltb = luatexbase
+ local to_be_checked = { 'pre_linebreak_filter', 'hpack_filter' }
+ check_callback_order = function()
+ for i,n in pairs(to_be_checked) do
+ local lotf_cb = ltb.priority_in_callback(n, 'luaotfload.letterspace')
+ local ltj_cb = ltb.priority_in_callback(n, 'ltj.main')
+ if lotf_cb then
+ to_be_checked[i]=nil
+ if ltj_cb<lotf_cb then
+ local f = ltb.remove_from_callback(n,'luaotfload.letterspace')
+ ltb.add_to_callback(n, f, 'luaotfload.letterspace',
+ ltb.priority_in_callback(n, 'luaotfload.node_processor') + 1)
+ end
+ end
+ end
+ end
+end
+
+do
local get_dir_count = ltjd.get_dir_count
local dir_tate = luatexja.dir_table.dir_tate
local tex_get_attr = tex.getattribute
@@ -374,54 +388,78 @@ do
end
do
- local gmatch = string.gmatch
- -- extract jfm_file_name and jfm_var
+ local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V
+ local lpegmatch = lpeg.match
+ local C, Cc, Cf, Ct, Cg = lpeg.C, lpeg.Cc, lpeg.Cf, lpeg.Ct, lpeg.Cg
+ local Cs, B = lpeg.Cs, lpeg.B
+ local spacing = S" \t\v"
+ local ws = spacing^0
+ local slash = P'/'
+ local semicolon = P';'
+ local comma = P','
+ local equals = P'='
+ local jf_field_char = 1 - S'/{};,='
+ local jf_field = C(jf_field_char^1)
+ local jf_assignment = jf_field * equals * jf_field
+ local jf_switch = P'-' * jf_field * Cc(false) + P'+'^-1 * jf_field * Cc(true)
+ local jf_feature_expr = Cg(jf_assignment + jf_switch) * comma^0
+ local jf_feature_list = P'{' * jf_feature_expr^0 * P'}' + jf_feature_expr^0
+ local jf_list = C((1-slash)^1) * (slash * Cf(Ct'' * jf_feature_list, rawset))^-1
+ local jf_value = (1 - semicolon)^1
+ local function rem(name,value)
+ if name=='jfm' then
+ local flag, t; jfm_name, t = lpegmatch(jf_list, value)
+ if type(t)=='table' then
+ for i,v in pairs(t) do
+ flag=true
+ if v=='true' then t[i]=true elseif v=='false' then t[i]=false end
+ end
+ end
+ luatexja.jfont.jfm_feature = flag and t
+ elseif name=='jfmvar' then jfm_var = value end
+ return ''
+ end
+ local jf_remainder = Cs( ( ( B(S':;') *
+ C(P'jfm' * P'var'^-1) * ws * equals * ws * C(jf_value) * semicolon^-1 ) / rem +1 )^0 )
+
+ local parser=luaotfload.parsers.font_request
+ function is_feature_specified(s,fname)
+ local t = lpegmatch(parser,s); return t and t.features and t.features[fname]
+ end
+ -- extract jfm_name, jfm_spec and jfm_var
-- normalize position of 'jfm=' and 'jfmvar=' keys
- local function extract_metric(name)
+ local function extract_jfm_spec(name)
name = (name:match '^{(.*)}$') or (name:match '^"(.*)"$') or name
- jfm_file_name = ''; jfm_var = ''; jfm_ksp = true
+ jfm_spec, jfm_var = '', ''
local tmp, index = name:sub(1, 5), 1
if tmp == 'file:' or tmp == 'name:' or tmp == 'psft:' then
index = 6
end
- local p = name:find(":", index); index = p and (p+1) or index
- while index do
- local l = name:len()+1
- local q = name:find(";", index) or l
- if name:sub(index, index+3)=='jfm=' and q>index+4 then
- jfm_file_name = name:sub(index+4, q-1)
- if l~=q then
- name = name:sub(1,index-1) .. name:sub(q+1)
- else
- name = name:sub(1,index-1); index = nil
- end
- elseif name:sub(index, index+6)=='jfmvar=' and q>index+6 then
- jfm_var = name:sub(index+7, q-1)
- if l~=q then
- name = name:sub(1,index-1) .. name:sub(q+1)
- else
- name = name:sub(1,index-1); index = nil
+ name = lpegmatch(jf_remainder, name)
+ if jfm_name~='' then
+ if luatexja.jfont.jfm_feature then
+ local l, t2 = name:sub(-1), {}
+ for i,v in pairs(luatexja.jfont.jfm_feature) do
+ -- print(i,type(v),v)
+ t2[#t2+1] = (v==true) and i
+ or ((v==false) and ('-'..i) or (i..'='..tostring(v)))
end
+ table.sort(t2); jfm_spec = jfm_name .. '/{' .. table.concat(t2, ',') .. '}'
else
- index = (l~=q) and (q+1) or nil
+ jfm_spec = jfm_name
end
- end
- if jfm_file_name~='' then
- local l = name:sub(-1)
- name = name
- .. ((l==':' or l==';') and '' or ';')
- .. 'jfm=' .. jfm_file_name
+ l = name:sub(-1)
+ name = name .. ((l==':' or l==';') and '' or ';') .. 'jfm=' .. jfm_spec
if jfm_var~='' then
name = name .. ';jfmvar=' .. jfm_var
end
+ -- print('NN>', name)
end
- for x in gmatch (name, "[:;]([+%%-]?)ltjks") do
- jfm_ksp = not (x=='-')
- end
+ jfm_ksp = (is_feature_specified(name,'ltjksp')~=false)
if jfm_dir == 'tate' then
- vert_activated = (not name:match '[:;]%-vert') and (not name:match '[:;]%-vrt2')
+ vert_activated = (is_feature_specified(name,'vert')~=false) and (is_feature_specified(name,'vrt2')~=false)
auto_enable_vrt2
- = (not name:match '[:;][+%-]?vert') and (not name:match '[:;][+%-]?vrt2')
+ = (is_feature_specified(name,'vert')==nil) and (is_feature_specified(name,'vrt2')==nil)
else
vert_activated, auto_enable_vrt2 = nil, nil
end
@@ -432,7 +470,7 @@ do
local otfl_fdr
local ltjr_font_callback = ltjr.font_callback
function luatexja.font_callback(name, size, id)
- local new_name = is_def_jfont and extract_metric(name) or name
+ local new_name = is_def_jfont and extract_jfm_spec(name) or name
is_def_jfont = false
local res = ltjr_font_callback(new_name, size, id, otfl_fdr)
luatexbase.call_callback('luatexja.define_font', res, new_name, size, id)
@@ -447,7 +485,7 @@ do
local function load_jfmonly()
local spec, size = match(scan_arg(), '(.+)%s+at%s*([%.%w]*)')
local dir = scan_arg()
- size = sp(size); extract_metric(spec)
+ size = sp(size); extract_jfm_spec(spec)
jfm_dir = dir
local i = load_jfont_metric()
local j = -update_jfm_cache(i, size)