OSDN Git Service

Another optimize; \[x]kanjiskip in a paragraph shares one glue_spec node.
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Sat, 20 Oct 2012 13:03:16 +0000 (22:03 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Sat, 20 Oct 2012 13:03:16 +0000 (22:03 +0900)
src/ltj-adjust.lua
src/ltj-jfmglue.lua
src/ltj-stack.lua

index 8314f07..6c554c9 100644 (file)
@@ -10,6 +10,7 @@ luatexbase.provides_module({
 module('luatexja.adjust', package.seeall)
 
 luatexja.load_module('jfont');     local ltjf = luatexja.jfont
+luatexja.load_module('jfmglue');   local ltjj = luatexja.jfmglue
 
 local id_glyph = node.id('glyph')
 local id_kern = node.id('kern')
@@ -26,6 +27,7 @@ local node_next = node.next
 local node_free = node.free
 
 local ltjf_font_metric_table = ltjf.font_metric_table
+local spec_zero_glue = ltjj.spec_zero_glue
 
 local PACKED = 2
 local FROM_JFM = 6
@@ -69,6 +71,7 @@ local function get_total_stretched(p)
    for i=1,#priority_table do res[priority_table[i]]=0 end
    if go ~= 0 then return nil end
    if gs ~= 1 and gs ~= 2 then return res end
+   local head = p.head
    q = p.head
    --luatexja.ext_show_node_list(p.head, '>>> ', print)
    while q do 
@@ -78,12 +81,30 @@ local function get_total_stretched(p)
             -- kanjiskip, xkanjiskip は段落内で spec を共有しているが,
             -- それはここでは望ましくないので,
             -- 各行ごとに異なる spec を使うようにする.
+            -- しかしここでは面倒なので,各 glue ごとに別の spec を使っている.
+            -- ぜひなんとかしたい!
             -- JFM グルーはそれぞれ異なる glue_spec を用いているので,問題ない.
             res[ic] = res[ic] + a
             if ic == KANJI_SKIP then
-               q.spec = node_copy(q.spec)
+               if q.spec ~= spec_zero_glue then
+                  if not new_ks then
+                     local ts; q.spec, ts = node_copy(q.spec), q.spec
+                     new_ks, q.spec = node.copy(q), ts
+                  end
+                  local g = node.copy(new_ks)
+                  node.insert_before(head, q, g);
+                  head = node.remove(head, q); node.free(q); q = g
+               end
             elseif ic == XKANJI_SKIP then
-               q.spec = node_copy(q.spec)
+               if q.spec ~= spec_zero_glue then
+                  if not new_xs then
+                     local ts; q.spec, ts = node_copy(q.spec), q.spec
+                     new_xs, q.spec = node.copy(q), ts
+                  end
+                  local g =node.copy(new_xs)
+                  node.insert_before(head, q, g);
+                  head = node.remove(head, q); node.free(q); q = g
+               end
             end
          else 
             res[0]  = res[0]  + a
index e27498a..7c5dfbb 100644 (file)
@@ -55,8 +55,8 @@ local sid_end_link = node.subtype('pdf_end_link')
 local sid_end_thread = node.subtype('pdf_end_thread')
 
 local ITALIC = 1
+-- 実装予定: non-packed jchar 2
 local PACKED = 2
--- 実装予定: non-packed jchar 3
 local KINSOKU = 3
 local FROM_JFM = 6
 -- FROM_JFM: 4, 5, 6, 7, 8 →優先度高
@@ -98,9 +98,12 @@ local function slow_find_char_class(c, m, oc)
    return cls, xc
 end
 
-local spec_zero_glue = node_new(id_glue_spec)
+local zero_glue = node_new(id_glue)
+spec_zero_glue = node_new(id_glue_spec) -- must be public, since mentioned from other sources
+local spec_zero_glue = spec_zero_glue
    spec_zero_glue.width = 0; spec_zero_glue.stretch_order = 0; spec_zero_glue.stretch = 0
    spec_zero_glue.shrink_order = 0; spec_zero_glue.shrink = 0
+   zero_glue.spec = spec_zero_glue
 
 local function skip_table_to_spec(n)
    local g, st = node_new(id_glue_spec), ltjs.fast_get_skip_table(n)
@@ -396,9 +399,11 @@ do
       local cls, c = slow_find_char_class(has_attr(x, attr_orig_char), m, x.char)
       Nx.class = cls; set_attr(x, attr_jchar_class, cls)
       Nx.met, Nx.char = m, c
-      Nx.pre = ltjs_fast_get_penalty_table('pre', c) or 0
-      Nx.post = ltjs_fast_get_penalty_table('post', c) or 0
-      Nx.xspc = ltjs_fast_get_penalty_table('xsp', c) or 3
+      local t = ltjs.fast_get_penalty_table_parent(c)
+      Nx.pre = t.pre or 0
+      Nx.post = t.post or 0
+      Nx.xspc = t.xsp or 3
+      Nx.kcat = t.kcat or 0
       Nx.auto_kspc, Nx.auto_xspc = (has_attr(x, attr_autospc)==1), (has_attr(x, attr_autoxspc)==1)
    end 
    local set_np_xspc_jachar = set_np_xspc_jachar
@@ -419,14 +424,16 @@ do
            end
             c = x.char
         end
-        Nx.pre = ltjs_fast_get_penalty_table('pre', c) or 0
-        Nx.post = ltjs_fast_get_penalty_table('post', c) or 0
+         local t = ltjs.fast_get_penalty_table_parent(c) 
+        Nx.pre = t.pre or 0
+        Nx.post = t.post or 0
+         Nx.xspc = t.xsp or 3
         Nx.char = 'jcharbdd'
       else
         Nx.pre, Nx.post, Nx.char = 0, 0, -1
+         Nx.xspc = ltjs_fast_get_penalty_table('xsp', -1) or 3
       end
       Nx.met = nil
-      Nx.xspc = ltjs_fast_get_penalty_table('xsp', c) or 3
       Nx.auto_xspc = (has_attr(x, attr_autoxspc)==1)
    end
    local set_np_xspc_alchar = set_np_xspc_alchar
@@ -549,30 +556,30 @@ local function get_kanjiskip_normal()
    if Np.auto_kspc or Nq.auto_kspc then
       return node_copy(kanji_skip)
    else
-      local g = node_new(id_glue); --copy_attr(g, Nq.nuc)
-      g.spec = node_copy(spec_zero_glue)
+      local g = node_copy(zero_glue)
       set_attr(g, attr_icflag, KANJI_SKIP)
       return g
    end
 end
 local function get_kanjiskip_jfm()
-   local g = node_new(id_glue); --copy_attr(g, Nq.nuc)
+   local g
    if Np.auto_kspc or Nq.auto_kspc then
-        local gx = node_new(id_glue_spec);
-        gx.stretch_order, gx.shrink_order = 0, 0
-         local pm, qm = Np.met, Nq.met
-        local bk = qm.size_cache.kanjiskip or {0, 0, 0}
-        if (pm.size_cache==qm.size_cache) and (qm.var==pm.var) then
-            gx.width = bk[1]; gx.stretch = bk[2]; gx.shrink = bk[3]
-         else
-            local ak = pm.size_cache.kanjiskip or {0, 0, 0}
-            gx.width = round(diffmet_rule(bk[1], ak[1]))
-            gx.stretch = round(diffmet_rule(bk[2], ak[2]))
-            gx.shrink = -round(diffmet_rule(-bk[3], -ak[3]))
-         end
-        g.spec = gx
+      g = node_new(id_glue); --copy_attr(g, Nq.nuc)
+      local gx = node_new(id_glue_spec);
+      gx.stretch_order, gx.shrink_order = 0, 0
+      local pm, qm = Np.met, Nq.met
+      local bk = qm.size_cache.kanjiskip or {0, 0, 0}
+      if (pm.size_cache==qm.size_cache) and (qm.var==pm.var) then
+         gx.width = bk[1]; gx.stretch = bk[2]; gx.shrink = bk[3]
+      else
+         local ak = pm.size_cache.kanjiskip or {0, 0, 0}
+         gx.width = round(diffmet_rule(bk[1], ak[1]))
+         gx.stretch = round(diffmet_rule(bk[2], ak[2]))
+         gx.shrink = -round(diffmet_rule(-bk[3], -ak[3]))
+      end
+      g.spec = gx
    else
-      g.spec =  node_copy(spec_zero_glue)
+      g =  node_copy(zero_glue)
    end
    set_attr(g, attr_icflag, KANJI_SKIP)
    return g
@@ -663,22 +670,22 @@ local function get_xkanjiskip_normal(Nn)
    if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then
       return node_copy(xkanji_skip)
    else
-      local g = node_new(id_glue); --copy_attr(g, Nn.nuc)
-      g.spec = node_copy(spec_zero_glue)
+      local g = node_copy(zero_glue)
       set_attr(g, attr_icflag, XKANJI_SKIP)
       return g
    end
 end
 local function get_xkanjiskip_jfm(Nn)
-   local g = node_new(id_glue); --copy_attr(g, Nn.nuc)
+   local g
    if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then
+      g =  node_new(id_glue); --copy_attr(g, Nn.nuc)
       local gx = node_new(id_glue_spec);
       gx.stretch_order, gx.shrink_order = 0, 0
       local bk = Nn.met.size_cache.xkanjiskip or {0, 0, 0}
       gx.width = bk[1]; gx.stretch = bk[2]; gx.shrink = bk[3]
       g.spec = gx
    else
-      g.spec = node_copy(spec_zero_glue)
+      g = node_copy(zero_glue)
    end
    set_attr(g, attr_icflag, XKANJI_SKIP)
    return g
@@ -726,7 +733,7 @@ local function handle_np_jachar(mode)
       end
       real_insert(0, g)
    end
-   if mode and (ltjs_fast_get_penalty_table('kcat', Np.char) or 0)%2~=1 then
+   if mode and Np.kcat%2~=1 then
       widow_Np.first, widow_Bp, Bp = Np.first, Bp, widow_Bp
    end
 end
index c7f52c9..21f71d6 100644 (file)
@@ -96,14 +96,14 @@ function set_stack_table(g,m,c,p,lb,ub)
                         "(-1 is used for denoting `math boundary')\n" ..
                         'So I changed this one to zero.')
       c=0
-   elseif not charprop_stack_table[i][m] then 
-      charprop_stack_table[i][m] = {} 
+   elseif not charprop_stack_table[i][c] then 
+      charprop_stack_table[i][c] = {} 
    end
-   charprop_stack_table[i][m][c] = p
+   charprop_stack_table[i][c][m] = p
   if g=='global' then
      for j,v in pairs(charprop_stack_table) do 
-       if not charprop_stack_table[j][m] then charprop_stack_table[j][m] = {} end
-       charprop_stack_table[j][m][c] = p
+       if not charprop_stack_table[j][c] then charprop_stack_table[j][c] = {} end
+       charprop_stack_table[j][c][m] = p
      end
   end
 end
@@ -117,14 +117,14 @@ function set_stack_font(g,m,c,p)
                         "The family number should in the range 0 .. 255.\n" ..
                          "I'm going to use 0 instead of that illegal family number.")
       c=0
-   elseif not charprop_stack_table[i][m] then 
-      charprop_stack_table[i][m] = {} 
+   elseif not charprop_stack_table[i][c] then 
+      charprop_stack_table[i][c] = {} 
    end
-   charprop_stack_table[i][m][c] = p
+   charprop_stack_table[i][c][m] = p
    if g=='global' then
      for j,v in pairs(charprop_stack_table) do 
-       if not charprop_stack_table[j][m] then charprop_stack_table[j][m] = {} end
-       charprop_stack_table[j][m][c] = p
+       if not charprop_stack_table[j][c] then charprop_stack_table[j][c] = {} end
+       charprop_stack_table[j][c][m] = p
      end
   end
 end
@@ -163,8 +163,13 @@ function fast_get_skip_table(m)
       or { width = 0, stretch = 0, shrink = 0, stretch_order = 0, shrink_order = 0 }
 end
 function fast_get_penalty_table(m,c)
-   local i = table_current_stack[m]
-   return (i and i[c])
+   local i = table_current_stack[c]
+   return (i and i[m])
+end
+
+local empty_table = {}
+function fast_get_penalty_table_parent(c)
+   return table_current_stack[c] or empty_table
 end
 
 -- For other situations, use the following instead:
@@ -173,8 +178,8 @@ function get_skip_table(m, idx)
       or { width = 0, stretch = 0, shrink = 0, stretch_order = 0, shrink_order = 0 }
 end
 function get_penalty_table(m,c,d, idx)
-   local i = charprop_stack_table[idx][m]
-   return (i and i[c]) or d
+   local i = charprop_stack_table[idx][c]
+   return (i and i[m]) or d
 end