OSDN Git Service

Fixed jfmglue.lua and updated documents.
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Mon, 20 Jun 2011 14:04:46 +0000 (23:04 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Mon, 20 Jun 2011 14:04:46 +0000 (23:04 +0900)
doc/jfmglue.pdf
doc/jfmglue.tex
doc/sample1.pdf
doc/sample1.tex
src/luatexja-core.lua
src/luatexja/jfmglue.lua
test/test04-jfm.pdf
test/test04-jfm.tex
test/test05-speed.pdf
test/test05-speed.tex

index 04a2bcc..5e01ed8 100644 (file)
Binary files a/doc/jfmglue.pdf and b/doc/jfmglue.pdf differ
index a9a5fed..5a26699 100644 (file)
@@ -25,7 +25,8 @@
 
 \bigskip
 {\large\bf\noindent これは仕様・内部処理の提案の1つにしかすぎません.最終的にこのようになる
-保証はどこにもありませんし,これを書いている時点では実際のLuaコードは書きあがっていません.}
+保証はどこにもありませんし,現時点でのLuaコードが本文書に従っている保証もありません.
+バグが混入している可能性も大きいです.}
 
 \beginsection 予備知識
 
@@ -56,16 +57,17 @@ $$
 $$
 \vbox{\halign{#:\ \hfil&#\hfil\quad&#:\ \hfil&#\hfil\cr
 1&イタリック補正由来のkern &
-2&禁則処理用penalty\cr
-3&JFM由来のglue/kern&
-4&「行末」との間に入るkern\cr
-5&|\kanjiskip|用glue&
-6&|\xkanjiskip|用glue\cr
-7&リスト先頭/末尾に入るglue/kern/penalty&
+2&幅補正のため,hboxにカプセル化された和文文字\cr
+3&禁則処理用penalty&
+4&JFM由来のglue/kern\cr
+5&「行末」との間に入るkern&
+6&|\kanjiskip|用glue\cr
+7&|\xkanjiskip|用glue&
 8&既に処理対象となったnode\cr
+15&リスト先頭/末尾に入るglue/kern/penalty\span\omit\span\cr
 }}
 $$
-和文処理グルーの挿入処理に一度通されたnodeは,みなicflagが2以上となることに注意.
+和文処理グルーの挿入処理に一度通されたnodeは,みなicflagが3以上となることに注意.
 
 なお,上添字はnodeのsubtypeを表す.
 \item {\sf jaxspmode}のようなサンセリフ体で,|\ltjsetparameter|で設定可能なパラメタ値を表す.
@@ -127,12 +129,12 @@ $$
 \medskip\noindent{\bf 定義}\quad
 「{\bf 塊}」(\IT{Nn}などで表す)とは,次の4つのいずれかの条件を満たすnode(達のリスト)
 のことである:
-\enum icflagが2以上6以下 or 8であるnode達の連続からなるリスト.
+\enum icflagが3以上15未満であるnode達の連続からなるリスト.
 
 このようなnode達は,既に組み上がったhboxを|\unpackage|により解体したときに発生する.
 一度和文処理グルーの挿入処理が行われているため,二重の処理を防ぐためにこうして1つの塊を構成させている.
 
-なお,icflagが7であるnodeは,処理中に発見されしだい削除される
+なお,icflagが15であるnodeは,処理中に発見されしだい削除される
 (hboxの先頭や末尾に挿入されたglue/kern/penaltyであるので,
 本来の「段落/hboxの中身に適宜グルーを挿入する」という目的を考えると存在すべきでない).
 \enum 数式開始を表す\IT{math\_node}から始まる文中数式を表すnodeのリスト:
@@ -149,6 +151,8 @@ $$
  \node{p}
  \Bigl[\node{\nk\hskip-.5em}_1\Bigr]
 $$
+但し,これには$p$が${\rm icflag}=2$のhboxである場合も含む.%
+{\small ←この場合の処理は実はおこらない?}
 \enum {\bf 以下のどれにもあてはまらない}node~$p$:
 \itemitem 組版結果からは消えてしまう,\IT{ins\_node}, 
 \IT{mark\_node}, \IT{adjust\_node}, \IT{whatsit\_node}.
@@ -173,7 +177,7 @@ $$
 \item \IT{.id}: \IT{Np}の種類を表す値.
 \itemitem 1.によるものである場合,\IT{id\_pbox}(Pseudo BOXのつもり).
 \itemitem 3.によるものであり,$p$が和文文字だった場合,\IT{id\_jglyph}.
-\itemitem 3.によるものであり,$p$が垂直変位がnon-zeroなhbox,
+\itemitem 4.によるものであり,$p$が垂直変位がnon-zeroなhbox,
 あるいはvbox, ruleだった場合,\IT{id\_box\_like}.
 \itemitem それ以外の場合,node~$p$の種別を表す数値$p.\mibox{id}$そのもの.
 (数値そのものだと使い勝手が悪いので,\IT{id\_glyph}, \IT{id\_glue}, \IT{id\_kern}などと
@@ -286,8 +290,10 @@ $\mibox{tail}(\mibox{Np})$の情報を算出する.終わったら,再びル
 \enditem
 $$
 \vcenter{\halign{$\mibox{mode}=#$:\qquad\hfil&$#$\hfil\cr
-\bot&\node{\kern-1em}\,\hbox{(リスト先頭)}\longrightarrow\cdots\node{g}_7\node{\mibox{Np}}\cr
-\top&\node{\hbox{{\tt\char92 parindent}由来hbox}}\longrightarrow\cdots\Bigl[\node{\np 10000}_7\Bigr]\node{g}_7\node{\mibox{Np}}\cr
+\bot&\node{\kern-1em}\,\hbox{(リスト先頭)}\longrightarrow\cdots\node{g}_{15}
+\node{\mibox{Np}}\cr
+\top&\node{\hbox{{\tt\char92 parindent}由来hbox}}\longrightarrow\cdots
+\Bigl[\node{\np 10000}_{15}\Bigr]\node{g}_{15}\node{\mibox{Np}}\cr
 }}
 $$
 ここで,$g$がglueかつ$\mibox{mode}=\top$かつ$\#\mibox{Bp}=0$のときのみ,|\parindent|由来のhboxの直後で改行されることを防ぐために
@@ -312,7 +318,7 @@ penaltyのため,\IT{Np}の直前での改行が起こり得る状態となっ
 \item $\mibox{Nq.id}=\mibox{id\_pbox}$であり,$\mibox{tail}(\mibox{Nq})$が和文文字であるとき.
 \enditem
 $$
-\node{\mibox{Nq}}\node{g}_7\longrightarrow\cdots\node{\nk\hbox{(番人)}}
+\node{\mibox{Nq}}\node{g}_{15}\longrightarrow\cdots\node{\nk\hbox{(番人)}}
 $$
 上の番人は,次のstepで除去されるのだった.
 
@@ -326,7 +332,7 @@ $$
 \item $\mibox{Nq.id}=\mibox{id\_pbox}$であり,$\mibox{tail}(\mibox{Nq})$が和文文字であるとき.
 \enditem
 $$
-\node{\mibox{Nq}}\node{\nk w}_7\node{\np10000}\longrightarrow\cdots
+\node{\mibox{Nq}}\node{\nk w}_{15}\node{\np10000}\longrightarrow\cdots
 \node{\ng (\hbox{\tt\char92 parfillskip})}
 $$
 次に,|\jcharwidowpenalty|の挿入処理を行う→省略.
index 4ca0be8..e078cbb 100644 (file)
Binary files a/doc/sample1.pdf and b/doc/sample1.pdf differ
index 19bdb49..e5e4e07 100644 (file)
@@ -97,7 +97,6 @@ JFM は和文文字の幅や,和文文字間の空白の入り方などを規
   \globaljfont<font>={<font_name>:<features>} <size> % global に定義
 \endtt
 
-
 \item {\bf <font_name> の指定について}\par\noindent
 内部でluaotfloadパッケージを読み込んでいる.大きくわけて,以下の4種類がある.
 このうち,前の2つはluaotfloadパッケージの機能である.
@@ -437,9 +436,11 @@ $i$番の文字クラスの文字と$j$番の文字クラスの文字の間に
 \beginsection 互換用命令(書きかけ)
 
 {\tt luatexja-compat.sty}を読み込むことで,次が追加.
-\item |\euc|, |\jis|, |\sjis|, |\kuten|, |\ucs|: up\TeX と同じ動作.
+\item |\euc|, |\jis|, |\sjis|, |\kuten|, |\ucs|: 
+それぞれEUC-JP,ISO-2022-JP,Shift-JIS,区点コードからUnicodeへの変換を行う.
+JIS~X~0208→Unicodeへの変換テーブルとしては,up\TeX-0.30で用いられているものを利用している.
 \item |\kansuji|
-\item |kansujichar={<num>, <char>}| key in |\ltjsetparameter|.
+\item |kansujichar={<num>, <char>}|~key in |\ltjsetparameter|.
 \enditem
 
 
@@ -490,47 +491,9 @@ $p$は「現在の和文フォント」の番号もattribute |\ltj@curjfnt|と
 
 \item {\bf (luaotfloadパッケージによるグリフ置換等の処理はこの位置で)}
 
-\item {\bf JFM由来glue/kernの挿入: |pre_linebreak_filter|, |hpack_filter| callbacks}
-
-ここで,JFMに由来する和文文字間のglue/kernを挿入する.
-基本的には連続する和文文字(を表すnode)間に挿入するが,
-\itemitem 水平ボックスの先頭/末尾,段落の先頭/末尾には「文字コード|'boxbdd'|の文字」があると
-見做して空白を挿入する.
-\itemitem 和文文字とそうでないもの(欧文文字,ボックス等)の間に関しては,
-和文文字でない方は「文字コード|'jcharbdd'|の文字」であると見做す.
-\itemitem フォントの異なる2つの和文文字においても,
-両者のフォントのJFMとsizeが一致した場合は,
-挿入処理においては「同じフォント」であるかのように扱う.
-\itemitem  そうでない場合は,両者の間に「文字コード|'diffmet'|の文字」があると見做して,
-両和文文字からそれぞれglue/kern |gb|, |ga|を計算し,そこから実際に入るglue/kernを
-計算している(|\ltjsetparameter|中の|differentjfm|キーを参照).
-\itemitem もうちょっと詳しく書くと,本処理前において,和文文字を表す
-2つの連続した|glyph_node| $Q$, $P$の間には,次のnode達が挿入される:
-$$
- \ldots,\ Q,\ (\hbox{|\kern|}\ w\,{\rm pt}),\ (\hbox{|\penalty|}\ p),\ 
-(\hbox{|\kern|}\ (k-w)\,{\rm pt})
-,\ P,\ \ldots
-$$
-上に書いた全てのnodeが挿入されるとは限らず,また4つめのkernもglueに変わる可能性がある.
-上に出てきた量の意味は次の通りである:
-\itemT $w$: $Q$が行末にきたときに,行末からどれだけずらすかを指定した量.
-\itemT $p$: $Q$の行末禁則用penaltyと$P$の行頭禁則用penaltyの合計値.ウィドウ防止用の
-|\jcharwidowpenalty|が挿入される時は,値はここに加算される.
-\itemT |\kern| $k$: 本来の$Q$と$P$の間に入る空き(glueであることも).
-$w$のために自然長を補正している.
-
-\item {\bf |kanjiskip|, |xkanjiskip|の挿入: |pre_linebreak_filter|, |hpack_filter| callbacks}
-
-p\TeX の|adjust_hlist| procedureとほぼ同様の処理を用いて,
-和文間glue |kanjiskip|や和欧文間glue |xkanjiskip|を
-挿入する.
-\itemitem 数式境界 (|math_node|) との間に|xkanjiskip|を自動挿入するかの決定は,
-p\TeX では数字{\tt 0}との間に挿入するかどうかで判定していたが,Lua\TeX-jaでは
-「文字コード$-1$の文字」で判定している.
-\itemitem 合字の周囲の空白挿入については,構成要素の文字列を通じて判断している.例えば,
-「漢ffi字」という文字列に対して,
-\itemT 「漢」と「ffi」間の空白挿入:「漢」と「f」間に入るかで判断
-\itemT 「ffi」と「字」間の空白挿入:「i」と「字」間に入るかで判断
+\item {\bf 和文処理グルーの挿入: |pre_linebreak_filter|, |hpack_filter| callbacks}
+
+動作については,{\tt jfmglue.pdf}(未完)を参照.
 
 \item {\bf ベースライン補正: |pre_linebreak_filter|, |hpack_filter| callbacks}
 
index 5a73fa5..c2c2468 100644 (file)
@@ -39,14 +39,14 @@ local ljfm_find_char_class = ltj.int_find_char_class
 
 
 local ITALIC = 1
-local KINSOKU = 2
-local FROM_JFM = 3
-local LINE_END = 4
-local KANJI_SKIP = 5
-local XKANJI_SKIP = 6
-local BOXBDD = 7
+local PACKED = 2
+local KINSOKU = 3
+local FROM_JFM = 4
+local LINE_END = 5
+local KANJI_SKIP = 6
+local XKANJI_SKIP = 7
 local PROCESSED = 8
-local PACKED = 9
+local BOXBDD = 15
 
 ------------------------------------------------------------------------
 -- naming:
@@ -272,7 +272,7 @@ local function main4_get_hss()
    return hss
 end
 
-local function main4_set_ja_width(head)
+local function main4_set_ja_width(head, dir)
    local p = head
    local met_tb, t, s, g, q, a, h
    local m = false -- is in math mode?
@@ -288,19 +288,32 @@ local function main4_set_ja_width(head)
               not(s.left==0.0 and s.down==0.0 and s.align=='left' 
                   and round(s.width*met_tb.size)==p.width) then
               -- must be encapsuled by a \hbox
-              head, q = node.remove(head,p)
-              p.next = nil
-              p.yoffset=round(p.yoffset-met_tb.size*s.down)
-              p.xoffset=round(p.xoffset-met_tb.size*s.left)
-              if s.align=='middle' or s.align=='right' then
-                 h = node_insert_before(p, p, main4_get_hss())
-              else h=p end
-              if s.align=='middle' or s.align=='left' then
-                 node_insert_after(h, p, main4_get_hss())
+              head, q = node.remove(head, p)
+              local full_width = round(s.width*met_tb.size)
+              p.yoffset=p.yoffset-round(met_tb.size*s.down)
+              p.xoffset=p.xoffset-round(met_tb.size*s.left)
+              
+              -- The next if block sets h:=(head of a new list)
+              if s.align=='left' then
+                 h = node_new(id_kern); h.subtype = 0
+                 h.kern = full_width - p.width
+                 p.next = h; h = p
+              elseif s.align=='right' then
+                 h = node_new(id_kern); h.subtype = 0
+                 h.kern = full_width - p.width
+                 p.next = nil; h.next = p
+              elseif s.align=='middle' then
+                 local total = full_width - p.width
+                 h = node_new(id_kern); h.subtype = 0
+                 h.kern = round(total/2); p.next = h
+                 h = node_new(id_kern); h.subtype = 0
+                 h.kern = total - round(total/2); h.next = p
               end
-              g = node_hpack(h, round(met_tb.size*s.width), 'exactly')
+              g = node_new(id_hlist); g.width = full_width
               g.height = round(met_tb.size*s.height)
               g.depth = round(met_tb.size*s.depth)
+              g.glue_set = 0; g.glue_order = 0; g.head = h
+              g.shift = 0; g.dir = dir or 'TLT'
               node.set_attribute(g, attr_icflag, PACKED)
               if q then
                  head = node_insert_before(head, q, g)
@@ -330,10 +343,10 @@ end
 
 -- main process
 -- mode = true iff main_process is called from pre_linebreak_filter
-local function main_process(head, mode)
+local function main_process(head, mode, dir)
    local p = head
    p = ltjj.main(p,mode)
-   p = main4_set_ja_width(p)
+   p = main4_set_ja_width(p, dir)
    return p
 end
 
@@ -362,12 +375,13 @@ function debug_show_node_X(p,print_fn)
    local k = debug_depth
    local s
    local pt=node_type(p.id)
+   local base = debug_depth .. string.format('%X', has_attr(p,attr_icflag) or 0) 
+     .. ' ' .. pt .. ' ' ..  p.subtype 
    if pt == 'glyph' then
-      print_fn(debug_depth.. ' GLYPH  ', p.subtype, utf.char(p.char), p.font)
+      print_fn(base, utf.char(p.char), p.font)
    elseif pt=='hlist' then
-      s = debug_depth .. ' hlist  ' ..  p.subtype
-        .. '(' .. print_scaled(p.height) .. '+' .. print_scaled(p.depth) .. ')x'
-         .. print_scaled(p.width)
+      s = base .. '(' .. print_scaled(p.height) .. '+' 
+         .. print_scaled(p.depth) .. ')x' .. print_scaled(p.width)
       if p.glue_sign >= 1 then 
         s = s .. ' glue set '
         if p.glue_sign == 2 then s = s .. '-' end
@@ -390,8 +404,7 @@ function debug_show_node_X(p,print_fn)
       end
       debug_depth=k
    elseif pt == 'glue' then
-      s = debug_depth.. ' glue   ' ..  p.subtype 
-        .. ' ' ..  print_spec(p.spec)
+      s = base .. ' ' ..  print_spec(p.spec)
       if has_attr(p, attr_icflag)==FROM_JFM then
            s = s .. ' (from JFM)'
       elseif has_attr(p, attr_icflag)==KANJI_SKIP then
@@ -401,12 +414,11 @@ function debug_show_node_X(p,print_fn)
       end
       print_fn(s)
    elseif pt == 'kern' then
-      s = debug_depth.. ' kern   ' ..  p.subtype
-        .. ' ' .. print_scaled(p.kern) .. 'pt'
-      if has_attr(p, attr_icflag)==ITALIC then
+      s = base .. ' ' .. print_scaled(p.kern) .. 'pt'
+      if p.subtype==2 then
+        s = s .. ' (for accent)'
+      elseif has_attr(p, attr_icflag)==ITALIC then
         s = s .. ' (italic correction)'
-      elseif has_attr(p, attr_icflag)==TEMPORARY then
-        s = s .. ' (might be replaced)'
       elseif has_attr(p, attr_icflag)==FROM_JFM then
         s = s .. ' (from JFM)'
       elseif has_attr(p, attr_icflag)==LINE_END then
@@ -414,13 +426,13 @@ function debug_show_node_X(p,print_fn)
       end
       print_fn(s)
    elseif pt == 'penalty' then
-      s = debug_depth.. ' penalty ' ..  tostring(p.penalty)
+      s = base .. ' ' .. tostring(p.penalty)
       if has_attr(p, attr_icflag)==KINSOKU then
         s = s .. ' (for kinsoku)'
       end
       print_fn(s)
    elseif pt == 'whatsit' then
-      s = debug_depth.. ' whatsit ' ..  tostring(p.subtype)
+      s = base .. ' subtype: ' ..  tostring(p.subtype)
       if p.subtype==sid_user then
         s = s .. ' user_id: ' .. p.user_id .. ' ' .. p.value
       else
@@ -428,7 +440,7 @@ function debug_show_node_X(p,print_fn)
       end
       print_fn(s)
    else
-      print_fn(debug_depth.. ' ' .. node.type(p.id), p.subtype)
+      print_fn(base)
    end
    p=node_next(p)
 end
@@ -437,9 +449,9 @@ end
 -- callbacks
 luatexbase.add_to_callback('pre_linebreak_filter', 
    function (head,groupcode)
-     return main_process(head, true)
+      return main_process(head, true, tex.textdir)
    end,'ltj.pre_linebreak_filter',2)
 luatexbase.add_to_callback('hpack_filter', 
-  function (head,groupcode,size,packtype)
-     return main_process(head, false)
+  function (head,groupcode,size,packtype, dir)
+     return main_process(head, false, dir)
   end,'ltj.hpack_filter',2)
index 140b622..5e5c256 100644 (file)
@@ -48,14 +48,14 @@ local id_pbox = node.id('hlist') + 512
 local sid_user = node.subtype('user_defined')
 
 local ITALIC = 1
-local KINSOKU = 2
-local FROM_JFM = 3
-local LINE_END = 4
-local KANJI_SKIP = 5
-local XKANJI_SKIP = 6
-local BOXBDD = 7
+local PACKED = 2
+local KINSOKU = 3
+local FROM_JFM = 4
+local LINE_END = 5
+local KANJI_SKIP = 6
+local XKANJI_SKIP = 7
 local PROCESSED = 8
-local PACKED = 9
+local BOXBDD = 15
 
 local kanji_skip
 local xkanji_skip
@@ -154,7 +154,7 @@ local function check_box(box_ptr, box_end)
       find_first_char = false; first_char = nil; last_char = nil
       return true
    end
-   while p~=box_end do
+   while p and p~=box_end do
       local pid = p.id
       if pid==id_kern then
         if p.subtype==2 then
@@ -169,20 +169,20 @@ local function check_box(box_ptr, box_end)
               first_char = p; find_first_char = false
            end
            last_char = p; found_visible_node = true; p=node_next(p)
-           if not p then return found_visible_node end
+           if (not p) or p==box_end then return found_visible_node end
         until p.id~=id_glyph
       end
       if pid==id_hlist then
         if has_attr(p, attr_icflag)==PACKED then
            for q in node.traverse_id(id_glyph, p.head) do
               if find_first_char then
-                 first_char = q; find_first_char = false
+                 first_char = q; find_first_char = false
               end
-              last_char = q; found_visible_node = true
+              last_char = q; found_visible_node = true; break
            end
         else
            if p.shift==0 then
-              if check_box(p.head) then found_visible_node = true end
+              if check_box(p.head, nil) then found_visible_node = true end
            else if find_first_char then 
                  find_first_char = false
               else 
@@ -213,14 +213,27 @@ local function check_next_ickern()
    else Np.last = Np.nuc end
 end
 
+local function calc_np_pbox()
+   Np.first = lp; Np.id = id_pbox
+   lpa = KINSOKU -- dummy
+   while lp~=last and lpa>=KINSOKU and lpa~=BOXBDD do
+      Np.nuc = lp; lp = node_next(lp); lpa = has_attr(lp, attr_icflag) or 0
+   end
+   check_next_ickern()
+end
+
 local function calc_np()
    -- We assume lp = node_next(Np.last)
-   local pBp = Bp
-   local lpi, lpa
+   local pBp = Bp; local lpi, lpa
    Nq = Np; Bp = {}; Bp[0] = 0; Np = {}; ihb_flag = false 
    while true do
       lpi = lp.id; lpa = has_attr(lp, attr_icflag) or 0
       if lp==last then Np = nil; return
+      elseif lpa>=PACKED then -- elseif lpa>=KINSOKU then 
+        if lpa == BOXBDD then
+           local lq = node_next(lp)
+           head = node_remove(head, lp); lp = lq
+        else calc_np_pbox(); return end -- id_pbox
       elseif lpi == id_ins or lpi == id_mark or lpi == id_adjust then
         lp = node_next(lp)
       elseif lpi == id_penalty then
@@ -234,23 +247,17 @@ local function calc_np()
         end
       else -- a `cluster' is found
         Np.first = lp
-        if lpa >=2 then
-           if lpa == BOXBDD then
-              local lq = node_next(lp)
-              head = node_remove(head, lp); lp = lq
-           else -- id_pbox
-              Np.id = id_pbox; Np.nuc = lp
-              while lp~=last and lpa>=2 and lpa~=7 do
-                 lp = node_next(lp); lpa = has_attr(lp, attr_icflag) or 0
-              end
-              Np.last = lp; check_next_ickern(); return
-           end
-        elseif lpi == id_glyph then -- id_[j]glyph
+        if lpi == id_glyph then -- id_[j]glyph
            if lp.font == has_attr(lp, attr_curjfnt) then Np.id = id_jglyph 
            else Np.id = id_glyph end
            Np.nuc = lp; lp = node_next(lp); check_next_ickern(); return
         elseif lpi == id_hlist then -- hlist
-           Np.nuc = lp; Np.last = lp
+           Np.last = lp; Np.nuc = lp
+           --if lpa == PACKED then
+           --   Np.id = id_jglyph
+           --   for q in node.traverse_id(id_glyph, lp.head) do
+           --    Np.nuc = q; break
+           --   end
            if lp.shift~=0 then Np.id = id_box_like
            else Np.id = lpi end
            lp = node_next(lp); return
@@ -258,11 +265,12 @@ local function calc_np()
            Np.nuc = lp; Np.last = lp; Np.id = id_box_like; break
         elseif lpi == id_math then -- id_math
            Np.nuc = lp; lp  = node_next(lp)
-           while lp.id~=id_math do lp  = node_next(lp) end
-           break
+           while lp.id~=id_math do lp  = node_next(lp) end; break
         elseif lpi == id_kern and lp.subtype==2 then -- id_kern
-           lp = node_next(node_next(node_next(lp))) 
-           Np.nuc = lp ; lp = node_next(lp); check_next_ickern(); return
+           lp = node_next(node_next(node_next(lp))); Np.nuc = lp
+           if lp.font == has_attr(lp, attr_curjfnt) then Np.id = id_jglyph 
+           else Np.id = id_glyph end
+           lp = node_next(lp); check_next_ickern(); return
         else -- id_disc, id_glue, id_kern
            Np.nuc = lp; break
         end
@@ -346,7 +354,7 @@ local function extract_np()
       end
    elseif Np.id == id_pbox then --  mikann 
       find_first_char = true; first_char = nil; last_char = nil
-      if check_box(Np.first, Np.last) then
+      if check_box(Np.first, node_next(Np.last)) then
         if first_char then
            if first_char.font == has_attr(first_char, attr_curjfnt) then 
               set_np_xspc_jachar(first_char.char,first_char)
@@ -409,37 +417,35 @@ local function lineend_fix(g)
 end
 
 -- change penalties (or create a new penalty, if needed)
-local function handle_penalty_normal(pre, post, g)
+local function handle_penalty_normal(post, pre, g)
    local a = (pre or 0) + (post or 0)
    if Bp[0] == 0 then
-      if (a~=0 and not(g and g.id==id_kern)) or Nq.lend~=0 then
+      if (a~=0 and not(g and g.id==id_kern)) or (Nq.lend and Nq.lend~=0) then
         local p = node_new(id_penalty)
         if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
         p.penalty = a
         head = node_insert_before(head, Np.first, p)
         Bp[1] = p; Bp[0] = 1; set_attr(p, attr_icflag, KINSOKU)
       end
-   else
-      for i, v in ipairs(Bp) do add_penalty(v,a) end
+   else for i, v in ipairs(Bp) do add_penalty(v,a) end
    end
 end
 
-local function handle_penalty_always(pre, post, g)
+local function handle_penalty_always(post, pre, g)
    local a = (pre or 0) + (post or 0)
    if Bp[0] == 0 then
-      if not (g and g.id==id_glue) or Nq.lend~=0 then
+      if not (g and g.id==id_glue) or (Nq.lend and Nq.lend~=0) then
         local p = node_new(id_penalty)
         if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
         p.penalty = a
         head = node_insert_before(head, Np.first, p)
         Bp[1] = p; Bp[0] = 1; set_attr(p, attr_icflag, KINSOKU)
       end
-   else
-      for i, v in ipairs(Bp) do add_penalty(v,a) end
+   else for i, v in ipairs(Bp) do add_penalty(v,a) end
    end
 end
 
-local function handle_penalty_suppress(pre, post, g)
+local function handle_penalty_suppress(post, pre, g)
    local a = (pre or 0) + (post or 0)
    if Bp[0] == 0 then
       if g and g.id==id_glue then
@@ -447,8 +453,7 @@ local function handle_penalty_suppress(pre, post, g)
         p.penalty = 10000; head = node_insert_before(head, Np.first, p)
         Bp[1] = p; Bp[0] = 1; set_attr(p, attr_icflag, KINSOKU)
       end
-   else
-      for i, v in ipairs(Bp) do add_penalty(v,a) end
+   else for i, v in ipairs(Bp) do add_penalty(v,a) end
    end
 end
 
@@ -673,12 +678,12 @@ local function handle_nq_jachar()
 end
 
 -- (anything) .. (和文文字で終わる hlist)
-local function handle_nq_ja_hlist()
+local function handle_np_ja_hlist()
    local g = nil
-   if Nq.id==id_jglyph or (Nq.id==id_pbox and Nq.pre) then 
+   if Nq.id==id_jglyph or (Nq.id==id_pbox and Nq.met) then 
       g = get_OB_skip() or get_kanjiskip() -- O_B->K
       g = lineend_fix(g)
-      handle_penalty_normal(Nq.post, Np.pre, g); real_insert(Nq.lend, g)
+      handle_penalty_normal(Nq.post, 0, g); real_insert(Nq.lend, g)
    elseif Nq.met then  -- Nq.id==id_hlist
       g = get_kanjiskip() -- K
       handle_penalty_suppress(0, 0, g); real_insert(0, g)
@@ -689,9 +694,9 @@ local function handle_nq_ja_hlist()
 end
 
 -- (和文文字で終わる hlist) .. (anything)
-local function handle_np_ja_hlist()
+local function handle_nq_ja_hlist()
    local g = nil
-   if Nq.pre then 
+   if Np.pre then 
       g = get_xkanjiskip(Nq) -- X
       handle_penalty_suppress(0, 0, g); real_insert(0, g)
    end
@@ -707,7 +712,7 @@ local function handle_list_tail()
       if Np.id == id_jglyph or (Np.id==id_pbox and Np.met) then 
         if Np.lend~=0 then
            g = node_new(id_kern); g.subtype = 0; g.kern = Np.lend
-           set_attr(g, attr_icflag, LINE_END)
+           set_attr(g, attr_icflag, BOXBDD)
            node_insert_after(head, Np.last, g)
         end
       end
@@ -722,7 +727,7 @@ local function handle_list_tail()
       if Np.id == id_jglyph or (Np.id==id_pbox and Np.met) then 
         local g = new_jfm_glue(Np, Np.class, find_char_class('boxbdd',Np.met))
         if g then
-           set_attr(g, attr_icflag, FROM_JFM)
+           set_attr(g, attr_icflag, BOXBDD)
            head = node_insert_after(head, Np.last, g)
         end
       end
@@ -735,9 +740,10 @@ local function handle_list_head()
    if Np.id ==  id_jglyph or (Np.id==id_pbox and Np.met) then 
       local g = new_jfm_glue(Np, find_char_class('boxbdd',Np.met), Np.class)
       if g then
-        set_attr(g, attr_icflag, FROM_JFM)
-        if g.id==id_glue then
-           handle_penalty_suppress(0, 0)
+        set_attr(g, attr_icflag, BOXBDD)
+        if g.id==id_glue and Bp[0]==0 then
+           local h = node_new(id_penalty)
+           h.penalty = 10000; set_attr(h, attr_icflag, BOXBDD)
         end
         head = node_insert_before(head, Np.first, g)
       end
@@ -771,10 +777,11 @@ function main(ahead, amode)
    head = ahead; mode = amode; init_var(); calc_np()
    if Np then 
       extract_np(); handle_list_head()
-   else
-      if not mode then
-        head = node_remove(head, last) -- remove the sentinel
+      if Np.id==id_glyph then after_alchar()
+      elseif Np.id==id_hlist or Np.id==id_pbox or Np.id==id_disc then after_hlist()
       end
+   else
+      if not mode then head = node_remove(head, last) end
       return head
    end
    calc_np()
@@ -796,7 +803,14 @@ function main(ahead, amode)
       end
       calc_np()
    end
-   handle_list_tail(); return head
+   handle_list_tail()
+   -- adjust attr_icflag
+   for p in node.traverse(head) do 
+      local a = has_attr(p, attr_icflag) or 0
+      if a==0 then set_attr(p, attr_icflag, PROCESSED) end
+   end
+   tex.attribute[attr_icflag] = -(0x7FFFFFFF)
+   return head
 end
 
 -- \inhibitglue
@@ -805,4 +819,4 @@ function create_inhibitglue_node()
    g.user_id=30111; g.type=100; g.value=1; node.write(g)
 end
 
--- TODO: 二重挿入の回避
\ No newline at end of file
+-- TODO: 二重挿入の回避
index 5fd93da..01d3149 100644 (file)
Binary files a/test/test04-jfm.pdf and b/test/test04-jfm.pdf differ
index 5efd82d..8916de6 100644 (file)
@@ -79,7 +79,7 @@
 \def\dumplist#1{\par\noindent\leavevmode
 \hbox to 0.2\hsize{\copy#1\hss}%
 \vbox{\hsize=0.6\hsize\sixtt\baselineskip=7.2pt\sixgt\let\\=\relax
-\directlua{ltj.ext_show_node_list(tex.getbox(#1).head, '\\par', tex.print)}\hrule}}
+\directlua{ltj.ext_show_node_list(tex.getbox(#1).head, '\\par ', tex.print)}\hrule}}
 
 %\tracingonline=1\tracingoutput=1\showboxdepth=3\showboxbreadth=100
 
 
 \setbox0=\hbox{\rmlh \hbox{}う}\dumplist0
 
-\head{JA--penalty (penなし)} TODO: この場合の挙動はこれで良いか?
-
-\setbox0=\hbox{\rmlh あ\penalty567}\dumplist0
-
-\setbox0=\hbox{\rmlh い\penalty567}\dumplist0
-
-\setbox0=\hbox{\rmlh う\penalty567}\dumplist0
-
-\setbox0=\hbox{\rmlh え\penalty567}\dumplist0
-
-\setbox0=\hbox{\rmlh か\penalty567}\dumplist0
-
-\head{penalty--JA (penなし)} TODO: この場合の挙動はこれで良いか?
-
-\setbox0=\hbox{\rmlh \penalty567あ}\dumplist0
-
-\setbox0=\hbox{\rmlh \penalty567い}\dumplist0
-
-\setbox0=\hbox{\rmlh \penalty567う}\dumplist0
-
 {\vfill\eject%
 
 \ltjsetparameter{prebreakpenalty={`(,123}}
 {\ltjsetparameter{alxspmode={`x,postonly}}
 \setbox0=\hbox{\rmlh まx}\dumplist0}
 
-\head{kanjiskip from JFM/autoxspacing (EN--JA)}
+\head{xkanjiskip from JFM/autoxspacing (EN--JA)}
 \setbox0=\hbox{\rmlh xま}\dumplist0
 
 \setbox0=\hbox{\rmlh x\naxspc ま}\dumplist0
 \setbox0=\hbox{\rmlh あ\penalty1701\penalty1701\penalty1701お}
 \dumplist0
 
-\head{その他}
+\head{その他: italic correction and accents}
 
-\setbox0=\hbox{\tenrm あ\/\v{A}あ}
+\setbox0=\hbox{\tenrm あ\/j}
 \dumplist0
+\setbox0=\hbox{\tenrm\rmlh れ\v{A})}
+\dumplist0
+
+\head{その他: box boundary}
+
 \setbox0=\hbox{\rmlh かあか}
 \dumplist0
-\setbox0=\hbox{\rmlh あか}
+\setbox0=\hbox{a\setbox3=\hbox{\rmlh  かあか}\unhbox3a}
+\dumplist0
+\setbox0=\hbox{a\setbox3=\hbox{\rmlh  か}\box3a}
 \dumplist0
-\setbox0=\hbox{\setbox3=\hbox{\rmlh かa}\unhbox3}
+\setbox0=\hbox{\rmlh き\hbox{か}き\hbox{き}き}
 \dumplist0
 
+{\ltjsetparameter{postbreakpenalty={`あ,1000},prebreakpenalty={`あ,1000}}
+\setbox0=\hbox{あ\hbox{(}あ\setbox3=\hbox{(}\unhbox3あ}
+\dumplist0}
+
 
 \end
index b956fdc..8167ed0 100644 (file)
Binary files a/test/test05-speed.pdf and b/test/test05-speed.pdf differ
index 5d8aa77..02431e9 100644 (file)
@@ -4,7 +4,7 @@
 \newcount\cnt\newcount\cnta
 \cnt=0
 \long\def\loop#1\repeat{\def\body{#1}\iterate}
-\loop\ifnum\cnt<10 % <= this value
+\loop\ifnum\cnt<20 % <= this value
   \cnta=0 \message{\the\cnt:}\par
   {\loop\ifnum\cnta<500 あ.「い,うえお・か(き)く)(けこ\advance\cnta1\repeat}
   \advance\cnt1
@@ -13,6 +13,6 @@
 \end
 
 %     real time:
-% 20:  9.950s    9.214
-% 10:  5.209s    5.119
+% 20:  9.950s    10.584
+% 10:  5.209s    5.523
 % env: C2D E7300, Mem 4GB, LuaTeX 0.71.0pre, Gentoo amd64 unstable
\ No newline at end of file