OSDN Git Service

ltj-jfmglue.lua: Fix handle_penalty_always() to always insert non-zero penalty.
[luatex-ja/luatexja.git] / src / ltj-jfmglue.lua
index e37e687..963c251 100644 (file)
@@ -9,6 +9,7 @@ luatexbase.provides_module({
 module('luatexja.jfmglue', package.seeall)
 local err, warn, info, log = luatexbase .errwarinf(_NAME)
 
+luatexja.load_module('base');      local ltjb = luatexja.base
 luatexja.load_module('stack');     local ltjs = luatexja.stack
 luatexja.load_module('jfont');     local ltjf = luatexja.jfont
 luatexja.load_module('direction'); local ltjd = luatexja.direction
@@ -34,19 +35,16 @@ local insert_before = Dnode.insert_before
 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 ltjd_make_dir_whatsit = ltjd.make_dir_whatsit
 local ltjf_font_metric_table = ltjf.font_metric_table
 local ltjf_find_char_class = ltjf.find_char_class
 local node_new = Dnode.new
 local node_copy = Dnode.copy
-local node_remove = luatexja.Dnode_remove -- Dnode.remove
+local node_remove = Dnode.remove
 local node_tail = Dnode.tail
 local node_free = Dnode.free
 local node_end_of_math = Dnode.end_of_math
 
-local dir_tate = 3
-local dir_yoko  = 4
-
 local id_glyph = node.id('glyph')
 local id_hlist = node.id('hlist')
 local id_vlist = node.id('vlist')
@@ -106,11 +104,21 @@ local function fast_find_char_class(c,m)
 end
 
 -- 文字クラスの決定
-local function slow_find_char_class(c, m, oc)
-   local xc = c or oc
-   local cls = ltjf_find_char_class(oc, m)
-   if xc ~= oc and  cls==0 then cls = ltjf_find_char_class(-xc, m) end
-   return cls, xc
+local slow_find_char_class
+do
+   local start_time_measure = ltjb.start_time_measure
+   local stop_time_measure = ltjb.stop_time_measure
+   slow_find_char_class = function (c, m, oc)
+      start_time_measure('slow_find_chr')
+      local cls = ltjf_find_char_class(oc, m)
+      if not c and  cls==0 then 
+        stop_time_measure('slow_find_chr')
+        return ltjf_find_char_class(-c, m), oc
+      else
+        stop_time_measure('slow_find_chr')
+        return cls, oc
+      end
+   end
 end
 
 local zero_glue = node_new(id_glue)
@@ -170,7 +178,8 @@ local ihb_flag -- JFM グルー挿入抑止用 flag
 -------------------- hlist 内の文字の検索
 
 local first_char, last_char, find_first_char
-
+do
+local ltjd_glyph_from_packed = ltjd.glyph_from_packed
 local function check_box(box_ptr, box_end)
    local p = box_ptr; local found_visible_node = false
    if not p then
@@ -196,7 +205,6 @@ local function check_box(box_ptr, box_end)
       end
       if pid==id_kern then
         local pa = get_attr_icflag(p)
-        --if pa==IC_PROCESSED or pa == PACKED then
         if pa==IC_PROCESSED then
            -- do nothing
         elseif getsubtype(p)==2 then
@@ -208,10 +216,11 @@ local function check_box(box_ptr, box_end)
         end
       elseif pid==id_hlist then
         if PACKED == get_attr_icflag(p) then
+           local s = ltjd_glyph_from_packed(p)
            if find_first_char then
-              first_char = getlist(p); find_first_char = false
+              first_char = s; find_first_char = false
            end
-           last_char = getlist(p); found_visible_node = true
+           last_char = s; found_visible_node = true
         else
            if getfield(p, 'shift')==0 then
               if check_box(getlist(p), nil) then found_visible_node = true end
@@ -254,7 +263,7 @@ function check_box_high(Nx, box_ptr, box_end)
    end
    return last_char
 end
-
+end
 -------------------- Np の計算と情報取得
 
 luatexbase.create_callback("luatexja.jfmglue.whatsit_getinfo", "data",
@@ -286,11 +295,17 @@ local function check_next_ickern(lp)
 end
 
 local function calc_np_pbox(lp, last)
+   local first, lpa, nc = (not Np.first), KINSOKU, nil
    Np.first = Np.first or lp; Np.id = id_pbox
-   local lpa, nc = KINSOKU, nil
    set_attr(lp, attr_icflag, get_attr_icflag(lp));
    while lp ~=last and (lpa>=PACKED) and (lpa<BOXBDD) do
-      nc, lp = lp, node_next(lp); lpa = lp and has_attr(lp, attr_icflag) or 0
+      if getid(lp)==id_hlist or getid(lp)==id_vlist then
+        head, lp, nc = ltjd_make_dir_whatsit(head, lp, list_dir, 'jfm pbox')
+        if first then Np.first = nc end
+      else
+        nc, lp = lp, node_next(lp)
+      end
+      first, lpa = false, (lp and has_attr(lp, attr_icflag) or 0)
      -- get_attr_icflag() ではいけない!
    end
    Np.nuc = nc
@@ -307,14 +322,15 @@ local calc_np_auxtable = {
    end,
    [id_hlist] = function(lp)
       local op, flag
-      head, lp, op, flag = ltjd_make_dir_node(head, lp, list_dir, 'jfm hlist')
+      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;
       Np.id = (flag or getfield(op, 'shift')~=0) and id_box_like or id_hlist
       return true, lp
    end,
    [id_vlist] =  function(lp)
       local op
-      head, lp, op = ltjd_make_dir_node(head, lp, list_dir, 'jfm:' .. getid(lp))
+      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
@@ -416,7 +432,8 @@ function calc_np(lp, last)
          if lpa%PROCESSED_BEGIN_FLAG == BOXBDD then
            local lq = node_next(lp)
             head = node_remove(head, lp); node_free(lp); lp = lq
-         else return calc_np_pbox(lp, last)
+         else 
+           return calc_np_pbox(lp, last)
          end -- id_pbox
       else
         k, lp = calc_np_auxtable[getid(lp)](lp)
@@ -440,6 +457,7 @@ do
   local POST = luatexja.stack_table_index.POST
   local KCAT = luatexja.stack_table_index.KCAT
   local XSP  = luatexja.stack_table_index.XSP
+  local dir_tate = luatexja.dir_table.dir_tate
 
 -- 和文文字のデータを取得
    local attr_jchar_class = luatexbase.attributes['ltj@charclass']
@@ -549,7 +567,7 @@ end
 local function handle_penalty_always(post, pre, g)
    local a = (pre or 0) + (post or 0)
    if #Bp == 0 then
-      if not (g and getid(g)==id_glue) then
+      if not (g and getid(g)==id_glue) or a~=0 then
         local p = node_new(id_penalty)
         if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
         setfield(p, 'penalty', a)
@@ -929,13 +947,13 @@ do
    local XKANJI_SKIP   = luatexja.icflag_table.XKANJI_SKIP
    local KSK  = luatexja.stack_table_index.KSK
    local XSK  = luatexja.stack_table_index.XSK
-   local DIR  = luatexja.stack_table_index.DIR
+   local dir_yoko = luatexja.dir_table.dir_yoko
    init_var = function (mode)
       -- 1073741823: max_dimen
       Bp, widow_Bp, widow_Np = {}, {}, {first = nil}
       table_current_stack = ltjs.table_current_stack
 
-      list_dir = table_current_stack[DIR] or dir_yoko
+      list_dir = ltjs.list_dir or dir_yoko
       kanji_skip = node_new(id_glue)
       setfield(kanji_skip, 'spec', skip_table_to_spec(KSK))
       set_attr(kanji_skip, attr_icflag, KANJI_SKIP)
@@ -976,9 +994,10 @@ do
    end
 end
 
+local tex_set_attr = tex.setattribute
 local function cleanup(mode)
    -- adjust attr_icflag for avoiding error
-   tex.setattribute('global', attr_icflag, 0)
+   tex_set_attr('global', attr_icflag, 0)
    node_free(kanji_skip); node_free(xkanji_skip)
    if mode then
       local h = node_next(head)
@@ -988,12 +1007,8 @@ local function cleanup(mode)
            return false
         end
       end
-      return head
-   else
-      set_attr(head, attr_icflag,
-               get_attr_icflag(head) + PROCESSED_BEGIN_FLAG);
-      return head
    end
+   return head
 end
 -------------------- 外部から呼ばれる関数