[Mozilla]Firefox 3系用にょずら欲しい!

http://d.hatena.ne.jp/nyama/20071020/1192841225
とか、
http://maguroban.s41.xrea.com/diary/diary.xcg?Date=20071020#2007102000
とか読んで、俺も俺もと速攻つられてみます。
って書けば頂けるのかどうか知らないのですが…(笑
ググっても見つからず、丁度ircにも誰も居なかったのでダメ元で書いておきます。メアドは KENZ.gelsoft at gmail dot com です。

ircでnorixさめに教えて頂きました。「ちらし☆のうら」にひっそりと書いてありますね(笑)。ありがたく試させていただきます。

直訳に満足できなくて、古いにょずらをベースに自分でnightly向けJLPを作っていた時期もありました。色々あって個人によるJLPは衰退した感もありましたが、ぜひ復活して欲しいものです。愛用します!

cairoを使うということ

俺は別に中の人でもなんでもないのですが、Geckoがcairoベースになることを肯定的にとらえている一人として、Piroさめのようにどうしてcairoなの?cairoとか変なものにこだわるから、ブラウザとしての進化が遅れてるんじゃないの?(印象訳)という風に感じる理由について考えてみました。

誇大広告と現実のギャップ

Firefox 3のレンダリングエンジンになるGecko 1.9において、cairoというベクトル描画ライブラリを使うようになる、ということが大きな変更点として宣伝されてきました。日本のニュースサイトでも取り上げられていました。
まずこれが間違いだと俺は思っています。というのは、Geckoがcairoベースになるよ、ということ自体では、ほとんどユーザーメリットがないのに、それがユーザー向けの宣伝として伝えられているからです。
実際、cairoベースにするために、ものすごく大量のコードが変更され、それによって大量のバグが埋め込まれ、一時的に性能が劣化しています。それにもかかわらず、cairoベースにすることによって得られる直接のユーザメリットは、「cairoではハードウェアアクセラレーションを利用することができるので、速くなる(かも)」という程度のものです。
今のところ、まだnon-cairoの速度を超えているとは思えませんし、多くのバグを抱えている現状をみると、なんでcairoなの?と、首をかしげてしまうのも仕方ありません。

cairoな世界のその先にあるもの

それでも、Geckoをcairoベースにすることにはメリットがあります。まずは、直接的なメリットから。

  1. バグの温床となっていた嫌なコードを減らせる。
    従来のGeckoでは、自前でgfxと呼ばれるグラフィック抽象化レイヤを作っていて、それがプラットフォーム毎/出力デバイス毎(プリンタとか)に実装をゴリゴリ書いていやなことをしていました。このあたりを、オープンソースプロジェクトであるcairoに任せることで、Geckoではより本質的なレンダリング処理に集中することができます。
    (実際には、cairoの開発にMozillaからも凄い人たちが何人も参加しているので、外で仕事をしているだけと見ることもできますが、cairoを専門にやっている人たちも居ますし、他にcairoを利用しているプロジェクトからの貢献も期待できます。)
  2. グラフィック抽象レイヤを一本化して、すっきりした設計にする。
    従来のgfxではHTMLやXULレンダリングに必要な描画機能しか用意されておらず、半透明だとかアンチエイリアス付きだとかベクトル描画だとかいうモダンな描画APIがありませんでした。そのため、そういう新しい描画APIを要求するSVGcanvasなどは、独自にプラットフォームのより高度なAPI(GDI+やQuartzなど)を呼び出すようになっていました。つまり、gfxを利用する描画コードと、それ以外の描画コードが混ざってけっこうイヤーな感じになっていたのです。
    この嫌な状況が、比較的モダンなベクトルベースのグラフィックスライブラリであるcairoですべて置き換えられるわけです。
  3. 一応、高速化の余地もある。
    既に触れましたが、cairoはその実装において3Dハードウェアアクセラレーションを利用するオプションを持っていて、それを利用することで、ソフトウェアだけでは負荷が高い高度な描画の高速化ができるかもしれません。実際に高速に動くまで信じませんが。

さて、ここまででは、ほとんど開発者がコードがすっきりして気持ちいいとか嬉しいとかそういうエゴイスティックな感じがします。しかも、ホントに速くなるの?疑わしいなあ、とゆー雰囲気です。が、上の様なことは次のような副次的なメリットをもたらします。

  1. (少なくとも長期的には)バグが減る。
    メンテナンスするコードが減って、構造がすっきりすることで、バグの修正が容易になります。また、グラフィック抽象レイヤを捨てて作り替えることになるので、そこに起因する根の深いバグを直すチャンスにもなります。
  2. 高度な描画を利用する機能が作れるように(or作りやすく)なる。
    レイアウトコードが利用するグラフィック抽象化レイヤが一本化されたことで、たとえばSVGのなかにHTMLを埋め込んで回転拡大縮小してみたり半透明にしてみたりできたりします。中に<video>要素をつっこんでSVGアニメーションで回転させたり半透明効果をかけたりしたらSilverlight的なこともできたりするのかもしれません。
    また、SVGcanvasの実装もシンプルになるので、新しい機能のサポートが加速される…はずです。

どちらも自信なさげな口調で書きましたが、それは、俺が作っているわけでもないし、まだ具体的なメリットを目にしていないからです。これらのメリットがもっと具体的なものになってはじめてユーザに伝わるのではないかな、と思っています。
しかし残念なことにFirefox 3のタイムスパンでは、具体的なユーザメリットが数えるほどしか出てこないので、ユーザにアピールしない状況になっているのではないかと思うわけです。

結論

cairoの採用は、歴史としがらみと難解なバグを含んだgfxという古いグラフィック抽象化レイヤを窓から投げ捨て、これからの10年を見据えてベクトルベースのグラフィック抽象化レイヤに移行するものです。
Mozillaでは、今まで多くの機能について全てを自分たちで作るという愚行を冒してきました(必要なものもあったでしょうが、Geckoを巨大で複雑なものにしてしまった要因であることは確かです)。しかし今回は、GTK+、Mono(のSystem.Drawing)、Eclipse(SWTのAdvanced Graphics機能)、Inkscapeなどに採用され、それらのプロジェクトからフィードバックや貢献が期待できるcairoというオープンソースプロジェクトにコミットするという正しい選択をしました。
Mozillaはcairoに多大なコードを寄付し、多くのプロジェクトがcairoがちゃんと動いていることを証明し、そしていままでよりも多くの人がMozillaの描画コードの信頼性に貢献してくれます。GeckoWeb標準やWebを豊かにする新しい機能に集中すればいいのです。つまり、みんなが幸せになるということです。

付録:ついでなのでcairo自体も擁護しておく

最近cairoへの風当たりが強いのでcairoファンの俺としては、とても悲しい状況です。ので、一応こっちも擁護しておいたりします。
cairoは、Geckoでcairo使おうかなーとか言ってた最初の頃は、Linuxでベクトルグラフィックスを使うのにちょこちょこ使われる一つのライブラリに過ぎませんでした。
それが、一年かそこらでWindowsMacでもそこそこの速度で表示できるようになり、印刷も使えるレベル(Windowsユーザの俺観点で、ですが)になってきたのです。今はまだ機能に不満があるかも知れないですが、いつまでもその状況だとは思いません。
俺はcairo MLをぼちぼち眺めている程度なのですが、それでも見て取れるのは、cairoはベクトルベースの描画ロジックが正しく完璧に高速に動くこと、まずはそこを目指してひた走っている最中だということです。
そのため、たとえばドロップシャドウをサポートするようなラスタライズをリッチにする仕組みは、当初の目標であるベクトル機能の完成をみてその後に検討される機能なのではないかな、と思っています。楽観的に過ぎますか。そうかもしれません。

WebKit 組み込み on Windows

WebKit といえば、最近話題の Safari for Windows のブラウザエンジンなわけですが、 Gecko 組み込みの先達である plus7 さめがそいつを自作アプリ(ってほどには作り込んでないみたいだけど)に組み込むことに成功した様子。
がんばっているなあ…。
Safari for Windows は入れてみた物の劣化 MacGUI が嫌すぎるのと、日本語の描画がまだまだだったので速攻消してしまったので、せめてガワだけでみおまともな WindowsGUI にしてくれることを期待してます>plus7さめ

いつも内容が分からないタイトル。内容見てもわかんないからいいか。

http://bugzilla.mozilla.gr.jp/show_bug.cgi?id=5725
について調べ中。
ConstructFrame()

の流れで、overflow: autoの場合はScrollFrameが作られるっぽい。
nsGfxScrollFrame.cppのBuildDisplayList()を見てる限りだと、ここでクリッピングかけない流れがあるみたいだけどその辺が怪しい感じがする、が難しくてよくわかりません。(オチ

引き続きメモ

もやもやと、Wii Mote APIと類似の方法でWiiリモコンのボタン状態をFlashに伝達してみてます。
実際に動かしてみていると、時折Flash側で把握しているWiiリモコンのボタン押下状態が不整合になって、たとえば、右ボタン押しっぱなしと認識されてしまったりします。
JavaScript側からonkeydownとonkeyupでぶち投げるようにしてるんですが、多分たまにonkeyupの後にonkeydownが発生してるか、処理がいっぱいいっぱいになってonkeyupで発生したresizeを処理し漏らしてしまう(多分こっち)のかなと疑ってみています。
アンテナ(resizeイベントでJavaScriptからFlashにイベントを伝達するためのFlash)が短くなるように、最後に発生したイベントしか伝達しないでいたのですが、JavaScriptでボタン状態を管理して、全ボタン状態をぶん投げるようにしたほうが安全確実な感じかも。。。