Shiki’s Weblog

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

2012/02/15 #ESウェブブラウザ通信

今回はCSS 2.1の15章「フォント」の仕様の実装をさらに進めて、CSS 2.1テストスイートを使ってテストしていきます。

フォントにグリフがない場合の処理

CSS 2.1仕様書15.2のフォント マッチング アルゴリズムでは、

4.  If there is a matching font face, but it does not contain a glyph for the current character, and if there is a next alternative 'font-family' in the font sets, then repeat step 2 with the next alternative 'font-family'.

という規程があります。使用中のフォントに表示したい文字のグリフがない場合は、それ以外のフォントで対応するグリフを持っているものがないかどうか探してみて、もしあればそのフォントを使って描画するように指示されているわけです。⊠のようなmissing-glyphを使うのは最後の手段ということになります。
first-letter-punctuation-334
このテストは#13で取り上げた5章「セレクタ」のテストですが、エーゲ数字の句読点のグリフがデフォルトで使用しているsans-serifのフォントにはないために⊠印で表示されてしまっていました。

r2325r2325

r2398では、フォント マッチング アルゴリズムの実装を進めて、フォントにグリフがなければ、そのグリフを持っているフォントを使って表示できるようにしました。

r2398r2398

エーゲ数字のフォントは、FedoraではGeorge Dourosさんが作成されたフォントがgdouros-aegean-fontsというパッケージとして用意されていますので、これを利用しています。

r2400 ( mf-001.html )r2400 ( mf-001.html )

r2400では、上ののように、generic-familyだけを指定している場合に、アルファベットの部分はデフォルトのLiberationフォントで、Liberationフォントにグリフがない日本語の部分はIPAフォントで表示する、といったことができるようになっています。

r2401 ( mf-002.html )r2401 ( mf-002.html )

r2401では、太字や斜体のフォントがない場合には、TrueTypeのアウトラインから生成して表示できるようにしました。上図の例では、Liberationフォントのように太字や斜体のフォントも用意されている部分はそのフォントの持っているグリフが、IPAフォントのように通常のグリフしかない部分は、アウトラインから生成したグリフが表示されています。FreeTypeを使ってこのような処理を行う方法については、ひがんばなさんのまとめを参考にさせていただきました。

Small-caps

日本語ではあまりなじみのないスモールキャップスですが、小文字部分が小文字と同じ大きさの(もしくは小文字より少しだけ大きめの)大文字で表示されます。CSS 2.1の15.5では、

It is acceptable (but not required)in CSS 2.1 if the small-caps font is a created by taking a normal font and replacing the lower case letters by scaled uppercase characters.

と、単純に大文字をスケーリングして表示してもよい、ということになっています(さらにTTYデバイスのように拡大・縮小不可能な場合は大文字で表示するだけでも可)。ただそれですと、文字の線幅の統一感が失われてしまうといった問題点もあるので、OpenTypeフォントではフォント デザイナーさんが別個スモールキャップス用のフォントを用意しておくこともできるようになっています(参考:LinuxLibertineフォント)。

c26-psudo-nest-000
これまで数回取り上げてきたこのテストでは、2段落目の1行目がスモールキャップスで表示できないといけません。

r2401r2401

r2402,r2408では、小文字を大文字に変換して、スケールダウンして表示するようにしました。OpenTypeフォントのsmall-cpas用のグリフの表示については、今後機会を見て対応していきます。

r2408r2408

フォントのテストスイートから

まったく実装のなかった仕様についてはr2401までで実装ができたので、続いてテストスイートを使ってより詳しくテストしていきます。

c522-font-family-000
このテストでは、7行目の、

font-family: monospace,serif

のようにフォント ファミリーに複数の一般フォント ファミリーが指定されていると、最後のものを優先してしまうというバグが見つかりました。

r2398r2398

r2399で修正しています。

r2399r2399

font-matching-rule-010

このテストをはじめ、15章のテストではW3CのCSSテスト用フォントが必要になるものがあります。

r2402r2402

r2403で、実行可能ファイルScript.testに-testfonts オプションを指定するとCSS 2.1のテストフォントが有効になるようにしています。フォントはビルド時に環境変数TEST_FONTSで指定したディレクトリの中にAhemExtra、CSSTestというディレクトリ内にそれぞれ展開しておきます。

r2403r2403

font-family-name-010

このテストは、TrueTypeフォントのローカライズされたファミリー名を使ってフォントを指定できるかどうかテストしています。CSS Testフォントのfamilyname.ttfには、"CSSTest FamilyName"というファミリー名の他に、"CSSテスト フォント名"というファミリー名が定義されているので、それでテストしています。

r2403r2403

r2404で、フォントの名前、スタイル等の情報をTrueTypeフォント自体から直接取得するように変更しました。ファミリー名についてはネーミング テーブルから、そのほかの必要な情報はこれまでにもときどき登場しているOS/2テーブルfsSelectionおよびpanoseフィールドから取得しています。(注: r2404ではウェイトもpanoseから取得していますが、これは誤りでこの後font-weight-normal-001のテストで修正しています。)

r2404r2404

r2404の変更で、今後はTrueTypeフォントのパス名さえ分かれば簡単にフォントを利用することができるようになりました。
font-family-rule-010

このテストは仕様書15.3の、

The keywords 'initial' and 'default' are reserved for future use and must also be quoted when used as font names. UAs must not consider these keywords as matching the '<family-name> ' type.

という部分のテストです。

r2404r2404

r2405で対応しています。

r2405r2405

font-weight-normal-001
このテストは100から900までのウェイトを指定した場合に、対応するウェイトのTrueTypeフォントがない場合に仕様通りに替わりのフォントを選択して表示しているかどうかテストしています。例えば、3列目のW15の場合は、TrueTypeフォントは100と500のウェイトのフォントしか用意されていません。

r2406r2406

r2407では仕様書15.6の規程、

If the font family already uses a numerical scale with nine values (like e.g., OpenType does), the font weights should be mapped directly.

に合わせて、フォントのウェイトをTrueTypeフォントOS/2テーブルusWeightClass から取得するように変更しましたほか、 ウェイトに応じて代替フォントを選択するアルゴリズムのバグを修正しています。

余談:usWeightClassが100から900までの値をとるので、CSSのウェイトも100から900までになっている、ということなのか、もともと活版でそういう文化だったのかは知っていたらトリビアのような気もしますが、知りません。f^_^;;

r2407r2407

また仕様上は明確になっていないと思うのですが、指定されたウェイトが600以上で、フォントのウェイトが400もしくは500の場合に、TrueTypeフォントのアウトラインから太字のグリフを生成するようにしています。CSS 3 Fontsでは、

Although the practice is not well-loved by typographers, bold faces are often synthesized by user agents for faces that lack actual bold faces. For the purposes of style matching, these faces must be treated as if they exist within the family.

という記述があります。アウトラインを変形させて作った太字は、フォントの作者からするとデザインした意図とは違うのでしょうね。

content-counter-009content-counter-010
このテストは12章のリスト スタイル'georgian'と'armenian'のテストですが、グルシア語アルメニア文字のフォントが必要になるので以前未対応のままでした。今回、既定のフォントにグリフがない場合でも代替フォントで表示することができるようになったので対応しておきます。

まず、r2409でアルメニア文字やグルシア文字のグリフなども保持している DejaVuフォントを利用できるようにしています。Fedoraではデフォルトでインストールされているフォントです。

r2409r2409

r2410で、armenianとgeorgianのカウンターに対応しました。数値から文字列への変換方法はローマ数字の方法と同様です。

r2410r2410

まとめ

今回で15章「フォント」のテストに関しては、ESウェブ ブラウザが未対応のCSSのテーブル モデルを使用しているfont-size-applies-to-015と、CSSの文法処理に関するfont-045を除いて成功するようになりました。CSS 2.1テストスイート全体の成功率は前回からほとんど変わらず約76%となっています。次回はこれまで取りこぼしてきた部分などを改めて見ていく予定です。