2012年2月5日日曜日

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

前回は、CSS 2.1テストスイートの5章、6章の確認とカスケーディング処理の高速化を行いました。今回からは、これまでまとまったテストは行っていなかった16章「テキスト」のテストを進めていきます。今回は、16.1の'text-indent'と16.6の'white-space'のテストを行っていきます。

改行可能位置の処理

c26-psudo-nest-000

テストスイートのテストに入る前に既知の改行可能位置の問題を修正しておきます。

r2364
前回テストしたこのテストをIPAフォントで表示してよく見てみると、3番目の段落の2行目が.(ピリオド)ではじまってしまっています。

HTMLファイル中ではこの部分は、
be <strong>teal≤/strong>.
のようになっていて、DOMツリーの中では'teal'と'.'は別のノードに入っています。r2364では、ノードの境界は常に改良可能として処理してしまっていたのでした。

r2366
r2366で修正しています。基本的には改行しないといけない水平位置までインラインブロックの処理が進んだときに、直前のインラインブロックとの間で改行可能かどうか確認して、改行不可能であれば手前のインラインブロックを改行可能な位置から分割して次の行にまわして処理するようにしています。

r2366は、もとの仮定が間違っていたので、大きな変更になってしまっています。リグレッションについては、CSS 2.1のテストスイートを使って、r2371(white-space-pre-001), r2372(white-space-processing-049), r2374(white-space-mixed-004)で修正をしています。

テキスト インデント

16.1の'text-indent'プロパティの実装とテストを進めていきます。

・ c547-indent-000

異なる単位を使って'text-indent'プロパティの処理をテストしています。

r2366
r2367では、ラインボックスの左端にインデントに対応する余白をとるように実装しましたが、次のtext-indent-013でこの実装は良くないことがわかります。

r2367
・ text-indent-013

このテストでは'text-indent'を指定している行にフローティング ボックスとインライン要素が両方入ります。そして、フローティング ボックスの配置は'text-indent'の設定には影響されないことをテストしています。テストに成功していれば、PASSという単語が表示されます。

r2367
r2367のようにラインボックスの左端にインデント分の余白をとってしまうと、フローティング ボックスとインライン要素が重なってPASSという文字が見えなくなってしまいます。r2368では、最初に'text-indent'の指定が有効になるインラインブロックの左マージンにインデント分の余白を追加するように修正しています。

r2368
・ text-indent-intrinsic-004

このテストではユニコードのzero width white-space (ZWSP)が使われています。

r2368
r2368では、ZWSPに対応するグリフがないということで、×印がそのまま表示されてしまっています。r2369ではZWSPについてはフォントを描画しないように修正しています。

r2369
なお、r2369では、HTML 5のwbr要素も適当にZWSPに対応付けるようにしてしまっていますが、このあたりはまだ落ち着いていない様子です。改行処理に関するヒントとしてのZWSPについては、今後改めて調べて実装していきます。

この段階でtext-indentのテストに関しては、数テストを残して成功するようになりました。残りはtext-indentの処理自体ではなくて、その他の実装の不具合による失敗のようなので、今後実装の進捗に合わせて改めてテストしていくことにします。

ホワイトスペース

・ white-space-007

CSS 2.1の仕様書16.6.1の、
When wrapping, line breaking opportunities are determined based on the text prior to the white space collapsing steps above.
という部分のテストです。空白のつぶしによってレンダーツリーに残らなかったインライン要素でも改行位置としては影響する、という2007年から2009年の変更でCSS 2.1の仕様書で明確化された箇所のようです。文章にするとたった一文なのですが、その実装はわりと複雑です。

r2369
このテストのオレンジ色の部分は、'<span>X </span> '(span要素の後にスペース1文字のテキスト ノード)が繰り返されています。span要素のwhite-spaceにはnowrapが、後ろのスペースにはnormalが設定されています。そのため、後ろのスペースは直前のspan要素の終わりのスペースでつぶされてなくなります。r2369では、つぶされたスペースの位置で改行可能だったという点を考慮していなかったのでテストに失敗しています。

r2370
正しく処理できるとr2370のようにレンダリングされるのですが、r2370の修正自体は正しい実装ではありませんでした。この点は、あとでwhite-space-mixed-001で改めて修正を進めています。

・ white-space-nowrap-attribute-001

こちらはtd, th要素のnowrap属性のテストです。現在では仕様上はobsoleteですので、今はHTMLの属性ではなくてCSSを使いましょう、というのはこれまでと同じです。

r2372
r2373で対応させています。

r2373
・ white-space-mixed-001

このテストはHixieのテストで、いろいろな空白の処理を組み合わせた複合的なテストになっています。
r2374
r2375でまだ残っていた空白のつぶしのバグを修正し、r2376でr2370での誤った実装も含めて改行位置の処理を修正しています。

r2376
なお、r2376の修正では結果オーライでこのテストにはパスしてしまっていますが、HTMLファイル中、
'(空白)xx<span class="normal">x<span class="nowrap">x(改行)'
のようになっている箇所があって、改行可能位置の判定はr2366の修正のように直前のインライン要素とだけチェックするのではダメで、2つ以上前のインライン要素やテキスト ノードまで遡ってチェックしないといけない、ということがわかります。この点は、CSS 2.1のテストスイートでテストケースが用意されていないようなので次のws-001を用意してテストすることにしました。

補足: このテストはFirefoxで失敗するようでバグがファイルされています。まだ"Assigned To: Nobody; OK to take it and work on it"のようです。

ws-001 (ESで追加したテスト。要Ahemフォント)

1単語が複数のインライン要素(このテストでは5要素)にまたがっている場合に、正しく改行位置の処理ができているかどうかテストしています。本来は2行同じパターンで描画されなければいけません(WebKit系のブラウザも表示が崩れるようです)。

r2376
テキストのレイアウトを行うBlockLevelBox::layOutTextはr2365で一度整理していたのですが、ここまでの修正でまたごちゃごちゃになってしまっていたので、r2378, r2379でまず先にソースコードの整理をしました。r2380では、素直に単語の先頭までインライン ブロックを戻っていって、そのインライン要素に対応するwhite-spaceプロパティをチェックして改行処理を行うように修正しています。

r2380
この段階で、16.6, 16.6.1のテストの成功率は約89%になりました。失敗している部分は、未サポートのbidiのテストの他、タブ文字の処理などになります。

まとめ

今回は少し短めですがここまでです。CSS 2.1テストスイート全体の成功率は71%になっています。次回も16章のテキスト処理の残ったテストを進めていきます。

0 件のコメント:

コメントを投稿