OSDN Git Service

Lua 5.3
[luatex-ja/luatexja.git] / src / ltj-adjust.lua
index 81a9ea8..382e760 100644 (file)
@@ -1,10 +1,12 @@
 --
 -- ltj-adjust.lua
 --
+luatexja.load_module('base');      local ltjb = luatexja.base
 luatexja.load_module('jfont');     local ltjf = luatexja.jfont
 luatexja.load_module('jfmglue');   local ltjj = luatexja.jfmglue
 luatexja.load_module('stack');     local ltjs = luatexja.stack
 luatexja.load_module('direction'); local ltjd = luatexja.direction
+luatexja.load_module('lineskip');  local ltjl = luatexja.lineskip
 luatexja.adjust = luatexja.adjust or {}
 
 local to_node = node.direct.tonode
@@ -67,7 +69,11 @@ do
    local function cmp(a,b) return a[1]>b[1] end -- 大きいほうが先!
    local function make_priority_table(glue_sign)
       for i,_ in pairs(tmp) do tmp[i]=nil end
-      for i=-2,2 do tmp[#tmp+1] = { i, FROM_JFM+i } end
+      if glue_sign==2 then -- shrink
+        for i=0,63 do tmp[#tmp+1] = { (i%8)-4, FROM_JFM+i } end
+      else -- stretch
+        for i=0,63 do tmp[#tmp+1] = { math.floor(i/8)-4, FROM_JFM+i } end
+      end    
       local pt = priority_table[glue_sign]
       tmp[#tmp+1] = { pt[2]/10, XKANJI_SKIP }
       tmp[#tmp+1] = { pt[2]/10, XKANJI_SKIP_JFM }
@@ -397,10 +403,11 @@ do
       return to_node(head)
    end
    local is_reg = false
-   function enable_cb(status_le, status_pr)
+   function enable_cb(status_le, status_pr, status_lp, status_ls)
       if (status_le>0 or status_pr>0) and (not is_reg) then
-        luatexbase.add_to_callback('post_linebreak_filter',
-                                   adjust_width, 'Adjust width', 100)
+        ltjb.add_to_callback('post_linebreak_filter',
+            adjust_width, 'Adjust width', 
+           luatexbase.priority_in_callback('post_linebreak_filter', 'ltj.lineskip')-1)
         is_reg = true
       elseif is_reg and (status_le==0 and status_pr==0) then
         luatexbase.remove_from_callback('post_linebreak_filter', 'Adjust width')
@@ -408,7 +415,7 @@ do
       end
       if status_le==2 then
         if not luatexbase.in_callback('luatexja.adjust_jfmglue', 'luatexja.adjust') then
-           luatexbase.add_to_callback('luatexja.adjust_jfmglue', insert_lineend_kern, 'luatexja.adjust')
+           ltjb.add_to_callback('luatexja.adjust_jfmglue', insert_lineend_kern, 'luatexja.adjust')
         end
          myaw_step1, myaw_step1_last = dummy, aw_step1_last
       else
@@ -422,9 +429,13 @@ do
          end
       end
       myaw_step2 = (status_pr>0) and aw_step2 or aw_step2_dummy
+      luatexja.lineskip.setting(
+         status_lp>0 and 'profile' or 'dummy',
+        status_ls>0 and 'step' or 'dummy'
+      )      
    end
    function disable_cb() -- only for compatibility
-       enable_cs(0)
+       enable_cs(0,0,0,0)
    end
    luatexja.adjust.enable_cb=enable_cb
    luatexja.adjust.disable_cb=disable_cb
@@ -433,3 +444,81 @@ end
 luatexja.unary_pars.adjust = function(t)
    return is_reg and 1 or 0
 end
+
+-- -----------------------------------
+luatexja.adjust.step_factor = 0.5
+do
+  local insert = table.insert
+  local rangedimensions, max = node.direct.rangedimensions, math.max
+  function ltjl.p_profile(before, after, mirrored, bw)
+    local t = {}
+    do
+      local w_acc, d_before = getfield(before,'shift'), 0
+      local x = getlist(before); local xn = node_next(x)
+      while x do
+        local w, d
+        if xn then w, _, d= rangedimensions(before,x,xn)
+        else w, _, d= rangedimensions(before,x) end
+        if d~=d_before then
+          d_before = d; t[w_acc] = t[w_acc] or {}
+          if t[w_acc][1] then t[w_acc][1]=max(t[w_acc][1],d)
+          else t[w_acc][1]=d end
+        end
+        w_acc = w_acc + w
+        x = xn; if x then xn = node_next(x) end
+      end
+    end
+    do
+      local w_acc, h_before = getfield(after,'shift'), 0
+      local x = getlist(after); local xn = node_next(x)
+      while x do
+        local w, h, d
+        if xn then w, h, d = rangedimensions(after,x,xn)
+       else w, h,d = rangedimensions(after,x) end
+       if mirrored then h=d end
+        if h~=h_before then
+          h_before = h; t[w_acc] = t[w_acc] or {}
+          if t[w_acc][2] then t[w_acc][2]=max(t[w_acc][2],h)
+          else t[w_acc][2]=h end
+        end
+        w_acc = w_acc + w
+        x = xn; if x then xn = node_next(x) end
+      end
+    end
+    local t2 = {}
+    for i,v in pairs(t) do insert(t2, { i, v[1], v[2] } ) end
+    table.sort(t2, function(a,b) return a[1]<b[1] end)
+    do
+      local dmax, d, hmax, h, lmin = 0, 0, 0, 0, 1/0
+      for i,v in ipairs(t2) do
+        d, h = (v[2] or d), (v[3] or h)
+        if d>dmax then dmax=d end
+        if h>hmax then hmax=h end
+        if (bw-h-d)<lmin then lmin=bw-h-d end
+      end
+      if lmin==1/0 then lmin = bw end
+      return lmin, 
+         bw - lmin - getfield(before, 'depth')
+             - getfield(after, mirrored and 'depth' or 'height')
+    end
+  end
+end
+
+do
+  local ltja = luatexja.adjust
+  local copy_glue = ltjl.copy_glue
+  local floor, max = math.floor, math.max
+  function ltjl.l_step(dist, g, adj, normal, bw, loc)
+    if loc=='alignment' then
+      return ltjl.l_dummy(dist, g, adj, normal, bw, loc)
+    end
+    if dist < tex.lineskiplimit then
+       local f = max(1, bw*ltja.step_factor)
+       copy_glue(g, tex.baselineskip, 1, normal - f * floor((dist-tex.lineskip.width)/f))
+    else
+       copy_glue(g, tex.baselineskip, 2, normal)
+    end
+  end
+end
+
+