css-font-loading/Overview.bs

Sun, 31 Jan 2016 15:42:31 -0800

author
Peter Linss <[email protected]>
date
Sun, 31 Jan 2016 15:42:31 -0800
changeset 16986
5be73fbc8592
parent 16467
2a731a2228ec
child 16989
255258410d1b
permissions
-rw-r--r--

change //dev.w3.org/csswg/ urls to //drafts.csswg.org/

jackalmage@10009 1 <h1>CSS Font Loading Module Level 3</h1>
jackalmage@8992 2
jackalmage@8992 3 <pre class='metadata'>
jackalmage@10009 4 Shortname: css-font-loading
jackalmage@13979 5 Level: 3
jackalmage@9499 6 Group: csswg
jackalmage@14063 7 Status: ED
jackalmage@15674 8 Work Status: Exploring
peter@16986 9 ED: https://drafts.csswg.org/css-font-loading/
jackalmage@10012 10 TR: http://w3.org/TR/css-font-loading/
jackalmage@14063 11 Previous Version: http://www.w3.org/TR/2014/WD-css-font-loading-3-20140522/
jackalmage@8992 12 Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/
jackalmage@9496 13 Former Editor: John Daggett, Mozilla, [email protected]
jackalmage@8992 14 Abstract: This CSS module describes events and interfaces used for dynamically loading font resources.
jackalmage@15466 15 Link Defaults: css-fonts-3 (descriptor) src, dom-ls (interface) Event, typedarray (interface) ArrayBuffer/ArrayBufferView
jackalmage@15974 16 Ignored Terms: EventHandler, InvalidModificationError, WorkerGlobalScope, CanvasProxy, Document, add(), src
jackalmage@8992 17 </pre>
jackalmage@8992 18
jackalmage@16463 19 <pre class="link-defaults">
jackalmage@16463 20 spec:dom-ls; type:interface; text:EventTarget
jackalmage@16463 21 </pre>
jackalmage@16463 22
jackalmage@8992 23 <h2 id="introduction">
jackalmage@8992 24 Introduction</h2>
jackalmage@8992 25
jackalmage@10011 26 CSS allows authors to load custom fonts from the web via the ''@font-face'' rule.
jackalmage@10011 27 While this is easy to use when authoring a stylesheet,
jackalmage@10011 28 it's much more difficult to use dynamically via scripting.
jackalmage@10011 29
jackalmage@10011 30 Further, CSS allows the user agent to choose when to actually load a font;
jackalmage@10011 31 if a font face isn't <em>currently</em> used by anything on a page,
jackalmage@10011 32 most user agents will not download its associated file.
jackalmage@10011 33 This means that later use of the font face will incur a delay
jackalmage@10011 34 as the user agent finally notices a usage and begins downloading and parsing the font file.
jackalmage@10011 35
jackalmage@10011 36 This specification defines a scripting interface to font faces in CSS,
jackalmage@10011 37 allowing font faces to be easily created and loaded from script.
jackalmage@10011 38 It also provides methods to track the loading status of an individual font,
jackalmage@10011 39 or of all the fonts on an entire page.
jackalmage@8992 40
jackalmage@14167 41 Issue: Several things in this spec use normal ES objects to define behavior,
jackalmage@14167 42 such as various things using Promises internally,
jackalmage@14167 43 and FontFaceSet using a Set internally.
jackalmage@14167 44 I believe the intention here is that these objects
jackalmage@14167 45 (and their prototype chains) are pristine,
jackalmage@14167 46 unaffected by anything the author has done.
jackalmage@14167 47 Is this a good intention?
jackalmage@14167 48 If so, how should I indicate this in the spec?
jackalmage@14167 49
jackalmage@10101 50 <h3 id="values">
jackalmage@10101 51 Values</h3>
jackalmage@10101 52
jackalmage@15132 53 This specification uses <dfn interface lt="Promise">Promises</dfn>,
jackalmage@13948 54 which are defined in <a href="http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts">ECMAScript 6</a>.
jackalmage@10101 55 HTML5Rocks has some <a href="http://www.html5rocks.com/en/tutorials/es6/promises/">good tutorial material introducing Promises</a>.
jackalmage@10101 56
jackalmage@14216 57 <h3 id='task-source'>
jackalmage@14216 58 Task Sources</h3>
jackalmage@14216 59
jackalmage@14216 60 Whenever this specification queues a task,
jackalmage@14216 61 it queues it onto the "font loading" task source.
jackalmage@14216 62
jackalmage@14019 63 <!--
jackalmage@14019 64 ████████ ███████ ██ ██ ████████ ████████ ███ ██████ ████████
jackalmage@14020 65 ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 66 ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 67 ██████ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██ ██████
jackalmage@14020 68 ██ ██ ██ ██ ████ ██ ██ █████████ ██ ██
jackalmage@14020 69 ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 70 ██ ███████ ██ ██ ██ ██ ██ ██ ██████ ████████
jackalmage@14019 71 -->
jackalmage@14019 72
jackalmage@9045 73 <h2 id="fontface-interface">
jackalmage@9045 74 The <code>FontFace</code> Interface</h2>
jackalmage@9018 75
jackalmage@14551 76 The {{FontFace}} interface represents a single usable font face.
jackalmage@9018 77 CSS ''@font-face'' rules implicitly define FontFace objects,
jackalmage@9018 78 or they can be constructed manually from a url or binary data.
jackalmage@9018 79
jackalmage@9018 80 <pre class="idl">
jackalmage@9018 81 typedef (ArrayBuffer or ArrayBufferView) BinaryData;
jackalmage@9018 82
jackalmage@9018 83 dictionary FontFaceDescriptors {
jackalmage@9018 84 DOMString style = "normal";
jackalmage@9018 85 DOMString weight = "normal";
jackalmage@9018 86 DOMString stretch = "normal";
jackalmage@9018 87 DOMString unicodeRange = "U+0-10FFFF";
jackalmage@9018 88 DOMString variant = "normal";
jackalmage@9018 89 DOMString featureSettings = "normal";
jackalmage@9018 90 };
jackalmage@9018 91
jackalmage@9018 92 enum FontFaceLoadStatus { "unloaded", "loading", "loaded", "error" };
jackalmage@9018 93
jackalmage@9019 94 [Constructor(DOMString family, (DOMString or BinaryData) source,
jackalmage@14641 95 optional FontFaceDescriptors descriptors),
jackalmage@14064 96 Exposed=Window,Worker]
jackalmage@9018 97 interface FontFace {
jackalmage@9018 98 attribute DOMString family;
jackalmage@9018 99 attribute DOMString style;
jackalmage@9018 100 attribute DOMString weight;
jackalmage@9018 101 attribute DOMString stretch;
jackalmage@9018 102 attribute DOMString unicodeRange;
jackalmage@9018 103 attribute DOMString variant;
jackalmage@9018 104 attribute DOMString featureSettings;
jackalmage@9018 105
jackalmage@9024 106 readonly attribute FontFaceLoadStatus status;
jackalmage@9018 107
jackalmage@13945 108 Promise&lt;FontFace> load();
jackalmage@14334 109 readonly attribute Promise&lt;FontFace> loaded;
jackalmage@9018 110 };
jackalmage@9018 111 </pre>
jackalmage@9018 112
jackalmage@14335 113 Issue: Other APIs use other names for .loaded, like .readyState. Can we align?
jackalmage@14335 114
jackalmage@14335 115 Issue: "unloaded" is usually used for things that start loaded and then become not loaded.
jackalmage@14335 116 Can we rename that value?
jackalmage@14335 117 Media stuff uses "none", other APIs use "empty", "idle", "nothing".
jackalmage@14335 118
jackalmage@16171 119 Issue: Clarify all mentions of "the document" to be clear about which document is being referenced,
jackalmage@16171 120 since objects can move between documents.
jackalmage@16171 121
jackalmage@14828 122 <div dfn-type=attribute dfn-for=FontFace>
jackalmage@14802 123 : <dfn>family</dfn>
jackalmage@14802 124 : <dfn>style</dfn>
jackalmage@14802 125 : <dfn>weight</dfn>
jackalmage@14802 126 : <dfn>stretch</dfn>
jackalmage@14802 127 : <dfn>unicodeRange</dfn>
jackalmage@14802 128 ::
jackalmage@9018 129 These attributes all represent the corresponding aspects of a font face,
jackalmage@9018 130 as defined by the descriptors defined in the CSS ''@font-face'' rule.
jackalmage@9018 131 They are parsed the same as the corresponding ''@font-face'' descriptors.
jackalmage@9018 132 They are used by the font matching algorithm,
jackalmage@9018 133 but otherwise have no effect.
jackalmage@9018 134
jackalmage@14551 135 For example, a {{FontFace}} with a {{FontFace/style}} of <code>"italic"</code>
jackalmage@9018 136 <em>represents</em> an italic font face;
jackalmage@9018 137 it does not <strong>make</strong> the font face italic.
jackalmage@9018 138
jackalmage@14092 139 On getting, return the string associated with this attribute.
jackalmage@14092 140
jackalmage@14092 141 On setting, parse the string according to the grammar for the CSS ''@font-face'' rule.
jackalmage@14092 142 If it does not match the grammar,
jackalmage@14120 143 throw a SyntaxError;
jackalmage@14121 144 otherwise, set the attribute to the serialization of the parsed value.
jackalmage@14092 145
jackalmage@14802 146 : <dfn>variant</dfn>
jackalmage@14802 147 : <dfn>featureSettings</dfn>
jackalmage@14802 148 ::
jackalmage@9018 149 These attributes have the same meaning,
jackalmage@9018 150 and are parsed the same as,
jackalmage@9018 151 the corresponding descriptors in the CSS ''@font-face'' rules.
jackalmage@9018 152
jackalmage@9018 153 They turn on or off specific features in fonts that support them.
jackalmage@9018 154 Unlike the previous attributes,
jackalmage@9018 155 these attributes actually affect the font face.
jackalmage@9018 156
jackalmage@14092 157 On getting, return the string associated with this attribute.
jackalmage@14092 158
jackalmage@14092 159 On setting, parse the string according to the grammar for the CSS ''@font-face'' rule.
jackalmage@14092 160 If it does not match the grammar,
jackalmage@14120 161 throw a SyntaxError;
jackalmage@14121 162 otherwise, set the attribute to the serialization of the parsed value.
jackalmage@14092 163
jackalmage@14802 164 : <dfn>status</dfn>
jackalmage@14802 165 ::
jackalmage@9018 166 This attribute reflects the current status of the font face.
jackalmage@14551 167 It must be "unloaded" for a newly-created {{FontFace}}.
jackalmage@9024 168
jackalmage@9024 169 It can change due to an author explicitly requesting a font face to load,
jackalmage@14551 170 such as through the {{FontFace/load()}} method on {{FontFace}},
jackalmage@9024 171 or implicitly by the user agent,
jackalmage@9024 172 due to it detecting that the font face is needed to draw some text on the screen.
jackalmage@13635 173
jackalmage@14802 174 : <dfn>loaded</dfn>
jackalmage@14802 175 ::
jackalmage@14551 176 This attribute reflects the {{[[FontStatusPromise]]}} of the font face.
jackalmage@14802 177 </div>
jackalmage@9018 178
jackalmage@14551 179 All {{FontFace}} objects contain an internal <dfn attribute for=FontFace>\[[FontStatusPromise]]</dfn> slot,
jackalmage@9018 180 which tracks the status of the font.
jackalmage@9018 181 It starts out pending,
jackalmage@9018 182 and fulfills or rejects when the font is successfully loaded and parsed, or hits an error.
jackalmage@9018 183
jackalmage@14551 184 All {{FontFace}} objects also contain
jackalmage@14551 185 internal <dfn attribute for=FontFace>\[[Urls]]</dfn> and <dfn attribute for=FontFace>\[[Data]]</dfn> slots,
jackalmage@14336 186 of which one is <code>null</code> and the other is not <code>null</code>
jackalmage@14336 187 (the non-null one is set by the constructor,
jackalmage@14336 188 based on which data is passed in).
jackalmage@9018 189
jackalmage@14019 190 <!--
jackalmage@14020 191 ██████ ███████ ██ ██ ██████ ████████ ████████ ██ ██ ██████ ████████ ███████ ████████
jackalmage@14019 192 ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 193 ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 194 ██ ██ ██ ██ ██ ██ ██████ ██ ████████ ██ ██ ██ ██ ██ ██ ████████
jackalmage@14020 195 ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 196 ██ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 197 ██████ ███████ ██ ██ ██████ ██ ██ ██ ███████ ██████ ██ ███████ ██ ██
jackalmage@14019 198 -->
jackalmage@14019 199
jackalmage@9045 200 <h3 id='font-face-constructor'>
jackalmage@9045 201 The Constructor</h3>
jackalmage@9018 202
jackalmage@14551 203 A {{FontFace}} can be constructed either
jackalmage@9019 204 from a URL pointing to a font face file,
jackalmage@9019 205 or from an ArrayBuffer (or ArrayBufferView) containing the binary representation of a font face.
jackalmage@9018 206
jackalmage@15132 207 When the <dfn constructor lt='FontFace()' for=FontFace>FontFace</dfn>(
jackalmage@14842 208 <span dfn-for="FontFace/FontFace(family, source, descriptors)">
jackalmage@14842 209 DOMString <dfn argument>family</dfn>,
jackalmage@14842 210 (DOMString or {{/BinaryData}}) <dfn argument>source</dfn>,
jackalmage@14842 211 {{/FontFaceDescriptors}} <dfn argument>descriptors</dfn>
jackalmage@14842 212 </span>
jackalmage@14842 213 )
jackalmage@14842 214 method is called,
jackalmage@9019 215 execute these steps:
jackalmage@9018 216
jackalmage@14552 217 1. Let <var>font face</var> be a fresh {{FontFace}} object.
jackalmage@14552 218 Set <var>font face's</var> {{FontFace/status}} attribute to <code>"unloaded"</code>,
jackalmage@14552 219 Set its internal {{[[FontStatusPromise]]}} slot to a fresh pending {{Promise}} object.
jackalmage@14208 220
jackalmage@14666 221 Parse the {{family!!argument}} argument,
jackalmage@14666 222 and the members of the {{descriptors!!argument}} argument,
jackalmage@14552 223 according to the grammars of the corresponding descriptors of the CSS ''@font-face'' rule.
jackalmage@15409 224 If the {{source!!argument}} argument is a {{DOMString}},
jackalmage@15409 225 parse it according to the grammar of the CSS ''@font-face/src'' descriptor of the ''@font-face'' rule.
jackalmage@14552 226 If any of them fail to parse correctly,
jackalmage@14552 227 reject <var>font face's</var> {{[[FontStatusPromise]]}} with a DOMException named "SyntaxError",
jackalmage@14552 228 set <var>font face’s</var> corresponding attributes to the empty string,
jackalmage@14552 229 and set <var>font face’s</var> {{FontFace/status}} attribute to "error".
jackalmage@14552 230 Otherwise, set <var>font face's</var> corresponding attributes to the serialization of the parsed values.
jackalmage@14209 231
jackalmage@14552 232 Note: Note that this means that passing a naked url as the source argument,
jackalmage@14552 233 like <code>"http://example.com/myFont.woff"</code>,
jackalmage@14552 234 won't work - it needs to be at least wrapped in a ''url()'' function,
jackalmage@14552 235 like <code>"url(http://example.com/myFont.woff)"</code>.
jackalmage@14552 236 In return for this inconvenience,
jackalmage@14552 237 you get to specify multiple fallbacks,
jackalmage@14552 238 specify the type of font each fallback is,
jackalmage@14552 239 and refer to local fonts easily.
jackalmage@9018 240
jackalmage@14552 241 Issue: Need to define the base url,
jackalmage@14552 242 so relative urls can resolve.
jackalmage@14552 243 Should it be the url of the document?
jackalmage@14552 244 Is that correct for workers too,
jackalmage@14552 245 or should they use their worker url?
jackalmage@14552 246 Is that always defined?
jackalmage@14122 247
jackalmage@15409 248 Return <var>font face</var>.
jackalmage@15409 249 If <var>font face’s</var> {{FontFace/status}} is "error",
jackalmage@15409 250 terminate this algorithm;
jackalmage@15409 251 otherwise,
jackalmage@15409 252 complete the rest of these steps asynchronously.
jackalmage@15409 253
jackalmage@15409 254 2. If the {{source!!argument}} argument was a {{DOMString}},
jackalmage@15409 255 set <var>font face's</var> internal {{[[Urls]]}} slot to the string.
jackalmage@15409 256
jackalmage@14552 257 If the {{source}} argument was a {{BinaryData}},
jackalmage@14552 258 set <var>font face's</var> internal {{[[Data]]}} slot to the passed argument.
jackalmage@9018 259
jackalmage@14552 260 3. If <var>font face's</var> {{[[Data]]}} slot is not <code>null</code>,
jackalmage@15424 261 queue a task to run the following steps synchronously:
jackalmage@15424 262
jackalmage@15424 263 1. Set <var>font face's</var> {{FontFace/status}} attribute to "loading".
jackalmage@15424 264 2. For each {{FontFaceSet}} <var>font face</var> is in:
jackalmage@15424 265 1. If the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list is empty,
jackalmage@15424 266 <a>switch the FontFaceSet to loading</a>.
jackalmage@15424 267 2. Append <var>font face</var> to the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list.
jackalmage@15424 268
jackalmage@15424 269 Asynchronously, attempt to parse the data in it as a font.
jackalmage@14552 270 When this is completed,
jackalmage@14552 271 successfully or not,
jackalmage@14552 272 queue a task to run the following steps synchronously:
jackalmage@14015 273
jackalmage@14552 274 1. If the load was successful,
jackalmage@14552 275 <var>font face</var> now represents the parsed font;
jackalmage@14552 276 fulfill <var>font face's</var> {{[[FontStatusPromise]]}} with <var>font face</var>,
jackalmage@14552 277 and set its {{FontFace/status}} attribute to "loaded".
jackalmage@14015 278
jackalmage@15424 279 For each {{FontFaceSet}} <var>font face</var> is in:
jackalmage@15424 280 1. Add <var>font face</var> to the {{FontFaceSet}}’s {{[[LoadedFonts]]}} list.
jackalmage@15424 281 2. Remove <var>font face</var> from the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list.
jackalmage@15424 282 If <var>font</var> was the last item in that list
jackalmage@15424 283 (and so the list is now empty),
jackalmage@15424 284 <a>switch the FontFaceSet to loaded</a>.
jackalmage@15424 285
jackalmage@14552 286 2. Otherwise,
jackalmage@14552 287 reject <var>font face's</var> {{[[FontStatusPromise]]}} with a DOMException named "SyntaxError"
jackalmage@14552 288 and set <var>font face's</var> {{FontFace/status}} attribute to "error".
jackalmage@9019 289
jackalmage@15424 290 For each {{FontFaceSet}} <var>font face</var> is in:
jackalmage@15424 291 1. Add <var>font face</var> to the {{FontFaceSet}}’s {{[[FailedFonts]]}} list.
jackalmage@15424 292 2. Remove <var>font face</var> from the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list.
jackalmage@15424 293 If <var>font</var> was the last item in that list
jackalmage@15424 294 (and so the list is now empty),
jackalmage@15424 295 <a>switch the FontFaceSet to loaded</a>.
jackalmage@15424 296
jackalmage@13480 297 Note: Newly constructed FontFace objects are not automatically added
jackalmage@13480 298 to the FontFaceSet associated with a document
jackalmage@13480 299 or a context for a worker thread.
jackalmage@13480 300 This means that while newly constructed fonts can be preloaded,
jackalmage@13480 301 they cannot actually be used until they are explicitly added to a FontFaceSet.
jackalmage@13480 302 See the following section for a more complete description of FontFaceSet.
jackalmage@10100 303
jackalmage@14019 304 <!--
jackalmage@14020 305 ██ ███████ ███ ████████ ███ ███
jackalmage@14020 306 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 307 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 308 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 309 ██ ██ ██ █████████ ██ ██ ██ ██
jackalmage@14020 310 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 311 ████████ ███████ ██ ██ ████████ ███ ███
jackalmage@14019 312 -->
jackalmage@14019 313
jackalmage@9045 314 <h3 id='font-face-load'>
jackalmage@9045 315 The <code>load()</code> method</h3>
jackalmage@9019 316
jackalmage@14551 317 The {{FontFace/load()}} method of {{FontFace}}
jackalmage@9034 318 forces a url-based font face to request its font data and load.
jackalmage@9034 319 For fonts constructed from binary data,
jackalmage@9034 320 or fonts that are already loading or loaded,
jackalmage@9034 321 it does nothing.
jackalmage@9034 322
jackalmage@9025 323 When the <dfn method for=FontFace>load()</dfn> method is called,
jackalmage@9025 324 execute these steps:
jackalmage@9019 325
jackalmage@15424 326 <ol>
jackalmage@9019 327 <li>
jackalmage@14551 328 Let <var>font face</var> be the {{FontFace}} object on which this method was called.
jackalmage@9018 329
jackalmage@9019 330 <li>
jackalmage@14551 331 If <var>font face's</var> {{[[Urls]]}} slot is <code>null</code>,
jackalmage@14551 332 or its {{FontFace/status}} attribute is anything other than <code>"unloaded"</code>,
jackalmage@14551 333 return <var>font face's</var> {{[[FontStatusPromise]]}}
jackalmage@10102 334 and abort these steps.
jackalmage@9018 335
jackalmage@9019 336 <li>
jackalmage@9495 337 Otherwise,
jackalmage@14551 338 set <var>font face's</var> {{FontFace/status}} attribute to "loading",
jackalmage@14551 339 return <var>font face's</var> {{[[FontStatusPromise]]}},
jackalmage@10102 340 and continue executing the rest of this algorithm asynchronously.
jackalmage@9018 341
jackalmage@9019 342 <li>
jackalmage@14551 343 Using the value of <var>font face's</var> {{[[Urls]]}} slot,
jackalmage@14762 344 attempt to load a font as defined in [[!CSS-FONTS-3]],
jackalmage@9025 345 as if it was the value of a ''@font-face'' rule's 'src' descriptor.
jackalmage@9018 346
jackalmage@9019 347 <li>
jackalmage@14015 348 When the load operation completes,
jackalmage@14015 349 successfully or not,
jackalmage@14126 350 queue a task to run the following steps synchronously:
jackalmage@9018 351
jackalmage@14015 352 <ol>
jackalmage@14015 353 <li>
jackalmage@14015 354 If the attempt to load fails,
jackalmage@14551 355 reject <var>font face's</var> {{[[FontStatusPromise]]}} with
jackalmage@14065 356 a DOMException whose name is "NetworkError"
jackalmage@14551 357 and set <var>font face's</var> {{FontFace/status}} attribute to "error".
jackalmage@14015 358
jackalmage@15424 359 For each {{FontFaceSet}} <var>font face</var> is in:
jackalmage@15424 360 1. Add <var>font face</var> to the {{FontFaceSet}}’s {{[[FailedFonts]]}} list.
jackalmage@15424 361 2. Remove <var>font face</var> from the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list.
jackalmage@15424 362 If <var>font</var> was the last item in that list
jackalmage@15424 363 (and so the list is now empty),
jackalmage@15424 364 <a>switch the FontFaceSet to loaded</a>.
jackalmage@15424 365
jackalmage@14015 366 <li>
jackalmage@14015 367 Otherwise,
jackalmage@14015 368 <var>font face</var> now represents the loaded font;
jackalmage@14551 369 fulfill <var>font face's</var> {{[[FontStatusPromise]]}} with <var>font face</var>
jackalmage@14551 370 and set <var>font face's</var> {{FontFace/status}} attribute to "loaded".
jackalmage@15424 371
jackalmage@15424 372 For each {{FontFaceSet}} <var>font face</var> is in:
jackalmage@15424 373 1. Add <var>font face</var> to the {{FontFaceSet}}’s {{[[LoadedFonts]]}} list.
jackalmage@15424 374 2. Remove <var>font face</var> from the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list.
jackalmage@15424 375 If <var>font</var> was the last item in that list
jackalmage@15424 376 (and so the list is now empty),
jackalmage@15424 377 <a>switch the FontFaceSet to loaded</a>.
jackalmage@14015 378 </ol>
jackalmage@9019 379 </ol>
jackalmage@9019 380
jackalmage@9030 381 User agents can initiate font loads on their own,
jackalmage@9030 382 whenever they determine that a given font face is necessary to render something on the page.
jackalmage@9030 383 When this happens,
jackalmage@14551 384 they must act as if they had called the corresponding {{FontFace}}’s {{FontFace/load()}} method described here.
jackalmage@9030 385
jackalmage@14579 386 Note: Some UAs utilize a "font cache"
jackalmage@14579 387 which avoids having to download the same font multiple times
jackalmage@14579 388 on a page or on multiple pages within the same origin.
jackalmage@14579 389 Multiple {{FontFace}} objects can be mapped to the same entry in the font cache,
jackalmage@14579 390 which means that a {{FontFace}} object might start loading unexpectedly,
jackalmage@14579 391 even if it's not in a {{FontFaceSet}},
jackalmage@14579 392 because some other {{FontFace}} object pointing to the same font data
jackalmage@14579 393 (perhaps on a different page entirely!)
jackalmage@14579 394 has been loaded.
jackalmage@14579 395
jackalmage@9045 396 <h3 id='font-face-css-connection'>
jackalmage@9047 397 Interaction with CSS’s ''@font-face'' Rule</h3>
jackalmage@9024 398
jackalmage@14551 399 A CSS ''@font-face'' rule automatically defines a corresponding {{FontFace}} object,
jackalmage@10099 400 which is automatically placed in the document's <a>font source</a>
jackalmage@10099 401 when the rule is parsed.
jackalmage@14551 402 This {{FontFace}} object is <dfn>CSS-connected</dfn>.
jackalmage@9024 403
jackalmage@14551 404 The {{FontFace}} object corresponding to a ''@font-face'' rule
jackalmage@14551 405 has its {{FontFace/family}}, {{FontFace/style}}, {{FontFace/weight}}, {{FontFace/stretch}}, {{FontFace/unicodeRange}}, {{FontFace/variant}}, and {{FontFace/featureSettings}} attributes
jackalmage@10011 406 set to the same value as the corresponding descriptors in the ''@font-face'' rule.
jackalmage@9024 407 There is a two-way connection between the two:
jackalmage@14551 408 any change made to a ''@font-face'' descriptor is immediately reflected in the corresponding {{FontFace}} attribute,
jackalmage@9024 409 and vice versa.
jackalmage@9024 410
jackalmage@16171 411 Issue: When a FontFace is transferred between documents, it's no longer CSS-connected.
jackalmage@16171 412
jackalmage@14551 413 The internal {{[[Urls]]}} slot of the {{FontFace}} object is set to the value of the ''@font-face'' rule's 'src' descriptor,
jackalmage@9024 414 and reflects any changes made to the 'src' descriptor.
jackalmage@9024 415
jackalmage@14551 416 Otherwise, a {{FontFace}} object created by a CSS ''@font-face'' rule is identical to one created manually.
jackalmage@9024 417
jackalmage@14551 418 If a ''@font-face'' rule is removed from the document, its corresponding {{FontFace}} object is no longer <a>CSS-connected</a>.
jackalmage@10011 419 The connection is not restorable by any means
jackalmage@14551 420 (but adding the ''@font-face'' back to the stylesheet will create a brand new {{FontFace}} object which <em>is</em> <a>CSS-connected</a>).
jackalmage@9104 421
jackalmage@14612 422 If a ''@font-face'' rule has its '@font-face/src' descriptor changed to a new value,
jackalmage@14612 423 the original connected {{FontFace}} object must stop being <a>CSS-connected</a>.
jackalmage@14612 424 A new {{FontFace}} reflecting its new '@font-face/src' must be created
jackalmage@14612 425 and <a>CSS-connected</a> to the ''@font-face''.
jackalmage@14613 426 (This will also remove the old and add the new {{FontFace}} objects from any <a>font sources</a> they appear in.)
jackalmage@14612 427
jackalmage@14019 428 <!--
jackalmage@14019 429 ████████ ███████ ██ ██ ████████ ████████ ███ ██████ ████████ ██████ ████████ ████████
jackalmage@14020 430 ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 431 ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 432 ██████ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██ ██████ ██████ ██████ ██
jackalmage@14020 433 ██ ██ ██ ██ ████ ██ ██ █████████ ██ ██ ██ ██ ██
jackalmage@14020 434 ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 435 ██ ███████ ██ ██ ██ ██ ██ ██ ██████ ████████ ██████ ████████ ██
jackalmage@14019 436 -->
jackalmage@9045 437
jackalmage@9045 438 <h2 id="FontFaceSet-interface">
jackalmage@9045 439 The <code>FontFaceSet</code> Interface</h2>
jackalmage@8992 440
jackalmage@8992 441 <pre class="idl">
jackalmage@14125 442 dictionary FontFaceSetLoadEventInit : EventInit {
jackalmage@14093 443 sequence&lt;FontFace> fontfaces = [];
jackalmage@8992 444 };
jackalmage@8992 445
jackalmage@14125 446 [Constructor(DOMString type, optional FontFaceSetLoadEventInit eventInitDict),
jackalmage@14124 447 Exposed=Window,Worker]
jackalmage@14125 448 interface FontFaceSetLoadEvent : Event {
jackalmage@14093 449 readonly attribute sequence&lt;FontFace> fontfaces;
jackalmage@9071 450 };
jackalmage@8992 451
jackalmage@9024 452 enum FontFaceSetLoadStatus { "loading", "loaded" };
jackalmage@9024 453
jackalmage@14117 454 callback ForEachCallback = void (FontFace font, long index, FontFaceSet self);
jackalmage@14117 455
jackalmage@14154 456 [Exposed=Window,Worker,
jackalmage@14154 457 Constructor(sequence<FontFace> initialFaces)]
jackalmage@14123 458 interface FontFaceSet : EventTarget {
jackalmage@14756 459 // FontFaceSet is Set-like!
jackalmage@14756 460 setlike&lt;FontFace>;
jackalmage@15424 461 FontFaceSet add(FontFace font);
jackalmage@15424 462 boolean delete(FontFace font);
jackalmage@15424 463 void clear();
jackalmage@8992 464
jackalmage@14756 465 // events for when loading state changes
jackalmage@9064 466 attribute EventHandler onloading;
jackalmage@9064 467 attribute EventHandler onloadingdone;
jackalmage@9064 468 attribute EventHandler onloadingerror;
jackalmage@8992 469
jackalmage@9033 470 // check and start loads if appropriate
jackalmage@9003 471 // and fulfill promise when all loads complete
jackalmage@13945 472 Promise&lt;sequence&lt;FontFace>> load(DOMString font, optional DOMString text = " ");
jackalmage@8992 473
jackalmage@8992 474 // return whether all fonts in the fontlist are loaded
jackalmage@8992 475 // (does not initiate load if not available)
jackalmage@9064 476 boolean check(DOMString font, optional DOMString text = " ");
jackalmage@8992 477
jackalmage@9003 478 // async notification that font loading and layout operations are done
jackalmage@14063 479 readonly attribute Promise&lt;FontFaceSet> ready;
jackalmage@8992 480
jackalmage@9907 481 // loading state, "loading" while one or more fonts loading, "loaded" otherwise
jackalmage@14079 482 readonly attribute FontFaceSetLoadStatus status;
jackalmage@8992 483 };
jackalmage@8992 484 </pre>
jackalmage@8992 485
jackalmage@14842 486 {{FontFaceSet/load()}}
jackalmage@14842 487
jackalmage@14828 488 <div dfn-for="FontFaceSet">
jackalmage@14802 489 : <dfn attribute>ready</dfn>
jackalmage@14802 490 :: This attribute reflects the {{FontFaceSet}}'s {{[[ReadyPromise]]}} slot.
jackalmage@14063 491
jackalmage@14580 492 See [[#font-face-set-ready]] for more details on this {{Promise}} and its use.
jackalmage@14117 493
jackalmage@15132 494 : <dfn constructor lt="FontFaceSet()">FontFaceSet</dfn>(sequence&lt;{{FontFace}}> <dfn argument for="FontFaceSet/FontFaceSet()">initialFaces</dfn>)
jackalmage@14802 495 :: The {{FontFaceSet}} constructor, when called,
jackalmage@14756 496 must iterate its {{initialFaces}} argument
jackalmage@14756 497 and add each value to its <a>set entries</a>.
jackalmage@14154 498
jackalmage@14802 499 : <dfn dfn>iteration order</dfn>
jackalmage@14802 500 :: When iterated over,
jackalmage@14756 501 all <a>CSS-connected</a> {{FontFace}} objects must come first,
jackalmage@14756 502 in document order of their connected ''@font-face'' rules,
jackalmage@14756 503 followed by the non-<a>CSS-connected</a> {{FontFace}} objects,
jackalmage@14756 504 in insertion order.
jackalmage@14168 505
jackalmage@14802 506 : <dfn dfn>set entries</dfn>
jackalmage@14802 507 :: If a {{FontFaceSet}} is a <a>font source</a>,
jackalmage@14756 508 its <a spec=webidl for>set entries</a> are initialized as specified in [[#document-font-face-set]].
jackalmage@14142 509
jackalmage@15424 510 Otherwise, its <a spec=webidl>set entries</a> are initially empty.
jackalmage@15424 511
jackalmage@15424 512 : <dfn method>add(font)</dfn>
jackalmage@15424 513 ::
jackalmage@15424 514 When the {{add()}} method is called,
jackalmage@15424 515 execute the following steps:
jackalmage@15424 516
jackalmage@15424 517 1. If <var>font</var> is already in the {{FontFaceSet}}’s <a>set entries</a>,
jackalmage@15424 518 skip to the last step of this algorithm immediately.
jackalmage@15424 519 2. If <var>font</var> is <a>CSS-connected</a>,
jackalmage@15424 520 throw an {{InvalidModificationError}} exception
jackalmage@15424 521 and exit this algorithm immediately.
jackalmage@15424 522 3. Add the <var>font</var> argument to the {{FontFaceSet}}’s <a>set entries</a>.
jackalmage@15424 523 2. If <var>font</var>’s {{FontFace/status}} attribute is "loading":
jackalmage@15424 524 1. If the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list is empty,
jackalmage@15424 525 <a>switch the FontFaceSet to loading</a>.
jackalmage@15424 526 2. Append <var>font</var> to the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list.
jackalmage@15424 527 3. Return the {{FontFaceSet}}.
jackalmage@15424 528
jackalmage@15424 529 : <dfn method>delete(font)</dfn>
jackalmage@15424 530 ::
jackalmage@15424 531 When the {{delete()}} method is called,
jackalmage@15424 532 execute the following steps:
jackalmage@15424 533
jackalmage@15424 534 1. If <var>font</var> is <a>CSS-connected</a>,
jackalmage@15424 535 return <code class='lang-javascript'>false</code>
jackalmage@15424 536 and exit this algorithm immediately.
jackalmage@15424 537 2. Let <var>deleted</var> be the result of removing <var>font</var> from the {{FontFaceSet}}’s <a>set entries</a>.
jackalmage@15424 538 3. If <var>font</var> is present in the {{FontFaceSet}}’s {{[[LoadedFonts]]}}, or {{[[FailedFonts]]}} lists,
jackalmage@15424 539 remove it.
jackalmage@15424 540 4. If <var>font</var> is present in the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list,
jackalmage@15424 541 remove it.
jackalmage@15424 542 If <var>font</var> was the last item in that list
jackalmage@15424 543 (and so the list is now empty),
jackalmage@15424 544 <a>switch the FontFaceSet to loaded</a>.
jackalmage@15424 545 5. Return <var>deleted</var>.
jackalmage@15424 546
jackalmage@15424 547 : <dfn method>clear()</dfn>
jackalmage@15424 548 ::
jackalmage@15424 549 When the {{clear()}} method is called,
jackalmage@15424 550 execute the following steps:
jackalmage@15424 551
jackalmage@15424 552 1. Remove all items from the {{FontFaceSet}}’s <a>set entries</a>,
jackalmage@15424 553 its {{[[LoadedFonts]]}} list,
jackalmage@15424 554 and its {{[[FailedFonts]]}} list.
jackalmage@15424 555 2. If the {{FontFaceSet}}’s {{[[LoadingFonts]]}} list is non-empty,
jackalmage@15424 556 remove all items from it,
jackalmage@15424 557 then <a>switch the FontFaceSet to loaded</a>.
jackalmage@14802 558 </div>
jackalmage@13945 559
jackalmage@14551 560 {{FontFaceSet}} objects also have internal
jackalmage@14551 561 <dfn attribute for=FontFaceSet>\[[LoadingFonts]]</dfn>,
jackalmage@14551 562 <dfn attribute for=FontFaceSet>\[[LoadedFonts]]</dfn>,
jackalmage@14551 563 and <dfn attribute for=FontFaceSet>\[[FailedFonts]]</dfn> slots,
jackalmage@14756 564 all of which are initialized to empty lists,
jackalmage@14756 565 and a <dfn attribute for=FontFaceSet>\[[ReadyPromise]]</dfn> slot,
jackalmage@14756 566 which is initialized to a fresh pending {{Promise}}.
jackalmage@9029 567
jackalmage@9495 568 Because font families are loaded only when they are used,
jackalmage@9495 569 content sometimes needs to understand when the loading of fonts occurs.
jackalmage@9495 570 Authors can use the events and methods defined here to allow greater control over actions
jackalmage@9025 571 that are dependent upon the availability of specific fonts.
jackalmage@8992 572
jackalmage@15424 573 A {{FontFaceSet}} is <dfn export for="FontFaceSet">pending on the environment</dfn> if any of the following are true:
jackalmage@14581 574
jackalmage@15424 575 * the document is still loading
jackalmage@15424 576 * the document has pending stylesheet requests
jackalmage@16461 577 * the document has pending layout operations which might cause the user agent to request a font,
jackalmage@16461 578 or which depend on recently-loaded fonts
jackalmage@16461 579
jackalmage@16461 580 Note: The idea is that once a {{FontFaceSet}} stops being <a>pending on the environment</a>,
jackalmage@16461 581 as long as nothing further changes the document,
jackalmage@16461 582 an author can depend on sizes/positions of things being "correct" when measured.
jackalmage@16461 583 If the above conditions do not fully capture this guarantee,
jackalmage@16461 584 they need to be amended to do so.
jackalmage@14118 585
jackalmage@14019 586 <!--
jackalmage@14020 587 ████████ ██ ██ ████████ ██ ██ ████████ ██████
jackalmage@14019 588 ██ ██ ██ ██ ███ ██ ██ ██ ██
jackalmage@14020 589 ██ ██ ██ ██ ████ ██ ██ ██
jackalmage@14020 590 ██████ ██ ██ ██████ ██ ██ ██ ██ ██████
jackalmage@14019 591 ██ ██ ██ ██ ██ ████ ██ ██
jackalmage@14019 592 ██ ██ ██ ██ ██ ███ ██ ██ ██
jackalmage@14020 593 ████████ ███ ████████ ██ ██ ██ ██████
jackalmage@14019 594 -->
jackalmage@9135 595
jackalmage@9045 596 <h3 id='FontFaceSet-events'>
jackalmage@9045 597 Events</h3>
jackalmage@8992 598
jackalmage@9029 599 Font load events make it easy to respond to the font-loading behavior of the entire document,
jackalmage@9029 600 rather than having to listen to each font specifically.
jackalmage@9029 601 The <dfn event for="FontFaceSet">loading</dfn> event
jackalmage@9029 602 fires when the document begins loading fonts,
jackalmage@9029 603 while the <dfn event for="FontFaceSet">loadingdone</dfn>
jackalmage@9029 604 and <dfn event for="FontFaceSet">loadingerror</dfn> events
jackalmage@9029 605 fire when the document is done loading fonts,
jackalmage@9029 606 containing the fonts that successfully loaded
jackalmage@9029 607 or failed to load,
jackalmage@9029 608 respectively.
jackalmage@8992 609
jackalmage@8992 610 The following are the event handlers (and their corresponding event handler event types)
jackalmage@9018 611 that must be supported by <code>FontFaceSet</code> objects as IDL attributes:
jackalmage@8992 612
jackalmage@8992 613 <table class="data" id="eventhandlers">
jackalmage@8992 614 <thead>
jackalmage@8992 615 <tr>
jackalmage@8992 616 <th>Event handler
jackalmage@8992 617 <th>Event handler event type
jackalmage@8992 618 <tbody>
jackalmage@8992 619 <tr>
jackalmage@14551 620 <th>{{onloading}}
jackalmage@14551 621 <td>{{loading}}
jackalmage@8992 622 <tr>
jackalmage@14551 623 <th>{{onloadingdone}}
jackalmage@14551 624 <td>{{loadingdone}}
jackalmage@8992 625 <tr>
jackalmage@14551 626 <th>{{onloadingerror}}
jackalmage@14551 627 <td>{{loadingerror}}
jackalmage@8992 628 </table>
jackalmage@8992 629
jackalmage@9495 630 To <dfn>fire a font load event</dfn> named <var>e</var>
jackalmage@14551 631 at a {{FontFaceSet}} <var>target</var>
jackalmage@9029 632 with optional <var>font faces</var>
jackalmage@8992 633 means to
jackalmage@8992 634 <a href="http://www.w3.org/TR/html5/webappapis.html#event-firing">fire a simple event</a> named <var>e</var>
jackalmage@14551 635 using the {{FontFaceSetLoadEvent}} interface that also meets these conditions:
jackalmage@8992 636
jackalmage@8992 637 <ol>
jackalmage@8992 638 <li>
jackalmage@15300 639 The {{FontFaceSetLoadEvent/fontfaces}} attribute is initialized to
jackalmage@15300 640 the result of filtering <var>font faces</var> to only contain {{FontFace}} objects contained in <var>target</var>.
jackalmage@8992 641 </ol>
jackalmage@8992 642
jackalmage@15424 643 When asked to <dfn>switch the FontFaceSet to loading</dfn> for a given {{FontFaceSet}},
jackalmage@9495 644 the user agent must run the following steps:
jackalmage@8992 645
jackalmage@8992 646 <ol>
jackalmage@8992 647 <li>
jackalmage@15424 648 Let <var>font face set</var> be the given {{FontFaceSet}}.
jackalmage@8992 649
jackalmage@8992 650 <li>
jackalmage@14551 651 Set the {{FontFaceSet/status}} attribute of <var>font face set</var> to "loading".
jackalmage@8992 652
jackalmage@8992 653 <li>
jackalmage@15972 654 If <var>font face set's</var> {{[[ReadyPromise]]}} slot currently holds a fulfilled promise,
jackalmage@15972 655 replace it with a fresh pending promise.
jackalmage@14063 656
jackalmage@14063 657 <li>
jackalmage@15972 658 Queue a task to <a>fire a font load event</a> named {{loading}} at <var>font face set</var>.
jackalmage@8992 659 </ol>
jackalmage@8992 660
jackalmage@15424 661 When asked to <dfn>switch the FontFaceSet to loaded</dfn> for a given {{FontFaceSet}},
jackalmage@9029 662 the user agent must run the following steps:
jackalmage@8992 663
jackalmage@15424 664 1. Let <var>font face set</var> be the given {{FontFaceSet}}.
jackalmage@8992 665
jackalmage@15424 666 2. If <var>font face set</var> is <a>pending on the environment</a>,
jackalmage@15424 667 mark it as <dfn export for=FontFaceSet>stuck on the environment</dfn>,
jackalmage@15424 668 and exit this algorithm.
jackalmage@8992 669
jackalmage@15424 670 3. Set <var>font face set’s</var> {{FontFaceSet/status}} attribute to "loaded".
jackalmage@8992 671
jackalmage@15972 672 4. Fulfill <var>font face set's</var> {{[[ReadyPromise]]}} attribute's value with <var>font face set</var>.
jackalmage@14581 673
jackalmage@15972 674 5. Queue a task to perform the following steps synchronously:
jackalmage@8992 675
jackalmage@15973 676 1. Let <var>loaded fonts</var> be the (possibly empty) contents of <var>font face set's</var> {{[[LoadedFonts]]}} slot.
jackalmage@15973 677 2. Let <var>failed fonts</var> be the (possibly empty) contents of <var>font face set's</var> {{[[FailedFonts]]}} slot.
jackalmage@15973 678 3. Reset the {{[[LoadedFonts]]}} and {{[[FailedFonts]]}} slots to empty lists.
jackalmage@15973 679 4. <a>Fire a font load event</a> named {{loadingdone}} at <var>font face set</var>
jackalmage@15973 680 with <var>loaded fonts</var>.
jackalmage@15973 681 5. If <var>font face set's</var> <var>failed fonts</var> is non-empty,
jackalmage@15972 682 <a>fire a font load event</a> named {{loadingerror}} at <var>font face set</var>
jackalmage@15973 683 with <var>failed fonts</var>.
jackalmage@8992 684
jackalmage@15424 685 Whenever a {{FontFaceSet}} goes from <a>pending on the environment</a> to not <a>pending on the environment</a>,
jackalmage@15424 686 the user agent must run the following steps:
jackalmage@9029 687
jackalmage@15424 688 1. If the {{FontFaceSet}} is <a>stuck on the environment</a> and its {{[[LoadingFonts]]}} list is empty,
jackalmage@15424 689 <a>switch the FontFaceSet to loaded</a>.
jackalmage@15424 690
jackalmage@15424 691 2. If the {{FontFaceSet}} is <a>stuck on the environment</a>,
jackalmage@15424 692 unmark it as such.
jackalmage@8992 693
jackalmage@9033 694
jackalmage@9904 695 If asked to <dfn export>find the matching font faces</dfn>
jackalmage@9904 696 from a FontFaceSet <var>source</var>,
jackalmage@9904 697 for a given font string <var>font</var>
jackalmage@14062 698 optionally some sample text <var>text</var>,
jackalmage@14062 699 and optionally an <var>allow system fonts</var> flag,
jackalmage@9904 700 run the following steps:
jackalmage@9033 701
jackalmage@9033 702 <ol>
jackalmage@9033 703 <li>
jackalmage@9904 704 Parse <var>font</var>
jackalmage@9033 705 using the CSS value syntax of the 'font' property.
jackalmage@9904 706 If a syntax error occurs,
jackalmage@9904 707 return a syntax error.
jackalmage@9033 708
jackalmage@15410 709 If the parsed value is a <a>CSS-wide keyword</a>,
jackalmage@15410 710 return a syntax error.
jackalmage@15410 711
jackalmage@15410 712 Absolutize all relative lengths against the initial values of the corresponding properties.
jackalmage@15422 713 (For example, a relative font weight like ''bolder'' is evaluated against the initial value ''font-weight/normal''.)
jackalmage@15410 714
jackalmage@9033 715 <li>
jackalmage@9904 716 If <var>text</var> was not explicitly provided,
jackalmage@9904 717 let it be a string containing a single space character (U+0020 SPACE).
jackalmage@9033 718
jackalmage@9033 719 <li>
jackalmage@9904 720 Let <var>font family list</var> be the list of font families parsed from <var>font</var>,
jackalmage@9904 721 and <var>font style</var> be the other font style attributes parsed from <var>font</var>.
jackalmage@9904 722
jackalmage@9904 723 <li>
jackalmage@9904 724 Let <var>available font faces</var> be the font faces within <var>source</var>.
jackalmage@14062 725 If the <var>allow system fonts</var> flag is specified,
jackalmage@14062 726 add all system fonts to <var>available font faces</var>.
jackalmage@9904 727
jackalmage@9904 728 <li>
jackalmage@9904 729 Let <var>matched font faces</var> initially be an empty list.
jackalmage@9033 730
jackalmage@9033 731 <li>
jackalmage@9495 732 For each family in <var>font family list</var>,
jackalmage@9904 733 use the font matching rules to select the font faces from <var>available font faces</var>
jackalmage@9904 734 that match the <var>font style</var>,
jackalmage@9904 735 and add them to <var>matched font faces</var>.
jackalmage@14551 736 The use of the {{FontFace/unicodeRange}} attribute means that this may be more than just a single font face.
jackalmage@9033 737
jackalmage@9033 738 <li>
jackalmage@15665 739 If <var>matched font faces</var> is empty,
jackalmage@15665 740 set the <var>found faces</var> flag to false.
jackalmage@15665 741 Otherwise, set it to true.
jackalmage@15665 742
jackalmage@15665 743 <li>
jackalmage@9904 744 For each font face in <var>matched font faces</var>,
jackalmage@9904 745 if its defined 'unicode-range' does not include the codepoint of at least one character in <var>text</var>,
jackalmage@9904 746 remove it from the list.
jackalmage@9033 747
jackalmage@9033 748 <li>
jackalmage@15665 749 Return <var>matched font faces</var> and the <var>found faces</var> flag.
jackalmage@9498 750 </ol>
jackalmage@9033 751
jackalmage@14019 752 <!--
jackalmage@14020 753 ██ ███████ ███ ████████ ███ ███
jackalmage@14020 754 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 755 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 756 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 757 ██ ██ ██ █████████ ██ ██ ██ ██
jackalmage@14020 758 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 759 ████████ ███████ ██ ██ ████████ ███ ███
jackalmage@14019 760 -->
jackalmage@9033 761
jackalmage@9045 762 <h3 id='font-face-set-load'>
jackalmage@9045 763 The <code>load()</code> method</h3>
jackalmage@8992 764
jackalmage@14842 765 The {{FontFaceSet/load()}} method of {{FontFaceSet}} will determine whether all fonts in the given font list
jackalmage@9019 766 have been loaded and are available.
jackalmage@9019 767 If any fonts are downloadable fonts and have not already been loaded,
jackalmage@9019 768 the user agent will initiate the load of each of these fonts.
jackalmage@9019 769 It returns a Promise,
jackalmage@9019 770 which is fulfilled when all of the fonts are loaded and ready to be used,
jackalmage@9019 771 or rejected if any font failed to load properly.
jackalmage@8992 772
jackalmage@15132 773 When the <dfn method for="FontFaceSet" lt="load(font, text)">load</dfn>(
jackalmage@14842 774 <span dfn-for="FontFaceSet/load(font, text)">
jackalmage@14842 775 <dfn argument>font</dfn>,
jackalmage@14842 776 <dfn argument>text</dfn>
jackalmage@14842 777 </span>
jackalmage@14842 778 ) method is called,
jackalmage@9019 779 execute these steps:
jackalmage@8992 780
jackalmage@9904 781 <ol>
jackalmage@8992 782 <li>
jackalmage@14551 783 Let <var>font face set</var> be the {{FontFaceSet}} object this method was called on.
jackalmage@9062 784 Let <var>promise</var> be a newly-created promise object.
jackalmage@9062 785
jackalmage@9062 786 <li>
jackalmage@9062 787 Return <var>promise</var>.
jackalmage@9062 788 Complete the rest of these steps asynchronously.
jackalmage@9002 789
jackalmage@9002 790 <li>
jackalmage@9904 791 <a>Find the matching font faces</a> from <var>font face set</var>
jackalmage@14551 792 using the {{FontFaceSet/load()/font}} and {{FontFaceSet/load()/text}} arguments passed to the function,
jackalmage@15665 793 and let <var>font face list</var> be the return value
jackalmage@15665 794 (ignoring the <var>found faces</var> flag).
jackalmage@9904 795 If a syntax error was returned,
jackalmage@9904 796 reject <var>promise</var> with a SyntaxError exception
jackalmage@9904 797 and terminate these steps.
jackalmage@8992 798
jackalmage@8992 799 <li>
jackalmage@14126 800 Queue a task to run the following steps synchronously:
jackalmage@8992 801
jackalmage@14015 802 <ol>
jackalmage@14015 803 <li>
jackalmage@14015 804 For all of the font faces in the <var>font face list</var>,
jackalmage@14551 805 call their {{FontFace/load()}} method.
jackalmage@14015 806
jackalmage@14015 807 <li>
jackalmage@14015 808 Resolve <var>promise</var> with the result of
jackalmage@14551 809 waiting for all of the {{[[FontStatusPromise]]}}s of each font face in the <var>font face list</var>, in order.
jackalmage@14015 810 </ol>
jackalmage@8992 811 </ol>
jackalmage@8992 812
jackalmage@14019 813 <!--
jackalmage@14020 814 ██████ ██ ██ ████████ ██████ ██ ██ ███ ███
jackalmage@14020 815 ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 816 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 817 ██ █████████ ██████ ██ █████ ██ ██
jackalmage@14019 818 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 819 ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 820 ██████ ██ ██ ████████ ██████ ██ ██ ███ ███
jackalmage@14019 821 -->
jackalmage@14019 822
jackalmage@9045 823 <h3 id='font-face-set-check'>
jackalmage@9045 824 The <code>check()</code> method</h3>
jackalmage@9019 825
jackalmage@14842 826 The {{FontFaceSet/check()}} method of {{FontFaceSet}} will determine whether all fonts in the given font list
jackalmage@9019 827 have been loaded and are available.
jackalmage@9019 828 If all fonts are available,
jackalmage@9019 829 it returns true;
jackalmage@9019 830 otherwise, it returns false.
jackalmage@9003 831
jackalmage@15132 832 When the <dfn method for="FontFaceSet" lt="check(font, text)|check(font)">check</dfn>(
jackalmage@14842 833 <span data-dfn-for="FontFaceSet/check(font, text)"><dfn argument>font</dfn>, <dfn argument>text</dfn>)</span>
jackalmage@14842 834 method is called,
jackalmage@9025 835 execute these steps:
jackalmage@8992 836
jackalmage@8992 837 <ol>
jackalmage@8992 838 <li>
jackalmage@14551 839 Let <var>font face set</var> be the {{FontFaceSet}} object this method was called on.
jackalmage@8992 840
jackalmage@8992 841 <li>
jackalmage@9904 842 <a>Find the matching font faces</a> from <var>font face set</var>
jackalmage@14551 843 using the {{FontFaceSet/check()/font}} and {{FontFaceSet/check()/text}} arguments passed to the function,
jackalmage@14062 844 and including system fonts,
jackalmage@15665 845 and let <var>font face list</var> be the returned list of font faces,
jackalmage@15665 846 and <var>found faces</var> be the returned <var>found faces</var> flag.
jackalmage@9904 847 If a syntax error was returned,
jackalmage@10068 848 throw a SyntaxError exception
jackalmage@9904 849 and terminate these steps.
jackalmage@8992 850
jackalmage@8992 851 <li>
jackalmage@15665 852 If <var>found faces</var> is false,
jackalmage@15665 853 throw an XXX error
jackalmage@15665 854 and abort this algorithm.
jackalmage@8992 855
jackalmage@8992 856 <li>
jackalmage@15665 857 If <var>font face list</var> is empty,
jackalmage@15665 858 or all fonts in the <var>font face list</var> either have a {{FontFace/status}} attribute of "loaded" or are system fonts,
jackalmage@9495 859 return <code>true</code>.
jackalmage@9033 860 Otherwise, return <code>false</code>.
jackalmage@8992 861 </ol>
jackalmage@8992 862
jackalmage@14019 863 <!--
jackalmage@14063 864 ████████ ████████ ███ ████████ ██ ██
jackalmage@14063 865 ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14063 866 ██ ██ ██ ██ ██ ██ ██ ████
jackalmage@14063 867 ████████ ██████ ██ ██ ██ ██ ██
jackalmage@14063 868 ██ ██ ██ █████████ ██ ██ ██
jackalmage@14063 869 ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14063 870 ██ ██ ████████ ██ ██ ████████ ██
jackalmage@14019 871 -->
jackalmage@14019 872
jackalmage@9045 873 <h3 id='font-face-set-ready'>
jackalmage@14063 874 The <code>ready</code> attribute</h3>
jackalmage@8992 875
jackalmage@9495 876 Because the number of fonts loaded depends on the how many fonts are used for a given piece of text,
jackalmage@9003 877 in some cases whether fonts need to be loaded or not may not be known.
jackalmage@14551 878 The {{FontFaceSet/ready}} attribute contains a {{Promise}} which is resolved when the document is done loading fonts,
jackalmage@9495 879 which provides a way for authors to avoid having to keep track of which fonts have or haven't been loaded
jackalmage@9003 880 before examining content which may be affected by loading fonts.
jackalmage@8992 881
jackalmage@9063 882 Note: Authors should note that a given <var>ready promise</var> is only fulfilled once,
jackalmage@9003 883 but further fonts may be loaded after it fulfills.
jackalmage@14551 884 This is similar to listening for a {{loadingdone}} event to fire,
jackalmage@14551 885 but the callbacks passed to the {{FontFaceSet/ready}} promise will <strong>always</strong> get called,
jackalmage@9495 886 even when no font loads occur because the fonts in question are already loaded.
jackalmage@9495 887 It's a simple, easy way to synchronize code to font loads
jackalmage@9003 888 without the need to keep track of what fonts are needed and precisely when they load.
jackalmage@8992 889
jackalmage@9063 890 Note: Note that the user agent may need to iterate over multiple font loads before the <var>ready promise</var> is fulfilled.
jackalmage@9495 891 This can occur with font fallback situations,
jackalmage@9495 892 where one font in the fontlist is loaded
jackalmage@9495 893 but doesn't contain a particular glyph
jackalmage@9495 894 and other fonts in the fontlist need to be loaded.
jackalmage@9495 895 The <var>ready promise</var> is only fulfilled after layout operations complete
jackalmage@9003 896 and no additional font loads are necessary.
jackalmage@8992 897
jackalmage@14551 898 Note: Note that the Promise returned by this {{FontFaceSet/ready}} attribute is only ever fulfilled,
jackalmage@9034 899 never rejected,
jackalmage@14551 900 unlike the Promise returned by the {{FontFace}} {{FontFace/load()}} method.
jackalmage@9034 901
jackalmage@9137 902 <h3 id='font-face-set-css'>
jackalmage@9137 903 Interaction with CSS Font Loading and Matching</h3>
jackalmage@9137 904
jackalmage@14762 905 When the font matching algorithm in [[CSS-FONTS-3]] is run automatically by the user-agent,
jackalmage@9137 906 the set of font faces it matches over must be precisely the set of fonts in the <a>font source</a> for the document,
jackalmage@9137 907 plus any local font faces.
jackalmage@9137 908
jackalmage@9137 909 When a user-agent needs to load a font face,
jackalmage@14551 910 it must do so by calling the {{FontFace/load()}} method
jackalmage@14551 911 of the corresponding {{FontFace}} object.
jackalmage@9137 912
jackalmage@9137 913 (This means it must run the same algorithm,
jackalmage@9137 914 not literally call the value currently stored in the <code>load</code> property of the object.)
jackalmage@9137 915
jackalmage@13481 916 <div class="example">
jackalmage@14551 917 Fonts are available when they are added to a {{FontFaceSet}}.
jackalmage@13481 918 Adding a new ''@font-face'' rule to a stylesheet
jackalmage@14551 919 also adds a new {{FontFace}} to the {{FontFaceSet}} of the {{Document}} object.
jackalmage@13481 920
jackalmage@13481 921 Adding a new ''@font-face'' rule:
jackalmage@13481 922
jackalmage@13481 923 <pre>
jackalmage@13481 924 document.styleSheets[0].insertRule(
jackalmage@13481 925 "@font-face { font-family: newfont; src: url(newfont.woff); }", 0);
jackalmage@13481 926 document.body.style.fontFamily = "newfont, serif";
jackalmage@13481 927 </pre>
jackalmage@13481 928
jackalmage@14551 929 Constructing a new {{FontFace}} object and adding it to <code>document.fonts</code>:
jackalmage@13481 930
jackalmage@13481 931 <pre>
jackalmage@13481 932 var f = new FontFace("newfont", "url(newfont.woff)");
jackalmage@13481 933 document.fonts.add(f);
jackalmage@13481 934 document.body.style.fontFamily = "newfont, serif";
jackalmage@13481 935 </pre>
jackalmage@13481 936
jackalmage@13481 937 In both cases, the loading of the font resource “newfont.woff” will be initiated by the layout engine,
jackalmage@13481 938 just as other ''@font-face'' rule fonts are loaded.
jackalmage@13481 939
jackalmage@13481 940 Omitting the addition to <code>document.fonts</code> means the font would never be loaded
jackalmage@13481 941 and text would be displayed in the default serif font:
jackalmage@13481 942
jackalmage@13481 943 <pre>
jackalmage@13481 944 var f = new FontFace("newfont", "url(newtest.woff)", {});
jackalmage@13481 945
jackalmage@14551 946 /* new {{FontFace}} not added to {{FontFaceSet}},
jackalmage@13481 947 so the 'font-family' property can't see it,
jackalmage@13481 948 and serif will be used instead */
jackalmage@13481 949 document.body.style.fontFamily = "newfont, serif";
jackalmage@13481 950 </pre>
jackalmage@13481 951
jackalmage@13481 952 To explicitly preload a font before using it,
jackalmage@14551 953 authors can defer the addition of a new {{FontFace}} to a {{FontFaceSet}} until the load has completed:
jackalmage@13481 954
jackalmage@13481 955 <pre>
jackalmage@13481 956 var f = new FontFace("newfont", "url(newfont.woff)", {});
jackalmage@13482 957 f.load().then(function (loadedFace) {
jackalmage@13482 958 document.fonts.add(loadedFace);
jackalmage@13481 959 document.body.style.fontFamily = "newfont, serif";
jackalmage@13481 960 });
jackalmage@13481 961 </pre>
jackalmage@13481 962
jackalmage@13481 963 In this case, the font resource “newfont.woff” is first downloaded.
jackalmage@13481 964 Once the download completes,
jackalmage@14551 965 the font is added to the document's {{FontFaceSet}},
jackalmage@13481 966 the body font is changed,
jackalmage@13481 967 and the layout engine uses the new font resource.
jackalmage@13481 968 </div>
jackalmage@13481 969
jackalmage@14019 970 <!--
jackalmage@14019 971 ████████ ███████ ██ ██ ████████ ████████ ███ ██████ ████████ ██████ ███████ ██ ██ ████████ ██████ ████████
jackalmage@14020 972 ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 973 ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 974 ██████ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██ ██████ ██████ ██ ██ ██ ██ ████████ ██ ██████
jackalmage@14020 975 ██ ██ ██ ██ ████ ██ ██ █████████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 976 ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14019 977 ██ ███████ ██ ██ ██ ██ ██ ██ ██████ ████████ ██████ ███████ ███████ ██ ██ ██████ ████████
jackalmage@14019 978 -->
jackalmage@14019 979
jackalmage@9047 980 <h2 id='font-face-source'>
jackalmage@9047 981 The <code>FontFaceSource</code> interface</h2>
jackalmage@9045 982
jackalmage@9047 983 <pre class='idl'>
jackalmage@10105 984 [NoInterfaceObject]
jackalmage@9906 985 interface FontFaceSource {
jackalmage@9906 986 readonly attribute FontFaceSet fonts;
jackalmage@9071 987 };
jackalmage@9045 988
jackalmage@9906 989 Document implements FontFaceSource;
jackalmage@9906 990 WorkerGlobalScope implements FontFaceSource;
jackalmage@9045 991 </pre>
jackalmage@9045 992
jackalmage@14551 993 Any document, workers, or other context which can use fonts in some manner must implement the {{FontFaceSource}} interface.
jackalmage@14551 994 The value of the context’s {{fonts}} attribute is its <dfn>font source</dfn>,
jackalmage@9047 995 which provides all of the fonts used in font-related operations,
jackalmage@9047 996 unless defined otherwise.
jackalmage@9047 997 Operations referring to “the font source” must be interpreted as referring to the <a>font source</a> of the relevant context in which the operation is taking place.
jackalmage@9045 998
jackalmage@9047 999 For any font-related operation that takes place within one of these contexts,
jackalmage@14551 1000 the {{FontFace}} objects within the <a>font source</a> are its <dfn>available font faces</dfn>.
jackalmage@9045 1001
jackalmage@13597 1002 <h3 id="fontfacesource-workers">
jackalmage@13597 1003 Worker FontFaceSources</h3>
jackalmage@13597 1004
jackalmage@13597 1005 Within a Worker document, the <a>font source</a> is initially empty.
jackalmage@13597 1006
jackalmage@14551 1007 Note: {{FontFace}} objects can be constructed and added to it as normal,
jackalmage@13597 1008 which affects CSS font-matching within the worker
jackalmage@14551 1009 (such as, for example, drawing text into a {{CanvasProxy}}).
jackalmage@13597 1010
jackalmage@9047 1011 <h3 id="document-font-face-set">
jackalmage@9047 1012 Interaction with CSS’s ''@font-face'' Rule</h3>
jackalmage@9047 1013
jackalmage@9047 1014 The set entries for a document's <a>font source</a>
jackalmage@14551 1015 must be initially populated with all the <a>CSS-connected</a> {{FontFace}} objects
jackalmage@9047 1016 from all of the CSS ''@font-face'' rules in the document's stylesheets,
jackalmage@9047 1017 in document order.
jackalmage@9135 1018 As ''@font-face'' rules are added or removed from a stylesheet,
jackalmage@9135 1019 or stylesheets containing ''@font-face'' rules are added or removed,
jackalmage@14551 1020 the corresponding <a>CSS-connected</a> {{FontFace}} objects
jackalmage@9135 1021 must be added or removed from the document's <a>font source</a>,
jackalmage@9495 1022 and maintain this ordering.
jackalmage@9135 1023
jackalmage@15407 1024 Any manually-added {{FontFace}} objects must be ordered <em>after</em>
jackalmage@15407 1025 the <a>CSS-connected</a> ones.
jackalmage@15407 1026
jackalmage@15407 1027 When a {{FontFaceSet}} object's {{FontFaceSet/add()}} method is called with a <a>CSS-connected</a> {{FontFace}} object,
jackalmage@15407 1028 if the object is already in the set,
jackalmage@15407 1029 the operation must be a no-op;
jackalmage@15407 1030 otherwise, the operation must do nothing,
jackalmage@15407 1031 and throw an {{InvalidModificationError}}.
jackalmage@15407 1032
jackalmage@15407 1033 When a {{FontFaceSet}} object's {{FontFaceSet/delete()}} method is called with a <a>CSS-connected</a> {{FontFace}} object,
jackalmage@15421 1034 the operation must be a no-op,
jackalmage@15421 1035 and return <code class="lang-javascript">false</code>.
jackalmage@15407 1036
jackalmage@14582 1037 Note: Authors can still maintain references to a removed {{FontFace}},
jackalmage@14582 1038 even if it's been automatically removed from a <a>font source</a>.
jackalmage@14582 1039 As specified in [[#font-face-css-connection]], though,
jackalmage@14582 1040 the {{FontFace}} is no longer <a>CSS-connected</a> at that point.
jackalmage@14582 1041
jackalmage@13598 1042 Note: It is expected that a future version of this specification
jackalmage@13598 1043 will define ways of interacting with and querying local fonts as well.
jackalmage@9137 1044
jackalmage@14019 1045 <!--
jackalmage@14020 1046 ███ ████████ ████ ████████ ██ ██ ███ ██ ██ ████████ ██ ████████ ██████
jackalmage@14019 1047 ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ███ ███ ██ ██ ██ ██ ██ ██
jackalmage@14020 1048 ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ████ ██ ██ ██ ██ ██
jackalmage@14020 1049 ██ ██ ████████ ██ ██████ ███ ██ ██ ██ ███ ██ ████████ ██ ██████ ██████
jackalmage@14019 1050 █████████ ██ ██ ██ ██ ██ █████████ ██ ██ ██ ██ ██ ██
jackalmage@14019 1051 ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
jackalmage@14020 1052 ██ ██ ██ ████ ████████ ██ ██ ██ ██ ██ ██ ██ ████████ ████████ ██████
jackalmage@14019 1053 -->
jackalmage@14019 1054
jackalmage@9045 1055 <h2 id="font-load-event-examples">
jackalmage@9045 1056 API Examples</h2>
jackalmage@8992 1057
jackalmage@8992 1058 <div class="example">
jackalmage@8992 1059 To show content only after all font loads complete:
jackalmage@8992 1060
jackalmage@8992 1061 <pre>
jaffathecake@15851 1062 document.fonts.ready.then(function() {
jackalmage@8992 1063 var content = document.getElementById("content");
jackalmage@8992 1064 content.style.visibility = "visible";
jackalmage@9003 1065 });
jackalmage@8992 1066 </pre>
jackalmage@8992 1067 </div>
jackalmage@8992 1068
jackalmage@8992 1069 <div class="example">
jackalmage@8992 1070 Drawing text in a canvas with a downloadable font, explicitly
jackalmage@8992 1071 initiating the font download and drawing upon completion:
jackalmage@8992 1072
jackalmage@8992 1073 <pre>
jackalmage@8992 1074 function drawStuff() {
jackalmage@8992 1075 var ctx = document.getElementById("c").getContext("2d");
jackalmage@8992 1076
jackalmage@8992 1077 ctx.fillStyle = "red";
jackalmage@8992 1078 ctx.font = "50px MyDownloadableFont";
jackalmage@8992 1079 ctx.fillText("Hello!", 100, 100);
jackalmage@8992 1080 }
jackalmage@8992 1081
jackalmage@9033 1082 document.fonts.load("50px MyDownloadableFont")
jackalmage@9033 1083 .then(drawStuff, handleError);
jackalmage@8992 1084 </pre>
jackalmage@8992 1085 </div>
jackalmage@8992 1086
jackalmage@8992 1087 <div class="example">
jackalmage@8992 1088 A rich text editing application may need to measure text elements
jackalmage@8992 1089 after editing operations have taken place. Since style changes may
jackalmage@8992 1090 or may not require additional fonts to be downloaded, or the fonts
jackalmage@8992 1091 may already have been downloaded, the measurement procedures need to
jackalmage@8992 1092 occur after those font loads complete:
jackalmage@8992 1093
jackalmage@8992 1094 <pre>
jackalmage@8992 1095 function measureTextElements() {
jackalmage@8992 1096 // contents can now be measured using the metrics of
jackalmage@8992 1097 // the downloadable font(s)
jackalmage@8992 1098 }
jackalmage@8992 1099
jackalmage@8992 1100 function doEditing() {
jackalmage@8992 1101 // content/layout operations that may cause additional font loads
jaffathecake@15851 1102 document.fonts.ready.then(measureTextElements);
jackalmage@8992 1103 }
jackalmage@8992 1104 </pre>
jackalmage@8992 1105 </div>
jackalmage@8992 1106
jackalmage@8992 1107 <div class="example">
jackalmage@14551 1108 The {{loadingdone}} event only fires after all font related loads have completed
jackalmage@9033 1109 <strong>and</strong> text has been laid out without causing additional font loads:
jackalmage@8992 1110
jackalmage@8992 1111 <pre>
jackalmage@10108 1112 &lt;style>
jackalmage@8992 1113 @font-face {
jackalmage@8992 1114 font-family: latin-serif;
jackalmage@8992 1115 src: url(latinserif.woff) format("woff"); /* contains no kanji/kana */
jackalmage@8992 1116 }
jackalmage@8992 1117 @font-face {
jackalmage@8992 1118 font-family: jpn-mincho;
jackalmage@8992 1119 src: url(mincho.woff) format("woff");
jackalmage@8992 1120 }
jackalmage@10108 1121 @font-face {
jackalmage@10108 1122 font-family: unused;
jackalmage@10108 1123 src: url(unused.woff);
jackalmage@10108 1124 }
jackalmage@8992 1125
jackalmage@8992 1126 body { font-family: latin-serif, jpn-mincho; }
jackalmage@10108 1127 &lt;/style>
jackalmage@8992 1128 &lt;p>納豆はいかがでしょうか
jackalmage@8992 1129 </pre>
jackalmage@8992 1130
jackalmage@8992 1131 In this situation, the user agent first downloads “latinserif.woff”
jackalmage@10108 1132 and then tries to use this to draw the Japanese text.
jackalmage@10108 1133 But because no Japanese glyphs are present in that font,
jackalmage@10108 1134 fallback occurs and the font “mincho.woff” is downloaded.
jackalmage@14551 1135 Only after the second font is downloaded and the Japanese text laid out does the {{loadingdone}} event fire.
jackalmage@10108 1136
jackalmage@10108 1137 The "unused" font isn't loaded,
jackalmage@10108 1138 but no text is using it,
jackalmage@10108 1139 so the UA isn't even <em>trying</em> to load it.
jackalmage@14551 1140 It doesn't interfere with the {{loadingdone}} event.
jackalmage@8992 1141 </div>
jackalmage@8992 1142
jackalmage@8992 1143
jackalmage@8992 1144 <h2 class="no-num" id="changes">Changes</h2>
jackalmage@8992 1145
jackalmage@14016 1146 Changes from the <a href="http://www.w3.org/TR/2014/WD-css-font-loading-3-20140522/">May 2014 CSS Font Loading Last Call Working Draft</a>:
jackalmage@8992 1147
jackalmage@14016 1148 <ol>
jackalmage@14016 1149 <li>
jackalmage@14126 1150 Corrected the async algorithms to use "queue a task" language,
jackalmage@14016 1151 to ensure that side-effect timing is well-defined.
jackalmage@14016 1152 </ol>
jackalmage@8992 1153
jackalmage@8992 1154 <h2 class=no-num id=acknowledgments>
jackalmage@8992 1155 Acknowledgments</h2>
jackalmage@8992 1156
jackalmage@8992 1157 Several members of the Google Fonts team provided helpful feedback on font load events,
jackalmage@9495 1158 as did Boris Zbarsky, Jonas Sicking and ms2ger.

mercurial