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

Side by Side Diff: Source/core/css/FontFaceSet.cpp

Issue 196383035: Fix promise resolution of FontFaceSet#load() (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
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
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "core/dom/StyleEngine.h" 42 #include "core/dom/StyleEngine.h"
43 #include "core/frame/FrameView.h" 43 #include "core/frame/FrameView.h"
44 #include "core/frame/LocalFrame.h" 44 #include "core/frame/LocalFrame.h"
45 #include "public/platform/Platform.h" 45 #include "public/platform/Platform.h"
46 46
47 namespace WebCore { 47 namespace WebCore {
48 48
49 static const int defaultFontSize = 10; 49 static const int defaultFontSize = 10;
50 static const char defaultFontFamily[] = "sans-serif"; 50 static const char defaultFontFamily[] = "sans-serif";
51 51
52 class LoadFontPromiseResolver : public CSSSegmentedFontFace::LoadFontCallback { 52 class LoadFontPromiseResolver : public FontFace::LoadFontCallback {
53 public: 53 public:
54 static PassRefPtr<LoadFontPromiseResolver> create(const FontFamily& family, ExecutionContext* context) 54 static PassRefPtr<LoadFontPromiseResolver> create(FontFaceArray faces, Execu tionContext* context)
55 { 55 {
56 int numFamilies = 0; 56 return adoptRef(new LoadFontPromiseResolver(faces, context));
57 for (const FontFamily* f = &family; f; f = f->next())
58 numFamilies++;
59 return adoptRef<LoadFontPromiseResolver>(new LoadFontPromiseResolver(num Families, context));
60 } 57 }
61 58
59 void loadFonts(ExecutionContext*);
62 ScriptPromise promise() { return m_resolver->promise(); } 60 ScriptPromise promise() { return m_resolver->promise(); }
63 61
64 virtual void notifyLoaded(CSSSegmentedFontFace*) OVERRIDE { loaded(); } 62 virtual void notifyLoaded(FontFace*) OVERRIDE;
65 virtual void notifyError(CSSSegmentedFontFace*) OVERRIDE { error(); } 63 virtual void notifyError(FontFace*) OVERRIDE;
66 void loaded();
67 void error();
68 64
69 private: 65 private:
70 LoadFontPromiseResolver(int numLoading, ExecutionContext* context) 66 LoadFontPromiseResolver(FontFaceArray faces, ExecutionContext* context)
71 : m_numLoading(numLoading) 67 : m_numLoading(faces.size())
72 , m_errorOccured(false) 68 , m_errorOccured(false)
73 , m_scriptState(ScriptState::current()) 69 , m_scriptState(ScriptState::current())
74 , m_resolver(ScriptPromiseResolver::create(context)) 70 , m_resolver(ScriptPromiseResolver::create(context))
75 { } 71 {
72 m_fontFaces.swap(faces);
73 }
76 74
75 FontFaceArray m_fontFaces;
77 int m_numLoading; 76 int m_numLoading;
78 bool m_errorOccured; 77 bool m_errorOccured;
79 ScriptState* m_scriptState; 78 ScriptState* m_scriptState;
80 RefPtr<ScriptPromiseResolver> m_resolver; 79 RefPtr<ScriptPromiseResolver> m_resolver;
81 }; 80 };
82 81
83 void LoadFontPromiseResolver::loaded() 82 void LoadFontPromiseResolver::loadFonts(ExecutionContext* context)
83 {
84 if (!m_numLoading) {
85 m_resolver->resolve(m_fontFaces);
86 return;
87 }
88
89 for (size_t i = 0; i < m_fontFaces.size(); i++)
90 m_fontFaces[i]->load(this, context);
91 }
92
93 void LoadFontPromiseResolver::notifyLoaded(FontFace* fontFace)
84 { 94 {
85 m_numLoading--; 95 m_numLoading--;
86 if (m_numLoading) 96 if (m_numLoading || m_errorOccured)
87 return; 97 return;
88 98
89 ScriptScope scope(m_scriptState); 99 ScriptScope scope(m_scriptState);
90 if (m_errorOccured) 100 m_resolver->resolve(m_fontFaces);
91 m_resolver->reject(ScriptValue::createNull());
92 else
93 m_resolver->resolve(ScriptValue::createNull());
94 } 101 }
95 102
96 void LoadFontPromiseResolver::error() 103 void LoadFontPromiseResolver::notifyError(FontFace* fontFace)
97 { 104 {
98 m_errorOccured = true; 105 m_numLoading--;
99 loaded(); 106 if (!m_errorOccured) {
107 m_errorOccured = true;
108 ScriptScope scope(m_scriptState);
109 m_resolver->reject(fontFace->error());
110 }
100 } 111 }
101 112
102 class FontsReadyPromiseResolver { 113 class FontsReadyPromiseResolver {
103 public: 114 public:
104 static PassOwnPtr<FontsReadyPromiseResolver> create(ExecutionContext* contex t) 115 static PassOwnPtr<FontsReadyPromiseResolver> create(ExecutionContext* contex t)
105 { 116 {
106 return adoptPtr(new FontsReadyPromiseResolver(context)); 117 return adoptPtr(new FontsReadyPromiseResolver(context));
107 } 118 }
108 119
109 void resolve(PassRefPtr<FontFaceSet> fontFaceSet) 120 void resolve(PassRefPtr<FontFaceSet> fontFaceSet)
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 resolvers[index]->resolve(this); 427 resolvers[index]->resolve(this);
417 } 428 }
418 } 429 }
419 430
420 static const String& nullToSpace(const String& s) 431 static const String& nullToSpace(const String& s)
421 { 432 {
422 DEFINE_STATIC_LOCAL(String, space, (" ")); 433 DEFINE_STATIC_LOCAL(String, space, (" "));
423 return s.isNull() ? space : s; 434 return s.isNull() ? space : s;
424 } 435 }
425 436
426 ScriptPromise FontFaceSet::load(const String& fontString, const String& text, Ex ceptionState& exceptionState) 437 ScriptPromise FontFaceSet::load(const String& fontString, const String& text)
427 { 438 {
428 if (!inActiveDocumentContext()) 439 if (!inActiveDocumentContext())
429 return ScriptPromise(); 440 return ScriptPromise();
430 441
431 Font font; 442 Font font;
432 if (!resolveFontStyle(fontString, font)) { 443 if (!resolveFontStyle(fontString, font)) {
433 exceptionState.throwDOMException(SyntaxError, "Could not resolve '" + fo ntString + "' as a font."); 444 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(e xecutionContext());
434 return ScriptPromise(); 445 ScriptPromise promise = resolver->promise();
446 resolver->reject(DOMError::create(SyntaxError, "Could not resolve '" + f ontString + "' as a font."));
447 return promise;
435 } 448 }
436 449
437 CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector(); 450 FontFaceCache* fontFaceCache = document()->styleEngine()->fontSelector()->fo ntFaceCache();
438 FontFaceCache* fontFaceCache = fontSelector->fontFaceCache(); 451 FontFaceArray faces;
439 RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(f ont.fontDescription().family(), executionContext()); 452 for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next( )) {
453 CSSSegmentedFontFace* segmentedFontFace = fontFaceCache->get(font.fontDe scription(), f->family());
454 if (segmentedFontFace)
455 segmentedFontFace->match(nullToSpace(text), faces);
456 }
457
458 RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(f aces, executionContext());
440 ScriptPromise promise = resolver->promise(); 459 ScriptPromise promise = resolver->promise();
441 for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next( )) { 460 resolver->loadFonts(executionContext()); // After this, resolver->promise() may return null.
442 CSSSegmentedFontFace* face = fontFaceCache->get(font.fontDescription(), f->family());
443 if (!face) {
444 resolver->error();
445 continue;
446 }
447 face->loadFont(font.fontDescription(), nullToSpace(text), resolver);
448 }
449 fontSelector->loadPendingFonts();
450 return promise; 461 return promise;
451 } 462 }
452 463
453 bool FontFaceSet::check(const String& fontString, const String& text, ExceptionS tate& exceptionState) 464 bool FontFaceSet::check(const String& fontString, const String& text, ExceptionS tate& exceptionState)
454 { 465 {
455 if (!inActiveDocumentContext()) 466 if (!inActiveDocumentContext())
456 return false; 467 return false;
457 468
458 Font font; 469 Font font;
459 if (!resolveFontStyle(fontString, font)) { 470 if (!resolveFontStyle(fontString, font)) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 } 566 }
556 567
557 void FontFaceSet::didLayout(Document& document) 568 void FontFaceSet::didLayout(Document& document)
558 { 569 {
559 if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(docu ment, supplementName()))) 570 if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(docu ment, supplementName())))
560 fonts->didLayout(); 571 fonts->didLayout();
561 } 572 }
562 573
563 574
564 } // namespace WebCore 575 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698