luatexja.load_module('base'); local ltjb = luatexja.base
luatexja.load_module('stack'); local ltjs = luatexja.stack
+luatexja.load_module('rmlgbm'); local ltjr = luatexja.rmlgbm
luatexja.direction = {}
local attr_dir = luatexbase.attributes['ltj@dir']
do
local tex_getcount = tex.getcount
- local function set_dir_flag(h)
- local new_dir = ltjs.table_current_stack[DIR]
- local w = node_new(id_whatsit, sid_user)
+ local function set_dir_flag(h, gc)
+ local hd, new_dir = to_direct(h), ltjs.table_current_stack[DIR]
+ local w
+ if hd and getid(hd)==id_whatsit and getsubtype(hd)==sid_user
+ and getfield(hd, 'user_id')==wh_DIR then
+ w = hd
+ else
+ w = node_new(id_whatsit, sid_user)
+ setfield(w, 'next', hd)
+ end
setfield(w, 'user_id', wh_DIR)
setfield(w, 'type', 100)
setfield(w, 'value', new_dir)
- setfield(w, 'next', to_direct(h))
return to_node(w)
end
luatexbase.add_to_callback('hpack_filter', set_dir_flag, 'ltj.set_dir_flag', 10000)
luatexbase.add_to_callback('vpack_filter',
- function (h)
+ function (h, gc)
local box_set, cl = 0, tex.currentgrouplevel + 1
for w in traverse_id(id_whatsit, to_direct(h)) do
if getfield(w, 'value')==cl then box_set = 1; break end
end
ltjs.report_stack_level(tex_getcount('ltj@@stack') + box_set)
- return set_dir_flag(h)
+ return set_dir_flag(h, gc)
end, 'ltj.set_dir_flag', 1)
luatexbase.add_to_callback('post_linebreak_filter',
function (h)
for line in traverse_id(id_hlist, to_direct(h)) do
set_attr(line, attr_dir, new_dir)
end
- return h
+ return set_dir_flag(h, gc)
end, 'ltj.set_dir_flag', 100)
end
},
}
- make_dir_node = function (head, b, new_dir)
+ make_dir_node = function (head, b, new_dir, origin)
-- head: list head, b: box
+ -- origin: コール元 (for debug)
-- return value: (new head), (next of b), (new b), (is_b_dir_node)
-- (new b): b か dir_node に被せられた b
local old_dir
and getfield(bh, 'user_id')==wh_DIR then
old_dir = getfield(bh, 'value')
setfield(b, 'head', node_next(bh))
- set_attr(b, attr_icflag, PROCESSED)
+ set_attr(b, attr_icflag, PROCESSED)
node_free(bh)
else
old_dir = has_attr(b, attr_dir) or dir_yoko
if old_dir==0 then old_dir =dir_yoko end
end
- if old_dir==new_dir then
+ --print('make_dir_node', origin, old_dir,new_dir)
+ if old_dir==new_dir then
set_attr(b, attr_icflag, PROCESSED)
return head, node_next(b), b, false
elseif -old_dir == new_dir then
return nh, nb, ret, flag
end
end
- local function process_dir_node(head)
+ local function process_dir_node(head, gc)
local h = to_direct(head)
local x, new_dir = h, ltjs.table_current_stack[DIR] or dir_yoko
while x do
local xid = getid(x)
- if (xid==id_hlist and has_attr(x, attr_icflag)~=PACKED) or xid==id_vlist then
- h, x = make_dir_node(h, x, new_dir)
+ if (xid==id_hlist and has_attr(x, attr_icflag)~=PACKED)
+ or xid==id_vlist then
+ h, x = make_dir_node(h, x, new_dir, 'process_dir_node:' .. gc)
else
x = node_next(x)
end
local font_vert_table = {} -- key: fontnumber
do
local font_vert_basename = {} -- key: basename
-
local function add_feature_table(tname, src, dest)
for i,v in pairs(src) do
if type(v.slookups)=='table' then
-- test if already loaded
if type(id)=='number' then -- sometimes id is an integer
font_vert_table[n] = font_vert_table[id]; return
- elseif not id then return
+ elseif (not id) or font_vert_table[n] then return
end
local fname = id.filename
function luatexja.direction.get_vert_glyph(n, chr)
local fn = font_vert_table[n]
- return (fn and fn[chr]) or chr
+ return fn and fn[chr] or chr
end
luatexbase.add_to_callback('luatexja.define_font',
prepare_vert_data(id, res)
end,
'prepare_vert_data', 1)
+
+ local function a (n, dat) font_vert_table[n] = dat end
+ luatexja.rmlgbm.vert_addfunc = a
end
local insert_after = Dnode.insert_after
local node_next = (Dnode ~= node) and Dnode.getnext or node.next
local round = tex.round
+local ltjd_make_dir_node = ltjd.make_dir_node
local ltjf_font_metric_table = ltjf.font_metric_table
local ltjf_find_char_class = ltjf.find_char_class
local node_new = Dnode.new
end,
[id_hlist] = function(lp)
local op, flag
- head, lp, op, flag = ltjd.make_dir_node(head, lp, list_dir)
+ head, lp, op, flag = ltjd_make_dir_node(head, lp, list_dir, 'jfm hlist')
Np.first = Np.first or op; Np.last = op; Np.nuc = op;
Np.id = (flag or getfield(op, 'shift')~=0) and id_box_like or id_hlist
return true, lp
end,
box_like = function(lp)
local op
- head, lp, op = ltjd.make_dir_node(head, lp, list_dir)
+ head, lp, op = ltjd_make_dir_node(head, lp, list_dir, 'jfm:' .. getid(lp))
Np.first = Np.first or op; Np.last = op; Np.nuc = op;
Np.id = id_box_like;
return true, lp
xkanjiskip=.25\zw plus 1pt minus 1pt,
autospacing, autoxspacing, jacharrange={-1},
yalbaselineshift=0pt, yjabaselineshift=0pt,
+ talbaselineshift=0pt, tjabaselineshift=0pt,
jcharwidowpenalty=500, differentjfm=paverage
}
local cidfont_data = {}
local cache_chars = {}
-local cache_ver = '2'
+local cache_ver = '3'
local cid_reg, cid_order, cid_supp, cid_name
local cid_replace = {
cidfont_data[cid_name] = k
-- CID => Unicode 符号空間
- -- TODO: vertical fonts?
- tt, cidm = {}, {}
+ local tth, cidmo = {}, {}
+ tt, cidm = tth, cidmo
for i = 0,kx[2] do cidm[i] = -1 end
open_cmap_file(kx[1] .. "-H", increment, tonumber, entry)
- k.characters = tt
+ k.characters = tth
-- Unicode にマップされなかった文字の処理
-- これらは TrueType フォントを使って表示するときはおかしくなる
local ttu, pricode = {}, 0xF0000
- for i,v in ipairs(cidm) do
+ for i,v in ipairs(cidmo) do
if v==-1 then
- tt[pricode], cidm[i], pricode
+ tth[pricode], cidmo[i], pricode
= { index = i }, pricode, pricode+1;
end
- ttu[cid_order .. '.' .. i] = cidm[i]
+ ttu[cid_order .. '.' .. i] = cidmo[i]
end
+
+ -- 縦書用字形
+ tt, cidm = {}, {}
+ for i = 0,kx[2] do cidm[i] = -1 end
+ open_cmap_file(kx[1] .. "-V", increment, tonumber, entry)
+ local ttv = {}
+ for i,v in pairs(tt) do ttv[i] = cidmo[v.index] end
+
-- shared
k.shared = {
otfdata = {
cidinfo= k.cidinfo, verbose = false,
shared = { featuredata = {}, },
- luatex = { features = {},
+ luatex = { features = {},
defaultwidth=1000,
- sequences = { }, },
+ },
},
dynamics = {}, features = {}, processes = {},
+ ltj_vert_table = ttv
}
k.resources = { unicodes = ttu, }
k.descriptions = {}
cache_chars[cid_name] = { [655360] = k.characters }
-- tounicode エントリ
- local cidp = {nil, nil}; local cidmo = cidm
- tt, ttu, cidm = {}, {}, {}
+ local cidp = {nil, nil}; tt, ttu, cidm = {}, {}, {}
open_cmap_file(cid_name .. "-UCS2",
function(a)
a[2] = a[2] +1 ; return a
local fontdata = {}
local cachedata = {}
local s = cidfont_data[cid_name]
+ luatexja.rmlgbm.vert_addfunc(id, s.shared.ltj_vert_table)
for k, v in pairs(s) do
fontdata[k] = v
cachedata[k] = v
end
end
-cid_reg, cid_order, cid_name, cid_supp = 'Adobe', 'Japan1', 'Adobe-Japan1'
-read_cid_font()
-
-
luatexja.rmlgbm = {
cidfont_data = cidfont_data,
font_callback = font_callback,
+ vert_addfunc = function () end, -- dummy, set in ltj-direction.lua
}
+
+cid_reg, cid_order, cid_name, cid_supp = 'Adobe', 'Japan1', 'Adobe-Japan1'
+read_cid_font()
+
+
local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
local attr_yablshift = luatexbase.attributes['ltj@yablshift']
local attr_ykblshift = luatexbase.attributes['ltj@ykblshift']
+local attr_tablshift = luatexbase.attributes['ltj@tablshift']
+local attr_tkblshift = luatexbase.attributes['ltj@tkblshift']
local attr_icflag = luatexbase.attributes['ltj@icflag']
local ltjf_font_metric_table = ltjf.font_metric_table
setfield(p, 'char', ltjd.get_vert_glyph(getfont(p), getchar(p)))
local y_shift
- = - getfield(p, 'yoffset') + (has_attr(p,attr_ykblshift) or 0)
+ = - getfield(p, 'yoffset') + (has_attr(p,attr_tkblshift) or 0)
local q
head, q = node_remove(head, p)
local box = node_new(id_hlist)
function luatexja.setwidth.set_ja_width(ahead, adir)
local p = ahead; head = p; dir = adir or 'TLT'
local m = false -- is in math mode?
- local capsule_glyph = (ltjs.table_current_stack[DIR]==dir_yoko)
- and capsule_glyph_yoko or capsule_glyph_tate
+ local is_dir_tate = ltjs.table_current_stack[DIR]==dir_tate
+ local capsule_glyph = is_dir_tate and capsule_glyph_tate or capsule_glyph_yoko
+ local attr_ablshift = is_dir_tate and attr_tablshift or attr_yablshift
while p do
local pid = getid(p)
if (pid==id_glyph)
else
set_attr(p, attr_icflag, PROCESSED + get_pr_begin_flag(p))
setfield(p, 'yoffset',
- getfield(p, 'yoffset') - (has_attr(p,attr_yablshift) or 0))
+ getfield(p, 'yoffset') - (has_attr(p,attr_ablshift) or 0))
p = node_next(p)
end
elseif pid==id_math then
\newluatexattribute\ltj@charclass %
\newluatexattribute\ltj@autospc % attribute for autospacing
\newluatexattribute\ltj@autoxspc % attribute for autoxspacing
-\newluatexattribute\ltj@yablshift % attribute for \yabaselineshift
-\newluatexattribute\ltj@ykblshift % attribute for \ykbaselineshift
+\newluatexattribute\ltj@yablshift % attribute for yalbaselineshift
+\newluatexattribute\ltj@ykblshift % attribute for yjabaselineshift
+\newluatexattribute\ltj@tablshift % attribute for talbaselineshift
+\newluatexattribute\ltj@tkblshift % attribute for tjabaselineshift
\newluatexattribute\jfam % index for current jfam
\newluatexattribute\ltj@dir % temp attr for indicating box direction
\directlua{tex.setattribute(luatexja.isglobal,
luatexbase.attributes['ltj@ykblshift'],
\ltj@safe@dimen@or\ltj@defdimen{#1})}}
+% talbaselineshift = <dimen>
+% tjabaselineshift = <dimen>
+\define@key[ltj]{japaram}{talbaselineshift}{%
+ \directlua{tex.setattribute(luatexja.isglobal,
+ luatexbase.attributes['ltj@tablshift'],
+ \ltj@safe@dimen@or\ltj@defdimen{#1})}}
+\define@key[ltj]{japaram}{tjabaselineshift}{%
+ \directlua{tex.setattribute(luatexja.isglobal,
+ luatexbase.attributes['ltj@tkblshift'],
+ \ltj@safe@dimen@or\ltj@defdimen{#1})}}
% jaxspmode = {<char_code>, <mode>}
% mode: inhibit, preonly, postonly, allow
yjabaselineshift = function(t)
return print_scaled(tex.getattribute('ltj@ykblshift'))..'pt'
end,
+ talbaselineshift = function(t)
+ return print_scaled(tex.getattribute('ltj@tablshift'))..'pt'
+ end,
+ tjabaselineshift = function(t)
+ return print_scaled(tex.getattribute('ltj@tkblshift'))..'pt'
+ end,
kanjiskip = function(t)
return print_spec(ltjs.get_stack_skip(stack_table_index.KSK, t))
end,
local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc
local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc
-- mode = true iff main_process is called from pre_linebreak_filter
- local function main_process(head, mode, dir)
+ local function main_process(head, mode, dir, gc)
+ --print('main_process', gc, mode, tex.getcount('ltj@@stack'))
tex.setattribute('global', attr_icflag, 0)
local p = to_direct(head)
p = ltjj.main(p,mode)
luatexbase.add_to_callback(
'pre_linebreak_filter',
function (head,groupcode)
- return main_process(head, true, tex.textdir)
+ return main_process(head, true, tex.textdir, groupcode)
end,'ltj.pre_linebreak_filter',
luatexbase.priority_in_callback('pre_linebreak_filter',
'luaotfload.node_processor') + 1)
luatexbase.add_to_callback(
'hpack_filter',
function (head,groupcode,size,packtype, dir)
- return main_process(head, false, dir)
+ return main_process(head, false, dir, groupcode)
end,'ltj.hpack_filter',
luatexbase.priority_in_callback('hpack_filter',
'luaotfload.node_processor') + 1)
local pt=node_type(p.id)
local base = debug_depth .. string.format('%X', get_attr_icflag(p))
.. ' ' .. pt .. ' ' .. tostring(p.subtype) .. ' '
- .. ' dir=' .. tostring(has_attr(p, attr_dir)) .. ' '
if pt == 'glyph' then
s = base .. ' ' .. utf.char(p.char) .. ' ' .. tostring(p.font)
.. ' (' .. print_scaled(p.height) .. '+'
.. print_scaled(p.depth) .. ')x' .. print_scaled(p.width)
print_fn(s)
- elseif pt=='hlist' or pt=='vlist' then
+ elseif pt=='hlist' or pt=='vlist' or pt=='unset' then
s = base .. '(' .. print_scaled(p.height) .. '+'
.. print_scaled(p.depth) .. ')x' .. print_scaled(p.width) .. p.dir
- if p.shift~=0 then
+ if p.shift or 0~=0 then
s = s .. ', shifted ' .. print_scaled(p.shift)
end
if p.glue_sign >= 1 then
end
print_fn(s)
elseif pt == 'whatsit' then
- s = base
+ s = base .. '(' .. node.whatsits()[p.subtype] .. ') '
if p.subtype==sid_user then
if p.type ~= 110 then
s = s .. ' user_id: ' .. p.user_id .. ' ' .. p.value