From: Hironori Kitagawa Date: Tue, 3 May 2011 23:48:02 +0000 (+0900) Subject: Changed structure of JFM. X-Git-Tag: master-20110808~15 X-Git-Url: http://git.osdn.jp/view?a=commitdiff_plain;h=9efef5f7e935fe48ca1c2fc49ae4361395946514;p=luatex-ja%2Fluatexja.git Changed structure of JFM. - Proportional glyph width is now supported by width = 'prop'. - Fixed the alignment of glyphs (e.g., U+201C). modified: doc/s1sty.tex modified: doc/sample1.pdf modified: doc/sample1.tex modified: src/jfm-mono.lua modified: src/jfm-ujis.lua modified: src/luatexja-core.lua modified: src/luatexja-core.sty modified: src/luatexja-jfont.lua modified: test/jfm-bad.lua modified: test/jfm-hang.lua modified: test/test04-jfm.pdf modified: test/test04-jfm.tex --- diff --git a/doc/s1sty.tex b/doc/s1sty.tex index 9c2baa6..2591395 100644 --- a/doc/s1sty.tex +++ b/doc/s1sty.tex @@ -93,7 +93,8 @@ \belowdisplayskip=\medskipamount \belowdisplayshortskip=\medskipamount % -\outer\def\begintt{$$\let\par=\endgraf \ttverbatim\parskip=0pt\catcode`\|=0 \rightskip-5pc\ttfinish} +\outer\def\begintt{$$\let\par=\endgraf\baselineskip=12pt +\ttverbatim\parskip=0pt\catcode`\|=0 \rightskip-5pc\ttfinish} {\catcode`\|=0 |catcode`|\=\other% | is temporary escape character |obeylines% end of line is active |gdef|ttfinish#1^^M#2\endtt{#1|parindent3|zw|noindent|vbox{#2}|hss|endgroup$$}} diff --git a/doc/sample1.pdf b/doc/sample1.pdf index b34a0f5..7bb6f24 100644 Binary files a/doc/sample1.pdf and b/doc/sample1.pdf differ diff --git a/doc/sample1.tex b/doc/sample1.tex index 13bfbf2..1e8c9bb 100644 --- a/doc/sample1.tex +++ b/doc/sample1.tex @@ -40,13 +40,17 @@ \item {\bf 現時点で\LaTeX での使用は殆ど考慮されていません.今は``plain Lua\TeX''で使ってください.} \item |\accent|を和文文字に対して使うことはできません. これは「フォントを後で置換する」という実装上,仕方のないことだと思われます. -{\small|\/|を試験的に日本語にも対応させました.|make_accent|の処理をLuaコードで書けば可能だと思われます.} +{\small|\/|を試験的に日本語にも対応させました. +アクセントも,|make_accent|の処理をLuaコードで書けば可能だと思われます.} \item 数式中の日本語は想定していません.|\hbox|か何かで囲ってください. \item p\TeX にあった以下の機能はまだ実装していません. \itemitem |\euc|, |\jis|, |\sjis|, |\kuten|といった,コード変換プリミティブ. \itemitem |\kansuji|, |\kansujichar|. -\itemitem |\showmode|, |\jfam|, |\jcharwidowpenalty|. +\itemitem |\showmode|, |\jfam|. \itemitem 縦組み関連一式.|\tate|, |\tfont|, |\tbaselineshift|, |\dtou|,$\,\ldots$ + +\item 和文間・和欧文間空白の自動挿入がglobalでしかできていません. +←解決はさほど難しくないので,仕様を決定した後に書き上げます. \enditem @@ -208,7 +212,8 @@ p\TeX の|\inhibitxspcode|に対応した設定項目である.で許さ \itemitem |3|, |allow|: 前後の和文文字との間の|\xkanjiskip|自動挿入を許可. \item |yalbaselineshift=|: -p\TeX の|\baselineshift|に対応したものであり,欧文文字のベースライン補正量をdimensionで指定する. +p\TeX の|\ybaselineshift|に対応したものであり, +欧文文字のベースライン補正量をdimensionで指定する. \itemitem 正の値を指定すると,その分だけ欧文文字は下にずれることとなる. \itemitem 数式中では,boxやruleもこの量だけずれる\hfil\break (よって,行中数式は全体が|yalbaselineshift|だけずれたように見える). @@ -299,53 +304,103 @@ glue/kern挿入処理で役目を終え,削除される)\inhibitglue}. \beginsection JFMについて -Lua\TeX-jaで用いる和文用のメトリック情報は,次のような構文で書かれたLuaファイルである. +Lua\TeX-jaで用いる和文用のメトリック情報は,次のようなLuaファイルである. 見本として,|jfm-ujis.lua|を入れてある. -\item |jfm.dir|: 組方向を指定する.将来的にはいずれ縦組(|'tate'|)を実装したいが, +\begintt +ltj.define_jfm { + dir = 'yoko', zw = 1.0, zh = 1.0, + [0] = { + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.0, + glue = { + [1] = { 0.5 , 0.0, 0.5 }, [3] = { 0.25, 0.0, 0.25 } + } + }, ... + [1] = { + chars = { + 0x2018, 0x201C, 0x3008, 0x300A, 0x300C, 0x300E, 0x3010, 0x3014, + 0x3016, 0x3018, 0x301D, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F + }, + align = 'right', left = 0.0, down = 0.0, ... + }, ... + [5] = { + ..., + glue = { + [1] = { 0.5 , 0.0, 0.5 }, + [3] = { 0.25, 0.0, 0.25 } + }, + kern = { [5] = 0.0 } + }, ... +} +\endtt + +全体は,「関数|ltj.define_jfm|にテーブルを引数として与える」という構造になっている. +以下に,テーブルの中身を述べる. +\item |dir|: 組方向を指定する.将来的にはいずれ縦組(|'tate'|)を実装したいが, 現時点では横組(|'yoko'|)のみの対応. -\item |jfm.zw|, |jfm.zh|: それぞれ|\zw|, |\zh|のフォントサイズに対する割合を記述する. +\item |zw|, |zh|: それぞれ|\zw|, |\zh|のフォントサイズに対する割合を記述する(必須). 通常は両方とも1.0となるだろう. -\item |jfm.define_char_type(, )| +\item 数字のindex $i$を持った値:$i$番の文字クラスについての情報を記述する. +\itemitem |glue|: 現在の文字クラスの文字の後に挿入するglueを指定する. +この項目の内容は +\begintt +{ [] = { , , }, ... } +\endtt +というテーブルであり,各要素は + +{\par\medskip\advance\leftskip3\zw\noindent\rightskip2\zw +$i$番の文字クラスの文字と$j$番の文字クラスの文字の間に, +自然長,伸び, 縮み(フォントサイズ基準)なる +glueを挿入 +\par\medskip} -p\TeX 用{\tt JFM}で言うところの「文字クラス」を定義する. -\itemitem は文字クラスを表す1以上$\hbox{\tt0x800}=2048$未満の整数. -\itemitem には,に属する「文字」達のUnicodeにおけるコード番号を +\noindent という意味である. + +\itemitem |kern|: 現在の文字クラスの文字の後に挿入するkernを指定する. +この項目の内容も, +\begintt +{ [] = , ... } +\endtt +というテーブルであり,各要素は + +{\par\medskip\advance\leftskip3\zw\noindent\rightskip2\zw +$i$番の文字クラスの文字と$j$番の文字クラスの文字の間に,\hfil\break +幅のkernを挿入 +\par\medskip} + +\noindent という意味である. + +\itemitem |chars|: 文字クラスに属する「文字」達のUnicodeにおけるコード番号を リストの形|{...}|で記述する. -\itemitem どの文字クラスにも属さなかった文字は,自動的に0番の文字クラスに属するとみなされる. +どの文字クラスにも属さなかった文字は,0番の文字クラスに属するとみなされる. +そのため,0番以外の文字クラスではこの項目は必須である. また,このリストには,以下の「仮想的な文字」も指定可能である. \itemT |'lineend'|: 行末. この「文字」を0以外の文字クラスに設定することで,ぶら下げ組のような組版も可能になる. -例えば,句点類の文字クラスが2のとき, -\begintt - jfm.define_char_type(8,{'linebdd'}}) - jfm.define_kern(2, 8, -0.5) -\endtt -と指定すればよい. \itemT |'boxbdd'|: 水平ボックスの先頭/末尾,段落の先頭/末尾. \itemT |'jcharbdd'|: 和文文字達の連続とそれ以外のもの(例えば欧文文字)との境界. \itemT |'diffmet'|: 異なるメトリックの和文文字間に入るglueの計算に使われる. +\enditem -\item |jfm.define_type_dim(,,,,,,)| - -文字クラスごとに,文字の寸法のフォントサイズに対する割合を記述する. -\itemitem : 例えば開き括弧類は組版をする際には半角幅だが,TrueTypeフォント内では -左に半角空白が付け加わって全角幅となっていることが多い.このような場合,逆に -TrueTypeフォントを基準にすると,「左に半角幅ずらす」ことをしないといけない. -はその「左へのずらし量」を指定する. -\itemitem : 同様に,「下へのずらし量」を指定する. -\itemitem , , : それぞれ幅,高さ,深さ. -\itemitem : イタリック補正値(未実装). +\noindent {\bf +以下の3項目は,文字クラスに属する文字が「仮想的な文字」達だけでない場合に必須.} -\item |jfm.define_glue(, , , , )| +\itemitem |align|: |'left'|, |'middle'|, |'right'|のどれかを指定する. -文字クラスの文字との文字の間に,自然長,伸び, 縮み -(いずれもフォントサイズ基準)のglueを挿入する. +例えば,開き括弧類は組版をする際には半角幅だが,TrueTypeフォント内では +左に半角空白が付け加わって全角幅となっていることが多い.そのような場合, +|align='right'|と指定することで, +「半角幅の領域に(右詰めで)フォントの実際の字形を入れる」といったことができる. -\item |jfm.define_kern(, , )| +\itemitem |width|, |height|, |depth|, |italic|: +それぞれ幅,高さ,深さ,そしてイタリック補正値をフォントサイズに対する割合で指定する. +例外として,|width='prop'|の場合には,その文字クラスは特に幅を定めず, +実際のフォントにおける文字幅そのままで出力する. -文字クラスの文字との文字の間に,幅のkernを挿入. +\itemitem |left|, |down|: それぞれ左右,上下方向のずらし量を指定する. +|align|項目のため,|left|はほとんどの場合0で良いだろう. \enditem diff --git a/src/jfm-mono.lua b/src/jfm-mono.lua index 2cfc433..f3eb63b 100644 --- a/src/jfm-mono.lua +++ b/src/jfm-mono.lua @@ -1,3 +1,9 @@ -jfm.dir = 'yoko' -jfm.zw= 1.0; jfm.zh = 1.0 -jfm.define_type_dim(0, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0) \ No newline at end of file +ltj.define_jfm { + dir = 'yoko', + zw = 1.0, zh = 1.0, + + [0] = { + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.0, + } +} \ No newline at end of file diff --git a/src/jfm-ujis.lua b/src/jfm-ujis.lua index e2239e3..6b4324e 100644 --- a/src/jfm-ujis.lua +++ b/src/jfm-ujis.lua @@ -1,89 +1,104 @@ --- A sample of Japanese font metric for pluatex --- The unit of , : --- The unit of other dimension: the design size +ltj.define_jfm { + dir = 'yoko', + zw = 1.0, zh = 1.0, -jfm.dir = 'yoko' --- 'yoko' + [0] = { + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.0, + glue = { + [1] = { 0.5 , 0.0, 0.5 }, + [3] = { 0.25, 0.0, 0.25 } + } + }, -jfm.zw= 1.0; jfm.zh = 1.0 --- amount of ``1zw'' and ``1zh'' (these units are used in pTeX) + [1] = { -- 開き括弧類 + chars = { + 0x2018, 0x201C, 0x3008, 0x300A, 0x300C, 0x300E, 0x3010, 0x3014, 0x3016, + 0x3018, 0x301D, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F + }, + align = 'right', left = 0.0, down = 0.0, + width = 0.5, height = 0.88, depth = 0.12, italic=0.0, + glue = { + [3] = { 0.25, 0.0, 0.25 } + } + }, + [2] = { -- 閉じ括弧類 + chars = { + 0x2019, 0x201D, 0x3001, 0x3009, 0x300B, 0x300D, 0x300F, 0x3011, 0x3015, + 0x3017, 0x3019, 0x301F, 0xFF09, 0xFF0C, 0xFF3D, 0xFF5D, 0xFF60 + }, + align = 'left', left = 0.0, down = 0.0, + width = 0.5, height = 0.88, depth = 0.12, italic=0.0, + glue = { + [0] = { 0.5 , 0.0, 0.5 }, + [1] = { 0.5 , 0.0, 0.5 }, + [3] = { 0.25, 0.0, 0.25 }, + [5] = { 0.5 , 0.0, 0.5 }, + [7] = { 0.5 , 0.0, 0.5 } + } + }, --- character type --- jfm.define_char_type(, ) -jfm.define_char_type(1, { - 0x2018, 0x201C, 0x3008, 0x300A, 0x300C, 0x300E, 0x3010, 0x3014, 0x3016, - 0x3018, 0x301D, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F - }) -- 開き括弧類 -jfm.define_char_type(2, { - 0x2019, 0x201D, 0x3001, 0x3009, 0x300B, 0x300D, 0x300F, 0x3011, 0x3015, - 0x3017, 0x3019, 0x301F, 0xFF09, 0xFF0C, 0xFF3D, 0xFF5D, 0xFF60 - }) -- 閉じ括弧類 -jfm.define_char_type(3, {0x30FB, 0xFF1A, 0xFF1B}) -- 中点類 -jfm.define_char_type(4, {0x3002, 0xFF0E}) -- 句点類 -jfm.define_char_type(5, {0x2015, 0x2025, 0x2026}) -- ダッシュ -jfm.define_char_type(6, {'boxbdd'}) -jfm.define_char_type(7, { - 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67, 0xFF68, 0xFF69, - 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F, 0xFF70, 0xFF71, 0xFF72, - 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79, 0xFF7A, 0xFF7B, - 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, - 0xFF85, 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, - 0xFF8E, 0xFF8F, 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, - 0xFF97, 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F -}) -- 半角カナ + [3] = { -- 中点類 + chars = {0x30FB, 0xFF1A, 0xFF1B}, + align = 'middle', left = 0.0, down = 0.0, + width = 0.5, height = 0.88, depth = 0.12, italic=0.0, + glue = { + [0] = { 0.25, 0.0, 0.25 }, + [1] = { 0.25, 0.0, 0.25 }, + [2] = { 0.25, 0.0, 0.25 }, + [3] = { 0.5 , 0.0, 0.5 }, + [4] = { 0.25, 0.0, 0.25 }, + [5] = { 0.25, 0.0, 0.25 }, + [7] = { 0.25, 0.0, 0.25 } + } + }, + [4] = { -- 句点類 + chars = {0x3002, 0xFF0E}, + align = 'left', left = 0.0, down = 0.0, + width = 0.5, height = 0.88, depth = 0.12, italic=0.0, + glue = { + [0] = { 0.5 , 0.0, 0.0 }, + [1] = { 0.5 , 0.0, 0.0 }, + [3] = { 0.75, 0.0, 0.25 }, + [5] = { 0.5 , 0.0, 0.0 }, + [7] = { 0.5 , 0.0, 0.0 } + } + }, --- 'boxbdd' matches --- o the beginning of paragraphs and hboxes, --- o the ending of paragraphs and hboxes, --- o just after the hbox created by \parindent. + [5] = { -- ダッシュ + chars = { 0x2015, 0x2025, 0x2026 }, + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.0, + glue = { + [1] = { 0.5 , 0.0, 0.5 }, + [3] = { 0.25, 0.0, 0.25 } + }, + kern = { + [5] = 0.0 + } + }, --- 'jcharbdd' matches the boundary between two Japanese characters whose metrics (or sizes) --- are different. + [6] = { -- box末尾 + chars = {'boxbdd'}, + }, --- 'diffmet' matches the boundary between a Japanese character --- and a material which is not a Japanese character. - --- 'lineend' matches the ending of a line. - --- dimension --- jfm.define_type_dim(, , , , --- , , ) -jfm.define_type_dim(0, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0) -jfm.define_type_dim(1, 0.5 , 0.0 , 0.5 , 0.88, 0.12, 0.0) -jfm.define_type_dim(2, 0.0 , 0.0 , 0.5 , 0.88, 0.12, 0.0) -jfm.define_type_dim(3, 0.25, 0.0 , 0.5 , 0.88, 0.12, 0.0) -jfm.define_type_dim(4, 0.0 , 0.0 , 0.5 , 0.88, 0.12, 0.0) -jfm.define_type_dim(5, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0) --- jfm.define_type_dim(6, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0): does not needed -jfm.define_type_dim(7, 0.0 , 0.0 , 0.5 , 0.88, 0.12, 0.0) - --- glue/kern --- jfm.define_glue(, , , , ) --- jfm.define_kern(, , ) -jfm.define_glue(0,1, 0.5 , 0.0, 0.5 ) -jfm.define_glue(7,1, 0.5 , 0.0, 0.5 ) -jfm.define_glue(0,3, 0.25, 0.0, 0.25) -jfm.define_glue(7,3, 0.25, 0.0, 0.25) -jfm.define_glue(1,3, 0.25, 0.0, 0.25) -jfm.define_glue(2,0, 0.5 , 0.0, 0.5 ) -jfm.define_glue(2,7, 0.5 , 0.0, 0.5 ) -jfm.define_glue(2,1, 0.5 , 0.0, 0.5 ) -jfm.define_glue(2,3, 0.25, 0.0, 0.25) -jfm.define_glue(2,5, 0.5 , 0.0, 0.5 ) -jfm.define_glue(3,0, 0.25, 0.0, 0.25) -jfm.define_glue(3,7, 0.25, 0.0, 0.25) -jfm.define_glue(3,1, 0.25, 0.0, 0.25) -jfm.define_glue(3,2, 0.25, 0.0, 0.25) -jfm.define_glue(3,3, 0.5 , 0.0, 0.5 ) -jfm.define_glue(3,4, 0.25, 0.0, 0.25) -jfm.define_glue(3,5, 0.25, 0.0, 0.25) -jfm.define_glue(4,0, 0.5 , 0.0, 0.0 ) -jfm.define_glue(4,7, 0.5 , 0.0, 0.0 ) -jfm.define_glue(4,1, 0.5 , 0.0, 0.0 ) -jfm.define_glue(4,3, 0.75, 0.0, 0.25) -jfm.define_glue(4,5, 0.5 , 0.0, 0.0 ) -jfm.define_glue(5,1, 0.5 , 0.0, 0.5 ) -jfm.define_glue(5,3, 0.25, 0.0, 0.25) -jfm.define_kern(5,5, 0.0) \ No newline at end of file + [7] = { -- 半角カナ + chars = { + 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67, 0xFF68, 0xFF69, + 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F, 0xFF70, 0xFF71, 0xFF72, + 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79, 0xFF7A, 0xFF7B, + 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, + 0xFF85, 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, + 0xFF8E, 0xFF8F, 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, + 0xFF97, 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F + }, + align = 'left', left = 0.0, down = 0.0, + width = 0.5, height = 0.88, depth = 0.12, italic=0.0, + glue = { + [1] = { 0.5 , 0.0, 0.5 }, + [3] = { 0.25, 0.0, 0.25 } + } + }, +} \ No newline at end of file diff --git a/src/luatexja-core.lua b/src/luatexja-core.lua index 9d0f931..de83c2e 100644 --- a/src/luatexja-core.lua +++ b/src/luatexja-core.lua @@ -291,36 +291,36 @@ end local function main2_find_size_metric(px) if is_japanese_glyph_node(px) then - return ltj.font_metric_table[px.font].size, ltj.font_metric_table[px.font].jfm + return ltj.font_metric_table[px.font].size, + ltj.font_metric_table[px.font].jfm, ltj.font_metric_table[px.font].var else - return nil, nil + return nil, nil, nil end end local function main2_new_jfm_glue(size,mt,bc,ac) -- mt: metric key, bc, ac: char classes local g=nil - local w=bc*0x800+ac - local z = ltj.metrics[mt] - if z.glue[w] then + local z = ltj.metrics[mt].char_type[bc] + if z.glue and z.glue[ac] then local h = node_new(id_glue_spec) - h.width = round(size*z.glue[w][0]) - h.stretch = round(size*z.glue[w][1]) - h.shrink = round(size*z.glue[w][2]) + h.width = round(size*z.glue[ac][1]) + h.stretch = round(size*z.glue[ac][2]) + h.shrink = round(size*z.glue[ac][3]) h.stretch_order=0; h.shrink_order=0 g = node_new(id_glue) g.subtype = 0; g.spec = h - elseif z.kern[w] then + elseif z.kern and z.kern[ac] then g = node_new(id_kern) - g.subtype = 1; g.kern = round(size*z.kern[w]) + g.subtype = 1; g.kern = round(size*z.kern[ac]) end return g end -- return value: g (glue/kern from JFM), w (width of 'lineend' kern) -local function main2_calc(qs,qm,q,p,last,ihb_flag) +local function main2_calc(qs,qm,qv,q,p,last,ihb_flag) -- q, p: node (possibly null) - local ps, pm, g, h + local ps, pm, pv, g, h local w = 0 if (not p) or p==last then -- q is the last node @@ -333,7 +333,7 @@ local function main2_calc(qs,qm,q,p,last,ihb_flag) end elseif qs==0 then -- p is the first node etc. - ps, pm = main2_find_size_metric(p) + ps, pm, pv = main2_find_size_metric(p) if not pm then return nil, 0 elseif not ihb_flag then @@ -342,10 +342,10 @@ local function main2_calc(qs,qm,q,p,last,ihb_flag) has_attr(p,attr_jchar_class)) end else -- p and q are not nil - ps, pm = main2_find_size_metric(p) + ps, pm, pv = main2_find_size_metric(p) if ihb_flag or ((not pm) and (not qm)) then g = nil - elseif (qs==ps) and (qm==pm) then + elseif (qs==ps) and (qm==pm) and (qv==pv) then -- Both p and q are Japanese glyph nodes, and same metric and size g = main2_new_jfm_glue(ps,pm, has_attr(q,attr_jchar_class), @@ -374,9 +374,9 @@ local function main2_calc(qs,qm,q,p,last,ihb_flag) if qm then local x = ljfm_find_char_class('lineend', qm) if x~=0 then - x = has_attr(q,attr_jchar_class)*0x800 + x - if ltj.metrics[qm].kern[x] then - w = round(qs*ltj.metrics[qm].kern[x]) + qv = ltj.metrics[qm].char_type[has_attr(q,attr_jchar_class)] + if qv.kern and qv.kern[x] then + w = round(qs*qv.kern[x]) end end end @@ -386,11 +386,11 @@ end local function main2_between_two_char(head,q,p,p_bp,ihb_flag,last) local qs = 0; local g, w - local qm = nil + local qm = nil, qv if q then - qs, qm = main2_find_size_metric(q) + qs, qm, qv = main2_find_size_metric(q) end - g, w = main2_calc(qs, qm, q, p, last, ihb_flag) + g, w = main2_calc(qs, qm, qv, q, p, last, ihb_flag) if w~=0 and (not p_bp) then p_bp = node_new(id_penalty); p_bp.penalty = 0 head = node_insert_before(head, p, p_bp) @@ -557,7 +557,7 @@ end local function main4_set_ja_width(head) local p = head - local met_tb, t, s, g, th, q, a + local met_tb, t, s, g, q, a, h local m = false -- is in math mode? while p do local v=has_attr(p,attr_yablshift) or 0 @@ -567,15 +567,21 @@ local function main4_set_ja_width(head) met_tb = ltj.font_metric_table[p.font] t = ltj.metrics[met_tb.jfm] s = t.char_type[has_attr(p,attr_jchar_class)] - if not(s.left==0.0 and s.down==0.0 + if s.width ~= 'prop' and + 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) - node_insert_after(p, p, main4_get_hss()) - g = node_hpack(p, round(met_tb.size*s.width), 'exactly') + 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()) + end + g = node_hpack(h, round(met_tb.size*s.width), 'exactly') g.height = round(met_tb.size*s.height) g.depth = round(met_tb.size*s.depth) head, p = node_insert_before(head, q, g) diff --git a/src/luatexja-core.sty b/src/luatexja-core.sty index 3868ddd..ac8724c 100644 --- a/src/luatexja-core.sty +++ b/src/luatexja-core.sty @@ -232,9 +232,9 @@ {\ltj@@getparam@one{#1}}% } \def\ltj@@getparam@one#1{% - \directlua{ltj.ext_get_parameter_unary('#1')}} + \directlua{ltj.ext_get_parameter_unary('#1')}}% \def\ltj@@getparam@two#1#2{\ltj@tempcnta=#2 - \directlua{ltj.ext_get_parameter_binary('#1', \the\ltj@tempcnta)} + \directlua{ltj.ext_get_parameter_binary('#1', \the\ltj@tempcnta)}% } diff --git a/src/luatexja-jfont.lua b/src/luatexja-jfont.lua index e0b2e53..82db6f6 100644 --- a/src/luatexja-jfont.lua +++ b/src/luatexja-jfont.lua @@ -15,53 +15,55 @@ local id_kern = node.id('kern') ltj.metrics={} -- this table stores all metric informations ltj.font_metric_table={} -- [font number] -> jfm_name, jfm_var, size -jfm={}; jfm.char_type={}; jfm.glue={}; jfm.kern={}; jfm.chars = {} - -local ljfm_jfm_cons local jfm_file_name, jfm_var +local defjfm_res -function jfm.define_char_type(t,lt) - if not jfm.char_type[t] then jfm.char_type[t]={} end - jfm.char_type[t].chars=lt - for i,v in pairs(lt) do - if v == 'linebdd' then - if #lt ~= 1 then ljfm_jfm_cons = false; return end - elseif not jfm.chars[v] then - jfm.chars[v] = t - else - ljfm_jfm_cons = false ; return - end - end -end -function jfm.define_type_dim(t,l,x,w,h,d,i) - if not jfm.char_type[t] then jfm.char_type[t]={} end - jfm.char_type[t].width=w; jfm.char_type[t].height=h; - jfm.char_type[t].depth=d; jfm.char_type[t].italic=i; - jfm.char_type[t].left=l; jfm.char_type[t].down=x -end -function jfm.define_glue(b,a,w,st,sh) - local j=b*0x800+a - if not jfm.glue[j] then jfm.glue[j]={} end - jfm.glue[j][0]=w; jfm.glue[j][1]=st; - jfm.glue[j][2]=sh -end -function jfm.define_kern(b,a,w) - local j=b*0x800+a - if not jfm.kern[j] then jfm.kern[j]=w end -end - --- return nil iff ltj.metrics[ind] is a bad metric -local function ljfm_consistency_check(ind) - local t = ltj.metrics[ind] - local r = nil - if ljfm_jfm_cons then r = ind end - if t.dir~='yoko' then -- TODO: tate? - r=nil +function ltj.define_jfm(t) + local real_char -- Does current character class have the 'real' character? + if t.dir~='yoko' then + defjfm_res= nil; return elseif type(t.zw)~='number' or type(t.zh)~='number' then - r=nil -- .zw, .zh must be present + defjfm_res= nil; return + end + t.char_type = {}; t.chars = {} + for i,v in pairs(t) do + if type(i) == 'number' then -- char_type + if not v.chars then + if i ~= 0 then defjfm_res= nil; return end + real_char = true + else + real_char = false + for j,w in pairs(v.chars) do + if w == 'lineend' then + if #v.chars ~= 1 then defjfm_res= nil; return end + elseif type(w) == 'number' then + real_char = true + end + if not t.chars[w] then + t.chars[w] = i + else + defjfm_res= nil; return + end + end + if real_char then + if not (type(v.width)=='number' or v.width~='prop') then + defjfm_res= nil; return + elseif type(v.height)~='number' or type(v.depth)~='number' then + defjfm_res= nil; return + end + end + v.chars = nil + end + if v.kern then + for j,w in pairs(v.glue) do + if v.kern[j] then defjfm_res= nil; return end + end + end + t.char_type[i] = v + t[i] = nil + end end - if not r then ltj.metrics[ind] = nil end - return r + defjfm_res= t end local function ljfm_find_char_class(c,m) @@ -78,22 +80,17 @@ local function ljfm_load_jfont_metric() [2]="The JFM 'ujis' will be used for now."}) jfm_file_name='ujis' end - local name=jfm_file_name .. ':' .. jfm_var - local i = nil for j,v in ipairs(ltj.metrics) do - if v.name==name then i=j; break end + if v.name==jfm_file_name then return j end end - local t = {} - if i then return i end - jfm.char_type={}; jfm.glue={}; jfm.kern={}; jfm.chars = {} - ljfm_jfm_cons = true ltj.loadlua('jfm-' .. jfm_file_name .. '.lua') - t.name=name - t.dir=jfm.dir; t.zw=jfm.zw; t.zh=jfm.zh - t.char_type=jfm.char_type; t.chars=jfm.chars - t.glue=jfm.glue; t.kern=jfm.kern - table.insert(ltj.metrics,t) - return ljfm_consistency_check(#ltj.metrics) + if defjfm_res then + defjfm_res.name = jfm_file_name + table.insert(ltj.metrics,defjfm_res) + return #ltj.metrics + else + return nil + end end @@ -124,7 +121,9 @@ function ltj.ext_jfontdefY() -- for horizontal font return end ltj.font_metric_table[fn]={} - ltj.font_metric_table[fn].jfm=j; ltj.font_metric_table[fn].size=f.size + ltj.font_metric_table[fn].jfm=j + ltj.font_metric_table[fn].size=f.size + ltj.font_metric_table[fn].var=jfm_var tex.sprint(ltj.is_global .. '\\protected\\expandafter\\def\\csname ' .. cstemp .. '\\endcsname' .. '{\\csname ltj@curjfnt\\endcsname=' .. fn diff --git a/test/jfm-bad.lua b/test/jfm-bad.lua index 9ee2a7c..422006f 100644 --- a/test/jfm-bad.lua +++ b/test/jfm-bad.lua @@ -1,8 +1,9 @@ -jfm.dir = 'yoko2' -- bad +ltj.define_jfm { + dir = 'yoko2', + zw = 1.0, zh = 1.0, -jfm.zw= 1.0; jfm.zh = 1.0 - --- character type --- jfm.define_char_type(, ) - -jfm.define_type_dim(0, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0) + [0] = { + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.0, + } +} \ No newline at end of file diff --git a/test/jfm-hang.lua b/test/jfm-hang.lua index 911319e..9d88f6c 100644 --- a/test/jfm-hang.lua +++ b/test/jfm-hang.lua @@ -1,34 +1,37 @@ - -jfm.dir = 'yoko' --- 'yoko' - -jfm.zw= 1.0; jfm.zh = 1.0 --- amount of ``1zw'' and ``1zh'' (these units are used in pTeX) - - --- character type --- jfm.define_char_type(, ) -jfm.define_char_type(1, { - 0x3042 -}) -jfm.define_char_type(2, { - 0x3044 -}) -jfm.define_char_type(3, { - 0x3048 -}) -jfm.define_char_type(4, { - 0x304A -}) -jfm.define_char_type(8, {'lineend'}) - - -jfm.define_type_dim(0, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0) -jfm.define_type_dim(1, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0) -jfm.define_type_dim(2, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0) -jfm.define_type_dim(3, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.0) -jfm.define_type_dim(4, 0.0 , 0.0 , 1.0 , 0.88, 0.12, 0.50) - -jfm.define_kern(1,8, -0.5) -jfm.define_glue(2,3, 0.25, 0.25, 0.25) -jfm.define_glue(1,3, 0.25, 0.0, 0.25) \ No newline at end of file +ltj.define_jfm { + dir = 'yoko', + zw = 1.0, zh = 1.0, + + [0] = { + align = 'left', left = 0.0, down = 0.0, + width = 'prop', height = 0.88, depth = 0.12, italic=0.0, + }, + [1] = { + chars = { 0x3042 }, + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.0, + glue = { [3] = { 0.25, 0.0, 0.25 } }, + kern = { [8] = -0.5 } + }, + [2] = { + chars = { 0x3044 }, + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.0, + glue = { [3] = { 0.25, 0.25, 0.25 } }, + }, + [3] = { + chars = { 0x3048 }, + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.0, + }, + [4] = { + chars = { 0x304A }, + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.3, + }, + [8] = { + chars = { 'lineend' }, + align = 'left', left = 0.0, down = 0.0, + width = 1.0, height = 0.88, depth = 0.12, italic=0.0, + } +} diff --git a/test/test04-jfm.pdf b/test/test04-jfm.pdf index a701597..110eade 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 a19a55b..a53012f 100644 --- a/test/test04-jfm.tex +++ b/test/test04-jfm.tex @@ -3,13 +3,16 @@ \def\head#1{\medskip\noindent{\bf\tengt ■ #1}\par} \jfont\rml={psft:Ryumin-Light:jfm=ujis} at 10pt -\rml あ\inhibitglue\char"201Cあ←Ryumin-Light +\rml あ\inhibitglue\char"201Cあ・い←Ryumin-Light \jfont\rml={file:ipam.ttf:jfm=ujis} at 10pt -\rml あ\inhibitglue\char"201Cあ←ipam +\rml あ\inhibitglue\char"201Cあ・い←IPA\hbox{}明朝 (ipam) \jfont\rml={file:KozMinPr6N-Regular.otf:jfm=ujis} at 10pt -\rml あ\inhibitglue\char"201Cあ←KozMinPr6N-Regular +\rml あ\inhibitglue\char"201Cあ・い←KozMinPr6N-Regular + +\jfont\rml={file:ipamp.ttf:jfm=ujis} at 10pt +\rml あ\inhibitglue\char"201Cあ・い←IPA P\hbox{}明朝 (ipamp) {\scrollmode \globaljfont\rml={psft:GothicBBB-Medium:jfm=bad} at 10pt % must be error @@ -38,9 +41,9 @@ \head{文字範囲の状況取得} -\ltjgetparameter{jcharrange}{0} -\ltjgetparameter{jcharrange}{1} -\ltjgetparameter{jcharrange}{2} +\ltjgetparameter{jacharrange}{0} +\ltjgetparameter{jacharrange}{1} +\ltjgetparameter{jacharrange}{2} \head{文字コード→文字範囲} \ltjgetparameter{chartorange}{`い} % must be 217 @@ -54,9 +57,16 @@ \ltjsetparameter{jacharrange={218}} 和文扱いにもどる +↓「あ」「い」「う」「お」以外はプロポーショナル組(IPA P明朝) + +\jfont\rmlh={file:ipamp.ttf:jfm=hang} at 10pt +\rmlh プロポーショナルのテスト!あいうえおさ,かき・くけこ + + + \vfill\eject -\jfont\rmlh={psft:Ryumin-Light:jfm=hang} at 10pt \head{‘lineend’検証} +\jfont\rmlh={psft:Ryumin-Light:jfm=hang} at 10pt \jfont\sixgt={psft:GothicBBB-Medium:jfm=ujis} at 6pt \font\sixtt=cmtt10 at 6pt