+ lx = node_next(node_next(lx))
+ elseif ls==0 then
+ Np.last = lx
+ elseif (ls==3) or (lai==ITALIC) then
+ Np.last = lx; set_attr(lx, attr_icflag, IC_PROCESSED)
+ else
+ lp=lx; break
+ end
+ else
+ lp=lx; break
+ end
+ end
+ end
+ local r
+ if adj_depth>node_depth then
+ r = node_new(id_rule,rule_subtype)
+ setfield(r, 'width', 0); setfield(r, 'height', 0)
+ setfield(r, 'depth',adj_depth); setfield(r, 'dir', tex_dir)
+ set_attr(r, attr_icflag, PROCESSED)
+ end
+ if last_glyph then
+ Np.last_char = last_glyph
+ if r then insert_after(head, first_glyph, r) end
+ else
+ local npn = Np.nuc
+ Np.last_char = npn
+ if r then
+ local nf, nc = getfont(npn), getchar(npn)
+ local ct = (font.getfont(nf) or font.fonts[nf] ).characters[nc]
+ if not ct then -- variation selector
+ node_free(r)
+ elseif (ct.left_protruding or 0) == 0 then
+ head = insert_before(head, npn, r)
+ Np.first = (Np.first==npn) and r or npn
+ elseif (ct.right_protruding or 0) == 0 then
+ insert_after(head, npn, r); Np.last, lp = r, r
+ else
+ ltjb.package_warning_no_line(
+ 'luatexja',
+ 'Check depth of glyph node ' .. tostring(npn) .. '(font=' .. nf
+ .. ', char=' .. nc .. '), because its \\lpcode is ' .. tostring(ct.left_protruding)
+ .. ' and its \\rpcode is ' .. tostring(ct.right_protruding)
+ ); node_free(r)
+ end
+ end
+ end
+ return true, lp
+ end
+end
+local calc_np_auxtable = {
+ [id_glyph] = calc_np_aux_glyph_common,
+ [id_hlist] = function(lp)
+ local op, flag
+ head, lp, op, flag = ltjd_make_dir_whatsit(head, lp, list_dir, 'jfm hlist')
+ set_attr(op, attr_icflag, PROCESSED)
+ Np.first = Np.first or op; Np.last = op; Np.nuc = op;
+ if (flag or getfield(op, 'shift')~=0) then
+ Np.id = id_box_like
+ else
+ Np.id = id_hlist
+ Np.last_char = check_box_high(Np, getlist(op), nil)
+ end
+ return true, lp
+ end,
+ [id_vlist] = function(lp)
+ local op
+ head, lp, op = ltjd_make_dir_whatsit(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
+ end,
+ box_like = function(lp)
+ Np.first = Np.first or lp; Np.last = lp; Np.nuc = lp;
+ Np.id = id_box_like;
+ return true, node_next(lp)
+ end,
+ skip = function(lp)
+ set_attr(lp, attr_icflag, PROCESSED)
+ return false, node_next(lp)
+ end,
+ [id_whatsit] = function(lp)
+ local lps = getsubtype(lp)
+ if lps==sid_user then
+ if getfield(lp, 'user_id')==luatexja.userid_table.IHB then
+ local lq = node_next(lp);
+ head = node_remove(head, lp); node_free(lp); non_ihb_flag = false
+ return false, lq;
+ else
+ set_attr(lp, attr_icflag, PROCESSED)
+ luatexbase.call_callback("luatexja.jfmglue.whatsit_getinfo",
+ Np, lp, Nq)
+ if Np.nuc then
+ Np.id = id_pbox_w; Np.first = Np.nuc; Np.last = Np.nuc;
+ return true, node_next(lp)
+ else
+ return false, node_next(lp)
+ end
+ end
+ else
+ -- we do special treatment for these whatsit nodes.
+ if lps == sid_start_link or lps == sid_start_thread then
+ Np.first = lp
+ elseif lps == sid_end_link or lps == sid_end_thread then
+ Np.first, Nq.last = nil, lp;
+ end
+ set_attr(lp, attr_icflag, PROCESSED)
+ return false, node_next(lp)
+ end
+ end,
+ [id_math] = function(lp)
+ Np.first, Np.nuc = (Np.first or lp), lp;
+ set_attr(lp, attr_icflag, PROCESSED)
+ set_np_xspc_alchar(Np, -1, lp)
+ local end_math = node_end_of_math(lp)
+ ltjw_apply_ashift_math(lp, end_math, attr_ablshift)
+ set_attr(end_math, attr_icflag, PROCESSED)
+ Np.last, Np.id = end_math, id_math;
+ return true, node_next(end_math);
+ end,
+ [id_glue] = function(lp)
+ Np.first, Np.nuc, Np.last = (Np.first or lp), lp, lp;
+ Np.id = getid(lp); set_attr(lp, attr_icflag, PROCESSED)
+ return true, node_next(lp)
+ end,
+ [id_disc] = function(lp)
+ Np.first, Np.nuc, Np.last = (Np.first or lp), lp, lp;
+ Np.id = getid(lp); set_attr(lp, attr_icflag, PROCESSED)
+ ltjw_apply_ashift_disc(lp, (list_dir==dir_tate), tex_dir)
+ Np.last_char = check_box_high(Np, getfield(lp, 'replace'), nil)
+ return true, node_next(lp)
+ end,
+ [id_kern] = function(lp)
+ if getsubtype(lp)==2 then
+ Np.first = Np.first or lp
+ set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp)
+ if getid(lp)==id_glyph then -- アクセント本体
+ setfield(lp, 'yoffset', getfield(lp, 'yoffset') - (has_attr(lp,attr_ablshift) or 0))
+ else -- アクセントは上下にシフトされている
+ setfield(lp, 'shift', getfield(lp, 'shift') + (has_attr(lp,attr_ablshift) or 0))
+ end
+ set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp)
+ set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp)
+ set_attr(lp, attr_icflag, PROCESSED);
+ return calc_np_aux_glyph_common(lp)
+ else
+ Np.first = Np.first or lp
+ Np.id = id_kern; set_attr(lp, attr_icflag, PROCESSED)
+ Np.last = lp; return true, node_next(lp)
+ end
+ end,
+ [id_penalty] = function(lp)
+ Bp[#Bp+1] = lp; set_attr(lp, attr_icflag, PROCESSED)
+ return false, node_next(lp)
+ end,