From: Hironori Kitagawa Date: Mon, 20 Jun 2011 14:04:46 +0000 (+0900) Subject: Fixed jfmglue.lua and updated documents. X-Git-Tag: 20120419.0~104^2~4 X-Git-Url: http://git.osdn.jp/view?a=commitdiff_plain;h=7f1b9d5a85d7be22fbde2ac7c125a5a3dd564dab;p=luatex-ja%2Fluatexja.git Fixed jfmglue.lua and updated documents. --- diff --git a/doc/jfmglue.pdf b/doc/jfmglue.pdf index 04a2bcc..5e01ed8 100644 Binary files a/doc/jfmglue.pdf and b/doc/jfmglue.pdf differ diff --git a/doc/jfmglue.tex b/doc/jfmglue.tex index a9a5fed..5a26699 100644 --- a/doc/jfmglue.tex +++ b/doc/jfmglue.tex @@ -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|の挿入処理を行う→省略. diff --git a/doc/sample1.pdf b/doc/sample1.pdf index 4ca0be8..e078cbb 100644 Binary files a/doc/sample1.pdf and b/doc/sample1.pdf differ diff --git a/doc/sample1.tex b/doc/sample1.tex index 19bdb49..e5e4e07 100644 --- a/doc/sample1.tex +++ b/doc/sample1.tex @@ -97,7 +97,6 @@ JFM は和文文字の幅や,和文文字間の空白の入り方などを規 \globaljfont={:} % global に定義 \endtt - \item {\bf の指定について}\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={, }| key in |\ltjsetparameter|. +\item |kansujichar={, }|~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} diff --git a/src/luatexja-core.lua b/src/luatexja-core.lua index 5a73fa5..c2c2468 100644 --- a/src/luatexja-core.lua +++ b/src/luatexja-core.lua @@ -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) diff --git a/src/luatexja/jfmglue.lua b/src/luatexja/jfmglue.lua index 140b622..5e5c256 100644 --- a/src/luatexja/jfmglue.lua +++ b/src/luatexja/jfmglue.lua @@ -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: 二重挿入の回避 diff --git a/test/test04-jfm.pdf b/test/test04-jfm.pdf index 5fd93da..01d3149 100644 Binary files a/test/test04-jfm.pdf and b/test/test04-jfm.pdf differ diff --git a/test/test04-jfm.tex b/test/test04-jfm.tex index 5efd82d..8916de6 100644 --- a/test/test04-jfm.tex +++ b/test/test04-jfm.tex @@ -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 @@ -151,26 +151,6 @@ \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}} @@ -249,7 +229,7 @@ {\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 @@ -274,16 +254,27 @@ \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 diff --git a/test/test05-speed.pdf b/test/test05-speed.pdf index b956fdc..8167ed0 100644 Binary files a/test/test05-speed.pdf and b/test/test05-speed.pdf differ diff --git a/test/test05-speed.tex b/test/test05-speed.tex index 5d8aa77..02431e9 100644 --- a/test/test05-speed.tex +++ b/test/test05-speed.tex @@ -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