Bugzilla – Bug 5180
[Cairo][pango] pangoによるフォントスイッチングがデタラメ
Last modified: 2006-09-26 16:17:17 UTC
pangoによるフォントスイッチングが、特定の言語に所属しない文字(例えば数字)ではデ タラメです。
Created attachment 3188 [details] screenshot '4'が状況によって二種類のフォントで描画されてしまっています。 これらは常に安定した結果を得られるべきだと思います。
この問題ですが、cairoが有効になる以前から起きています。 cairoというよりは、pango自体の問題かなと思っています。
デフォルトで選択しているフォントに依存するようです。 デフォルトフォントで選択しているフォントが日本語を持たない場合、例えば '4444あいうえお44' が日本語として認識され、日本語を持つフォントで描画され、続く 'a4' が英語と認識されて、デフォルトフォントで描画されることで発生するようです。 normalに引き下げます。
(Comment #2 への返信) > この問題ですが、cairoが有効になる以前から起きています。 > cairoというよりは、pango自体の問題かなと思っています。 はい、pangoの問題であることは確認してます。 ただ、修正方法があっても元のpangoのソースを修正するつもりはないので [Cairo]を付けています。
Created attachment 3189 [details] Patch rv0.1 (work in progress)
pangoのソースを追いかけていましたが、pango側への指示での修正は無理なようです。 そこで、言語からニュートラルな文字のみの部分と、そうではない部分に分割して pangoに処理させることでかなり改善することができます。 提出中のパッチはまだ数字にしか対応できていませんし、letter-spacing等に対応できて いません。 また、letter-spacing対応の時から感じていたのですが、処理速度、メモリ利用の 双方のパフォーマンスに問題があります。このへんはGecko1.9リリース前に一度 リファクタリングが必要かもしれません。
Created attachment 3190 [details] Patch rv0.2 (work in progress) ニュートラル文字の抽出が終了しました。 あとはletter-spacingに対応させるのみです。 どうもこのパッチで、文字が重なることがあるバグも修正されるようです。
Created attachment 3191 [details] Patch rv1.0 RC1 おそらくこれで完璧だと思いますが、例によってBeOSではテストできていません。 Linux上でもどなたか確認とってもらえると助かります。
Created attachment 3192 [details] パッチ(attahcment 3191)をあてた場合 タブのBug #5180の数字の部分を見てください。
Created attachment 3193 [details] 公式Trunk(パッチ無し)
(Comment #8 への返信) > Created an attachment (id=3191) [編集] > Patch rv1.0 RC1 > > おそらくこれで完璧だと思いますが、例によってBeOSではテストできていません。 > Linux上でもどなたか確認とってもらえると助かります。 試してみました。 当初の問題は解決しているように見えますが、数字の部分の間隔が ひろがりすぎているように見えます。 attachment 3192 [details]とattachment 3193を御覧ください。
(Comment #11 への返信) > 試してみました。 > 当初の問題は解決しているように見えますが、数字の部分の間隔が > ひろがりすぎているように見えます。 数字部分が日本語フォントで描画時のみ、boldが効いていないので、広がっているように 見えているのだと思います。(計算時はおそらくboldが効いていると思います。)
Bug-org 339513に登録しました。
(Comment #12 への返信) > (Comment #11 への返信) > > 試してみました。 > > 当初の問題は解決しているように見えますが、数字の部分の間隔が > > ひろがりすぎているように見えます。 > > 数字部分が日本語フォントで描画時のみ、boldが効いていないので、広がっているように > 見えているのだと思います。(計算時はおそらくboldが効いていると思います。) 数字部分が日本語フォントで描画されているのは、意図してのことなのでしょうか? もしそうなら、英字と異なるフォントが使用されているのは、違和感があるのですが。
(Comment #14 への返信) > 数字部分が日本語フォントで描画されているのは、意図してのことなのでしょうか? > もしそうなら、英字と異なるフォントが使用されているのは、違和感があるのですが。 数字部分が日本語フォントで描画されているのは意図通りです。 しかし、英字が日本語フォント内のASCII文字を無視してしまっているのが予定外です。 これはpangoの仕様上仕方ないのかもしれませんが、CSSの仕様とは異なります。
(Comment #15 への返信) > (Comment #14 への返信) > > 数字部分が日本語フォントで描画されているのは、意図してのことなのでしょうか? > > もしそうなら、英字と異なるフォントが使用されているのは、違和感があるのですが。 > > 数字部分が日本語フォントで描画されているのは意図通りです。 > しかし、英字が日本語フォント内のASCII文字を無視してしまっているのが予定外です。 > これはpangoの仕様上仕方ないのかもしれませんが、CSSの仕様とは異なります。 fontconfigで、欧文フォントを優先して使用するようにしているつもりです。 Firefox意外は、欧文フォントにない文字の場合は、フォールバックして日本語フォントが 使用されています。 Firefoxの表示エリアが上記と異なり、全て日本語のフォントで表示されるのが CSSの仕様上正しいとしても、タブやメニューなどは他のGNOMEアプリケーションと 同じ表示の方がいいと思うですが。 あるいは、userChromeとかで設定するのがFirefox的には正しいということ なのでしょうか。
(Comment #16 への返信) > Firefoxの表示エリアが上記と異なり、全て日本語のフォントで表示されるのが > CSSの仕様上正しいとしても、タブやメニューなどは他のGNOMEアプリケーションと > 同じ表示の方がいいと思うですが。 > あるいは、userChromeとかで設定するのがFirefox的には正しいということ > なのでしょうか。 そうです。 UI部分については難しい問題ですが、少なくともWebページの表示に関してはそうなります。 font-family: "日本語フォント", "英語フォント"; となっている場合、日本語フォントに含まれていない文字だけが英語フォントで代用され るべきです。 font-family: "英語フォント", "日本語フォント"; であれば、大島さんの期待通りになります。 lang="ja"の場合、"font-family: sans-serif;"という指定で、前者が指定されているこ とになりますが、表示結果が後者になってしまっています。
ちなみに、後者の指定ならおそらく数字も英語フォントになるかと思います。 # 試していませんが
なんとなく原因が分かってきました。 pangoの一番高級なAPIに頼りすぎているようです。 Windowsとほぼ同等のAPIが用意されているようなので、これを利用することでpangoビル ドのレンダリングを飛躍的にCSS仕様に近づけることができそうです。 数日中に新しいパッチのファーストショットが容易できると思います。
Created attachment 3280 [details] Patch rv0.1 (work in progress) パッチの草案です。 # まだこのパッチを取り込んでも描画できません。 pango自体、詳しく無いので空論で設計していますが、リファレンスを見る限りでは こういう形でWindowsと同じ描画ができそうです。
Created attachment 3281 [details] Patch rv0.2 (work in progress)
Created attachment 3283 [details] Patch rv0.3 (work in progress)
Created attachment 3284 [details] Patch rv0.4 (work in progress) とりあえず動くものができました。 まだletter-spacingがあったり、複雑なフォントスイッチングの時には処理が破綻します ので常用はできません。
Created attachment 3285 [details] Patch rv0.5 (work in progress) letter-spacing fixed.
Created attachment 3286 [details] Patch rv0.6 (work in progress) 大枠は完成しましたが、まだ出力結果が予定通りに出ていません。 テストページ: http://www.spreadfirefox.com/blog/17528
Created attachment 3287 [details] Patch rv0.7 (work in progress)
Created attachment 3288 [details] Patch rv0.8 (work in progress) かなり完成度は上がりました。日本語、中国語混在のページでも表示できるようになりま した。また、上記テストページのようにlang="en"の要素に日本語があっても表示可能に なりました。 ToDo XP部分の変更でWinでビルドできるか要確認 RTLページでフリーズするバグの修正 コードのクリーンナップ パフォーマンス測定
ToDo パフォーマンス低下への対策 中央ヨーロッパフォント設定への対応
Created attachment 3290 [details] Patch rv0.9 (work in progress) RTLテキストも表示できるようになりました。 あとは中央ヨーロッパへの対応と、チューニングだけです。
Created attachment 3291 [details] Patch rv0.10 (work in progress) 中央ヨーロッパに対応し、Win/Macでもビルドできるように修正しました。 あとは最適化のみです。
(Comment #30 への返信) > Patch rv0.10 (work in progress) をcairo-gtk2自前ビルド (2006082417_trunk) でテストしました。 URLにあるテストケースでも、すべて同一フォントで表示されています。
Created attachment 3293 [details] Patch rv1.0 ようやく完成しました。 一回しかテストしていないので誤差の可能性もありますが、パフォーマンスが若干上がっ ています。(2-3%?) このパッチで修正される点は https://bugzilla.mozilla.org/show_bug.cgi?id=339513#c21 を参照してください。
Created attachment 3294 [details] testcase
Created attachment 3295 [details] Patch rv1.1
FC5 で patch rv1.1 をあててビルドしてみました(つもり)。 bug 5138 のtestcase(attachment 3175 [details]) をcgi出力で開くぶんには平気でしたが http://www2.wbs.ne.jp/~chado/work/js_ucoder/ucoder_s.txt (EUC-JP) や http://www2.wbs.ne.jp/~chado/work/js_ucoder/ucoder_utf_s.txt (UTF-8) を 開くと落ちちゃいました。 patch を当てる前から挙動がおかしいので自分のビルドがアヤシいんですが、 一応確認していただけると幸いです。
私の環境では再現しないです。 takenさんと同様に合成フォントにアクセスしてpangoが落ちちゃってることはないでしょ うか?
Created attachment 3297 [details] Patch rv1.3
Patch rv1.3 で Comment #35 と同じことをやってみたら落ちませんでした。 # 念のためご報告まで。
(Comment #37 への返信) 当方でも問題なく動作しています。
(Comment #37 への返信) > Created an attachment (id=3297) [編集] > Patch rv1.3 こちらでも問題なく動いています。
(Comment #37 への返信) > Created an attachment (id=3297) [編集] > Patch rv1.3 http://debian.fam.cx/ このページの上の方にある 「Debian GNU/Linux スレッドテンプレ内 全文検索」というリンクの 「全文検索」の部分のみserifで表示されてしまいます。
(Comment #41 への返信) > (Comment #37 への返信) > > Created an attachment (id=3297) [編集] [編集] > > Patch rv1.3 > > http://debian.fam.cx/ > このページの上の方にある > 「Debian GNU/Linux スレッドテンプレ内 全文検索」というリンクの > 「全文検索」の部分のみserifで表示されてしまいます。 再現しません。はて?
Created attachment 3299 [details] FC5でのスクリーンショット (Comment #41 への返信) Edit -> Perferences -> Content -> Fonts & Colors -> Advanced Proportional: Sans Serif Serif: serif Sans-serif: sans-serif Monospace: monospace で、添付のようになりました。 # 当方では各フォントエイリアスにIPAフォントを入れています Debian GNU/Linux スレッドテンプレ内 全文検索 ではフォントが変わりますが、その下にある Debian GNU/Linux スレッドテンプレ内の全文検索 ではフォントは変わっていません。 内部で読み込んでいるpukuwiki.cssを読み込まないようにすると再現しないようです。 これ以上の追求はしていません。
Bug-org 334064のチェックインの影響で、attachment 3297 [details]が適用できないようです。
フォントが変わってしまうのはbug 5319と同じバグかもしれません。 最新のパッチにはbug 5319の対応を含んでいますので、そちらでテストしてみてもらえま すか?
Created attachment 3300 [details] Rev 1.5 on FC5 (Comment #45 への返信) Bug-org 339513のattachment-org 236116 [details]を適用したもののスクリーンショットです。 フォントは Serif: serif Sans-serif: sans-serif Monospace: monospace です。 緑の●はカーソルの位置です。 最後の行は、図中コメントの4行目と同内容を入力した直後に同7行目冒頭4文字をcopy and pasteしたものです。 マウスで4文字分選択すると「あ」の半ばくらい (図中コメント2行目相当) まで反転表示 されます。 フォントを Serif: IPA P明朝 Sans-serif: IPA Pゴシック Monospace: IPA ゴシック とした場合は、表示に問題はありません。 Bug 5319およびComment #41については修正されていました。 sans, serif, monospace等は、bug 5319 comment #7にも書きましたように、フォントリ ストへのエイリアスです。
(Comment #46 への返信) > マウスで4文字分選択すると「あ」の半ばくらい (図中コメント2行目相当) まで反転表示 > されます。 Bug-org 334064のregressionです。 選択範囲がASCII文字のみになるとpangoではなく、新しいxft側のコードが使われて、そ の異なるフォント選択ロジックで決定されたフォントが利用されることによる問題です。 日本語の高速化も含めて現在、対応を検討中ですが、現在のパッチが既に大きすぎて、他 の修正をブロックしてもらっているので先に今のまま入れて、後で対応しようと考えてい ます。 > Bug 5319およびComment #41については修正されていました。 了解です。確認ありがとうございます。
Created attachment 3303 [details] Patch rv1.8
Created attachment 3304 [details] Patch rv1.9
Created attachment 3305 [details] Patch rv1.10 bug-org 334064によるregressionを修正できました。
Created attachment 3306 [details] Rev 1.10 on FC5 (Comment #50 への返信) > Patch rv1.10 Serif: serif Sans-serif: sans-serif Monospace: monospace で、例えば、 都道府県 は同一フォントで表示されますが、 都 道府県 は旧と市街地で別のフォントになります。 市区町村 では、 市 区町村 とすると、「区」以降が消えました。
(Comment #50 への返信) Comment #49の設定では、 font-family: sans-serif の日本語部分がserifのフォントで表示されます。
私の環境では再現しないです。accept-languageのリストはどうなっていますか? # bugzilla-jpのHTMLもバグってて、lang="ja"が効いていないですね
accept-languageからCJKを削除して、IPAフォントをFxで指定すると、文字が消える現象 は確認できました。
accept-languageは関係なさそうですね。IPAフォントを利用した場合にのみ、ランダムに 文字が消えることがあります。
serif : MS P明朝 sans-serif : MS Pゴシック monospace : MS ゴシック では、特に問題はないようです。 #ちょっと、特殊な環境かもしれませんが、参考までに。
IPAフォントで文字が消える現象はXftで描画されている場所でも発生しますね。 ただ、ビットマップフォントとして表示されているときは問題が発生しますがTextZoomで 大きくしてベクタで表示させると文字が消える現象は確認できなくなりました。
文字が消えるのはcairoのバグのようです。 cairo_show_glyphsを二回走らせると表示されます。
(Comment #58 への返信) > 文字が消えるのはcairoのバグのようです。 > cairo_show_glyphsを二回走らせると表示されます。 失礼間違いです。関係ないようです。
フォントがスペースを境に変わってしまうのは他のフォントで再現しますか?
(Comment #51 への返信) > 旧と市街地 都と道府県 です。
(Comment #60 への返信) Serif: IPA P明朝 Sans-serif: IPA Pゴシック Monospace: IPAゴシック Serif: さざなみ明朝 Sans-serif: さざなみゴシック Monospace: さざなみゴシック では、フォントの変更は発生しません。 Serif: serif Sans-serif: sans-serif Monospace: monospace では、フォントの変更が発生します。 都 道府県 の場合、使用されているフォントは見た目から、 都: さざなみ明朝 道府: Baekmuk Batang 県: AR PL ZenKai Uni と推測されます。 serifのリストは Bitstream Vera Serif Times New Roman Thorndale AMT Times Nimbus Roman No9 L Luxi Serif Sazanami Mincho Kochi Mincho AR PL ZenKai Uni AR PL SungtiL GB AR PL Mingti2L Big5 MS 明朝 Baekmuk Batang FreeSerif MgOpen Canonica となっており、 「都」をさざなみ明朝で表示 「スペース」 「道」のグリフを持つものをKochi Mincho以降から検索。AR PL ZenKai Uniで表示 「府」はAR PL ZenKai Uniに含まれるので引き続きAR PL ZenKai Uniで表示 「県」のグリフを持つものをAR PL SungtiL GB以降から検索。Baekmuk Batangで表示 のような動作をしていると考えられます。 serif, sans-serif, monospaceでは、スペース等が表れるたびにフォントリス トのどのフォントを適用するか検討されているのでしょうか。 この形式 (serif等があるフォントリストのエイリアス) は、fontconfigを採 用するディストリビューション (最近のものはほぼすべて?) で標準で採用さ れていると思われますので、影響は大きいと考えられます。 また、URLにある中野さんのテストケースでは、日本語部分がserifで表示されます。
(Comment #62 への返信) > serif, sans-serif, monospaceでは、スペース等が表れるたびにフォントリス > トのどのフォントを適用するか検討されているのでしょうか。 現在、二種類の描画機能があります。 ひとつは|gfxPangoTextRun::MeasureOrDrawFast|、 もうひとつは|gfxPangoTextRun::MeasureOrDrawItemizing|です。 まずFastで描画がトライされます。この時、利用されるフォントは候補で最初のフォント のみです。もし、このフォントのみで描画できると判断できた場合、実行されます。も し、一文字でもそのフォント内にグリフが含まれないフォントがあった場合、Itemizing に移行します。 Itemizingに突入すると、まず、テキストをアイテム化します。このアイテム化は pango_itemizeに頼っているので詳しい仕様は不明ですが、松浦さんの環境で見る限り、 空白の前、もしくは後ろで一旦区切っている可能性があることが分かります。(断言はで きません。) つぎに、各アイテムについて、最初のフォント候補からグリフの存在確認を行います。も しグリフが無ければ、文字単位で次のフォントにトライすることになります。そういった 形でフォントを探しながらフォントリストの候補の上位から順に描画にトライしていくこ とになります。 ここで問題なのは実フォントではなく、エイリアスの場合ですが、ここの仕様はよく分 かっていません。コンテキストに設定された言語からエイリアスの中からフォントが選ば れているものと思われるのですが、どうにもそのへんの細かい資料というのが見あたらな いので間違っているのかもしれません。もし、間違っていれば、アイテム毎に異なる優先 順位のフォントリストで描画にトライしている可能性はあります。 ちなみに、何もいじっていない私のFC5環境ではserif/sans-serif/monospaceを指定して いても問題は発生していません。
(Comment #63 への返信) 当方では、FC5に含まれる全てのフォントをインストールしています。 そのせいで問題が露呈しているのでしょうか。 > 一文字でもそのフォント内にグリフが含まれないフォントがあった場合、Itemizing > に移行します。 上で例示した「都 道府県」「市 区町村」の例では、日本語のフォントであれば全ての文 字を同じフォントで書けると思うのですが、Firefoxで「書けない」と判断されて Itemizingに回されていることが、そもそもおかしいのでしょうか。 それとも、Firefoxで「書ける」と判断された後、どこかで分解されているのでしょうか。 FC6が出るまで新規インストールの予定もないし、cairo-gtk2ビルドで長時間 (実行中に フォント変更を繰り返しているためかも知れませんが) 使用しているとメモリ使用量が数 GBになることもあるので常用できないし…、どうしましょう。
(Comment #64 への返信) > > 一文字でもそのフォント内にグリフが含まれないフォントがあった場合、Itemizing > > に移行します。 > > 上で例示した「都 道府県」「市 区町村」の例では、日本語のフォントであれば全ての文 > 字を同じフォントで書けると思うのですが、Firefoxで「書けない」と判断されて > Itemizingに回されていることが、そもそもおかしいのでしょうか。 おそらくこっちです。 シンプルな日本語の文章ですので、lang="ja"指定があればfastで事足りているはずなの です。 > FC6が出るまで新規インストールの予定もないし、cairo-gtk2ビルドで長時間 (実行中に > フォント変更を繰り返しているためかも知れませんが) 使用しているとメモリ使用量が数 > GBになることもあるので常用できないし…、どうしましょう。 これはシンプルにリークしているかもしれません。
Created attachment 3312 [details] Patch rv1.11 一カ所、メモリリークを見つけました。
Created attachment 3315 [details] Patch rv1.12 フォンとキャッシュを改善してメモり消費を抑えました(Itemizing時)。
Created attachment 3316 [details] Patch rv1.13 おそらく最終版です。松浦さんの現象もlang指定が間違っているサイトで再現しました。 このパッチはその問題も修正できています。
バグの原因はおそらくcomment 62の解析からして、フォントのインデックスの管理失敗で す。フォントのインデックスを下げてリトライしないといけない場面で、それができてい なかったということだと思いますが、rv1.12までは効率のためにややこしいロジックだっ たので修正できませんでした。rv1.13ではあまり効率を落とさないようにしつつ、ロジッ クを単純化して修正しています。
Created attachment 3317 [details] Rev 1.13 on FC5 (Comment #64 への返信) デフォルトのfontconfig設定で、 Serif: serif Sans-serif: sans-serif Monospace: monospace Default font: serif としたときの、gtk2ビルドとcairo-gtk2ビルドの比較です。 Comment #51の件は修正されていることを確認しました。 メモリの使用量もgtk2ビルドと比較して大きく変わりません。 ただ、sans-serifで表示されるべき日本語がserifで表示されるようです。 また、描画時間はcairo-gtk2ビルドでは非常に遅いようです。 本bugページの表示では、gtk2ビルドではストレスなく表示されるのに対し、cairo-gtk2 ビルドでは「いつになったら表示されるんだろう…」と思う程時間がかかります。
おそらく現象からして松浦さんの環境ではlang="ja"が無視されていますね。 何故だか分かりませんが。(bug 5327でbugzilla-jp側も修正したのですが) それがデフォルトフォントがserifになったり、遅い原因だと思います。 serifになってしまうか、sans-serifになるかはおそらくwesternか、 もしくはCJKのJ以外の設定が優先されているためだと思います。 例えば、lang="en"のコンテンツ内で日本語を表示する場合、lang="en"のデフォルトの genericが継承されて、lang="en"のserif/sans-serif設定がそのまま日本語フォントにも 適用されます。 また、そういう感じで日本語を優先的に選択されていないのがパフォーマンスに影響して いるので、ワークアラウンドとしてはOther languagesに日本語フォントを選択しておい てください。それでかなり高速になるはずです。(それでもfastが使われない、というの は速度低下の最大の原因になってしまいますが。)
(Comment #71 への返信) > それがデフォルトフォントがserifになったり、遅い原因だと思います。 > serifになってしまうか、sans-serifになるかはおそらくwesternか、 > もしくはCJKのJ以外の設定が優先されているためだと思います。 > 例えば、lang="en"のコンテンツ内で日本語を表示する場合、lang="en"のデフォルトの > genericが継承されて、lang="en"のserif/sans-serif設定がそのまま日本語フォントにも > 適用されます。 これ、嘘でした。私のパッチが、というか、言語のthebesのコードがバグってて、そうな らないといけないのになってないです。 こうなると、松浦さんの現象は、私には次のような原因しか思い浮かびません。 1. jaのfont.name-listにserifのフォントが列挙されている 2. westernか何か、別の言語のフォントから日本語のserifのグリフにリンクされてい る、もしくはそのフォントがそのグリフを持っている 1ですが、これは通常、いじらないと思うので問題無いと思います。たとえいじってて も、他の日本語サイト(lang="ja"が適切に設定されていたり、日本語固有のエンコーディ ングのサイト)でも同じくserifで表示されてしまいます。 2もパフォーマンスが落ちている、ということから、westernでは無い可能性が高いです し、フォント間のリンクを現在の手法で維持できているかどうか疑問です。また、グリフ を多言語のフォントが持っているというのもちょっと考えにくいです。 というわけで、よくわかりません。 # とりあえず、なんで松浦さんの環境ではlang="ja"が無視されてんだ、という話ですが。 # bugzilla-jp内で適当な所で右クリックして、"properties"は出ますか? # 出た場合、言語はどうなっていますか?
> 言語のthebesのコードが 現行の……
(Comment #72 への返信) > # とりあえず、なんで松浦さんの環境ではlang="ja"が無視されてんだ、という話ですが。 > # bugzilla-jp内で適当な所で右クリックして、"properties"は出ますか? > # 出た場合、言語はどうなっていますか? gtk2, cairo-gtk2ともにpropertiesは表示され、 Miscellaneous Properties Text language: Japanese と表示されます。
configureオプションをバイナリ配布のnightlyのabout:buildconifgと合わせて、 パッチの有無で動作を比較したところ、パッチ適用時のみsans-serif部分の日 本語がserifで表示されました。 Firefoxで使用しているライブラリは、FC5の標準のもの (最新状態にupdate済) のみのはずなんですが…。 ところで、バイナリ配布のnightlyで、このBugのURLに示されたテストケース を表示したところ、 Pango-WARNING **: Error loading GPOS table 4097 が表示されますが、すべて同じフォントで表示されました。 # attachment 3317 [details]のcairo-gtk2でserifの日本語部分のboldが効かないのは、 # cairo側の問題でしょうか。別bug?
> # attachment 3317 [details] [編集]のcairo-gtk2でserifの日本語部分のboldが効かないのは、 > # cairo側の問題でしょうか。別bug? see bug 5097.
-> FIXED