texjporg / tex-jp-build

Minimum source repository to build Japanese TeX processing tools
23 stars 6 forks source link

[dvipdfmx] TrueType フォント使用時に一部の漢字が出力されない #155

Open h20y6m opened 1 year ago

h20y6m commented 1 year ago

dvipdfmx で TrueType 利用時に一部の漢字が出力できなくなりました。

%ptex
\special{pdf:mapline rml H ipaexm.ttf}
逢う
\bye
dvipdfmx:warning: Unable to map CID to code: CID=1133
%uptex
\special{pdf:mapline uprml-h UniJIS-UTF16-H ipaexm.ttf}
神% U+FA19
\bye
dvipdfmx:warning: CID=8580 mapped to non-single Unicode characters...
dvipdfmx:warning: Unable to map CID to code: CID=8580

2023年1月中頃に Adobe-Japan1-UCS2 が更新され一部の漢字等に異体字セレクタ付きのものになった影響のようです。 https://www.tug.org/svn/texlive/trunk/Master/texmf-dist/fonts/cmap/adobemapping/mapping-resources-pdf/pdf2unicode/Adobe-Japan1-UCS2?r1=50714&r2=65589t-tk さんの指摘も反映されているようです。)

異体字セレクタ付きになったのは

  1. JIS90字形(162文字)
  2. CJK互換漢字(89文字)
  3. CJK部首補助?(4文字)
  4. \CIDな異体字(1000文字くらい?)

あたりのようです。 参考: https://gist.github.com/h20y6m/093e9085d0c10b6e7e69abd4502a9568

1 は kanji-config-updmap コマンドや pxchfon パッケージで jis2004 オプションなし(デフォルト)で TrueType フォントに切り替えしている場合に JIS2004 で字形が変わる文字が豆腐になります。jis2004 オプションを指定することで回避できますがデフォルトが90字形なので引っかかる人でそうです。

2 は Unicode 正規化で化けることで有名な奴です。Unicode 6.3 で追加されたCJK互換漢字を選択する異体字セレクタを使うように変更されたようです。CJK互換漢字がどの程度使われているのかは分かりませんが、upTeX でしか使えない文字なのでフォントマップを Unicode 直接指定にすれば(1 も含めて)回避できます。ただし Unicode 直接指定による問題もあるのでこの回避策が使えないこともあるかもしれません。

3 は使う人いるのかなぁ……

4 はもともと TrueType フォントでは CID 指定は使えないので影響はないとは思いますが、いままで異体字は規定?の字形で出力されていたのが豆腐になります。


対応策としては

どうすべきでしょうか?


TeX Live 2023 には間に合いそうにありませんが、一応突貫で dvipdfmx のパッチを書いてみました。

https://github.com/h20y6m/tex-jp-build/compare/master...dvipdfmx_uvs

t-tk commented 1 year ago

ありがとうございます。 思わぬ不具合ですが

Adobe-Japan1-UCS2 を古いものに戻してもらう

は無いと思います。しかし一年我慢もちょっと、と思います。 一昨日 "the final updates for TL23 on Friday" とKarlさんからメールが出ていましたが、ねじ込めないかなあ。

aminophen commented 1 year ago

dvipdfmx の変更は第一に平田さんの意向を聞いた方が良いと思います。とりあえず https://github.com/shirat74/dvipdfm-x/issues/8 には書き込みましたが,メールの方が良かったかもしれません。

aminophen commented 1 year ago

Adobe-Japan1-UCS2 を古いものに戻してもらう

これは「Adobe に戻してもらう」と「CTAN/TeX Live で古いものに戻す」の2パターンがあって,後者ならば Karl さんの裁量次第です。(また,安定志向の人が年度末の TL2022 frozen を好んで使うケースがあります。もしも TL2023 initial だけでなく TL2022 frozen も是正を狙うなら,CTAN/TeX Live で戻す手しかありません。)

t-tk commented 1 year ago

なるほど。「Adobe に戻してもらう」は無いと思いますが、 「CTAN/TeX Live で古いもの」と現状の dvipdfmx の組み合わせにしてもらい、 dvipdfmx の update とともに CTAN/TeX Liveも新しくしてもらう、 なら大丈夫のような気がしてきました。

aminophen commented 1 year ago

とりあえず「CTAN/TeX Live で古いもの」にすべく

https://github.com/aminophen/ctan-adobemapping/tree/tlfreeze-20190730

のようにしました。Karl さんには別途メールを入れました。

adobemapping-230311
aminophen commented 1 year ago

CTAN/TeX Live で adobemapping が無事(?)戻りました。dvipdfmx が更新するまで adobemapping の新版を取り入れないようにします。

h20y6m commented 1 year ago

動きがないまま半年経ちましたがどうしましょう?

とりあえず突貫で作ったパッチを見直しました。

  1. 390675c893d684263162a0cf233f6541d241139f
    • マップ先が基底文字+異体字セレクタ(U+FE00--U+FE0F or U+E0100--U+E01EF)だったら異体字セレクタを無視する。
    • 逢のJIS90字形(CID+1133; U+9022 U+E0100)は U+9022 にマップされる。
  2. a7dae3ad2861afa05314ead3d9c1bac707cfa1c7
    • マップ先がCJK互換漢字に対応するCJK統合漢字と異体字セレクタの組合せだったらCJK互換漢字に変換する。
    • 神(CID+8580; U+795E U+FE00)は U+FA19 にマップされる。
      1. cd1d1e0c4f26f758c4b3179f99b72756560282df
        • フォントに 2 で変換した互換漢字がなかったときは変換前の異体字セレクタを無視した統合漢字でグリフを検索する。
        • 神(CID+8580; U+795E U+FE00)の変換先 U+FA19 がフォントになければ U+795E を検索する。
        • これは余計だったかも

1 と 2 は互換性のために必要だと思います。3 ちょっと余計な変更だった気もしてきました。

より理想的にはフォントがサポートしていれば Format 14 テーブルを読んで異体字を出力できればよいのでしょうが…… (Format 14 テーブルは #46 でも必要になりそうなので考えてみようかな?)

t-tk commented 1 year ago

異体字セレクタに SVS (互換漢字など)と IVS (字形の差異) の違いもあるのですね。 あるべき姿はどうなのか、もまだ考えがまとまっていません。たたき台です。


SVS対象 (例: CID+13393 → U+9686 U+FE00 (隆︀) → U+F9DC (隆) というマップ) (1) U+F9DC (隆) に対し U+F9DC を出力する (2) U+9686 U+FE00 (隆︀) (→ U+F9DC) に対し U+F9DC を出力する (U+9686 U+FE00 → U+F9DC の変換は dvipdfmxで行う) (3a) U+9686 U+FE00 に対し、フォントに U+9686 U+FE00 があれば U+9686 U+FE00 を出力する。 (3b) フォントに U+9686 U+FE00 がなく、フォントに U+F9DC があれば U+F9DC を出力する (U+9686 U+FE00 → U+F9DC の変換は dvipdfmxで行う) (3c) フォントに U+9686 U+FE00, U+F9DC がなく、フォントに U+9686 があれば SVSを無視して U+9686 を出力する

IVS対象 (例: CID+8686 → U+9686 U+E0102 (隆󠄂) というマップ) (4) IVSを無視してフォントに U+9686 があれば U+9686 を出力する。 (5a) フォントに U+9686 U+E0102 があれば U+9686 U+E0102 を出力する。 (5b) フォントに U+9686 U+E0102 がなく、フォントに U+9686 があれば U+9686 を出力する


SVS対象では (1)は現状のもの。 (2)は Adobe-Japan1-UCS2 の異体字セレクタ付き新版に対応したもの。 a7dae3ad2861afa05314ead3d9c1bac707cfa1c7 相当? (3a)(3b) は、将来あるべき姿でしょうか。 (3c) は、過剰かもしれません。

IVS対象では (4)は、異体字セレクタを無視してほしくない人にとってはかえってありがたくない機能かもしれませんが、過去の互換性のために要りますか? 390675c893d684263162a0cf233f6541d241139f 相当? (5a)は、将来あるべき姿でしょうか。 (5b)は、(4)よりも異体字セレクタの考え方からすれば正しい動作に思えますが、それでも異体字セレクタを無視してほしくない人にとってはかえってありがたくない機能かもしれません。

IVSの場合、互換性維持に(4)は必要なのでしょうか? とりあえず(4)を実装して将来(5a)(5b)に移行するとか?

390675c893d684263162a0cf233f6541d241139f は IVS のみ対象にして SVS は対象外にした方がよいかもしれません。

t-tk commented 1 year ago

https://www.unicode.org/ivd/data/2022-09-13/IVD_Sequences.txt によると

9022 E0100; Adobe-Japan1; CID+1133   一点しんにょう
9022 E0101; Adobe-Japan1; CID+8266  二点しんにょう
9022 E0102; Adobe-Japan1; CID+13408  一点しんにょう

5078.Adobe-Japan1-6.pdfを見てもCID+1133 と CID+13408 の違いがよく分かりません。そっくりです。

texmf-dist/fonts/cmap/adobemapping/mapping-resources-pdf/pdf2unicode/Adobe-Japan1-UCS2 によると Version: 9.002 では CID+1133 → U+9022 CID+13408 → U+9022

Version: 10.002 では CID+1133 → U+9022 U+E0100 CID+13408 → U+9022 U+E0102

なので、IVSであっても互換性のためには 上記「(4) IVSを無視してフォントに U+9022 があれば U+9022 を出力する。」が当面必要と理解しました。 「(5a) U+9022 U+E0100, U+9022 U+E0102 があればそちらを出力する。さもなければ(5b) U+9022を出力する」が実現できたら移行する、という方針が妥当と思いました。

h20y6m commented 1 year ago

なので、IVSであっても互換性のためには 上記「(4) IVSを無視してフォントに U+9022 があれば U+9022 を出力する。」が当面必要と理解しました。

新しいAdobe-Japan1-UCS2で以前と同等の結果を得るために必要だと思っています。

異体字セレクタを無視してほしくない人にとってはかえってありがたくない機能かもしれません

そうかもしれません。無視した場合に警告を出力するとかでしょうか?

390675c893d684263162a0cf233f6541d241139f は IVS のみ対象にして SVS は対象外にした方がよいかもしれません

たしかにそうですね。


とりあえず当面の方針はこんな感じでしょうか?

さらに将来的に実現できそうであれば

という感じでしょうか?


5078.Adobe-Japan1-6.pdfを見てもCID+1133 と CID+13408 の違いがよく分かりません。そっくりです。

たぶん「三」の部分の上が短いか真ん中が短いかの違いですかね?

t-tk commented 1 year ago

新版で SVS 付きかつ互換漢字でないもので、旧版の割り当てが SVS無しになっているものもありました。 そうすると、互換漢字じゃないものも、「豆腐ではなく、SVS無しに割り当てる」のが、現在までの環境との互換性という観点では正解のようにも思えてきました。

「異体字セレクタに未対応の警告を出力しつつSVS無しに割り当てる」位がベストでしょうか。


旧割り当てが互換漢字への変換ではないもの。(見つけたものだけ。網羅はしていない。)

245 < <0278> <0030> CID+632 斜線付きゼロ 0 245 > <0278> <0030fe00>

7069 < <2024> CID+8228 斜線付きゼロ 0 7072 > <2024>

7584 < <22f5> <0030> CID+8949 斜線付きゼロ 90度回転 7587 > <22f5> <0030fe00>

7627 < <2379> <0030> 7627 > <2379> <0030fe00>

7829 < <25c9> <0030> 7829 > <25c9> <0030fe00>

7961 < <269a> <0030> 7961 > <269a> <0030fe00>

h20y6m commented 12 months ago

コメントするのを忘れていましたが、 https://github.com/h20y6m/tex-jp-build/commit/060d39b7d62ba6437e2b983d09cb074c79b724c6 で警告メッセージを入れてみました。

t-tk commented 12 months ago

ありがとうございます。 私は近々時間を作って試してみようと思います。

dvipdfm-x の cmap14 対応は、 tt_cmap.c を拡張していけばよくて、 cmap14 の形式はややこしいけれども やりたいことは freetype2 の src/sfnt/ttcmap.{c,h} に実装されているのでマネすればよい、 というところまではたどり着きました。

チャレンジされる方はいらっしゃいますか? 意味不明で迷宮入りになる懸念はなさそうですが、手間が掛かりそうで。

t-tk commented 11 months ago

遅ればせながら https://github.com/h20y6m/tex-jp-build/commit/060d39b7d62ba6437e2b983d09cb074c79b724c6 を拝見しました。 二点ほど思ったことです。いかがでしょうか。

(1) 非漢字は? 変なことを言っていたようです。撤回します。

(2) バイナリーサーチの可能性は? UC_Combine_CJK_compatibility_ideograph() の中の、ucv, usv を探してくるあたり、リニアサーチをバイナリーサーチにしないのかな、と少し思いました。 1000行ほどソート済みのテーブルで、実装の費用対効果は微妙ではありますが。


dvipdfm-x の cmap14 対応は気が向いたらぼちぼち手を付けてみようと思っています。

h20y6m commented 11 months ago

(2) バイナリーサーチの可能性は?

https://github.com/h20y6m/tex-jp-build/commit/ca5e2281cde5edc55675b7b2f9bca26266a5c221 でやってみました。 ……が、ほとんど効果はないようです。 UC_Combine_CJK_compatibility_ideograph() は手元の環境で 2 倍程度高速になりますが、 全体に占める時間が 1% にも満たないようで誤差以上の差が出ませんでした。

t-tk commented 10 months ago

update ありがとうございます。動作確認しました。

誤差以上の差が出ません

そうでしたか。 私の好みでは、 https://github.com/h20y6m/tex-jp-build/commit/ca5e2281cde5edc55675b7b2f9bca26266a5c221 を TeX Live svn に入れてよいと思います。 警告メッセージも、今のように、あった方がよいと思います。 あとは ChangeLog を書いてコミットするだけですが、どうされますか? @h20y6m さんがアカウントを取得されたとのことなので、ご自身でなさってもよいですし、私が代理コミットしてもよいです。

h20y6m commented 10 months ago

せっかくなので自分でコミットしてみようかと思います。(SVN使うのは10年ぶりくらいかな……)

https://github.com/h20y6m/tex-jp-build/commit/eedea0596fc2ed3021bc3b8a4503e2f2e57cc8e2 で過去のログを参考にChangeLogを書いてバージョンも上げてみました。

h20y6m commented 10 months ago

TeX Live svn にコミットしました。 https://tug.org/svn/texlive?revision=68889&view=revision

norbusan commented 10 months ago

@h20y6m svnにコミットをありがとうございます。githubのtexlive-sourceのgit mirrorの更新のため、svnユーザからメールアドに書き換えないといけません。使用してほしいメールアドをお伝えください。よろしくお願いいたします。

h20y6m commented 9 months ago

format 14 サブテーブルを読んで Variation Sequences を変換するに手を付けてみました。 https://github.com/h20y6m/tex-jp-build/tree/dvipdfmx_cmap14 とりあえずは動いているような感じです。

format 14 サブテーブルは他のサブテーブルとだいぶ性質が違う感じがするので、実装を他の tt_cmap とは分けたほうがいいのかなぁ……と迷っています。

h20y6m commented 8 months ago

https://github.com/h20y6m/tex-jp-build/commit/b557cb9ccfc68ff36ef65a90ec06fd97e32172a6 で想定通りに動いていそうです。

Adobe-Japan1-UCS2 で UVS 付きにマップされていた場合以下の順でグリフを検索します。

  1. フォントが format 14 cmap サブテーブルを持っていたら、format 14 cmap サブテーブルから検索する。
  2. CJK互換漢字に変換可能なら、CJK互換漢字に変換して検索する(SVS)。
  3. UVSを無視して検索する。

それと、以下のように動作を変更しています。

前者はIVSや互換漢字以外のSVSと挙動をそろえたい、 後者は望まない字形で出力されたかもしれないという警告なのでそもそもグリフが見つからない場合は意味がない という考えからです。


いちおう、UniJIS2004-UTF16-H (1.022) で出力できる文字について、古い Adobe-Japan1-UCS2 (9.002) と IPAex 明朝フォントで、TeX Live 2023 の dvipdfmx (20220710) と同じ結果が得られることを確認しています。 万一の時は Adobe-Japan1-UCS2 を古いものに差し替えることで以前の動作に戻せるはずです。

あと、新しい Adobe-Japan1-UCS2 (10.002) と IPAex 明朝フォントで、VS付になった文字以外にも出力できなくなったもじがそれなりにあるようですが、これは仕方ないですよねぇ……。(ざっと見た感じ UniJIS2004-UTF16-H → Adobe-Japan1-UCS2 で元の Unicode に戻るようになった文字がほとんどのようなので、本来 IPAex 明朝フォントで出力できない文字なんだと思います。)

t-tk commented 7 months ago

ご検討ありがとうございます。 こちらの手元でご提案の仕様をチェックするのは、私がたどり着けない感じがするので、以下感想だけですみません。

前者はIVSや互換漢字以外のSVSと挙動をそろえたい、 後者は望まない字形で出力されたかもしれないという警告なのでそもそもグリフが見つからない場合は意味がない

そうですね。賛成します。 念のためですが、 「UVSを無視して検索してグリフが見つかった場合は警告メッセージを出す」 で合っていますか?

もう大丈夫そうなので TeX Live svnにコミットしてよいと感じます。

46 は、今年はまだだと思っています。

h20y6m commented 7 months ago

TeX Live svn にコミットしました。 r69764

念のためですが、 「UVSを無視して検索してグリフが見つかった場合は警告メッセージを出す」 で合っていますか?

はい、その通りです。

https://github.com/texjporg/tex-jp-build/issues/46 は、今年はまだだと思っています。

あちらはまだまだ考えないといけないことが山積みですね。


あとは、(TL2023 frozen 後に) adobemapping を更新すればこちらは完了ですかね。 (それと https://github.com/texjporg/ptex-fontmaps/issues/32 も)

t-tk commented 6 months ago

あとは、(TL2023 frozen 後に) adobemapping を更新すればこちらは完了ですかね。

TL2024がリリースされたようです。 状況が分からないのですが、これ(adobemappingの更新依頼)って実施していましたか?

aminophen commented 6 months ago

adobemapping ごめんなさい,私の管轄です。時間がなくて出来ていませんでした。更新依頼というか,私が CTAN に上げれば自動で入ります。もうしばらくお待ちください。