OSDN Git Service

test27-lineprofile.tex: 行間計算方法のテスト
[luatex-ja/luatexja.git] / test / test27-lineprofile.tex
1 \documentclass[10ptj]{ltjsarticle}
2 \usepackage[width=40\zw, lines=40,centering]{geometry}
3 \usepackage{amsmath,luacode,xcolor}
4 \begin{luacode}
5   lineskip = {}
6 do
7   local insert = table.insert
8   local rangedimensions, max = node.rangedimensions, math.max
9   function lineskip.p_profile(before, after)
10     local t = {}
11     do
12       local w_acc, d_before = 0, 0
13       local x = before.head; local xn = x.next
14       while x do
15         local w, d
16         if xn then w, _, d= rangedimensions(before,x,xn)
17         else w, _, d= rangedimensions(before,x) end
18         if d~=d_before then
19           d_before = d; t[w_acc] = t[w_acc] or {}
20           if t[w_acc][1] then t[w_acc][1]=max(t[w_acc][1],d)
21           else t[w_acc][1]=d end
22         end
23         w_acc = w_acc + w
24         x = xn; if x then xn = x.next end
25       end
26     end
27     do
28       local w_acc, h_before = 0, 0
29       local x = after.head; local xn = x.next
30       while x do
31         local w, h
32         if xn then w, h = rangedimensions(after,x,xn)
33         else w, h = rangedimensions(after,x) end
34         if h~=h_before then
35           h_before = h; t[w_acc] = t[w_acc] or {}
36           if t[w_acc][2] then t[w_acc][2]=max(t[w_acc][2],h)
37           else t[w_acc][2]=h end
38         end
39         w_acc = w_acc + w
40         x = xn; if x then xn = x.next end
41       end
42     end
43     local t2 = {}
44     for i,v in pairs(t) do insert(t2, { i, v[1], v[2] } ) end
45     table.sort(t2, function(a,b) return a[1]<b[1] end)
46     do
47       local bls = tex.baselineskip.width
48       local dmax, d, hmax, h, lmin = 0, 0, 0, 0, 1/0
49       for i,v in ipairs(t2) do
50         d, h = (v[2] or d), (v[3] or h)
51         if d>dmax then dmax=d end
52         if h>hmax then hmax=h end
53         if (bls-h-d)<lmin then lmin=bls-h-d end
54         --print(v[1], d, h, bls-h-d)
55       end
56       return lmin, bls - lmin - (before.depth+after.height)
57     end
58   end
59   function lineskip.p_dummy(before, after)
60     local bls = tex.baselineskip.width
61     return nil, 0
62   end
63 end
64 do
65   local setglue = node.setglue
66   local floor, min = math.floor, math.min
67   function lineskip.l_dummy(dist, g, adj, normal)
68     if dist < tex.lineskiplimit then
69       local ng = tex.lineskip; g.subtype=2
70       setglue(g, ng.width + adj, ng.stretch, ng.shrink, ng.stretch_order, ng.shrink_order)
71     else
72       local ng = tex.baselineskip; g.subtype=2
73       setglue(g, normal, ng.stretch, ng.shrink, ng.stretch_order, ng.shrink_order)
74     end
75   end
76   function lineskip.l_fixed(dist, g, adj, normal)
77     local ng = tex.baselineskip; local f = ng.width*lineskip.fixed_factor
78     g.subtype=2
79     setglue(g,
80       normal - f * floor((dist-lineskip.fixed_mindist)/f),
81       ng.stretch, ng.shrink, ng.stretch_order, ng.shrink_order)
82   end
83 end
84
85   local l_profiler, l_skip = lineskip.p_dummy, lineskip.l_dummy
86   function lineskip.setting(profiler, skip_method)
87     l_profiler = lineskip['p_'..tostring(profiler)] or lineskip.p_dummy
88     l_skip = lineskip['l_'..tostring(skip_method)] or lineskip.l_dummy
89   end
90   
91   luatexbase.add_to_callback('post_linebreak_filter',
92     function(h)
93       for x in node.traverse_id(12, h) do
94         if (x.subtype==1)or(x.subtype==2)then
95           local p, n = x.prev, x.next
96           if p then 
97             while ((p.id==14)or(p.id==12)or(p.id==13)) and p.prev do p = p.prev end
98             if p.id==0 and n.id==0 then
99               local normal = tex.baselineskip.width - p.depth - n.height
100               local lmin, adj; lmin, adj = l_profiler(p,n)
101               l_skip(lmin or normal,x,adj, normal)
102               print(p.depth, x.width, n.height, p.depth+x.width+n.height)
103             end
104           end
105         end
106       end
107       return true
108     end, 'test', 10000
109   )
110 \end{luacode}
111 \begin{document}
112 \directlua{%
113   lineskip.fixed_mindist = tex.lineskip.width
114   lineskip.fixed_factor = 0.5
115 }
116
117
118 \def\R#1#2{\directlua{lineskip.setting('#1','#2')}%
119 \noindent\fbox{\parbox{25\zw}{%
120 \baselineskip14pt\noindent
121 \setbox2=\vtop{\noindent\hsize20\zw\textcolor{cyan!30!white}{%
122  □□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■
123  □□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■
124  □□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■
125  □□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■
126  □□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■
127  □□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■
128  □□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■
129  □□□□■□□□□■□□□□■□□□□■
130 }}\dp2=0pt\rlap{\copy2}\par\vspace*{-\baselineskip}
131 \textbf{#1, #2}\\
132 \the\baselineskip あああああああああああああああ\\
133 あああああああああ$X_{X_{X_X}}$ああああああ\\
134 ああああああああああああああああああ\\
135 ……であるから$b=\dfrac1{X_2}$となる.\\
136 一方$\dfrac{A^A}{B_B}=21$なので……\\
137 ……であるから$b=\dfrac1{X_2}$となる.\vadjust{あああああ$\dfrac34$}\\
138 一方$\dfrac{A^A}{B_B}=21$なので……
139
140 ……であるから$b=\dfrac1{X_2}$となる.\\
141 一方$\dfrac{A^A}{B_B}=21$なので……
142 }}\par}
143
144
145 \R{null}{null}
146 \R{profile}{null}
147 \R{null}{fixed}
148 \R{profile}{fixed}
149
150 \end{document}