X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=src%2Fltj-jfmglue.lua;h=0659fd01dd26868f9ecc4eb236e545306da81705;hb=2e9566b50d653da63edab02f263bcbf96df78d0e;hp=228d3763084bbdf43939d11ff1338668a815b8f5;hpb=784b9d6b79d08fd89eb36b166dbe26bb9d58707a;p=luatex-ja%2Fluatexja.git diff --git a/src/ltj-jfmglue.lua b/src/ltj-jfmglue.lua index 228d376..0659fd0 100644 --- a/src/ltj-jfmglue.lua +++ b/src/ltj-jfmglue.lua @@ -3,8 +3,8 @@ -- 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) @@ -52,6 +52,11 @@ local id_pbox = node.id('hlist') + 512 -- already processed nodes (by \un 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 @@ -178,12 +183,8 @@ local function check_box(box_ptr, box_end) end while p and p~=box_end do local pid = p.id - if pid==id_kern then - if p.subtype==2 then - p = node_next(node_next(node_next(p))); pid = p.id - elseif has_attr(p, attr_icflag)==IC_PROCESSED then - p = node_next(p); pid = p.id - end + if pid==id_kern and p.subtype==2 then + p = node_next(node_next(node_next(p))); pid = p.id -- p must be glyph_node end if pid==id_glyph then repeat @@ -193,8 +194,11 @@ local function check_box(box_ptr, box_end) 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 -- p must be non-nil end - if pid==id_hlist then + if pid==id_kern and has_attr(p, attr_icflag)==IC_PROCESSED then + p = node_next(p); + elseif pid==id_hlist then if has_attr(p, attr_icflag)==PACKED then for q in node.traverse_id(id_glyph, p.head) do if find_first_char then @@ -272,7 +276,7 @@ end 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 @@ -284,17 +288,17 @@ end 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 @@ -304,12 +308,12 @@ local calc_np_auxtable = { 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, @@ -326,30 +330,37 @@ local calc_np_auxtable = { 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) @@ -359,11 +370,11 @@ local calc_np_auxtable = { 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) @@ -386,7 +397,7 @@ local calc_np_auxtable = { 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, @@ -461,8 +472,9 @@ function set_np_xspc_alchar(Nx, c,x, lig) end Nx.pre = ltjs_get_penalty_table('pre', c, 0, box_stack_level) Nx.post = ltjs_get_penalty_table('post', c, 0, box_stack_level) + Nx.char = 'jcharbdd' else - Nx.pre = 0; Nx.post = 0 + Nx.pre = 0; Nx.post = 0; Nx.char = -1 end Nx.met = nil local y = ltjs_get_penalty_table('xsp', c, 3, box_stack_level) @@ -737,16 +749,14 @@ end local function get_OA_skip() if not ihb_flag then - local c - if Nq.id == id_math then c = -1 else c = 'jcharbdd' end + local c = Nq.char or 'jcharbdd' return new_jfm_glue(Np, fast_find_char_class(c,Np.met), Np.class) else return nil end end local function get_OB_skip() if not ihb_flag then - local c - if Np.id == id_math then c = -1 else c = 'jcharbdd' end + local c = Np.char or 'jcharbdd' return new_jfm_glue(Nq, Nq.class, fast_find_char_class(c,Nq.met)) else return nil end @@ -764,6 +774,7 @@ local function handle_np_jachar() 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 @@ -784,6 +795,7 @@ end 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) @@ -822,11 +834,21 @@ local function handle_nq_ja_hlist() 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 @@ -851,9 +873,7 @@ local function handle_list_tail() 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 -- リスト先頭の処理 @@ -913,13 +933,22 @@ local function init_var() 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 -------------------- 外部から呼ばれる関数 @@ -931,8 +960,7 @@ function main(ahead, amode) 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 @@ -950,15 +978,49 @@ function main(ahead, amode) calc_np() end handle_list_tail() - -- adjust attr_icflag - tex.attribute[attr_icflag] = -(0x7FFFFFFF) - return head + return cleanup() end -- \inhibitglue -local inhibitglue_node=node_new(id_whatsit, sid_user) -inhibitglue_node.user_id=30111; inhibitglue_node.type=100; inhibitglue_node.value=1 function create_inhibitglue_node() - node.write(node.copy(inhibitglue_node)) + local tn = node_new(id_whatsit, sid_user) + tn.user_id=30111; tn.type=100; tn.value=1 + node.write(tn) +end + +-- Node for indicating beginning of a paragraph +-- (for ltjsclasses) +function create_beginpar_node() + local tn = node_new(id_whatsit, sid_user) + tn.user_id=30114; tn.type=100; tn.value=1 + node.write(tn) end + +local function whatsit_callback(Np, lp, Nq, bsl) + 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 + Np.pre = 0; Np.post = 0 + Np.xspc_before = false + Np.xspc_after = false + Np.auto_xspc = false + return Np + end +end +local function whatsit_after_callback(s, Nq, Np, bsl) + if not s and Nq.nuc.user_id == 30114 then + local x, y = node.prev(Nq.nuc), Nq.nuc + Nq.first, Nq.nuc, Nq.last = x, x, x + head = node_remove(head, y) + end + return s +end + +luatexbase.add_to_callback("luatexja.jfmglue.whatsit_getinfo", whatsit_callback, + "luatexja.beginpar.np_info", 1) +luatexbase.add_to_callback("luatexja.jfmglue.whatsit_after", whatsit_after_callback, + "luatexja.beginpar.np_info_after", 1) +