OSDN Git Service

moved codes in test27-lineprofile.tex to ltj-{adjust,lineskip}.lua
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Tue, 24 Jul 2018 06:18:54 +0000 (15:18 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Tue, 24 Jul 2018 06:18:54 +0000 (15:18 +0900)
src/ltj-adjust.lua
src/ltj-direction.lua
src/ltj-lineskip.lua [new file with mode: 0644]
src/luatexja.lua
test/test27-lineprofile.pdf
test/test27-lineprofile.tex

index 7131bbc..e349258 100644 (file)
@@ -5,6 +5,7 @@ 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
@@ -437,3 +438,77 @@ end
 luatexja.unary_pars.adjust = function(t)
    return is_reg and 1 or 0
 end
+
+-- -----------------------------------
+ltjl.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 = 0, 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 = 0, 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 = 0 end
+      return lmin, 
+         bw - lmin - getfield(before, 'depth')
+             - getfield(after, mirrored and 'depth' or 'height')
+    end
+  end
+end
+
+do
+  local copy_glue = ltjl.copy_glue
+  local floor, max = math.floor, math.max
+  function ltjl.l_step(dist, g, adj, normal, bw)
+    if dist < tex.lineskiplimit then
+       local f = max(1, bw*ltjl.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
+
+
index 6915bcb..0df63db 100644 (file)
@@ -1059,45 +1059,7 @@ do
    end
 end
 
--- append_to_vlist filter
-do
-   local id_glue = node.id('glue')
-   local getglue = node.direct.getglue or
-      function(g)
-        return getfield(g,'width'), getfield(g,'stretch'), getfield(g,'shrink'),
-        getfield(g,'stretch_order'), getfield(g,'shrink_order')
-      end
-local setglue = luatexja.setglue
-   local function copy_glue (new_glue, old_glue, subtype, new_w)
-      setfield(new_glue, 'subtype', subtype)
-      local w,st,sp,sto,spo = getglue(to_direct(old_glue))
-      setglue(new_glue, new_w or w, st, sp, sto, spo)
-   end
-   local node_write = node.direct.write
-   local function dir_adjust_append_vlist(b, loc, prev, mirrored)
-      local old_b = to_direct(b)
-      local new_b = loc=='box' and 
-        make_dir_whatsit(old_b, old_b, get_dir_count(), 'append_vlist') or old_b
-      
-      if prev > -65536000 then
-        local d = tex.baselineskip.width - prev 
-           - getfield(new_b, mirrored and 'depth' or 'height')
-        local g = node_new(id_glue)
-        if d < tex.lineskiplimit then
-           copy_glue(g, tex.lineskip, 1)
-        else
-           copy_glue(g, tex.baselineskip, 2, d);
-        end
-        node_write(g)
-      end
-      node_write(new_b)
-      tex.prevdepth = getfield(new_b, mirrored and 'height' or 'depth')
-      return nil -- do nothing on tex side
-   end
-   ltjb.add_to_callback('append_to_vlist_filter',
-                       dir_adjust_append_vlist,
-                       'ltj.direction', 10000)
-end
+-- append_to_vlist filter: done in ltj-lineskip.lua
 
 -- finalize (executed just before \shipout)
 -- we supply correct pdfsavematrix nodes etc. inside dir_node
diff --git a/src/ltj-lineskip.lua b/src/ltj-lineskip.lua
new file mode 100644 (file)
index 0000000..dbbdebe
--- /dev/null
@@ -0,0 +1,110 @@
+--
+-- ltj-lineskip.lua
+--
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('direction'); local ltjd = luatexja.direction
+luatexja.lineskip = luatexja.lineskip or {}
+
+local to_direct, to_node = node.direct.todirect, node.direct.tonode
+local ltjl = luatexja.lineskip
+local id_glue = node.id('glue')
+local id_hlist = node.id('hlist')
+local setfield = node.direct.setfield
+local getfield = node.direct.getfield
+local getlist = node.direct.getlist
+local node_new = node.direct.new
+local node_prev = node.direct.getprev
+local node_next = node.direct.getnext
+local getid = node.direct.getid
+local getsubtype = node.direct.getsubtype
+
+local node_getglue = node.getglue
+local setglue = node.direct.setglue
+local function copy_glue (new_glue, old_glue, subtype, new_w)
+   setfield(new_glue, 'subtype', subtype)
+   local w,st,sp,sto,spo = node_getglue(old_glue)
+   setglue(new_glue, new_w or w, st, sp, sto, spo)
+end
+ltjl.copy_glue = copy_glue
+
+function ltjl.p_dummy(before, after)
+   return nil, 0
+end
+function ltjl.l_dummy(dist, g, adj, normal, bw)
+   if dist < tex.lineskiplimit then
+      copy_glue(g, tex.lineskip, 1, tex.lineskip.width + adj)
+   else
+      copy_glue(g, tex.baselineskip, 2, normal)
+   end
+end
+
+local ltj_profiler, ltj_skip = ltjl.p_dummy, ltjl.l_dummy
+function ltjl.setting(profiler, skip_method)
+   ltj_profiler = ltjl['p_'..tostring(profiler)] or ltjl.p_dummy
+   ltj_skip = ltjl['l_'..tostring(skip_method)] or ltjl.l_dummy
+end
+
+do
+   local traverse_id = node.direct.traverse_id
+   local function adjust_glue(nh)
+      local h = to_direct(nh)
+      local bw = tex.baselineskip.width
+      for x in traverse_id(id_glue, h) do
+        local xs = getsubtype(x)
+        if (xs==1) or (xs==2) then
+           local p, n = node_prev(x), node_next(x)
+           if p then
+              local pid = getid(p)
+             while (12<=pid) and (pid<=14) and node_prev(p) do p = node_prev(p); pid = getid(p) end
+             if pid==id_hlist and getid(n)==id_hlist then
+                local normal = bw - getfield(p, 'depth') - getfield(n, 'height')
+                local lmin, adj = ltj_profiler(p, n, false, bw)
+                ltj_skip(lmin or normal, x, adj, normal, bw)
+              end
+           end
+        end
+      end
+      return true
+   end
+   luatexbase.add_to_callback('post_linebreak_filter', 
+      adjust_glue, 'ltj.lineskip', 10000)
+end
+
+do
+   local make_dir_whatsit = luatexja.direction.make_dir_whatsit
+   local get_dir_count = luatexja.direction.get_dir_count
+   local node_write = node.direct.write
+
+   local function dir_adjust_append_vlist(b, loc, prev, mirrored)
+      local old_b = to_direct(b)
+      local new_b = loc=='box' and 
+        make_dir_whatsit(old_b, old_b, get_dir_count(), 'append_vlist') or old_b      
+      if prev > -65536000 then
+         local bw = tex.baselineskip.width
+        local normal = bw - prev 
+           - getfield(new_b, mirrored and 'depth' or 'height')
+         local lmin, adj = nil, 0
+         local tail = to_direct(tex.nest[tex.nest.ptr].tail)
+         if tail and getid(tail)==id_glue and getsubtype(tail)==3 then
+            tail = node_prev(tail)
+         end
+        if tail then
+           if getid(tail)==id_hlist and getid(new_b)==id_hlist then
+              if getfield(tail, 'depth')==prev then 
+                 lmin, adj = ltj_profiler(tail, new_b, mirrored, bw)
+              end
+           end
+        end
+        local g = node_new(id_glue)
+         ltj_skip(lmin or normal, g, adj, normal, bw)
+        node_write(g)
+      end
+      node_write(new_b)
+      tex.prevdepth = getfield(new_b, mirrored and 'height' or 'depth')
+      return nil -- do nothing on tex side
+   end
+   ltjb.add_to_callback('append_to_vlist_filter',
+                       dir_adjust_append_vlist,
+                       'ltj.lineskip', 10000)
+end
+
index 2fc1160..59204df 100644 (file)
@@ -102,13 +102,14 @@ if luatexja_debug then load_module('debug') end
 load_module('charrange'); local ltjc = luatexja.charrange
 load_module('stack');     local ltjs = luatexja.stack
 load_module('direction'); local ltjd = luatexja.direction -- +1 hlist +1 attr_list
+load_module('lineskip');  local ltjl = luatexja.lineskip -- +1 hlist +1 attr_list
 load_module('jfont');     local ltjf = luatexja.jfont
 load_module('inputbuf');  local ltji = luatexja.inputbuf
 load_module('pretreat');  local ltjp = luatexja.pretreat
 load_module('setwidth');  local ltjw = luatexja.setwidth
 load_module('jfmglue');   local ltjj = luatexja.jfmglue -- +1 glue +1 gs +1 attr_list
 load_module('math');      local ltjm = luatexja.math
-load_module('base');    local ltjb = luatexja.base
+load_module('base');      local ltjb = luatexja.base
 
 
 local attr_jchar_class = luatexbase.attributes['ltj@charclass']
index b112390..4ad2e86 100644 (file)
Binary files a/test/test27-lineprofile.pdf and b/test/test27-lineprofile.pdf differ
index 7fd402d..f05c48b 100644 (file)
 \documentclass[10ptj]{ltjsarticle}
 \usepackage[width=40\zw, lines=40,centering]{geometry}
-\usepackage{amsmath,luacode,xcolor}
-\begin{luacode}
-  lineskip = {}
-do
-  local insert = table.insert
-  local rangedimensions, max = node.rangedimensions, math.max
-  function lineskip.p_profile(before, after)
-    local t = {}
-    do
-      local w_acc, d_before = 0, 0
-      local x = before.head; local xn = x.next
-      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 = x.next end
-      end
-    end
-    do
-      local w_acc, h_before = 0, 0
-      local x = after.head; local xn = x.next
-      while x do
-        local w, h
-        if xn then w, h = rangedimensions(after,x,xn)
-        else w, h = rangedimensions(after,x) 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 = x.next 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 bls = tex.baselineskip.width
-      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 (bls-h-d)<lmin then lmin=bls-h-d end
-      end
-      if lmin==1/0 then lmin = 0 end
-      return lmin, bls - lmin - (before.depth+after.height)
-    end
-  end
-  function lineskip.p_dummy(before, after)
-    return nil, 0
-  end
-end
-do
-  local setglue = node.setglue
-  local floor, max = math.floor, math.max
-  function lineskip.l_dummy(dist, g, adj, normal)
-    if dist < tex.lineskiplimit then
-      local ng = tex.lineskip; g.subtype=1
-      setglue(g, ng.width + adj, ng.stretch, ng.shrink, ng.stretch_order, ng.shrink_order)
-    else
-      local ng = tex.baselineskip; g.subtype=2
-      setglue(g, normal, ng.stretch, ng.shrink, ng.stretch_order, ng.shrink_order)
-    end
-  end
-  function lineskip.l_step(dist, g, adj, normal)
-    if dist < tex.lineskiplimit then
-      local ng = tex.baselineskip; g.subtype=1
-      local f = max(1,ng.width*lineskip.step_factor)
-      setglue(g,
-        normal - f * floor((dist-tex.lineskip.width)/f),
-        ng.stretch, ng.shrink, ng.stretch_order, ng.shrink_order)
-    else
-      local ng = tex.baselineskip; g.subtype=2
-      setglue(g, normal, ng.stretch, ng.shrink, ng.stretch_order, ng.shrink_order)
-    end
-  end
-end
-
-  local l_profiler, l_skip = lineskip.p_dummy, lineskip.l_dummy
-  function lineskip.setting(profiler, skip_method)
-    l_profiler = lineskip['p_'..tostring(profiler)] or lineskip.p_dummy
-    l_skip = lineskip['l_'..tostring(skip_method)] or lineskip.l_dummy
-  end
-  
-do
-  luatexbase.add_to_callback('post_linebreak_filter',
-    function(h)
-      for x in node.traverse_id(12, h) do
-        if (x.subtype==1)or(x.subtype==2)then
-          local p, n = x.prev, x.next
-          if p then 
-            while ((p.id==14)or(p.id==12)or(p.id==13)) and p.prev do p = p.prev end
-            if p.id==0 and n.id==0 then
-              local normal = tex.baselineskip.width - p.depth - n.height
-              local lmin, adj; lmin, adj = l_profiler(p,n)
-              l_skip(lmin or normal,x,adj, normal)
-            end
-          end
-        end
-      end
-      return true
-    end, 'test', 10000
-  )
-end
-
-do
-  local to_direct, to_node = node.direct.todirect, node.direct.tonode
-  local make_dir_whatsit = luatexja.direction.make_dir_whatsit
-  local get_dir_count = luatexja.direction.get_dir_count
-  local function lineskip_append_vlist(b, loc, prev, mirrored)
-     local new_b = to_node(loc=='box' and 
-          make_dir_whatsit(to_direct(b), to_direct(b), get_dir_count(), 'append_vlist')) or b
-     local tail = tex.nest[tex.nest.ptr].tail
-     if tail and tail.id==12 and tail.subtype==3 then
-        tail = tail.prev
-     end
-     if tail and (prev > -65536000) then
-        local normal = tex.baselineskip.width - prev - new_b.height
-        local lmin, adj = nil, 0;
-        if tail.id==0 and new_b.id==0 then
-          if tail.depth==prev then lmin, adj = l_profiler(tail,new_b) end
-        end
-        local g = node.new(12); l_skip(lmin or normal, g, adj, normal)
-        node.write(g)
-      end
-      node.write(new_b)
-      tex.prevdepth = new_b.depth
-      return nil -- do nothing on tex side
-   end
-   luatexbase.remove_from_callback('append_to_vlist_filter','ltj.direction')
-   luatexja.base.add_to_callback('append_to_vlist_filter',
-                       lineskip_append_vlist,
-                       'line profile', 10000)
-end  
-\end{luacode}
+\usepackage{amsmath,luacode,xcolor,luatexja-adjust}
 \begin{document}
-\directlua{%
-  lineskip.step_factor = 0.5
-}
-
 % #1: null(TeX 既定) or profile(行の中身を考慮した行間測定)
 % #2: null(TeX 既定)
 %   or step(行送りが \baselineskip で十分でなかった場合,
 %            lineskip.step_factor * \baselineskip の倍数だけ広げて
 %            行間が \lineskip 以上になるようにする)
-\def\R#1#2{\directlua{lineskip.setting('#1','#2')}%
+\def\R#1#2{\directlua{luatexja.lineskip.setting('#1','#2')}%
 \noindent\fbox{\parbox{25\zw}{%
 \baselineskip14pt\noindent
 \setbox2=\vtop{\noindent\hsize20\zw\textcolor{cyan!30!white}{%