--
luatexbase.provides_module({
name = 'luatexja.jfmglue',
- date = '2012/04/02',
- version = '0.3',
+ date = '2012/04/25',
+ version = '0.4',
description = 'Insertion process of JFM glues and kanjiskip',
})
module('luatexja.jfmglue', package.seeall)
local id_pbox_w = node.id('hlist') + 513 -- cluster which consists of a whatsit
local sid_user = node.subtype('user_defined')
+local sid_start_link = node.subtype('pdf_start_link')
+local sid_start_thread = node.subtype('pdf_start_thread')
+local sid_end_link = node.subtype('pdf_end_link')
+local sid_end_thread = node.subtype('pdf_end_thread')
+
local ITALIC = 1
local PACKED = 2
local KINSOKU = 3
last_char = p; found_visible_node = true; p=node_next(p)
if (not p) or p==box_end then return found_visible_node end
until p.id~=id_glyph
+ pid = p.id
end
if pid==id_hlist then
if has_attr(p, attr_icflag)==PACKED then
local function calc_np_pbox()
local uid = has_attr(lp, attr_uniqid)
- Np.first = lp; Np.id = id_pbox
+ Np.first = Np.first or lp; Np.id = id_pbox
lpa = KINSOKU -- dummy=
while lp~=last and lpa>=PACKED and lpa~=BOXBDD
and has_attr(lp, attr_uniqid) == uid do
local calc_np_auxtable = {
[id_glyph] = function()
- Np.first = lp
+ Np.first = Np.first or lp
if lp.font == has_attr(lp, attr_curjfnt) then
Np.id = id_jglyph
else
Np.id = id_glyph
end
- Np.first = lp; Np.nuc = lp; set_attr_icflag_processed(lp)
+ Np.nuc = lp; set_attr_icflag_processed(lp)
lp = node_next(lp); check_next_ickern(); return true
end,
[id_hlist] = function()
- Np.first = lp; Np.last = lp; Np.nuc = lp;
+ Np.first = Np.first or lp; Np.last = lp; Np.nuc = lp;
set_attr_icflag_processed(lp)
if lp.shift~=0 then
Np.id = id_box_like
lp = node_next(lp); return true
end,
[id_vlist] = function()
- Np.first = lp; Np.nuc = lp; Np.last = lp;
+ Np.first = Np.first or lp; Np.nuc = lp; Np.last = lp;
Np.id = id_box_like; set_attr_icflag_processed(lp);
lp = node_next(lp); return true
end,
[id_rule] = function()
- Np.first = lp; Np.nuc = lp; Np.last = lp;
+ Np.first = Np.first or lp; Np.nuc = lp; Np.last = lp;
Np.id = id_box_like; set_attr_icflag_processed(lp);
lp = node_next(lp); return true
end,
return false
end,
[id_disc] = function()
- Np.first = lp; Np.nuc = lp; set_attr_icflag_processed(lp);
+ Np.first = Np.first or lp;
+ Np.nuc = lp; set_attr_icflag_processed(lp);
Np.last = lp; Np.id = id_disc; lp = node_next(lp); return true
end,
[id_whatsit] = function()
if lp.subtype==sid_user then
- if lp.user_id==30111 then
- local lq = node_next(lp)
- head = node_remove(head, lp); node_free(lp); lp = lq; ihb_flag = true
- else
- set_attr_icflag_processed(lp)
- luatexbase.call_callback("luatexja.jfmglue.whatsit_getinfo"
- , Np, lp, Nq, box_stack_level)
- lp = node_next(lp)
- if Np.nuc then
- Np.id = id_pbox_w; Np.first = Np.nuc; Np.last = Np.nuc; return true
- end
+ if lp.user_id==30111 then
+ local lq = node_next(lp)
+ head = node_remove(head, lp); node_free(lp); lp = lq; ihb_flag = true
+ else
+ set_attr_icflag_processed(lp)
+ luatexbase.call_callback("luatexja.jfmglue.whatsit_getinfo"
+ , Np, lp, Nq, box_stack_level)
+ lp = node_next(lp)
+ if Np.nuc then
+ Np.id = id_pbox_w; Np.first = Np.nuc; Np.last = Np.nuc; return true
+ end
+ end
+ else
+ -- we do special treatment for these whatsit nodes.
+ if lp.subtype == sid_start_link or lp.subtype == sid_start_thread then
+ Np.first = lp
+ elseif lp.subtype == sid_end_link or lp.subtype == sid_end_thread then
+ Nq.last = lp; Np.first = nil
end
- else
- set_attr_icflag_processed(lp)
+ set_attr_icflag_processed(lp); lp = node_next(lp)
end
return false
end,
[id_math] = function()
- Np.first = lp; Np.nuc = lp;
+ Np.first = Np.first or lp; Np.nuc = lp;
set_attr_icflag_processed(lp); lp = node_next(lp)
while lp.id~=id_math do
set_attr_icflag_processed(lp); lp = node_next(lp)
return true
end,
[id_glue] = function()
- Np.first = lp; Np.nuc = lp; set_attr_icflag_processed(lp);
+ Np.first = Np.first or lp; Np.nuc = lp; set_attr_icflag_processed(lp);
Np.last = lp; Np.id = id_glue; lp = node_next(lp); return true
end,
[id_kern] = function()
- Np.first = lp
+ Np.first = Np.first or lp
if lp.subtype==2 then
set_attr_icflag_processed(lp); lp = node_next(lp)
set_attr_icflag_processed(lp); lp = node_next(lp)
lp = node_next(lp); return false
end,
[13] = function()
- Np.first = lp; Np.nuc = lp; Np.last = lp;
+ Np.first = Np.first or lp; Np.nuc = lp; Np.last = lp;
Np.id = id_box_like; set_attr_icflag_processed(lp);
lp = node_next(lp); return true
end,
handle_penalty_normal(0, Np.pre, g); real_insert(0, g)
elseif Nq.pre then
g = get_OA_skip() or get_xkanjiskip(Np) -- O_A->X
+ if Nq.id==id_hlist then Nq.post = 0 end
handle_penalty_normal(Nq.post, Np.pre, g); real_insert(0, g)
else
g = get_OA_skip() -- O_A
local function handle_nq_jachar()
local g
if Np.pre then
+ if Np.id==id_hlist then Np.pre = 0 end
g = get_OB_skip() or get_xkanjiskip(Nq) -- O_B->X
g = lineend_fix(g)
handle_penalty_normal(Nq.post, Np.pre, g); real_insert(Nq.lend, g)
end
end
+-- Nq が前側のクラスタとなることによる修正
+local function adjust_nq()
+ if Nq.id==id_glyph then after_alchar(Nq)
+ elseif Nq.id==id_hlist or Nq.id==id_pbox or Nq.id==id_disc then after_hlist(Nq)
+ elseif Nq.id == id_pbox_w then
+ luatexbase.call_callback("luatexja.jfmglue.whatsit_after",
+ false, Nq, Np, box_stack_level)
+ end
+end
+
-------------------- 開始・終了時の処理
-- リスト末尾の処理
local function handle_list_tail()
- Np = Nq
+ adjust_nq(); Np = Nq
if mode then
-- the current list is to be line-breaked:
if Np.id == id_jglyph or (Np.id==id_pbox and Np.met) then
head = node_insert_after(head, Np.last, g)
end
end
- head = node_remove(head, last); node_free(last);-- remove the sentinel
end
- node_free(kanji_skip); node_free(xkanji_skip)
end
-- リスト先頭の処理
end
end
--- Nq が前側のクラスタとなることによる修正
-local function adjust_nq()
- if Nq.id==id_glyph then after_alchar(Nq)
- elseif Nq.id==id_hlist or Nq.id==id_pbox or Nq.id==id_disc then after_hlist(Nq)
- elseif Nq.id == id_pbox_w then
- luatexbase.call_callback("luatexja.jfmglue.whatsit_after",
- false, Nq, Np, box_stack_level)
+local function cleanup()
+ -- adjust attr_icflag for avoiding error
+ tex.attribute[attr_icflag] = -(0x7FFFFFFF)
+ node_free(kanji_skip); node_free(xkanji_skip)
+ if mode then
+ local h = node_next(head)
+ if h.id == id_penalty and h.penalty == 10000 then
+ h = h.next
+ if h.id == id_glue and h.subtype == 15 and not h.next then
+ return false
+ end
+ end
+ return head
+ else
+ head = node_remove(head, last); node_free(last);-- remove the sentinel
+ return head
end
end
-------------------- 外部から呼ばれる関数
if Np then
extract_np(); handle_list_head()
else
- if not mode then head = node_remove(head, last); node_free(last) end
- return head
+ return cleanup()
end
calc_np()
while Np do
calc_np()
end
handle_list_tail()
- -- adjust attr_icflag
- tex.attribute[attr_icflag] = -(0x7FFFFFFF)
- return head
+ return cleanup()
end
-- \inhibitglue
end
local function whatsit_callback(Np, lp, Nq, bsl)
- if Np.nuc then return Np
- elseif lp.user_id == 30114 then
+ if Np and Np.nuc then return Np
+ elseif Np and lp.user_id == 30114 then
Np.first = lp; Np.nuc = lp; Np.last = lp
Np.char = 'parbdd'
Np.met = nil