OSDN Git Service

Commit 2f7b22e is somehow reverted.
[luatex-ja/luatexja.git] / src / ltj-adjust.lua
index ad7596e..4c418b3 100644 (file)
@@ -3,13 +3,13 @@
 --
 luatexbase.provides_module({
   name = 'luatexja.adjust',
-  date = '2012/09/27',
-  version = '0.1',
+  date = '2013/03/14',
   description = 'Advanced line adjustment for LuaTeX-ja',
 })
 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')
@@ -21,21 +21,25 @@ local set_attr = node.set_attribute
 local attr_icflag = luatexbase.attributes['ltj@icflag']
 local attr_jchar_class = luatexbase.attributes['ltj@charclass']
 local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
+local node_copy = node.copy
+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
-local KANJI_SKIP = 9
-local XKANJI_SKIP = 10
+local PACKED       = luatexja.icflag_table.PACKED
+local FROM_JFM     = luatexja.icflag_table.FROM_JFM
+local KANJI_SKIP   = luatexja.icflag_table.KANJI_SKIP
+local XKANJI_SKIP  = luatexja.icflag_table.XKANJI_SKIP
 
 local priority_table = {
-   XKANJI_SKIP,
    FROM_JFM + 2,
    FROM_JFM + 1,
    FROM_JFM,
    FROM_JFM - 1,
    FROM_JFM - 2,
+   XKANJI_SKIP,
    KANJI_SKIP
 }
 
@@ -56,6 +60,7 @@ local function get_stretched(q, go, gs)
    end
 end
 
+-- local new_ks, new_xs
 local function get_total_stretched(p)
    local go, gf, gs = p.glue_order, p.glue_set, p.glue_sign
    local res = {
@@ -65,12 +70,31 @@ 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
-   for q in node.traverse_id(id_glue, p.head) do
-      local a, ic = get_stretched(q, go, gs), get_attr_icflag(q)
-      --print(ic)
-      if   type(res[ic]) == 'number' then res[ic] = res[ic] + a
-      else                                res[0]  = res[0]  + a
+   local head = p.head
+   q = p.head
+   --luatexja.ext_show_node_list(p.head, '>>> ', print)
+   while q do 
+      if q.id==id_glue then
+         local a, ic = get_stretched(q, go, gs), get_attr_icflag(q)
+         if   type(res[ic]) == 'number' then 
+            -- kanjiskip, xkanjiskip は段落内で spec を共有しているが,
+            -- それはここでは望ましくないので,各 glue ごとに異なる spec を使う.
+            -- JFM グルーはそれぞれ異なる glue_spec を用いているので,問題ない.
+            res[ic] = res[ic] + a
+            if ic == KANJI_SKIP or ic == XKANJI_SKIP  then
+               if q.spec ~= spec_zero_glue then
+                  local ts, g; 
+                  q.spec, ts = node_copy(q.spec), q.spec
+                  g = node.copy(q); q.spec = ts
+                  node.insert_before(head, q, g);
+                  head = node.remove(head, q); node.free(q); q = g
+               end
+            end
+         else 
+            res[0]  = res[0]  + a
+         end
       end
+      q = node_next(q)
    end
    return res
 end
@@ -87,15 +111,23 @@ local function clear_stretch(p, ic, name)
    end
 end
 
+local set_stretch_table = {}
 local function set_stretch(p, after, before, ic, name)
    if before > 0 then
       --print (ic, before, after)
       local ratio = after/before
+      for i,_ in pairs(set_stretch_table) do
+         set_stretch_table[i] = nil
+      end
       for q in node.traverse_id(id_glue, p.head) do
          if get_attr_icflag(q) == ic then
-            local qs = q.spec
-            if qs.writable and qs[name..'_order'] == 0 then
-               qs[name] = qs[name]*ratio
+            local qs, do_flag = q.spec, true
+            for i=1,#set_stretch_table do 
+               if set_stretch_table[i]==qs then do_flag = false end 
+            end
+            if qs.writable and qs[name..'_order'] == 0 and do_flag then
+               qs[name] = qs[name]*ratio; 
+               set_stretch_table[#set_stretch_table+1] = qs
             end
          end
       end
@@ -113,23 +145,23 @@ local function aw_step1(p, res, total)
       x = node.prev(node.prev(x)) 
    end
 
-   local xc
-   if x.id == id_glyph and has_attr(x, attr_curjfnt) == x.font then
+   local xi, xc = x.id
+   if xi == id_glyph and has_attr(x, attr_curjfnt) == x.font then
       -- 和文文字
       xc = x
-   elseif x.id == id_hlist and get_attr_icflag(x) == PACKED then
+   elseif xi == id_hlist and get_attr_icflag(x) == PACKED then
       -- packed JAchar
       xc = x.head
    else
      return false-- それ以外は対象外.
    end
    local xk = ltjf_font_metric_table -- 
-     [xc.font].size_cache.char_type[has_attr(xc, attr_jchar_class) or 0]
+     [xc.font].char_type[has_attr(xc, attr_jchar_class) or 0]
      ['end_' .. res.name] or 0
-     print(res.name, total, xk, unicode.utf8.char(xc.char))
+     --print(res.name, total, xk, unicode.utf8.char(xc.char))
 
    if xk>0 and total>=xk then
-      print("ADDED")
+      --print("ADDED")
       total = total - xk
       local kn = node.new(id_kern)
       kn.kern = (res.name=='shrink' and -1 or 1) * xk
@@ -192,9 +224,23 @@ function adjust_width(head)
             end
          end; total = tex.round(total * res.glue_set)
          local added_flag = aw_step1(p, res, total)
+         --print(total, res[0], res[KANJI_SKIP], res[FROM_JFM])
          aw_step2(p, res, total, added_flag)
       end
    end
    return head
 end
 
+local is_reg = false
+function enable_cb()
+   if not is_reg then
+      luatexbase.add_to_callback('post_linebreak_filter', adjust_width, 'Adjust width', 100)
+      is_reg = true
+   end
+end
+function disable_cb()
+   if is_reg then
+      luatexbase.remove_from_callback('post_linebreak_filter', 'Adjust width')
+      is_reg = false
+   end
+end