2011年12月17日土曜日

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

気がつけばCSSテストスイートのブログも今回で10回目になりました。前回はHTMLテーブルの実装を進めました。今回はフォントまわりの改善や、これまでのスキップしてきていた9章のフロートに関するより複雑なテストを進めていきます。

フォント

これまではTrueTypeフォントから32pxのフォントをFree Type 2で展開してOpenGLで拡大・縮小して表示していたのですが、特に小さいテキストでの読み難さが気になってきました。

r2184

r2185では、11px, 22px, 44pxと3つ異なる大きさのフォントをFree Type 2で展開して、OpenGLのミップマップを使うように変更しています。(ピクセル単位の部分ですので細かい違いはスクリーンショットをクリックして拡大して見てみてください。)

r2185
ミップマップを使う関係上、TrueTypeのヒンティングは使わないようになっているのでコントラストは低くなってしまっていますが、ひとまずはこのスタイルで進めていきます。

補足: ヒンティングを使っていると以下のような感じになって、フィルター(GL_LINEAR_MIPMAP_LINEAR)が意図通りに働きません。"世界"の部分などを見てみると、サイズの異なるフォントテクスチャがきちんと重なり合わないことが分かるかと思います。


ヒンティングとミップマップの不整合の例 
また、フォントのテクスチャマッピングに関する基本的な議論については1997年頃のページのようですが以下のページが参考になります。
A Simple OpenGL-based API for Texture Mapped Text 著 Mark Kilgard
著者のMark KilgardさんはESウェブブラウザでも使用しているGLUT(OpenGL Utility Toolkit)の作者でもあったのでした。

ズーム

ミップマップを利用することで比較的スムーズにフォントを拡大縮小できるようになってきたので、r2187ではマウスのホイールを使って10%きざみでズームイン、ズームアウトできるようにしてみました。以下はAcid1のページで倍率を変えているときの様子です。

ズームイン

ズームアウト

スマートフォンのブラウザではごくふつうの処理になりましたが、デスクトップでも悪くないかな、と思ったりしています。まだズームインしたときのパンを実装していませんが、おいおい作り込んでいくことにします。

@mediaルール

表示できるサイトを増やしていこう、ということで今回はウィキペデイアに挑戦です。ウィキペデイアは@mediaルールを使って表示デバイスに合わせたレイアウトをしているのですが、@mediaルールにESウェブブラウザが対応していなかったのでした。

r2191

r2191で@mediaルールに対応しました。ところどころベースラインが揃っていない箇所が残っています。

r2198
r2198でセルのvertical-alignとインライン要素のvertical-alignを区別していなかったバグを修正しています。(前回のr2181の修正が必要だった直接の原因は実はこちらのバグの所為だったりします。修正自体はいずれにしても必要なものでしたが。)'」'の前で改行してしまっているというテキストまわりのバグが見える以外は結構よくなってきました。

フローティング ボックスとマージン

ふたたびCSSテストスイートに戻ります。まず、8.3.1のマージンのつぶしの実装が完了していないとテストするできなかった、マージンの処理と連動している9.5節のフロートのテストを進めていきます。

・ floats-015

このテストは#4で一度対応したテストですが、マージンのつぶしの処理を入れた後に(違う形で)また崩れるようになっていました。

r2198
マージンのつぶしの実装では、collapse-throughに対応するために、上マージンはすぐには確定しないで、FormattingContextにマージンを確定するまで保持しておく実装にしました。ただ、このテストでは右下の青いフローティングボックスは上マージン10px分を先に消費しておかないと綺麗に横一列に並べることができません。

マイナスのマージンのことを考えるとどう実装したらよいか頭痛がしてきそうなところですが、CSSの仕様書はよくできていて、
But in CSS 2.1, if, within the block formatting context, there is an in-flow negative vertical margin such that the float's position is above the position it would be at were all such negative margins set to zero, the position of the float is undefined.    - 9.5.1
と、そういう場合は未定義、ということにしてくれています。

r2199
r2199では、マージンのつぶし関連の処理とは別個に、フローティングボックスをレイアウトする前にその時点のマージンの高さ分だけレイアウト済みのフローティングボックスの高さを消費してしまうようにしました。

・ clear-float-003

このテストはこれまでのところ対応に一番苦労したテストかもしれません。HTMLファイル中のコメントには、
Clearance is introduced as spacing above the top margin after margin collapsing occurs.
と書かれているのですが、緑色のフローティングボックスのclear: rightの処理を最初に行うときには、直前のcollapse-throughしたボックスのマージン96pxが赤いフローティング ボックスの高さをすべて消費しているのでクリアランスが発生しません。ただし、そのままマージンのつぶし処理をかけると、このギャップを作っていた96pxのマージンが親の上マージンに吸収されてしまって下図のような結果になってしまいます。

r2201
IEをはじめメージャーなブラウザでは、コメントに書かれている通り、このような状態にしたあとで改めて96px分のクリアランスを導入して、緑色のボックスを下に96px移動させるような実装をしているように見えます。ただ、そういう動作は直感的には浮かんでこないと思うのですが、どうでしょうか?

マージンのつぶし処理はクリアランスの有無で動作が変わる(clearance is introduced, and margins collapse according to the rules in 8.3.1. - 9.5.2)のに、マージンをつぶしてからクリアランスを導入するというのはすこし違和感があったので、r2201以降さらに修正を加えていって、最終的に落ち着いたのがr2205です。

r2205
r2205では96px分のマージンが親に吸収されないような実装になっています。レンダーツリーは以下のようになっています:
* block-level box [html] (0, 0) w:816 h:253.051 m:0:0:0:0 transparent * block-level box [body] (0, 0) w:800 h:227.131 m:17.92:8:8:8 transparent * block-level box [p] (8, 17.92) w:800 h:17.2109 m:0:0:0:0 transparent * line box (8, 17.92) w:361.278 h:17.2109 m:0:0:0:0 * inline-level box (8, 17.92) w:361.278 h:17.2109 m:0:0:0:0 "Test passes if there is no red visible on the page." #000000 * block-level box [div] (8, 35.1309) w:192 h:192 m:17.92:608:0:0 transparent * block-level box [anonymous] (8, 53.0509) w:192 h:0 t:0 m:0:0:0:0 transparent * line box (8, 53.0509) w:0 h:0) m:0:0:0:0 * block-level box [div] (104, 53.0509) w:96 h:96 m:0:0:0:0 #ff0000 * block-level box [div] (8, 53.0509) w:192 h:0 t:0 m:0:0:0:0 transparent * block-level box [anonymous] (8, 53.0509) w:192 h:0 t:0 m:96:0:0:0 transparent * line box (8, 149.051) w:0 h:0 m:0:0:0:0 * block-level box [div] (104, 149.051) w:96 h:96 m:-96:0:0:0 #008000

最後の行の緑色のフローティングボックスを保持している匿名ボックス(*)に、上マージン96pxが残って、値0のクリアランスがあるときのようなレイアウトになっています。
(*) 9.5.1の"When the float occurs between two collapsing margins, the float is positioned as if it had an otherwise empty anonymous block parent taking part in the flow."に対応する匿名ボックスです。
補足: このテストの期間中だけ、Fedora 16の動作が不安定な時期に被ってしまって、スクリーンショットがKDEのものからGNOMEのものに変わっています。

・ floats-104.htmfloats-105.htm

これは左右のマージンなのでマージンのつぶしは関係ないのですが、やはりマージンがらみということでTODOになっていたテストです。

r2205 - floats-104
r2205 - floats-105
104, 105ともにフューシャのフローティングボックスが紫色の左マージンのあるボックスの中で生成されているのですが、r2205では、それ以降の緑色のボックスの中では、その左マージンがなかったかのようにテキストをレイアウトしてしまっています。

r2206 - floats-104
r2206 - flosts-105
r2206で、左右のフローティングボックスのエッジをフォーマッティングコンテキスト内の絶対座標で保持するように修正して、こういった場合にも対応できるようにしました。

・ floats-138

このテストではクリアランスによってLine 2がLine 1よりも下にいけばOKです。

r2206

フロートのテストに含まれていますが、r2206はフロートの処理には問題はなくて、マージンのつぶし処理に関するバグが残っていたのでr2207で修正しています。

r2207
マージンのつぶしについては、Mozillaの開発をされているDavid Baronさんは昨年のブログの中で、collapse-throughには実際のユースケースはおよそないにも関わらず仕様の詳細化に集中しすぎてしまったと述べられています。仕様を策定するときには、実装を複雑にし過ぎないように立ち止まって仕様を見直すことも大切だったと。
if you're fixing a spec that's unclear, you should evaluate whether the complexity of the fix is really needed - David Baron
およそ誰も使わなさそうな場面の動作の仕様は詳細に動作を詰めるよりも、先ほどのマイナスのマージンの場合の様に未定義としておいたり、上限値を決めたりしてしまった方がいい、というのはブラウザの仕様策定に限らない話かもしれないですね。

より複雑なフロートのテスト

・ c414-flt-fit-001

r2207
r2207では2つのバグが複合して崩れていました。1つは、最後の右下のimgはフロートではないので、レイアウト中にラインボックスをシフトダウンすることになるのですが、シフトダウンしてできたスペースに未処理のフローティングボックスが収まる場合は、先にそれを収めないといけません。r2207では、左下のイメージよりも右下のイメージが先に配置されてしまっています。

もう1つのバグは、シフトダウンするときには、もっとも内側の残りの高さの低いフローティングボックスから処理していくわけですが、このテストの場合は左上と右上のフロートで配置されているイメージは、高さが同じなので1回のシフトダウンでをどちらも消去されます。r2207ではラインボックスの利用可能な幅がそれに対応して広げられていなかったので、右下のimgの前に空白が残っています。

r2208
r2208でこれらのバグを修正しました。

・ c414-flt-fit-005

このテストでは上下のパターンが同じになるだけではなくて、赤い部分が見えてもいけないのですが、r2208ではフローティングボックスの位置はあっているものの、赤い部分が見えてしまっています。
r2208
これはESウェブブラウザの初期の実装の誤りで、フローティング ボックスの高さを包含ブロックの高さに含めてしまっていたバグのたぶん最後のものです。フローティング ボックスをシフトダウンしながら配置していくときにラインボックスのマージンを使ってしまっていたので、下側のテストパターンでブロックボックスに高さが発生して赤い背景が描画されてしまっていました。

r2209
r2209でLineBoxクラスのclearanceメンバ変数(CSSの仕様書で言うclearanceとは関係ありません)にシフトダウンする高さを保持するように修正して、ブロックボックスには高さが発生しないようにしました。

・ c5525-fltmult-000

このテストはテーブル関連でスキップしていたテストです。

r2209
フロートの処理には問題はなくて、下側のテーブルでつくったリファレンス パターンでHTMLのcellspacing属性を使っているのですが未対応でした。

r2210
r2210で対応しています。なお、HTMLのcellspacing属性はHTML 5ではnon-conformingにされているので、これからウェブページをつくる時はCSSのborderspacingプロパティを使いましょう、というお話でした。

・ floats-placement-vertical-004

このテストは、文字が小さくて見にくいのですが、緑色のフローティングボックスの横に'H'が1文字あって、改行したあと本当ならすぐその真下から(緑色のボックスの右側に)青色のフローティングボックスが配置されないといけません。

r2210
ブラウザの内部処理的には、通常のインライン要素のレイアウト部分から、収まりきらなかったフローティングボックスの処理に切り替わる部分で、実はシフトダウンしなくてもフローティングボックスが収まってしまう場合があったのでした。よい境界条件のテストになってます。
r2211
r2211でバグを修正しています。

・ floats-rule7-outside-left-001

これはDavid Baronさんの書かれたテストみたいですね。このテストは現状すべてのメジャーなブラウザで崩れているそうなので、CSS 2.1のテストスイートのページのfloats-rule7-outside-left-001の横にある'='マークをクリックするとリファレンスのレンダリングを見ることができます。(Mozillaから提供されているテストはこういうパターンで、別の方法でレイアウトした画面と同じになるかどうかテストさせるものがちょこちょこあります。)

r2212
r2212でも他のブラウザと同じように崩れてしまっています。「これで良くない?」ということがW3Cのメーリングリストでも議論されていたようですが、現在の仕様書通りに実装するとやはりリファレンス通りになると思います。Firebugなどで見てみると、青色のフローティングボックスは包含ブロックの右端を突き抜けてしまっていることがわかると思います。

r2213
r2213で修正しています。ただGeckoまでなぜ未対応なんだろう、ということで調べてみたところ、こちらにDavid Baronさんからバグがファイルされているようです:
https://bugzilla.mozilla.org/show_bug.cgi?id=616334
今日(12/17)の時点でも、まだ"Assigned To: Nobody; OK to take it and work on it"だそうです。

・ floats-bfc-001

フロールートはフローティングボックスと重なり合ってはいけない、という仕様のテストです。
r2213
CSS 2.1の仕様書ではこのあたりの規程は緩めで、フロールートのところで必要ならクリアすべき(should)だけれど、クリアしないでも配置できるスペースがあったらそこに配置してもいい(may) よ、という感じになっているようです。
If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space.  - 9.5
r2214
r2214では、ひとまずフロールートのところでクリアという実装にしています。なお、テストスイートの次のfloats-bfc-002margin-collapse-clear-010は、クリアしないで空きスペースに配置する実装を仮定しているようです。仕様書ではそうしないといけない、というようには読めないのですが、Optionalにはされていないようです。今回はこの2つの修正はスキップしておきます(現状のESウェブブラウザの実装だとすこし大きめの変更になるので)。

リグレッション テスト

ここまでで色々と変更が入ってきたので、また9.5節以外のテストで崩れたものがないかどうか確認しておきます。

・ margin-bottom-103

collase-throughを使っているテストなのですが、重なり合うはずの赤と黒のボーダーがずれてしまっています。
r2214
これは、clear-float-003の一連の修正でclear-001も同時にパスするように行っていた修正が間違っていたというものでした。CSSの仕様書には、
The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance. - 8.3.1
という例が載っていますが、ここは実際にはもう少し複雑ですね(8.3.1のthe above rules imply that:に続く部分は例なのでこの通り実装したらいいというわけではない点は注意なのです)。
r2215
r2215でcollapse-throughしている先頭の子の直後に、クリアランスのあるボックスが続いている場合は、先頭の子自体にはクリアランスがなくても、上ボーダーエッジをクリアしないという処理に修正しています。これで、clear-001margin-bottom-103も同時にパスできるようになりました。クリアランスがある場合、その上下のボックスは一塊になっているように処理しないとおかしくなってしまうのでした。

・ c5526c-display-000

ふたたびAcid1の登場です。r2515では再び崩れてしまっています。

r2215
このテストでは、HTMLソース中のul要素は、画面上で右上の黒枠の中の左上から順番に4つ目のpluot?までのフローティングボックスだけを含んだブロックボックスになっています。

r2208まではこのブロックボックスは1行目のフローティングボックスの高さを持ってしまうというバグがあったので、結果的にそれまでAcid1にパスしているように見えていたのでした。

r2209の修正によって、このフローティングボックスしか含んでいないul要素のボックスの高さは正しく0となっているので、逆に続く5番目、6番目のフローティング ボックスの位置が上にズレてしまっているのでした。このようにフローティング ボックスの高さを一部でも消費している、collapse-throughしたボックスに続くボックスは、その消費された分だけはじめからクリアランスがあるかのように中のボックスを配置していかないといけないことがわかります。
r2216
r2216で、collapse-throughしたボックスが消費したフローティングボックスの高さをフォーマッティング コンテキストに保存しておくようにして対策をしています。

9.5のフロートのテストでは、まだモジラから提供されているfloats-wrap-*シリーズがほぼ全滅していまず。ラインボックスの高さの途中で次のフローティング ボックスのクリアランスが確保できた場合の処理など、Geckoでよく実装されている部分も、このシリーズでテストされています。ESウェブブラウザでは、今先にここに手をつけてしまうと、後々のテキスト処理の修正が大変なことになってしまいそうなので、テキスト処理の実装を落ち着いてから改めてテストを進めていくことにします。

まとめ

今回の最後のr2216では、CSS 2.1のW3Cのテストスイートの成功率が約48%というところまで来ました。今後の予定としては、まだ手をつけていないリストの実装などを進めてから、セレクタまわりの処理のテストと高速化(今の実装はものすごく遅いのです)を進めいって、単体のブラウザとしての使い勝手を向上させていくような流れで考えています。

2011年12月2日金曜日

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

前回はline-heightのテストを進めました。今回はテーブルの実装をもう少し進めて、CSS 2.1の17章のテストを少し進めていきます。

その前に

ESウェブブラウザで、もうすこし色々なサイトを表示できるようにしておきたい、ということでいくつか修正を入れています。

r2155では、EUC-JPとJISコードを使っているページを表示できるようにしています。ICUのucnv_open()の使い方が悪いのかもしれないのですが、エンコード名のエイリアスが一部期待通りに動いてくれていないのでした。

r2156以前はHTTPリクエストのホストヘッダーに、
Host: shiki.esrille.com:80
のようにデフォルトのポート番号80まで表記して送信していました。r2156では、
Host: shiki.esrille.com
のようにデフォルトのポート番号は省略するようにしました。意外なことにかなりのウェブサイトがこの違いをチェックして、:80がついていると、管理画面らしきものを表示するサイト、英語ページを表示するサイト、等々予想外の動きします。

r2157では大きさが0のフローティング ボックスの処理で問題があったので修正しています(なお、この修正自体もr2179で再修正しています)。

r2157

この段階でまだ崩れている部分が結構ありますが、このブログもESウェブブラウザでひとまず何かは表示されるようになりました。

テーブル

テーブルに関しては、もともとGoogleのトップページを表示できるように、という目的だけで実装したものなのでかなり適当な実装になっていました。そのため一連のCSS 2.1のテストでも、テーブルの処理の所為で表示が一部崩れているテストが結構ありました。今回はもう少し標準に合わせた実装を進めていきます。

CSSのテーブルの処理で面倒な部分は列の幅や行の高さを解決していく部分だと思います。特に結合ボーダーモデル(collapsing border model. こういった用語の日本語訳はどこのものが好まれているのでしょう?)ではボーダーの幅を先に解決しないと列や行の大きさも解決できない、ということがあるので、順序はひっくり返りますがまず17.6.2.1のBorder conflict resolutionから実装を進めていきます。

r2158

r2158まではまったく実装が入っていなかったので、r2159でひとまずの実装とバグの修正を入れています。仕様書に出てくるはそれなりに表示できるようになりました。

r2159
これを見ているとcolspanやrowspanが使われたときの動作が気になってきます。先ほどの例を少し改造したこの例では、r2159ではまだスパンに対応していないので、競合を解決する前の状態が見えます。

r2159 (スパンが使われている場合)
この場合、テーブルのセル2の右辺とセル6の左辺はどう処理したらいいのか、仕様書では明確には記載されていない気がします。単純にどちらのエッジが優先されるかというだけの判定でよいとすれば、2の右辺は6の左辺に勝つので、6の左辺がすべて、つまり8の右辺まで青くなりそうです。もっと丁寧にエッジをグリッドごとに処理するのだとすれば、6の左辺の上半分はブルーに、下半分は緑の破線で描画することもできそうです。

実際のブラウザはどんな感じになってるか見てみました。

Chrome 15

Firefox 8
Chromeは前者、Firefoxは後者の考え方で実装されているようです。こうメジャーなブラウザで実装が割れると、ESウェブブラウザでどちらの実装にするかちょっと悩むところです。Webデザイナの期待に近いのどちらでしょうか?そもそもこういうテーブルは使わない、という説が一番有力な気もしますが、とりあえずより直感的なFirefoxのスタイルに倣ってみます。

r2163
r2163で実装を追加して、それらしくなってきました。すこし大きめの変更ですが、考え方としては、各セルのボーダーに相当する幅はCellBoxクラス中ではマージンとして確保しておいて、実際の結合したボーダーの描画はTableWrapperBoxクラスで行うようにしてみました(各セルからすると、ボーダーはテーブボックスに描かれたものが透けて見えている感じになります)。

改めて17.6.2.1の例に戻って見比べてみると、ボーダーとボーダーの交差する部分の処理がr2163ではあまり綺麗ではありません。r2163では左上から順にボーダーを描画しているので、セル6の右下隅が黄色になっている、とか色々と細かい部分で違います。

r2163
このへんはFirefoxでもそこまで作り込まれてはいないようですが、仕様の解釈としてはボーダーの交点についても、もっとも目立つボーダーがそこを占有する、と考えるべき、ということなんだと思います。いまはこの点はTODOということにしておいて、先に進みます。

補足: この例はCSS テストスイートのborder-conflict-example-001としても含まれています。

・ table-intro-example-004 (その1)

結合ボーダーモデルの実装はすこし進められたので、分離ボーダーモデルもサポートしておきます。

r2163
r2164で実装を追加しました。内部的には、CellBoxのマージンにborder-spacingに相当する値を入れるようにしています。結合ボーダーモデルのときも、ボーダーがある部分はCellBoxではマージンになっていて背後のテーブルボックスが見えるようにしていたので、コードとしては共通になっている部分がわりとあります。

r2164
r2165でキャプションもとにかく表示するようにしました。

r2165
まだテーブルの幅の計算ができていないので、キャプションの位置はだいぶズレています。(あとで修正しています。)

・ fixed-table-layout-006

必要な部品はひととおり揃ってきたので、テーブルのレイアウトの処理のもう少し詳細な実装を進めていきます。まずは簡単な固定テーブルレイアウトをr2166で一気に実装しています。

r2165
固定テーブルレイアウトは、アルゴリズム自体は単純なのですが、分離ボーダーモデルでは、ボーダー幅が未指定のカラムに幅を設定しく際に、幅が指定されているカラムのボーダーの幅なども差し引いて計算しないといけません。 列の幅を確定する前に一部のセルやカラムのスタイルの解決値が必要になる点がやや面倒なところです。

r2166
fixed-table-layout-006はその処理ができていないと表示が崩れます(WebKit系が現状失敗しているようです)。

・ fixed-table-layout-010

r2166
このテストに関してはテーブルのレイアウトではなくて、white-spaceの'pre'に対応していなかったために途中で改行してしまっていました。r2167で対応しました。

r2167
この段階でfixed-table-layout-xxxシリーズはひとまずすべてパスするようになりました。

・ border-conflict-element-001

自動表組みアルゴリズムに入る前に、17.6.2.1のボーダーの競合のテストを進めておきます。

r2167
ひとまずr2168でテーブルに指定されたwidth, heightが効いていなかったバグを修正しました。

r2168
これで17.6.2.1のボーダーの競合のテストを進められます。

・ border-conflict-style-005

これは、ボーダーが'hidden'のときは他の要素の設定に関わらず'hidden'扱いになっているかどうかのテストです。

r2168
r2169でhiddenの処理を修正しています。

r2169
・ border-conflict-resolution-002

tr要素で設定したボーダーが表示されるかどうかテストしています。

r2169
r2170で下端・右端のボーダーを処理できていなかったバグを修正しています。

r2170
・ border-conflict-resolution-003

前の002と似てますが、tbody要素で(display設定が'table-row'ではなくて'table-row-group')ボーダーを指定したときのテストです。

r2170
r2171で対応しています。

r2171
・ border-conflict-element-004

ボーダーの色だけが違う場合のテストです。

r2171
r2172で要素の処理順にバグがあったので修正しています。

r2172
ここまでで、未対応のrtlに関する3つのテストを除いて、17.6.2.1のボーダーの競合のテストにすべてパスするようになりました。続いて、テーブルのレイアウトのごく基本的なバグをつぶしていきます。

・ border-spacing-001

Microsoft社からのお約束の無効な負の値がborder-spacingに指定された場合のテストです。

r2172
CSSの仕様上の初期値は0なのですが、HTMLのデフォルトのスタイルシートでの初期値は2なので、負の値が設定された場合には2を返すようにr2174で修正しています。これまでもこういった感じで対処してきましたが、そろそろCSSパーサーの段階で無効な値を無視する仕組みを導入しないといけない感じがしてきました。

r2174
・ separated-border-model-004

このテストでは黒いテーブルと青いボックスの幅が同じになれば成功です。テーブル内では、'table-cell'がdisplayに設定されている要素のwidthに'50px'が設定されているのですが、テーブルのwidthが'200px'、border-spacingが'50px 0' (水平方向が50px)なので、セルの幅は最終的に200px - 2 x 50px = 100px まで広げないといけないのです。

r2174
r2175で幅が'auto'でないセルの幅を広げることができなっていたのを修正しています(関連してTableWrapperBox::layOutFixedで'border-spacing'の幅もwidths[]に含めるように修正しています)。

r2175
・ table-intro-example-004 (その2)

その1のときは放置していましたが、キャプションの幅も合わせておくようにします。

r2175
r2177では、自動テーブルレイアウトは仕様の方も割と緩い( they can use any other algorithm even if it results in different behavior. )ということもあって、あまり凝ったことはしていないので、とりあえずテーブルボックスの幅でキャプションのボックスをレイアウトしています。キャプションのボックスにもっと広い幅が指定されていたりすると、デザイナの期待としては各列の幅も広がるのだと思いますが、いまはそこまではしていません。

r2177
なお、ふだん表示に使用しているIPAフォントですと、まだフォントマネージャーの側で太字での表示に対応できていないので、LiberationSansフォントを使った場合の様子も載せておきます。この場合は1列目は本来の意図通り太字で表示されます。

r2177 (LiberationSansでの表示)
・ c411-vt-mrgn-000

テーブルのレイアウトの基本的な部分は出来てきたので、一度harnessをつかってリグレッション テストをします。

r2129
これまではテーブルを使っているテストで最後の列やボーダーの色違いは無視してください、という断りをいれていたものが結構あったのですが、今回の修正でそういった点はほとんど解決していそうです。このテストでも最後に色違いの行が見えていたのが消えました。

r2177
r2178からr2180では、これまで成功していたテストを崩してしまっていた修正を再修正しています。

・ block-in-inline-001

このテストもテーブルの処理の問題で赤い行が最後に残っているかと思っていたのですが、r2180でも赤い部分が残ったままでしたので、詳しく見てみました。

r2180
調べてみると、ブラウザ内部では左の列のLine 3というテキストの後に空白が1文字一度追加されていて、行末ということで改めてその空白が削除されています。問題は、最後の1文字の空白がラインボックスの高さを大きくしていて、その効果がそのまま残っていて一番下のセルの高さを想定よりも高くしてしまっていたのでした。ラインボックスから行末の空白を削除した場合には、幅だけでなくて高さも再計算しないといけない場合があったのでした。r2181で修正しています(実際に再計算しているわけではなくて、取り除いた行末の空白を追加する前の値に戻すようにしています)。

r2181
・ table-visual-layout-010

リグレッション テストは大丈夫そうなので、またもう少し細かいテーブルのテストに戻ります。このテストでは青いボックスが右側のオレンジのボックスの上端から下端まで伸びていれば成功です。

r2181
クリックして拡大して見てみないと分かりにくいのですが、青いセルの高さが1pxだけ大きくなってしまっています。r2182でスパンが2以上のセルの端がテーブルの右端と下端まで来たときのborder-spacingの処理が入っていなかったのを修正しています。

r2182
・ table-visual-layout-013

このテストでは、黒いセルが1列右に行き過ぎていました。

r2182
r2183で自分自身のスパンの分まで右に位置をずらしていたバグを修正しています。

r2183
・ collapsing-border-model-001

このテストではオレンジとブルーのボックスの幅が同じであれば成功なのですが、r2183ではブルーのボックスの表示位置が間違っていました。

r2183
つぶしボーダーモデルでは、テーブルボックスにもボーダーが付きます。r2184でその分の計算が入っていなかったのを修正しています。また、テーブルの2行目以降で収まりきらなかったボーダーの分はテーブルラッパーボックスのマージンに含まれる、という処理も入れています(collapsing-border-model-002がそのテストしています)。

r2184
今回はここまでです。17章のテストスイートに関しては50%強のテストに成功するようになりました。テストスイート全体では40%強のテストに成功するようになりました。

テーブルに関しては、まだ背景やアラインの部分が未実装だったり、17.2のCSSのテーブルモデルには基本的には未対応(ESウェブブラウザが現在実装しているのはHTMLのテーブルモデルの方です)だったり、さらに、CSS 2.1の仕様自体でも細かい部分で議論が続いているようなので、残りのテーブルのテストについては対応するのはしばらく先になりそうです。

次回はまた細かな改善から進めて行く予定です。