1. はじめに
CSS では、作者が @font-face 規則を介して Web からカスタムフォントを読み込むことができます。 スタイルシートを作成する際には簡単に使用できますが、 スクリプトを介して動的に使用することははるかに困難です。
さらに、CSS では、ユーザーエージェントが実際にフォントをいつ読み込むかを選択できます。 フォントフェイスがページ上の何かによって現在使用されていない場合、 ほとんどのユーザーエージェントは関連するファイルをダウンロードしません。 つまり、後でそのフォントフェイスを使用すると、 ユーザーエージェントがようやく使用を認識してフォントファイルのダウンロードと解析を開始するため、遅延が発生します。
この仕様は、CSS のフォントフェイスに対するスクリプト用インターフェイスを定義し、
フォントフェイスを容易に作成できるようにし(FontFace
インターフェイスを介して)、
スクリプトから読み込めるようにします(document.fonts を介して)。
また、個々のフォント、
またはページ全体のすべてのフォントの読み込み状態を追跡するためのメソッドも提供します。
この 仕様では、動作を定義するために通常の ES オブジェクトを使用している箇所がいくつかあります。 たとえば、内部で Promise を使用するさまざまな箇所や、 内部で Set を使用する FontFaceSet などです。 ここでの意図は、これらのオブジェクト (およびそのプロトタイプチェーン)が変更されていない初期状態であり、 作者が行ったいかなる操作にも影響されないことだと考えています。 これは適切な意図でしょうか? もしそうなら、この仕様ではどのように示すべきでしょうか?
1.1. 値
この仕様では Promise
を使用します。
これは ECMAScript
6 で定義されています。
MDN には、Promise を紹介する有用な
チュートリアル資料があります。
1.2. タスクソース
この仕様でタスクをキューに入れる場合は常に、 そのタスクを「font loading」タスクソースにキューに入れます。
2. FontFace インターフェイス
FontFace
インターフェイスは、単一の使用可能なフォントフェイスを表します。
CSS の @font-face 規則は暗黙的に FontFace オブジェクトを定義します。
また、URL またはバイナリデータから手動で構築することもできます。
typedef (ArrayBuffer or ArrayBufferView );BinaryData dictionary {FontFaceDescriptors CSSOMString = "normal";style CSSOMString = "normal";weight CSSOMString = "normal";stretch CSSOMString = "U+0-10FFFF";unicodeRange CSSOMString = "normal";variant CSSOMString = "normal";featureSettings CSSOMString = "normal";variationSettings CSSOMString = "auto";display CSSOMString = "normal";ascentOverride CSSOMString = "normal";descentOverride CSSOMString = "normal"; };lineGapOverride enum {FontFaceLoadStatus ,"unloaded" ,"loading" ,"loaded" }; ["error" Exposed =(Window ,Worker )]interface {FontFace constructor (CSSOMString , (family CSSOMString or BinaryData ),source optional FontFaceDescriptors = {});descriptors attribute CSSOMString family ;attribute CSSOMString style ;attribute CSSOMString weight ;attribute CSSOMString stretch ;attribute CSSOMString unicodeRange ;attribute CSSOMString variant ;attribute CSSOMString featureSettings ;attribute CSSOMString variationSettings ;attribute CSSOMString display ;attribute CSSOMString ascentOverride ;attribute CSSOMString descentOverride ;attribute CSSOMString lineGapOverride ;readonly attribute FontFaceLoadStatus status ;Promise <FontFace >load ();readonly attribute Promise <FontFace >loaded ; };
オブジェクトは文書間を移動できるため、 どの文書を参照しているのかが明確になるよう、 「the document」へのすべての言及を明確化する必要があります。
family, 型は CSSOMStringstyle, 型は CSSOMStringweight, 型は CSSOMStringstretch, 型は CSSOMStringunicodeRange, 型は CSSOMString-
これらの属性はすべて、CSS の @font-face 規則で定義される記述子によって定義される、 フォントフェイスの対応する側面を表します。 これらは、対応する @font-face 記述子と同じ方法で解析されます。 これらはフォントマッチングアルゴリズムによって使用されますが、 それ以外の効果はありません。
たとえば、
FontFaceのstyleが"italic"の場合、その FontFace はイタリックのフォントフェイスを表します。 フォントフェイスを実際にイタリックにするわけではありません。取得時には、この属性に関連付けられた文字列を返します。
設定時には、対応する @font-face 記述子の文法に従って文字列を解析します。 文法に一致しない場合は、
SyntaxErrorを投げます。 それ以外の場合は、属性を解析済みの値の直列化結果に設定します。 variant, 型は CSSOMStringfeatureSettings, 型は CSSOMStringvariationSettings, 型は CSSOMStringdisplay, 型は CSSOMStringascentOverride, 型は CSSOMStringdescentOverride, 型は CSSOMStringlineGapOverride, 型は CSSOMString-
これらの属性は、CSS の @font-face 規則内の対応する記述子と同じ意味を持ち、 同じ方法で解析されます。
これらは、それをサポートするフォント内の特定の機能をオンまたはオフにします。 前述の属性とは異なり、 これらの属性は実際にフォントフェイスに影響します。
取得時には、この属性に関連付けられた文字列を返します。
設定時には、対応する @font-face 記述子の文法に従って文字列を解析します。 文法に一致しない場合は、
SyntaxErrorを投げます。 それ以外の場合は、属性を解析済みの値の直列化結果に設定します。 status, 型は FontFaceLoadStatus、読み取り専用-
この属性は、フォントフェイスの現在の状態を反映します。 新しく作成された
FontFaceでは "unloaded" でなければなりません。作者がフォントフェイスの読み込みを明示的に要求したことにより変更される場合があります。 たとえば、
FontFaceのload()メソッドを介した場合です。 また、ユーザーエージェントが、 画面上にテキストを描画するためにそのフォントフェイスが必要であることを検出したため、 暗黙的に変更される場合もあります。 loaded, 型は Promise<FontFace>、 読み取り専用-
この属性は、フォントフェイスの
[[FontStatusPromise]]を反映します。
すべての FontFace
オブジェクトは、内部に [[FontStatusPromise]] スロットを持ち、
これはフォントの状態を追跡します。
最初は保留状態であり、
フォントが正常に読み込まれて解析された場合に履行され、エラーが発生した場合に拒否されます。
すべての FontFace
オブジェクトはさらに、
内部 [[Urls]] および [[Data]] スロットも持ちます。
そのうち一方は null で、もう一方は null ではありません(null ではない方は、
どのデータが渡されたかに基づいてコンストラクターによって設定されます)。
2.1. コンストラクター
FontFace は、
フォントフェイスファイルを指す URL、
またはフォントフェイスのバイナリ表現を含む ArrayBuffer
(または ArrayBufferView)
のいずれかから構築できます。
FontFace(family, source, descriptors) メソッドが呼び出された場合、
次の手順を実行します:
-
font face を新しい
FontFaceオブジェクトとします。 font face のstatus属性を"unloaded"に設定し、 その内部[[FontStatusPromise]]スロットを、新しい保留中のPromiseオブジェクトに設定します。family引数と、descriptors引数のメンバーを、 CSS の @font-face 規則の対応する記述子の文法に従って解析します。source引数がCSSOMStringである場合、 CSS の src 記述子の文法に従って解析します。これは @font-face 規則の記述子です。 いずれかが正しく解析できなかった場合、 font face の[[FontStatusPromise]]を "SyntaxError" という名前の DOMException で拒否し、 font face の対応する属性を空文字列に設定し、 font face のstatus属性を "error" に設定します。 それ以外の場合は、font face の対応する属性を解析済みの 値の直列化結果に設定します。注: これは、source 引数として URL をそのまま渡す、 たとえば
"http://example.com/myFont.woff"のような形式では 動作しないことを意味する点に注意してください。少なくとも url() 関数で囲む必要があり、"url(http://example.com/myFont.woff)"のようにします。 この不便さと引き換えに、 複数のフォールバックを指定したり、 各フォールバックのフォントタイプを指定したり、 ローカルフォントを簡単に参照したりできます。相対 URL を解決できるように、 ベース URL を定義する必要があります。 文書の URL にすべきでしょうか? これは Worker に対しても正しいでしょうか。 それとも Worker 自身の URL を使用すべきでしょうか? それは常に定義されているでしょうか?
font face を返します。 font face の
statusが "error" の場合、 このアルゴリズムを終了します。 それ以外の場合、 残りの手順を非同期で完了します。 -
source引数がCSSOMStringであった場合、 font face の内部[[Urls]]スロットをその文字列に設定します。source引数がBinaryDataであった場合、 font face の内部[[Data]]スロットを渡された引数に設定します。 -
font face の
[[Data]]スロットがnullでない場合、 次の手順を同期的に実行するタスクをキューに入れます:-
font face の
status属性を "loading" に設定します。 -
font face が属する各
FontFaceSetについて:-
FontFaceSetの[[LoadingFonts]]リストが空の場合、FontFaceSet を loading に切り替えます。 -
font face を
FontFaceSetの[[LoadingFonts]]リストに追加します。
-
非同期で、その中のデータをフォントとして解析することを試みます。 これが完了したら、 成功したか否かにかかわらず、 次の手順を同期的に実行するタスクをキューに入れます:
-
読み込みが成功した場合、font face は解析されたフォントを表すようになります。 font face の
[[FontStatusPromise]]を font face で履行し、 そのstatus属性を "loaded" に設定します。font face が属する各
FontFaceSetについて:-
font face を
FontFaceSetの[[LoadedFonts]]リストに追加します。 -
font face を
FontFaceSetの[[LoadingFonts]]リストから削除します。 font がそのリストの最後の項目であった場合 (したがってリストが空になった場合)、FontFaceSet を loaded に切り替えます。
-
-
それ以外の場合、 font face の
[[FontStatusPromise]]を "SyntaxError" という名前の DOMException で拒否し、 font face のstatus属性を "error" に設定します。font face が属する各
FontFaceSetについて:-
font face を
FontFaceSetの[[FailedFonts]]リストに追加します。 -
font face を
FontFaceSetの[[LoadingFonts]]リストから削除します。 font がそのリストの最後の項目であった場合 (したがってリストが空になった場合)、FontFaceSet を loaded に切り替えます。
-
-
注: 新しく構築された FontFace オブジェクトは、 文書に関連付けられた FontFaceSet または Worker スレッドのコンテキストに自動的に追加されません。 これは、新しく構築されたフォントをプリロードすることはできますが、 FontFaceSet に明示的に追加されるまでは実際には使用できないことを意味します。 FontFaceSet のより完全な説明については、次のセクションを参照してください。
2.2. load() メソッド
load()
メソッドは、FontFace
の
URL ベースのフォントフェイスに対して、フォントデータの要求と読み込みを強制します。
バイナリデータから構築されたフォント、
またはすでに読み込み中もしくは読み込み済みのフォントに対しては、
何もしません。
load() メソッドが呼び出された場合、
次の手順を実行します:
- font face を、このメソッドが呼び出された
FontFaceオブジェクトとします。 - font face の
[[Urls]]スロットがnullである、 またはそのstatus属性が"unloaded"以外である場合、 font face の[[FontStatusPromise]]を返し、これらの手順を中止します。 - それ以外の場合、
font face の
status属性を "loading" に設定し、 font face の[[FontStatusPromise]]を返して、 このアルゴリズムの残りを非同期で実行し続けます。 - font face の
[[Urls]]スロットの値を使用し、 [CSS-FONTS-3] で定義される方法でフォントの読み込みを試みます。 これは、@font-face 規則の src 記述子の値であるかのように扱います。 -
読み込み操作が完了したら、
成功したか否かにかかわらず、
次の手順を同期的に実行するタスクをキューに入れます:
-
読み込みの試行が失敗した場合、
font face の
[[FontStatusPromise]]を 名前が "NetworkError" の DOMException で拒否し、 font face のstatus属性を "error" に設定します。font face が属する各
FontFaceSetについて:-
font face を
FontFaceSetの[[FailedFonts]]リストに追加します。 -
font face を
FontFaceSetの[[LoadingFonts]]リストから削除します。 font がそのリストの最後の項目であった場合 (したがってリストが空になった場合)、FontFaceSet を loaded に切り替えます。
-
-
それ以外の場合、font face は読み込まれたフォントを表すようになります。
font face の
[[FontStatusPromise]]を font face で履行し、font face のstatus属性を "loaded" に設定します。font face が属する各
FontFaceSetについて:-
font face を
FontFaceSetの[[LoadedFonts]]リストに追加します。 -
font face を
FontFaceSetの[[LoadingFonts]]リストから削除します。 font がそのリストの最後の項目であった場合 (したがってリストが空になった場合)、FontFaceSet を loaded に切り替えます。
-
-
読み込みの試行が失敗した場合、
font face の
ユーザーエージェントは、
特定のフォントフェイスがページ上の何かをレンダリングするために必要であると判断した場合、
自らフォントの読み込みを開始できます。
この場合、
ここで説明されている対応する FontFace の load()
メソッドを呼び出したかのように動作しなければなりません。
注: 一部の UA は「フォントキャッシュ」を利用しており、
同じフォントを同じページまたは同一オリジン内の複数のページで
複数回ダウンロードする必要をなくしています。
複数の FontFace
オブジェクトを
フォントキャッシュ内の同じエントリに対応付けることができます。
つまり、FontFace
オブジェクトが、
FontFaceSet
に含まれていなくても、
同じフォントデータを指す別の FontFace オブジェクトが
(まったく別のページ上にある場合であっても!)
読み込まれたために、予期せず読み込みを開始する可能性があります。
2.3. CSS の @font-face 規則との相互作用
CSS の @font-face 規則は、対応する FontFace
オブジェクトを自動的に定義し、
規則が解析されると、そのオブジェクトは文書の フォントソースに自動的に配置されます。
この FontFace
オブジェクトは CSS 接続済みです。
@font-face 規則に対応する FontFace
オブジェクトでは、
family、
style、
weight、
stretch、
unicodeRange、
variant、
および featureSettings
属性が、
@font-face 規則内の対応する記述子と同じ値に設定されます。
両者の間には双方向の接続があります。
@font-face 記述子に加えられた変更は、
対応する FontFace
属性に即座に反映され、
その逆も同様です。
FontFace が 文書間で転送されると、CSS 接続済みではなくなります。
FontFace
オブジェクトの内部 [[Urls]]
スロットは、@font-face 規則の src 記述子の値に設定され、
src 記述子に加えられた変更を反映します。
それ以外の点では、CSS の @font-face 規則によって作成された FontFace
オブジェクトは、
手動で作成されたものと同一です。
@font-face 規則が文書から削除された場合、対応する
FontFace
オブジェクトはもはや CSS 接続済みではありません。
この接続は、いかなる方法でも復元できません
(ただし、@font-face をスタイルシートに再び追加すると、
まったく新しい FontFace
オブジェクトが作成され、
これは CSS 接続済みになります)。
@font-face 規則の src 記述子が新しい値に変更された場合、
元の接続済み FontFace オブジェクトは
CSS 接続済みであることを停止しなければなりません。
新しい src を反映する新しい FontFace
を作成し、@font-face に CSS 接続しなければなりません。
(これにより、古い FontFace
オブジェクトが、それが現れる任意の
フォントソースから削除され、
新しいオブジェクトが追加されます。)
2.4. フォントに関する情報の検出
FontFace
オブジェクトには、フォントファイルの内容に関するさまざまな読み取り専用情報が含まれます。
[Exposed =(Window ,Worker )]interface { /* CSSWG では、ここに何を含めるかについてまだ議論中です */ }; [FontFaceFeatures Exposed =(Window ,Worker )]interface {FontFaceVariationAxis readonly attribute DOMString ;name readonly attribute DOMString ;axisTag readonly attribute double ;minimumValue readonly attribute double ;maximumValue readonly attribute double ; }; [defaultValue Exposed =(Window ,Worker )]interface {FontFaceVariations readonly setlike <FontFaceVariationAxis >; }; [Exposed =(Window ,Worker )]interface {FontFacePalette iterable <DOMString >;readonly attribute unsigned long ;length getter DOMString (unsigned long );index readonly attribute boolean ;usableWithLightBackground readonly attribute boolean ; }; [usableWithDarkBackground Exposed =(Window ,Worker )]interface {FontFacePalettes iterable <FontFacePalette >;readonly attribute unsigned long ;length getter FontFacePalette (unsigned long ); };index partial interface FontFace {readonly attribute FontFaceFeatures ;features readonly attribute FontFaceVariations ;variations readonly attribute FontFacePalettes ; };palettes
注: この読み取り専用データは、 font-feature-settings、font-variation-settings、 および @font-palette-values で どの値が受け入れられるかを作者が把握できるようにすることを目的としています。
3. FontFaceSet インターフェイス
dictionary :FontFaceSetLoadEventInit EventInit {sequence <FontFace >= []; }; [fontfaces Exposed =(Window ,Worker )]interface :FontFaceSetLoadEvent Event {(constructor CSSOMString ,type optional FontFaceSetLoadEventInit = {}); [eventInitDict SameObject ]readonly attribute FrozenArray <FontFace >; };fontfaces enum {FontFaceSetLoadStatus ,"loading" }; ["loaded" Exposed =(Window ,Worker )]interface :FontFaceSet EventTarget {constructor (sequence <FontFace >);initialFaces setlike <FontFace >;FontFaceSet add (FontFace );font boolean delete (FontFace );font undefined clear (); // 読み込み状態が変化したときのイベントattribute EventHandler ;onloading attribute EventHandler ;onloadingdone attribute EventHandler ; // 必要に応じて読み込みを確認し、開始する // すべての読み込みが完了したときに Promise を履行するonloadingerror Promise <sequence <FontFace >>load (CSSOMString font ,optional CSSOMString text = " "); // fontlist 内のすべてのフォントが読み込み済みかどうかを返す // (利用できない場合でも読み込みは開始しない)boolean check (CSSOMString font ,optional CSSOMString text = " "); // フォント読み込みとレイアウト操作が完了したことを非同期で通知するreadonly attribute Promise <FontFaceSet >ready ; // 読み込み状態。1 つ以上のフォントが読み込み中なら "loading"、それ以外は "loaded"readonly attribute FontFaceSetLoadStatus ; };status
ready, 型は Promise<FontFaceSet>、 読み取り専用-
この属性は
FontFaceSetの[[ReadyPromise]]スロットを反映します。この
Promiseとその使用方法の詳細については、§ 3.4 ready 属性を参照してください。 FontFaceSet(initialFaces)-
FontFaceSetコンストラクターは、呼び出されたとき、initialFaces引数を反復処理し、 各値をその set entries に追加しなければなりません。 - 反復順序
-
反復処理される場合、 すべての CSS 接続済み
FontFaceオブジェクトが最初に現れなければならず、 接続された @font-face 規則の文書順に並び、 その後に CSS 接続済みではないFontFaceオブジェクトが、 挿入順に続かなければなりません。 - 集合エントリ
-
FontFaceSetが フォントソースである場合、 その 集合エントリは、§ 4.2 CSS の @font-face 規則との相互作用で指定されているとおりに初期化されます。それ以外の場合、その 集合エントリは初期状態では空です。
add(font)-
add()メソッドが呼び出された場合、 次の手順を実行します:-
font がすでに
FontFaceSetの 集合エントリに含まれている場合、 直ちにこのアルゴリズムの最後の手順へ進みます。 -
font が CSS 接続済みである場合、
InvalidModificationError例外を投げ、 直ちにこのアルゴリズムを終了します。 -
font 引数を
FontFaceSetの 集合エントリに追加します。 -
font の
status属性が "loading" の場合:-
FontFaceSetの[[LoadingFonts]]リストが空の場合、FontFaceSet を loading に切り替えます。 -
font を
FontFaceSetの[[LoadingFonts]]リストに追加します。
-
-
FontFaceSetを返します。
-
delete(font)-
delete()メソッドが呼び出された場合、 次の手順を実行します:-
font が CSS 接続済みである場合、
を返し、直ちにこの アルゴリズムを終了します。false -
deleted を、
FontFaceSetの 集合エントリから font を削除した結果とします。 -
font が
FontFaceSetの[[LoadedFonts]]または[[FailedFonts]]リストに存在する場合、 そこから削除します。 -
font が
FontFaceSetの[[LoadingFonts]]リストに存在する場合、 そこから削除します。 font がそのリストの最後の項目であった場合 (したがってリストが空になった場合)、FontFaceSet を loaded に切り替えます。 -
deleted を返します。
-
clear()-
clear()メソッドが呼び出された場合、 次の手順を実行します:-
FontFaceSetの 集合エントリ、 その[[LoadedFonts]]リスト、 およびその[[FailedFonts]]リストから、CSS 接続済みでないすべての項目を削除します。 -
FontFaceSetの[[LoadingFonts]]リストが空でない場合、 そのすべての項目を削除し、 その後 FontFaceSet を loaded に切り替えます。
-
FontFaceSet
オブジェクトには、内部 [[LoadingFonts]]、[[LoadedFonts]]、
および [[FailedFonts]] スロットもあり、
これらはすべて空のリストに初期化されます。
また、[[ReadyPromise]] スロットもあり、
これは新しい保留中の Promise
に初期化されます。
フォントファミリーは使用された場合にのみ読み込まれるため、 コンテンツは、フォントの読み込みがいつ発生するかを把握する必要がある場合があります。 作者は、ここで定義されているイベントとメソッドを使用することで、 特定のフォントが利用可能であることに依存する処理をより細かく制御できます。
FontFaceSet
は、次のいずれかが真である場合、環境で保留中です:
-
文書がまだ読み込み中である
-
文書に保留中のスタイルシート要求がある
-
文書に、ユーザーエージェントにフォントを要求させる可能性がある、 または最近読み込まれたフォントに依存する、保留中のレイアウト操作がある
注: 考え方としては、FontFaceSet
が 環境で保留中でなくなった時点で、
その後文書に何も変更が加えられない限り、
作者は、測定したときの要素のサイズや位置が「正しい」ことを前提にできるということです。
上記の条件がこの保証を完全に捉えていない場合は、
そうなるように修正する必要があります。
3.1. イベント
フォント読み込みイベントにより、各フォントを個別に監視する代わりに、
文書全体のフォント読み込み動作に簡単に応答できます。
loading イベントは
文書がフォントの読み込みを開始したときに発火し、
loadingdone および loadingerror イベントは、
文書のフォント読み込みが完了したときに発火し、
それぞれ、正常に読み込まれたフォント
または読み込みに失敗したフォントを含みます。
以下は、FontFaceSet オブジェクトが IDL 属性としてサポートしなければならない
イベントハンドラー(および対応するイベントハンドラーイベント型)です:
| イベントハンドラー | イベントハンドラーのイベント型 |
|---|---|
onloading
| loading
|
onloadingdone
| loadingdone
|
onloadingerror
| loadingerror
|
FontFaceSet
target で、名前が e、任意の font faces を伴う
フォント読み込みイベントを発火するとは、
FontFaceSetLoadEvent
インターフェイスを使用して、名前が e の単純イベントを発火することであり、
さらに次の条件も満たすことを意味します:
与えられた FontFaceSet
について、
FontFaceSet を loading に切り替えるよう求められた場合、
ユーザーエージェントは次の手順を実行しなければなりません:
- font face set を、与えられた
FontFaceSetとします。 - font face set の
status属性を "loading" に設定します。 - font face set の
[[ReadyPromise]]スロットが現在履行済みの Promise を保持している場合、 新しい保留中の Promise に置き換えます。 - font face set で、名前が
loadingの フォント読み込みイベントを発火するタスクをキューに入れます。
与えられた FontFaceSet
について、
FontFaceSet
を loaded に切り替えるよう求められた場合、
ユーザーエージェントは次の手順を実行しなければなりません:
-
font face set を、与えられた
FontFaceSetとします。 -
font face set が 環境で保留中である場合、 それを 環境で停止中としてマークし、 このアルゴリズムを終了します。
-
font face set の
status属性を "loaded" に設定します。 -
font face set の
[[ReadyPromise]]属性の値を font face set で履行します。 -
次の手順を同期的に実行するタスクをキューに入れます:
-
loaded fonts を、font face set の
[[LoadedFonts]]スロットの(空の場合もある)内容とします。 -
failed fonts を、font face set の
[[FailedFonts]]スロットの(空の場合もある)内容とします。 -
[[LoadedFonts]]および[[FailedFonts]]スロットを空のリストにリセットします。 -
font face set で、loaded fonts を伴う、名前が
loadingdoneの フォント読み込みイベントを発火します。 -
font face set の failed fonts が空でない場合、 font face set で、failed fonts を伴う、名前が
loadingerrorの フォント読み込み イベントを発火します。
-
FontFaceSet
が 環境で保留中から 環境で保留中ではない状態へ移行するたびに、
ユーザーエージェントは次の手順を実行しなければなりません:
-
FontFaceSetが 環境で停止中であり、かつその[[LoadingFonts]]リストが空の場合、FontFaceSet を loaded に切り替えます。 -
FontFaceSetが 環境で停止中である場合、 そのマークを解除します。
FontFaceSet source から、与えられたフォント文字列 font、 任意のサンプルテキスト text、 および任意の allow system fonts フラグについて、 一致する フォントフェイスを検索するよう求められた場合、 次の手順を実行します:
-
font プロパティの CSS 値構文を使用して font を解析します。
構文エラーが発生した場合、
構文エラーを返します。
解析された値が CSS 全体キーワードである場合、 構文エラーを返します。
すべての相対長を、対応するプロパティの初期値に対して絶対化します。 (たとえば、bolder のような相対フォントウェイトは、初期値 normal に対して評価されます。)
- text が明示的に指定されていない場合、 単一のスペース文字(U+0020 SPACE)を含む文字列とします。
- font family list を font から解析されたフォントファミリーのリストとし、 font style を font から解析されたその他のフォントスタイル属性とします。
- available font faces を、source 内の 利用可能なフォントフェイスとします。 allow system fonts フラグが指定されている場合、 すべてのシステムフォントを available font faces に追加します。
- matched font faces を最初は空のリストとします。
- font family list 内の各ファミリーについて、
フォントマッチング規則を使用して、available font faces から
font style に一致するフォントフェイスを選択し、
それらを matched font faces に追加します。
unicodeRange属性を使用するため、これは単一のフォントフェイスだけではない場合があります。 - matched font faces が空の場合、 found faces フラグを false に設定します。 それ以外の場合は true に設定します。
-
matched font faces 内の各フォントフェイスについて、
定義された unicode-range が、
text 内の少なくとも 1 文字のコードポイントを含まない場合、
そのフォントフェイスをリストから削除します。
注: したがって、text が空文字列の場合、 すべてのフォントが削除されます。
- matched font faces と found faces フラグを返します。
3.2. load() メソッド
load()
メソッドは、FontFaceSet
において、指定されたフォントリスト内のすべてのフォントが
読み込み済みで利用可能かどうかを判定します。
いずれかのフォントがダウンロード可能なフォントで、まだ読み込まれていない場合、
ユーザーエージェントはそれら各フォントの読み込みを開始します。
これは Promise を返し、
すべてのフォントが読み込まれて使用可能になると履行され、
いずれかのフォントが正常に読み込めなかった場合は拒否されます。
load( font, text ) メソッドが
呼び出された場合、
次の手順を実行します:
- font face set を、このメソッドが呼び出された
FontFaceSetオブジェクトとします。 promise を新しく作成された Promise オブジェクトとします。 - promise を返します。 残りの手順を非同期で完了します。
- 関数に渡された
fontおよびtext引数を使用して font face set から一致するフォントフェイスを検索し、 font face list を戻り値とします (found faces フラグは無視します)。 構文エラーが返された場合、 promise を SyntaxError 例外で拒否し、 これらの手順を終了します。 -
次の手順を同期的に実行するタスクをキューに入れます:
- font face list 内のすべてのフォントフェイスについて、
それぞれの
load()メソッドを呼び出します。 - font face list 内の各フォントフェイスの
[[FontStatusPromise]]を 順番にすべて待機した結果で promise を解決します。
- font face list 内のすべてのフォントフェイスについて、
それぞれの
3.3. check() メソッド
check()
メソッドは、FontFaceSet
において、指定されたテキストを特定のフォントリストで「安全に」
レンダリングできるかどうか、すなわち後で「フォントスワップ」が発生しないかどうかを判定します。
指定されたテキストとフォントの組み合わせが、
未読み込みまたは現在読み込み中のフォントを使用しようとせずにレンダリングされる場合、
このメソッドは true を返します。
それ以外の場合は false を返します。
-
指定されたフォントが存在するものの、 すべての候補フェイスが、その unicode-range が指定された テキストをカバーしていないため除外される場合、 このメソッドは
trueを返します。 これは、代わりにテキストが UA のフォールバックフォントでレンダリングされ、 フォント読み込みが発生しないためです。 -
同様に、指定されたフォントが 1 つも存在しない場合(たとえば、名前のスペルが間違っている場合)も、 このメソッドは
trueを返します。 このフォントリストを使用しても読み込みは発生せず、 代わりにフォールバックが行われるためです。
check( font, text) メソッドが
呼び出された場合、
次の手順を実行します:
- font face set を、このメソッドが呼び出された
FontFaceSetオブジェクトとします。 - 関数に渡された
fontおよびtext引数を使用し、システムフォントも含めて、 font face set から一致するフォントフェイスを検索し、 font face list を返されたフォントフェイスのリスト、 found faces を返された found faces フラグとします。 構文エラーが返された場合、 SyntaxError 例外を投げ、 これらの手順を終了します。 - font face list が空である、
または font face list 内のすべてのフォントが、
status属性が "loaded" であるかシステムフォントである場合、trueを返します。 それ以外の場合はfalseを返します。
3.4. ready 属性
読み込まれるフォントの数は、特定のテキスト片にいくつのフォントが使用されるかに依存するため、
場合によっては、フォントを読み込む必要があるかどうかが事前には分からないことがあります。
ready
属性には、文書のフォント読み込みが完了したときに解決される Promise
が含まれます。
これにより、作者は、フォント読み込みによって影響を受ける可能性のあるコンテンツを調べる前に、
どのフォントが読み込まれたか、または読み込まれていないかを追跡し続ける必要を避けられます。
注: 作者は、特定の ready
promise が履行されるのは 1 回だけであるものの、
その履行後にさらにフォントが読み込まれる可能性があることに注意する必要があります。
これは、loadingdone
イベントの発火を監視することに似ています。
ただし、ready
Promise に渡されたコールバックは、
対象のフォントがすでに読み込まれているためフォント読み込みが発生しない場合でも、
常に呼び出されます。
どのフォントが必要か、また正確にいつ読み込まれるかを追跡する必要なしに、
コードをフォント読み込みと同期させる簡単な方法です。
注: ready promise が履行されるまでに、 ユーザーエージェントが複数回のフォント読み込みを繰り返す必要がある場合があることに注意してください。 これはフォントフォールバックの場合に発生することがあります。 たとえば、fontlist 内の 1 つのフォントが読み込まれたものの、 特定のグリフを含んでおらず、 fontlist 内の他のフォントを読み込む必要がある場合です。 ready promise は、レイアウト操作が完了し、 追加のフォント読み込みが不要になった後にのみ履行されます。
注: この ready
属性によって返される Promise は、
FontFace の
load()
メソッドによって返される Promise とは異なり、
常に履行されるだけで、
拒否されることはありません。
3.5. CSS フォント読み込みおよびマッチングとの相互作用
[CSS-FONTS-3] のフォントマッチングアルゴリズムがユーザーエージェントによって自動的に実行される場合、 マッチング対象となるフォントフェイスの集合は、文書の フォントソース内のフォントの集合に、 任意のローカルフォントフェイスを加えたものと正確に一致しなければなりません。
ユーザーエージェントがフォントフェイスを読み込む必要がある場合、
対応する FontFace
オブジェクトの
load()
メソッドを呼び出すことによって読み込まなければなりません。
(これは、同じアルゴリズムを実行しなければならないという意味であり、
オブジェクトの load プロパティに現在格納されている値を文字どおり呼び出すという意味ではありません。)
FontFaceSet
に追加されると利用可能になります。
新しい @font-face 規則をスタイルシートに追加すると、
FontFace も新たに、
Document
オブジェクトの FontFaceSet
に追加されます。
新しい @font-face 規則を追加する場合:
document. styleSheets[ 0 ]. insertRule( "@font-face { font-family: newfont; src: url(newfont.woff); }" , 0 ); document. body. style. fontFamily= "newfont, serif" ;
新しい FontFace
オブジェクトを構築して document に追加する場合:
var f= new FontFace( "newfont" , "url(newfont.woff)" ); document. fonts. add( f); document. body. style. fontFamily= "newfont, serif" ;
どちらの場合も、フォントリソース “newfont.woff” の読み込みはレイアウトエンジンによって開始され、 他の @font-face 規則のフォントと同様に読み込まれます。
document への追加を省略すると、フォントは
決して読み込まれず、
テキストはデフォルトの serif フォントで表示されます:
var f= new FontFace( "newfont" , "url(newtest.woff)" , {}); /* 新しい {{FontFace}} は {{FontFaceSet}} に追加されていないため、 'font-family' プロパティからは認識できず、 代わりに serif が使用される */ document. body. style. fontFamily= "newfont, serif" ;
フォントを使用する前に明示的にプリロードするには、
作者は、新しい FontFace を
FontFaceSet
に追加するのを、読み込みが完了するまで遅らせることができます:
var f= new FontFace( "newfont" , "url(newfont.woff)" , {}); f. load(). then( function ( loadedFace) { document. fonts. add( loadedFace); document. body. style. fontFamily= "newfont, serif" ; });
この場合、最初にフォントリソース “newfont.woff” がダウンロードされます。
ダウンロードが完了すると、
フォントは文書の FontFaceSet
に追加され、
body のフォントが変更され、
レイアウトエンジンが新しいフォントリソースを使用します。
4. FontFaceSource ミックスイン
interface mixin {FontFaceSource readonly attribute FontFaceSet ; };fonts Document includes FontFaceSource ;WorkerGlobalScope includes FontFaceSource ;
何らかの方法でフォントを使用できる文書、Worker、またはその他のコンテキストは、FontFaceSource
ミックスインを含まなければなりません。
コンテキストの fonts
属性の値は、その フォント
ソースであり、
特に定義されていない限り、
フォント関連の操作で使用されるすべてのフォントを提供します。
「the font source」を参照する操作は、その操作が行われている関連コンテキストの フォントソースを参照するものとして解釈しなければなりません。
これらのコンテキストのいずれかで行われるフォント関連の操作について、
フォントソース内の FontFace
オブジェクトが、その 利用可能なフォント
フェイスです。
4.1. Worker の FontFaceSource
Worker 文書内では、フォント ソースは初期状態では空です。
注: FontFace オブジェクトは
通常どおり構築して追加でき、
これは Worker 内の CSS フォントマッチングに影響します
(たとえば、OffscreenCanvas
にテキストを描画する場合など)。
4.2. CSS の @font-face 規則との相互作用
文書の フォント
ソースの 集合
エントリには、初期状態で、文書または Shadow Root の CSS
スタイルシート内にあるすべての CSS @font-face 規則から、
すべての CSS 接続済み FontFace オブジェクトを
文書順で格納しなければなりません。
@font-face 規則がスタイルシートに追加または削除されたり、
@font-face 規則を含むスタイルシートが
追加または削除されたりすると、
対応する CSS 接続済み FontFace オブジェクトも
文書の フォントソースに追加または削除されなければならず、
この順序を維持しなければなりません。
手動で追加されたすべての FontFace
オブジェクトは、
CSS
接続済みのものより後に並べなければなりません。
FontFaceSet
オブジェクトの add()
メソッドが CSS 接続済み FontFace
オブジェクトを引数として呼び出された場合、
オブジェクトがすでに集合に含まれていれば、
操作は何もしないものでなければなりません。
それ以外の場合も、操作は何もしてはならず、
InvalidModificationError
を投げなければなりません。
FontFaceSet
オブジェクトの delete()
メソッドが CSS 接続済み FontFace
オブジェクトを引数として呼び出された場合、
操作は何もしないものでなければならず、
を返さなければなりません。
注: 作者は、削除された FontFace への参照を、
フォントソースから自動的に削除された後でも保持できます。
ただし、§ 2.3 CSS の @font-face 規則との相互作用で指定されているとおり、
その時点で FontFace
はもはや CSS 接続済みではありません。
注: この仕様の将来のバージョンでは、 ローカルフォントとやり取りしたり、照会したりする方法も定義されることが期待されています。
5. API の例
document. fonts. ready. then( function () { var content= document. getElementById( "content" ); content. style. visibility= "visible" ; });
function drawStuff() { var ctx= document. getElementById( "c" ). getContext( "2d" ); ctx. fillStyle= "red" ; ctx. font= "50px MyDownloadableFont" ; ctx. fillText( "こんにちは!" , 100 , 100 ); } document. fonts. load( "50px MyDownloadableFont" ) . then( drawStuff, handleError);
function measureTextElements() { // これで、ダウンロード可能なフォントのメトリックを使用して // コンテンツを測定できる } function doEditing() { // 追加のフォント読み込みを引き起こす可能性のあるコンテンツ/レイアウト操作 document. fonts. ready. then( measureTextElements); }
loadingdone
イベントは、すべてのフォント関連の読み込みが完了し、かつ追加のフォント読み込みを発生させずに
テキストのレイアウトが完了した後にのみ発火します:
< style > @ font-face { font-family : latin-serif ; src : url ( latinserif . woff ) format ( "woff" ); /* 漢字/かなを含まない */ } @ font-face { font-family : jpn-mincho ; src : url ( mincho . woff ) format ( "woff" ); } @ font-face { font-family : unused ; src : url ( unused . woff ); } body { font-family : latin-serif , jpn-mincho ; } </ style > < p > 納豆はいかがでしょうか
この状況では、ユーザーエージェントは最初に “latinserif.woff” をダウンロードし、
次にこれを使用して日本語テキストの描画を試みます。
しかし、そのフォントには日本語のグリフが存在しないため、
フォールバックが発生してフォント “mincho.woff” がダウンロードされます。
2 番目のフォントがダウンロードされ、日本語テキストがレイアウトされた後にのみ、loadingdone
イベントが発火します。
"unused" フォントは読み込まれませんが、
それを使用しているテキストがないため、
UA はそのフォントを読み込もうとさえしていません。
したがって、loadingdone
イベントに影響しません。
変更点
2014年5月 CSS Font Loading 最終草案作業草案からの変更点:
- フォント情報を検出するための IDL を追加しました。
- FontFaceSet.clear() が CSS 接続済み項目を消去しないことを明確化しました。
- はじめにで document.fonts に言及しました。
- フォント読み込みが、文書だけでなく Shadow Root にも適用されるようにしました。
- 指定されたフォントが 1 つも存在しない場合はフォント読み込みが発生しないため、エラーを投げないようにしました。
- WebIDL との整合性を向上しました。
- constructor() メソッド構文に切り替えました。
- マッチ対象の文字列が空の場合の、一致するフォントフェイスアルゴリズムの動作を明確化しました。
- FontFaceSource をミックスインに変更しました。
- 従来の用語 CanvasProxy を OffscreenCanvas に変更しました。
- FontFace と @font-face を調和させ、variationSettings と fontDisplay を追加しました。
- IDL 全体で [Exposed] を一貫して使用するようにしました。
- DOMString より CSSOMString を優先するようにしました。
- check() の導入説明を改善しました。
- 最近読み込まれたフォントに依存するレイアウト操作を完了できるようにしなければならないことを明確化しました。
- 読み込みイベントを発火する際のより多くのエッジケースをカバーしました。
- 同期呼び出しよりも非同期イベントキューイングタスクを優先するようにしました。
- fonts.ready は関数ではなくプロパティです。
- 存在しないフォントと、存在するが必要なグリフを持たないフォントを区別しました。
- いくつかのメソッドについて、手順の順序を正確に列挙しました。
- load() および check() 関数におけるグローバルキーワードと相対値の処理を明確化しました。
- src 引数の解析は、CSS @font-face src 記述子の解析と同じであることを明確化しました。
- CSS 接続済みフォントを削除しようとしても効果がなく、false を返すことを明確化しました。
- 重複するフォントの追加は効果がないことを明確化しました。
- 手動で追加された FontFace オブジェクトの順序を明確化しました。
- 読み込みイベントには、集合内にまだ存在するフェイスのみが含まれることを明確化しました。
variationSettingsおよびdisplayを追加し、 @font-face と同期しました。fontfacesを FrozenArray に変更し、 適切な IDL の慣例に合わせました。- 読み込み中のフォントが FontFaceSet に追加された場合に、loading イベントを発火し、Promise を処理するようにしました。
- 副作用のタイミングが明確に定義されるよう、 非同期アルゴリズムを "queue a task" という表現を使用するよう修正しました。
- いくつかの参照を最新バージョンに更新しました。
- IDL を修正しました。
- さまざまな誤字および文法上の誤りを修正しました。
謝辞
Google Fonts チームの複数のメンバーがフォント読み込みイベントについて有益なフィードバックを提供してくれました。 Boris Zbarsky、Jonas Sicking、ms2ger からも同様にフィードバックをいただきました。
プライバシーに関する考慮事項
FontFaceSet
オブジェクトは、ユーザーがインストールしているフォントに関する情報を漏洩しますが、
既存の @font-face 規則とまったく同じ方法です。
新しい情報が漏洩することはなく、
また、目立って容易な方法で漏洩することもありません。
セキュリティに関する考慮事項
この仕様について、セキュリティ上の考慮事項は提起されていません。