summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua223
1 files changed, 151 insertions, 72 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua
index 0e2673400b5..c3ffb6a57e4 100644
--- a/Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua
+++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-jfont.lua
@@ -3,7 +3,7 @@
--
luatexbase.provides_module({
name = 'luatexja.jfont',
- date = '2014/01/02',
+ date = '2014/02/01',
description = 'Loader for Japanese fonts',
})
module('luatexja.jfont', package.seeall)
@@ -11,11 +11,25 @@ module('luatexja.jfont', package.seeall)
luatexja.load_module('base'); local ltjb = luatexja.base
luatexja.load_module('charrange'); local ltjc = luatexja.charrange
-local node_new = node.new
-local has_attr = node.has_attribute
-local set_attr = node.set_attribute
+local mem_leak_glue, mem_leak_gs, mem_leak_kern = 0, 0, 0
+
+local Dnode = node.direct or node
+
+local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end
+local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end
+local getfont = (Dnode ~= node) and Dnode.getfont or function(n) return n.font end
+local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end
+
+local nullfunc = function(n) return n end
+local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc
+
+local node_new = Dnode.new
+local node_free = Dnode.free
+local has_attr = Dnode.has_attribute
+local set_attr = Dnode.set_attribute
+local node_write = Dnode.write
local round = tex.round
-local getfont = font.getfont
+local font_getfont = font.getfont
local attr_icflag = luatexbase.attributes['ltj@icflag']
local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
@@ -55,9 +69,7 @@ function define_jfm(t)
else
real_char = false
for j,w in pairs(v.chars) do
- if w == 'lineend' then
- if #v.chars ~= 1 then defjfm_res= nil; return end
- elseif type(w) == 'number' then
+ if type(w) == 'number' then
real_char = true;
elseif type(w) == 'string' and utf.len(w)==1 then
real_char = true; w = utf.byte(w)
@@ -101,8 +113,7 @@ function define_jfm(t)
end
v.chars = nil
end
- if not v.kern then v.kern = {} end
- if not v.glue then v.glue = {} end
+ v.kern = v.kern or {}; v.glue = v.glue or {}
for j in pairs(v.glue) do
if v.kern[j] then defjfm_res= nil; return end
end
@@ -122,6 +133,7 @@ function define_jfm(t)
defjfm_res = t
end
+local update_jfm_cache
do
local function mult_table(old,scale) -- modified from table.fastcopy
if old then
@@ -139,26 +151,36 @@ do
else return nil end
end
- function update_jfm_cache(j,sz)
+ update_jfm_cache = function (j,sz)
if metrics[j].size_cache[sz] then return end
local t = {}
metrics[j].size_cache[sz] = t
t.chars = metrics[j].chars
t.char_type = mult_table(metrics[j].char_type, sz)
for i,v in pairs(t.char_type) do
+ v.align = (v.align=='left') and 0 or
+ ((v.align=='right') and 1 or 0.5)
if type(i) == 'number' then -- char_type
for k,w in pairs(v.glue) do
- local g, h = node.new(id_glue), node_new(id_glue_spec)
- v.glue[k] = {g, (w[5] and w[5]/sz or 0)}
- h.width, h.stretch, h.shrink = w[1], w[2], w[3]
- h.stretch_order, h.shrink_order = 0, 0
- g.subtype = 0; g.spec = h; set_attr(g, attr_icflag, FROM_JFM +
- (w[4] and w[4]/sz or 0));
+ local h = node_new(id_glue_spec)
+mem_leak_gs = mem_leak_gs+1
+ v[k] = {true, h, (w[5] and w[5]/sz or 0), FROM_JFM + (w[4] and w[4]/sz or 0)}
+ setfield(h, 'width', w[1])
+ setfield(h, 'stretch', w[2])
+ setfield(h, 'shrink', w[3])
+ setfield(h, 'stretch_order', 0)
+ setfield(h, 'shrink_order', 0)
end
for k,w in pairs(v.kern) do
- w[2] = w[2]/sz
+ local g = node_new(id_kern)
+mem_leak_kern = mem_leak_kern +1
+ setfield(g, 'kern', w[1])
+ setfield(g, 'subtype', 1)
+ set_attr(g, attr_icflag, FROM_JFM)
+ v[k] = {false, g, w[2]/sz}
end
end
+ v.glue, v.kern = nil, nil
end
t.kanjiskip = mult_table(metrics[j].kanjiskip, sz)
t.xkanjiskip = mult_table(metrics[j].xkanjiskip,sz)
@@ -166,7 +188,7 @@ do
t.zh = round(metrics[j].zh*sz)
end
end
-local update_jfm_cache = update_jfm_cache
+
luatexbase.create_callback("luatexja.find_char_class", "data",
function (arg, fmtable, char)
return 0
@@ -186,6 +208,7 @@ end
do
local cstemp
+ local global_flag -- true if \globaljfont, false if \jfont
local function load_jfont_metric()
if jfm_file_name=='' then
ltjb.package_error('luatexja',
@@ -211,7 +234,7 @@ do
function jfontdefX(g)
local t = token.get_next()
cstemp=token.csname_name(t)
- if g then luatexja.is_global = '\\global' else luatexja.is_global = '' end
+ global_flag = g and '\\global' or ''
tex.sprint(cat_lp, '\\expandafter\\font\\csname ' .. cstemp .. '\\endcsname')
end
@@ -221,17 +244,18 @@ do
function jfontdefY() -- for horizontal font
local j = load_jfont_metric()
local fn = font.id(cstemp)
- local f = getfont(fn)
+ local f = font_getfont(fn)
if not j then
ltjb.package_error('luatexja',
"bad JFM `" .. jfm_file_name .. "'",
'The JFM file you specified is not valid JFM file.\n'..
'So defining Japanese font is cancelled.')
- tex.sprint(cat_lp, luatexja.is_global .. '\\expandafter\\let\\csname ' ..cstemp
+ tex.sprint(cat_lp, global_flag .. '\\expandafter\\let\\csname ' ..cstemp
.. '\\endcsname=\\relax')
return
end
update_jfm_cache(j, f.size)
+ --print('MEMORY LEAK (acc): ', mem_leak_glue, mem_leak_gs, mem_leak_kern)
local sz = metrics[j].size_cache[f.size]
local fmtable = { jfm = j, size = f.size, var = jfm_var,
zw = sz.zw, zh = sz.zh,
@@ -241,21 +265,20 @@ do
fmtable = luatexbase.call_callback("luatexja.define_jfont", fmtable, fn)
font_metric_table[fn]=fmtable
- tex.sprint(cat_lp, luatexja.is_global .. '\\protected\\expandafter\\def\\csname '
+ tex.sprint(cat_lp, global_flag .. '\\protected\\expandafter\\def\\csname '
.. cstemp .. '\\endcsname{\\ltj@curjfnt=' .. fn .. '\\relax}')
end
end
do
--- EXT: zw, zh
- function load_zw()
+ -- PUBLIC function
+ function get_zw()
local a = font_metric_table[tex.attribute[attr_curjfnt]]
- tex.setdimen('ltj@zw', a and a.zw or 0)
+ return a and a.zw or 0
end
-
- function load_zh()
+ function get_zh()
local a = font_metric_table[tex.attribute[attr_curjfnt]]
- tex.setdimen('ltj@zh', a and a.zh or 0)
+ return a and a.zw or 0
end
end
@@ -296,6 +319,57 @@ do
end
------------------------------------------------------------------------
+-- LATEX INTERFACE
+------------------------------------------------------------------------
+do
+ -- these function are called from ltj-latex.sty
+ local kyenc_list, ktenc_list = {}, {}
+ function add_kyenc_list(enc) kyenc_list[enc] = 'true ' end
+ function add_ktenc_list(enc) ktenc_list[enc] = 'true ' end
+ function is_kyenc(enc)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if' .. (kyenc_list[enc] or 'false '))
+ end
+ function is_kyenc(enc)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if' .. (kyenc_list[enc] or 'false '))
+ end
+ function is_kenc(enc)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if'
+ .. (kyenc_list[enc] or ktenc_list[enc] or 'false '))
+ end
+
+ local kfam_list, Nkfam_list = {}, {}
+ function add_kfam_list(enc, fam)
+ if not kfam_list[enc] then kfam_list[enc] = {} end
+ kfam_list[enc][fam] = 'true '
+ end
+ function add_Nkfam_list(enc, fam)
+ if not Nkfam_list[enc] then Nkfam_list[enc] = {} end
+ Nkfam_list[enc][fam] = 'true '
+ end
+ function is_kfam(enc, fam)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if'
+ .. (kfam_list[enc] and kfam_list[enc][fam] or 'false ')) end
+ function is_Nkfam(enc, fam)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if'
+ .. (Nkfam_list[enc] and Nkfam_list[enc][fam] or 'false ')) end
+
+ local ffam_list, Nffam_list = {}, {}
+ function add_ffam_list(enc, fam)
+ if not ffam_list[enc] then ffam_list[enc] = {} end
+ ffam_list[enc][fam] = 'true '
+ end
+ function add_Nffam_list(enc, fam)
+ if not Nffam_list[enc] then Nffam_list[enc] = {} end
+ Nffam_list[enc][fam] = 'true '
+ end
+ function is_ffam(enc, fam)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if'
+ .. (ffam_list[enc] and ffam_list[enc][fam] or 'false ')) end
+ function is_Nffam(enc, fam)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if'
+ .. (Nffam_list[enc] and Nffam_list[enc][fam] or 'false ')) end
+end
+------------------------------------------------------------------------
-- ALTERNATE FONTS
------------------------------------------------------------------------
alt_font_table = {}
@@ -323,7 +397,7 @@ function set_alt_font(b,e,ind,bfnt)
end
if not alt_font_table[bfnt] then alt_font_table[bfnt]={} end
local t = alt_font_table[bfnt]
- local ac = getfont(ind).characters
+ local ac = font_getfont(ind).characters
if bfnt==ind then ind = nil end -- ind == bfnt の場合はテーブルから削除
if e>=0 then -- character range
for i=b, e do
@@ -348,8 +422,8 @@ end
------ used in ltjp.suppress_hyphenate_ja callback
function replace_altfont(pf, pc)
- return (alt_font_table[pf] and alt_font_table[pf][pc])
- and alt_font_table[pf][pc] or pf
+ local a = alt_font_table[pf]
+ return a and a[pc] or pf
end
------ for LaTeX interface
@@ -405,26 +479,30 @@ end
-- ここから先は 新 \selectfont の内部でしか実行されない
do
local alt_font_base, alt_font_base_num
-
--- EXT
- function print_aftl_address(bbase)
- local t = alt_font_table_latex[bbase]
- if not t then t = {}; alt_font_table_latex[bbase] = t end
- tex.sprint(cat_lp, (tostring(t):gsub('table: 0x','ltjaltfont')))
+ local aftl_base
+ -- EXT
+ function does_alt_set(bbase)
+ aftl_base = alt_font_table_latex[bbase]
+ tex.sprint(cat_lp, '\\if' .. (aftl_base and 'true' or 'false'))
end
+ -- EXT
+ function print_aftl_address()
+ tex.sprint(cat_lp, ';ltjaltfont' .. tostring(aftl_base):sub(8))
+ end
+
-- EXT
function output_alt_font_cmd(bbase)
alt_font_base = bbase
alt_font_base_num = tex.getattribute(attr_curjfnt)
local t = alt_font_table[alt_font_base_num]
if t then
- for i,_ in pairs(t) do t[i]=nil end
+ for i,_ in pairs(t) do t[i]=nil end
end
t = alt_font_table_latex[bbase]
if t then
- for i,_ in pairs(t) do
- tex.sprint(cat_lp, '\\ltj@pickup@altfont@aux{' .. i .. '}')
- end
+ for i,_ in pairs(t) do
+ tex.sprint(cat_lp, '\\ltj@pickup@altfont@aux{' .. i .. '}')
+ end
end
end
@@ -432,38 +510,38 @@ do
function pickup_alt_font_a(size_str)
local t = alt_font_table_latex[alt_font_base]
if t then
- for i,v in pairs(t) do
- tex.sprint(cat_lp, '\\expandafter\\ltj@pickup@altfont@copy'
- .. '\\csname ' .. i .. '/' .. size_str .. '\\endcsname{' .. i .. '}')
- end
+ for i,v in pairs(t) do
+ tex.sprint(cat_lp, '\\expandafter\\ltj@pickup@altfont@copy'
+ .. '\\csname ' .. i .. '/' .. size_str .. '\\endcsname{' .. i .. '}')
+ end
end
- end
+ end
local function pickup_alt_font_class(class, afnt_num, afnt_chars)
local t = alt_font_table[alt_font_base_num]
local tx = font_metric_table[alt_font_base_num].chars
for i,v in pairs(tx) do
- if v==class and afnt_chars[i] then t[i]=afnt_num end
+ if v==class and afnt_chars[i] then t[i]=afnt_num end
end
end
-- EXT
function pickup_alt_font_b(afnt_num, afnt_base)
local t = alt_font_table[alt_font_base_num]
- local ac = getfont(afnt_num).characters
+ local ac = font_getfont(afnt_num).characters
if not t then t = {}; alt_font_table[alt_font_base_num] = t end
for i,v in pairs(alt_font_table_latex[alt_font_base]) do
- if i == afnt_base then
- for j,_ in pairs(v) do
- if j>=0 then
- if ac[j] then t[j]=afnt_num end
- else -- -n (n>=1) means that the character class n,
- -- which is defined in the JFM
- pickup_alt_font_class(-j, afnt_num, ac)
- end
- end
- return
- end
+ if i == afnt_base then
+ for j,_ in pairs(v) do
+ if j>=0 then
+ if ac[j] then t[j]=afnt_num end
+ else -- -n (n>=1) means that the character class n,
+ -- which is defined in the JFM
+ pickup_alt_font_class(-j, afnt_num, ac)
+ end
+ end
+ return
+ end
end
end
@@ -474,28 +552,29 @@ end
-- MISC
------------------------------------------------------------------------
-local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char
+local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct
-- EXT: italic correction
function append_italic()
- local p = tex.nest[tex.nest.ptr].tail
- if p and p.id==id_glyph then
- local f = p.font
+ local p = to_direct(tex.nest[tex.nest.ptr].tail)
+ if p and getid(p)==id_glyph then
+ local f = getfont(p)
local g = node_new(id_kern)
- g.subtype = 1; node.set_attribute(g, attr_icflag, ITALIC)
+ setfield(g, 'subtype', 1)
+ set_attr(g, attr_icflag, ITALIC)
if is_ucs_in_japanese_char(p) then
f = has_attr(p, attr_curjfnt)
local j = font_metric_table[f]
- g.kern = j.char_type[find_char_class(p.char, j)].italic
+ setfield(g, 'kern', j.char_type[find_char_class(getchar(p), j)].italic)
else
- local h = getfont(f)
+ local h = font_getfont(f)
if h then
- g.kern = h.characters[p.char].italic
+ setfield(g, 'kern', h.characters[getchar(p)].italic)
else
- tex.attribute[attr_icflag] = -(0x7FFFFFFF)
- return node.free(g)
+ tex.attribute[attr_icflag] = 0
+ return node_free(g)
end
end
- node.write(g)
- tex.attribute[attr_icflag] = -(0x7FFFFFFF)
+ node_write(g)
+ tex.attribute[attr_icflag] = 0
end
end