Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: sky/engine/core/css/FontFaceSet.cpp

Issue 922893002: Merge the Sky Engine changes from the SkyDart branch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/engine/core/css/FontFaceSet.h ('k') | sky/engine/core/css/FontFaceSet.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met: 5 * modification, are permitted provided that the following conditions are met:
6 * 6 *
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE 16 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
23 * DAMAGE. 23 * DAMAGE.
24 */ 24 */
25 25
26 #include "sky/engine/config.h" 26 #include "sky/engine/config.h"
27 #include "sky/engine/core/css/FontFaceSet.h" 27 #include "sky/engine/core/css/FontFaceSet.h"
28 28
29 #include "sky/engine/bindings/core/v8/Dictionary.h"
30 #include "sky/engine/bindings/core/v8/ScriptPromiseResolver.h"
31 #include "sky/engine/bindings/core/v8/ScriptState.h"
32 #include "sky/engine/core/css/CSSFontSelector.h" 29 #include "sky/engine/core/css/CSSFontSelector.h"
33 #include "sky/engine/core/css/CSSSegmentedFontFace.h" 30 #include "sky/engine/core/css/CSSSegmentedFontFace.h"
34 #include "sky/engine/core/css/FontFaceCache.h" 31 #include "sky/engine/core/css/FontFaceCache.h"
35 #include "sky/engine/core/css/FontFaceSetLoadEvent.h" 32 #include "sky/engine/core/css/FontFaceSetLoadEvent.h"
36 #include "sky/engine/core/css/StylePropertySet.h" 33 #include "sky/engine/core/css/StylePropertySet.h"
37 #include "sky/engine/core/css/parser/BisonCSSParser.h" 34 #include "sky/engine/core/css/parser/BisonCSSParser.h"
38 #include "sky/engine/core/css/resolver/StyleResolver.h" 35 #include "sky/engine/core/css/resolver/StyleResolver.h"
39 #include "sky/engine/core/dom/Document.h" 36 #include "sky/engine/core/dom/Document.h"
40 #include "sky/engine/core/dom/StyleEngine.h" 37 #include "sky/engine/core/dom/StyleEngine.h"
41 #include "sky/engine/core/frame/FrameView.h" 38 #include "sky/engine/core/frame/FrameView.h"
42 #include "sky/engine/core/frame/LocalFrame.h" 39 #include "sky/engine/core/frame/LocalFrame.h"
43 #include "sky/engine/core/rendering/style/RenderStyle.h" 40 #include "sky/engine/core/rendering/style/RenderStyle.h"
44 #include "sky/engine/core/rendering/style/StyleInheritedData.h" 41 #include "sky/engine/core/rendering/style/StyleInheritedData.h"
45 #include "sky/engine/public/platform/Platform.h" 42 #include "sky/engine/public/platform/Platform.h"
46 43
47 namespace blink { 44 namespace blink {
48 45
49 static const int defaultFontSize = 10; 46 static const int defaultFontSize = 10;
50 static const char defaultFontFamily[] = "sans-serif"; 47 static const char defaultFontFamily[] = "sans-serif";
51 48
52 class LoadFontPromiseResolver final : public FontFace::LoadFontCallback {
53 public:
54 static PassRefPtr<LoadFontPromiseResolver> create(FontFaceArray faces, Scrip tState* scriptState)
55 {
56 return adoptRef(new LoadFontPromiseResolver(faces, scriptState));
57 }
58
59 void loadFonts(ExecutionContext*);
60 ScriptPromise promise() { return m_resolver->promise(); }
61
62 virtual void notifyLoaded(FontFace*) override;
63 virtual void notifyError(FontFace*) override;
64
65 private:
66 LoadFontPromiseResolver(FontFaceArray faces, ScriptState* scriptState)
67 : m_numLoading(faces.size())
68 , m_errorOccured(false)
69 , m_resolver(ScriptPromiseResolver::create(scriptState))
70 {
71 m_fontFaces.swap(faces);
72 }
73
74 Vector<RefPtr<FontFace> > m_fontFaces;
75 int m_numLoading;
76 bool m_errorOccured;
77 RefPtr<ScriptPromiseResolver> m_resolver;
78 };
79
80 void LoadFontPromiseResolver::loadFonts(ExecutionContext* context)
81 {
82 if (!m_numLoading) {
83 m_resolver->resolve(m_fontFaces);
84 return;
85 }
86
87 for (size_t i = 0; i < m_fontFaces.size(); i++)
88 m_fontFaces[i]->loadWithCallback(this, context);
89 }
90
91 void LoadFontPromiseResolver::notifyLoaded(FontFace* fontFace)
92 {
93 m_numLoading--;
94 if (m_numLoading || m_errorOccured)
95 return;
96
97 m_resolver->resolve(m_fontFaces);
98 }
99
100 void LoadFontPromiseResolver::notifyError(FontFace* fontFace)
101 {
102 m_numLoading--;
103 if (!m_errorOccured) {
104 m_errorOccured = true;
105 m_resolver->reject(fontFace->error());
106 }
107 }
108
109 class FontsReadyPromiseResolver {
110 public:
111 static PassOwnPtr<FontsReadyPromiseResolver> create(ScriptState* scriptState )
112 {
113 return adoptPtr(new FontsReadyPromiseResolver(scriptState));
114 }
115
116 void resolve(PassRefPtr<FontFaceSet> fontFaceSet)
117 {
118 m_resolver->resolve(fontFaceSet);
119 }
120
121 ScriptPromise promise() { return m_resolver->promise(); }
122
123 private:
124 explicit FontsReadyPromiseResolver(ScriptState* scriptState)
125 : m_resolver(ScriptPromiseResolver::create(scriptState))
126 {
127 }
128
129 RefPtr<ScriptPromiseResolver> m_resolver;
130 };
131
132 FontFaceSet::FontFaceSet(Document& document) 49 FontFaceSet::FontFaceSet(Document& document)
133 : ActiveDOMObject(&document) 50 : ActiveDOMObject(&document)
134 , m_shouldFireLoadingEvent(false) 51 , m_shouldFireLoadingEvent(false)
135 , m_asyncRunner(this, &FontFaceSet::handlePendingEventsAndPromises) 52 , m_asyncRunner(this, &FontFaceSet::handlePendingEventsAndPromises)
136 { 53 {
137 suspendIfNeeded(); 54 suspendIfNeeded();
138 } 55 }
139 56
140 FontFaceSet::~FontFaceSet() 57 FontFaceSet::~FontFaceSet()
141 { 58 {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 void FontFaceSet::handlePendingEventsAndPromisesSoon() 95 void FontFaceSet::handlePendingEventsAndPromisesSoon()
179 { 96 {
180 // m_asyncRunner will be automatically stopped on destruction. 97 // m_asyncRunner will be automatically stopped on destruction.
181 m_asyncRunner.runAsync(); 98 m_asyncRunner.runAsync();
182 } 99 }
183 100
184 void FontFaceSet::didLayout() 101 void FontFaceSet::didLayout()
185 { 102 {
186 if (m_loadingFonts.isEmpty()) 103 if (m_loadingFonts.isEmpty())
187 m_histogram.record(); 104 m_histogram.record();
188 if (!m_loadingFonts.isEmpty() || (!hasLoadedFonts() && m_readyResolvers.isEm pty())) 105 if (!m_loadingFonts.isEmpty() || !hasLoadedFonts())
189 return; 106 return;
190 handlePendingEventsAndPromisesSoon(); 107 handlePendingEventsAndPromisesSoon();
191 } 108 }
192 109
193 void FontFaceSet::handlePendingEventsAndPromises() 110 void FontFaceSet::handlePendingEventsAndPromises()
194 { 111 {
195 fireLoadingEvent(); 112 fireLoadingEvent();
196 fireDoneEventIfPossible(); 113 fireDoneEventIfPossible();
197 } 114 }
198 115
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 m_loadingFonts.add(fontFace); 165 m_loadingFonts.add(fontFace);
249 } 166 }
250 167
251 void FontFaceSet::removeFromLoadingFonts(PassRefPtr<FontFace> fontFace) 168 void FontFaceSet::removeFromLoadingFonts(PassRefPtr<FontFace> fontFace)
252 { 169 {
253 m_loadingFonts.remove(fontFace); 170 m_loadingFonts.remove(fontFace);
254 if (m_loadingFonts.isEmpty()) 171 if (m_loadingFonts.isEmpty())
255 handlePendingEventsAndPromisesSoon(); 172 handlePendingEventsAndPromisesSoon();
256 } 173 }
257 174
258 ScriptPromise FontFaceSet::ready(ScriptState* scriptState)
259 {
260 if (!inActiveDocumentContext())
261 return ScriptPromise();
262 OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::crea te(scriptState);
263 ScriptPromise promise = resolver->promise();
264 m_readyResolvers.append(resolver.release());
265 handlePendingEventsAndPromisesSoon();
266 return promise;
267 }
268
269 void FontFaceSet::add(FontFace* fontFace, ExceptionState& exceptionState) 175 void FontFaceSet::add(FontFace* fontFace, ExceptionState& exceptionState)
270 { 176 {
271 if (!inActiveDocumentContext()) 177 if (!inActiveDocumentContext())
272 return; 178 return;
273 if (!fontFace) { 179 if (!fontFace) {
274 exceptionState.throwTypeError("The argument is not a FontFace."); 180 exceptionState.ThrowTypeError("The argument is not a FontFace.");
275 return; 181 return;
276 } 182 }
277 if (m_nonCSSConnectedFaces.contains(fontFace)) 183 if (m_nonCSSConnectedFaces.contains(fontFace))
278 return; 184 return;
279 if (isCSSConnectedFontFace(fontFace)) { 185 if (isCSSConnectedFontFace(fontFace)) {
280 exceptionState.throwDOMException(InvalidModificationError, "Cannot add a CSS-connected FontFace."); 186 exceptionState.ThrowDOMException(InvalidModificationError, "Cannot add a CSS-connected FontFace.");
281 return; 187 return;
282 } 188 }
283 CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector(); 189 CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
284 m_nonCSSConnectedFaces.add(fontFace); 190 m_nonCSSConnectedFaces.add(fontFace);
285 fontSelector->fontFaceCache()->addFontFace(fontSelector, fontFace, false); 191 fontSelector->fontFaceCache()->addFontFace(fontSelector, fontFace, false);
286 if (fontFace->loadStatus() == FontFace::Loading) 192 if (fontFace->loadStatus() == FontFace::Loading)
287 addToLoadingFonts(fontFace); 193 addToLoadingFonts(fontFace);
288 fontSelector->fontFaceInvalidated(); 194 fontSelector->fontFaceInvalidated();
289 } 195 }
290 196
(...skipping 10 matching lines...) Expand all
301 } 207 }
302 m_nonCSSConnectedFaces.clear(); 208 m_nonCSSConnectedFaces.clear();
303 fontSelector->fontFaceInvalidated(); 209 fontSelector->fontFaceInvalidated();
304 } 210 }
305 211
306 bool FontFaceSet::remove(FontFace* fontFace, ExceptionState& exceptionState) 212 bool FontFaceSet::remove(FontFace* fontFace, ExceptionState& exceptionState)
307 { 213 {
308 if (!inActiveDocumentContext()) 214 if (!inActiveDocumentContext())
309 return false; 215 return false;
310 if (!fontFace) { 216 if (!fontFace) {
311 exceptionState.throwTypeError("The argument is not a FontFace."); 217 exceptionState.ThrowTypeError("The argument is not a FontFace.");
312 return false; 218 return false;
313 } 219 }
314 ListHashSet<RefPtr<FontFace> >::iterator it = m_nonCSSConnectedFaces.find(fo ntFace); 220 ListHashSet<RefPtr<FontFace> >::iterator it = m_nonCSSConnectedFaces.find(fo ntFace);
315 if (it != m_nonCSSConnectedFaces.end()) { 221 if (it != m_nonCSSConnectedFaces.end()) {
316 m_nonCSSConnectedFaces.remove(it); 222 m_nonCSSConnectedFaces.remove(it);
317 CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector( ); 223 CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector( );
318 fontSelector->fontFaceCache()->removeFontFace(fontFace, false); 224 fontSelector->fontFaceCache()->removeFontFace(fontFace, false);
319 if (fontFace->loadStatus() == FontFace::Loading) 225 if (fontFace->loadStatus() == FontFace::Loading)
320 removeFromLoadingFonts(fontFace); 226 removeFromLoadingFonts(fontFace);
321 fontSelector->fontFaceInvalidated(); 227 fontSelector->fontFaceInvalidated();
322 return true; 228 return true;
323 } 229 }
324 if (isCSSConnectedFontFace(fontFace)) 230 if (isCSSConnectedFontFace(fontFace))
325 exceptionState.throwDOMException(InvalidModificationError, "Cannot delet e a CSS-connected FontFace."); 231 exceptionState.ThrowDOMException(InvalidModificationError, "Cannot delet e a CSS-connected FontFace.");
326 return false; 232 return false;
327 } 233 }
328 234
329 bool FontFaceSet::has(FontFace* fontFace, ExceptionState& exceptionState) const 235 bool FontFaceSet::has(FontFace* fontFace, ExceptionState& exceptionState) const
330 { 236 {
331 if (!inActiveDocumentContext()) 237 if (!inActiveDocumentContext())
332 return false; 238 return false;
333 if (!fontFace) { 239 if (!fontFace) {
334 exceptionState.throwTypeError("The argument is not a FontFace."); 240 exceptionState.ThrowTypeError("The argument is not a FontFace.");
335 return false; 241 return false;
336 } 242 }
337 return m_nonCSSConnectedFaces.contains(fontFace) || isCSSConnectedFontFace(f ontFace); 243 return m_nonCSSConnectedFaces.contains(fontFace) || isCSSConnectedFontFace(f ontFace);
338 } 244 }
339 245
340 const ListHashSet<RefPtr<FontFace> >& FontFaceSet::cssConnectedFontFaceList() co nst 246 const ListHashSet<RefPtr<FontFace> >& FontFaceSet::cssConnectedFontFaceList() co nst
341 { 247 {
342 Document* d = document(); 248 Document* d = document();
343 return d->styleEngine()->fontSelector()->fontFaceCache()->cssConnectedFontFa ces(); 249 return d->styleEngine()->fontSelector()->fontFaceCache()->cssConnectedFontFa ces();
344 } 250 }
345 251
346 bool FontFaceSet::isCSSConnectedFontFace(FontFace* fontFace) const 252 bool FontFaceSet::isCSSConnectedFontFace(FontFace* fontFace) const
347 { 253 {
348 return cssConnectedFontFaceList().contains(fontFace); 254 return cssConnectedFontFaceList().contains(fontFace);
349 } 255 }
350 256
351 void FontFaceSet::forEach(PassOwnPtr<FontFaceSetForEachCallback> callback, const ScriptValue& thisArg) const
352 {
353 forEachInternal(callback, &thisArg);
354 }
355
356 void FontFaceSet::forEach(PassOwnPtr<FontFaceSetForEachCallback> callback) const
357 {
358 forEachInternal(callback, 0);
359 }
360
361 void FontFaceSet::forEachInternal(PassOwnPtr<FontFaceSetForEachCallback> callbac k, const ScriptValue* thisArg) const
362 {
363 if (!inActiveDocumentContext())
364 return;
365 const ListHashSet<RefPtr<FontFace> >& cssConnectedFaces = cssConnectedFontFa ceList();
366 Vector<RefPtr<FontFace> > fontFaces;
367 fontFaces.reserveInitialCapacity(cssConnectedFaces.size() + m_nonCSSConnecte dFaces.size());
368 for (ListHashSet<RefPtr<FontFace> >::const_iterator it = cssConnectedFaces.b egin(); it != cssConnectedFaces.end(); ++it)
369 fontFaces.append(*it);
370 for (ListHashSet<RefPtr<FontFace> >::const_iterator it = m_nonCSSConnectedFa ces.begin(); it != m_nonCSSConnectedFaces.end(); ++it)
371 fontFaces.append(*it);
372
373 for (size_t i = 0; i < fontFaces.size(); ++i) {
374 FontFace* face = fontFaces[i].get();
375 if (thisArg)
376 callback->handleItem(*thisArg, face, face, const_cast<FontFaceSet*>( this));
377 else
378 callback->handleItem(face, face, const_cast<FontFaceSet*>(this));
379 }
380 }
381
382 unsigned long FontFaceSet::size() const 257 unsigned long FontFaceSet::size() const
383 { 258 {
384 if (!inActiveDocumentContext()) 259 if (!inActiveDocumentContext())
385 return m_nonCSSConnectedFaces.size(); 260 return m_nonCSSConnectedFaces.size();
386 return cssConnectedFontFaceList().size() + m_nonCSSConnectedFaces.size(); 261 return cssConnectedFontFaceList().size() + m_nonCSSConnectedFaces.size();
387 } 262 }
388 263
389 void FontFaceSet::fireDoneEventIfPossible() 264 void FontFaceSet::fireDoneEventIfPossible()
390 { 265 {
391 if (m_shouldFireLoadingEvent) 266 if (m_shouldFireLoadingEvent)
392 return; 267 return;
393 if (!m_loadingFonts.isEmpty() || (!hasLoadedFonts() && m_readyResolvers.isEm pty())) 268 if (!m_loadingFonts.isEmpty() || !hasLoadedFonts())
394 return; 269 return;
395 270
396 // If the layout was invalidated in between when we thought layout 271 // If the layout was invalidated in between when we thought layout
397 // was updated and when we're ready to fire the event, just wait 272 // was updated and when we're ready to fire the event, just wait
398 // until after the next layout before firing events. 273 // until after the next layout before firing events.
399 Document* d = document(); 274 Document* d = document();
400 if (!d->view() || d->view()->needsLayout()) 275 if (!d->view() || d->view()->needsLayout())
401 return; 276 return;
402 277
403 if (hasLoadedFonts()) { 278 if (hasLoadedFonts()) {
404 RefPtr<FontFaceSetLoadEvent> doneEvent = nullptr; 279 RefPtr<FontFaceSetLoadEvent> doneEvent = nullptr;
405 RefPtr<FontFaceSetLoadEvent> errorEvent = nullptr; 280 RefPtr<FontFaceSetLoadEvent> errorEvent = nullptr;
406 doneEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames::loa dingdone, m_loadedFonts); 281 doneEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames::loa dingdone, m_loadedFonts);
407 m_loadedFonts.clear(); 282 m_loadedFonts.clear();
408 if (!m_failedFonts.isEmpty()) { 283 if (!m_failedFonts.isEmpty()) {
409 errorEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames ::loadingerror, m_failedFonts); 284 errorEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames ::loadingerror, m_failedFonts);
410 m_failedFonts.clear(); 285 m_failedFonts.clear();
411 } 286 }
412 dispatchEvent(doneEvent); 287 dispatchEvent(doneEvent);
413 if (errorEvent) 288 if (errorEvent)
414 dispatchEvent(errorEvent); 289 dispatchEvent(errorEvent);
415 } 290 }
416
417 if (!m_readyResolvers.isEmpty()) {
418 Vector<OwnPtr<FontsReadyPromiseResolver> > resolvers;
419 m_readyResolvers.swap(resolvers);
420 for (size_t index = 0; index < resolvers.size(); ++index)
421 resolvers[index]->resolve(this);
422 }
423 } 291 }
424 292
425 static const String& nullToSpace(const String& s) 293 static const String& nullToSpace(const String& s)
426 { 294 {
427 DEFINE_STATIC_LOCAL(String, space, (" ")); 295 DEFINE_STATIC_LOCAL(String, space, (" "));
428 return s.isNull() ? space : s; 296 return s.isNull() ? space : s;
429 } 297 }
430 298
431 ScriptPromise FontFaceSet::load(ScriptState* scriptState, const String& fontStri ng, const String& text)
432 {
433 if (!inActiveDocumentContext())
434 return ScriptPromise();
435
436 Font font;
437 if (!resolveFontStyle(fontString, font)) {
438 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(s criptState);
439 ScriptPromise promise = resolver->promise();
440 resolver->reject(DOMException::create(SyntaxError, "Could not resolve '" + fontString + "' as a font."));
441 return promise;
442 }
443
444 FontFaceCache* fontFaceCache = document()->styleEngine()->fontSelector()->fo ntFaceCache();
445 FontFaceArray faces;
446 for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next( )) {
447 CSSSegmentedFontFace* segmentedFontFace = fontFaceCache->get(font.fontDe scription(), f->family());
448 if (segmentedFontFace)
449 segmentedFontFace->match(nullToSpace(text), faces);
450 }
451
452 RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(f aces, scriptState);
453 ScriptPromise promise = resolver->promise();
454 resolver->loadFonts(executionContext()); // After this, resolver->promise() may return null.
455 return promise;
456 }
457
458 bool FontFaceSet::check(const String& fontString, const String& text, ExceptionS tate& exceptionState) 299 bool FontFaceSet::check(const String& fontString, const String& text, ExceptionS tate& exceptionState)
459 { 300 {
460 if (!inActiveDocumentContext()) 301 if (!inActiveDocumentContext())
461 return false; 302 return false;
462 303
463 Font font; 304 Font font;
464 if (!resolveFontStyle(fontString, font)) { 305 if (!resolveFontStyle(fontString, font)) {
465 exceptionState.throwDOMException(SyntaxError, "Could not resolve '" + fo ntString + "' as a font."); 306 exceptionState.ThrowDOMException(SyntaxError, "Could not resolve '" + fo ntString + "' as a font.");
466 return false; 307 return false;
467 } 308 }
468 309
469 CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector(); 310 CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
470 FontFaceCache* fontFaceCache = fontSelector->fontFaceCache(); 311 FontFaceCache* fontFaceCache = fontSelector->fontFaceCache();
471 312
472 bool hasLoadedFaces = false; 313 bool hasLoadedFaces = false;
473 for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next( )) { 314 for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next( )) {
474 CSSSegmentedFontFace* face = fontFaceCache->get(font.fontDescription(), f->family()); 315 CSSSegmentedFontFace* face = fontFaceCache->get(font.fontDescription(), f->family());
475 if (face) { 316 if (face) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 return fonts.release(); 413 return fonts.release();
573 } 414 }
574 415
575 void FontFaceSet::didLayout(Document& document) 416 void FontFaceSet::didLayout(Document& document)
576 { 417 {
577 if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(docu ment, supplementName()))) 418 if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(docu ment, supplementName())))
578 fonts->didLayout(); 419 fonts->didLayout();
579 } 420 }
580 421
581 } // namespace blink 422 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/css/FontFaceSet.h ('k') | sky/engine/core/css/FontFaceSet.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698