Shiki’s Weblog

ESウェブブラウザ通信 - CSS 2.1 Test Suite #3

2011/10/12 #ESウェブブラウザ通信

今回も前回に引き続きW3C CSS 2.1テストスイートの9章の続きです。今回は、こまごまとした修正に加えて、以前から宿題にしていたOpenGLのMultisample Transparencyを使わないz-indexの実装を行いました。・inlines-003 このテストはインライン要素の折り返しのテストです。長い文字列を含んだテキストノードは下のスクリーンショットで見ても折り返せているのですが、インライン要素が並んだ場合を考慮できていませんでした。

r2009r2009

r2010,r2012で、インライン要素の余白部分などでラインボックスに収まりきらなくなった場合にも改行するように修正しました。

r2010r2010

inlines-013

このテストは、9.2.2のテストに含まれていますが、10.8.1の"'line-height' specifies the minimal height of line boxes within the element."という仕様のテストのような感じになっています。

r2013r2013

の部分に高さ1pxの画像があってそれに続いて"XXXX"というテキストを含んだフロートがくるので、画像を含んだ行の'line-height'が正しく設定されて入れば、"XXXX"はFAILの上に表示される、という具合です。

r2018r2018

r2014でのいったん修正したのですが、その修正ではフロートしか含んでいないラインボックスの高さまで0以外にしてしまうので、r2018でさらに修正しています。

inlines-020

このテストも9.2.2に含まれていますが、実際には10.8の"Empty inline elements generate empty inline boxes, but these boxes still have margins, padding, borders and a line height, and thus influence these calculations just like elements with content."という仕様のテストのような気がします。

r2007r2007

"FAIL"というテキストの前に空のインライン要素があるので、空のインライン要素を取り除いていなければ、"FAIL"は1行下にずれて、絶対配置されている、グリーンのテキストが"FAIL"という行を隠す、という具合になってます。この辺はHixieがもう12年も前に"Evil Tests:  Empty Inline Elements"というページを作っているくらいなので歴史的にも色々あったのかもしれないですね。実装のことだけ考えると、空のインライン要素は無視できた方が簡単なので端折られがちだったのかも、とか。

r2008r2008

r2008で修正をいれました。またこの後のテストとの関連でr2016でさらに修正が入っています。ただ、この辺りはまだ仕様を完全に把握できていないところもあって、しばらく修正が続くかもしれません。

after-content-display-001

このテストは':after'セレクタを使った簡単なテストです。一見大丈夫そうですが、r2014では"Filler"の'F'が小文字になってしまっていました。

r2014r2014

r2015で、'content'プロパティで大文字・小文字を無視しないように修正しています。

r2015r2015

block-in-inline-008

このテストでは、inlines-020のときの修正で消さないといけないインラインボックスまで残していたバグがあって、下のように赤い部分が見えてしまっていました。

r2015r2015

r2016で再度修正しています。

r2016r2016

root-box-003

このテストはr2016ではESブラウザがクラッシュしてしまっていたので、修正前のスクリーンショットはありません。テスト内容はルートのhtml要素に"display: none"を指定することでボックスを一切生成しないようにする一方で、"background: green"の指定がウィンドウのキャンバスに反映されるかどうかチェックする、というものです。

r2017r2017

r2016の段階では(NULLポインタになっている)存在しないボックスを描画しようとしてクラッシュしていました。r2017でこの問題は修正しています。また、CSS 2.1の仕様通りであればキャンバスはr2017のような白色ではなくて緑色でないといけないのですが、この点についてはMozillaのDavid Baronさんが"I think it's pretty silly"とバグをファイルされているのでひとまず保留にしています。(この仕様に依存しているサイトってないですよね?)

position-004

このテストは'position'の'fixed'のテストです。

r2018r2018

最初は上図のように表示されるのですが、このウィンドウをスクロールしたときに青い部分は'fixed'なので動いてはいけない、というテストです。

r2018r2018

r2018では'fixed'のスクロールを考慮した実装が入っていないので、普通にオレンジのバーに青いボックスも付いていってしまっていました。

r2019r2019

r2019で修正しています。2行の修正だけでまあ最初から実装しておこうよ、という感じですけれど。・position-absolute-002

このテストも本来は何ということはないテストなのですが、shrink-to-fitを適用する条件を仕様通りにしていなくて、本来表示される筈のオレンジのボックスの幅を0にしてしまっていました。

r2020r2020

r2021で修正しています。仕様書はちゃんと読まないとですね。

r2021r2021

z-indexとスタッキング コンテキスト

この辺りまでテストが進んでくると、テストに失敗する原因がz-indexの実装の不具合のため、というテストが増えてきました(これまではグーグルのトップページを表示できるように、というためだけの簡易的な実装でした)。r2024からは、ごく普通にスタッキング コンテクストを下側から順番に描画していく、という実装に変更しています。r2023では、各ボックスの原点(x, y)を描画前に計算するようにしました。今までは描画するまで親ボックスと兄のボックスとの相対的な位置関係しか計算していなかったのでした。この変更でスタッキング コンテキストを生成した各ボックスをワールド座標からいきなり描画するための準備ができました。

r2024では、StackingContextの実装を進めて、スタッキング コンテキスト順にボックスを描画するようにしました。OpenGLのGL_SAMPLE_ALPHA_TO_COVERAGEも無効にして大丈夫になりました。スタッキング コンテキスト順に描画するといっても、毎回ボックスツリーのルートから処理するわけではなくて、スタッキング コンテキストを生成したボックスから直接描画をはじめるので、レンダーツリーをなぞる処理は特に増えていません。また、GL_SAMPLE_ALPHA_TO_COVERAGE の半透明処理は網戸のような感じになってしまうのですが、その問題もなくなっています(下図参照)。

Googleトップページの右上端の描画(r2024以前・以降。2倍に拡大

なお厳密には、各スタッキング コンテキストで、すべての子孫の非インラインレベルボックスをインラインレベルボックスより先に描画する、といった処理も必要です。現状では、背景、ボーダー、インライン要素は各ボックス単位で描画してしまっています。overflowの関係等で、この実装では標準通りにならない場合も出てくると思いますが、9.9.1のz-indexのテストはだいたいパスするようになりました。今回はここまでです。9章はフロート周りをはじめ、まだたくさんテストが残っています。次回以降もテストと修正を続けて行きます。