| Index: Source/core/css/FontFaceSet.cpp
|
| diff --git a/Source/core/css/FontFaceSet.cpp b/Source/core/css/FontFaceSet.cpp
|
| index 54e200df8fa236f3ade575c88ff933195031d016..0becaa3f8129ea7b6e79c75a44b65490f464b2fb 100644
|
| --- a/Source/core/css/FontFaceSet.cpp
|
| +++ b/Source/core/css/FontFaceSet.cpp
|
| @@ -49,54 +49,65 @@ namespace WebCore {
|
| static const int defaultFontSize = 10;
|
| static const char defaultFontFamily[] = "sans-serif";
|
|
|
| -class LoadFontPromiseResolver : public CSSSegmentedFontFace::LoadFontCallback {
|
| +class LoadFontPromiseResolver : public FontFace::LoadFontCallback {
|
| public:
|
| - static PassRefPtr<LoadFontPromiseResolver> create(const FontFamily& family, ExecutionContext* context)
|
| + static PassRefPtr<LoadFontPromiseResolver> create(FontFaceArray faces, ExecutionContext* context)
|
| {
|
| - int numFamilies = 0;
|
| - for (const FontFamily* f = &family; f; f = f->next())
|
| - numFamilies++;
|
| - return adoptRef<LoadFontPromiseResolver>(new LoadFontPromiseResolver(numFamilies, context));
|
| + return adoptRef(new LoadFontPromiseResolver(faces, context));
|
| }
|
|
|
| + void loadFonts(ExecutionContext*);
|
| ScriptPromise promise() { return m_resolver->promise(); }
|
|
|
| - virtual void notifyLoaded(CSSSegmentedFontFace*) OVERRIDE { loaded(); }
|
| - virtual void notifyError(CSSSegmentedFontFace*) OVERRIDE { error(); }
|
| - void loaded();
|
| - void error();
|
| + virtual void notifyLoaded(FontFace*) OVERRIDE;
|
| + virtual void notifyError(FontFace*) OVERRIDE;
|
|
|
| private:
|
| - LoadFontPromiseResolver(int numLoading, ExecutionContext* context)
|
| - : m_numLoading(numLoading)
|
| + LoadFontPromiseResolver(FontFaceArray faces, ExecutionContext* context)
|
| + : m_numLoading(faces.size())
|
| , m_errorOccured(false)
|
| , m_scriptState(ScriptState::current())
|
| , m_resolver(ScriptPromiseResolver::create(context))
|
| - { }
|
| + {
|
| + m_fontFaces.swap(faces);
|
| + }
|
|
|
| + FontFaceArray m_fontFaces;
|
| int m_numLoading;
|
| bool m_errorOccured;
|
| ScriptState* m_scriptState;
|
| RefPtr<ScriptPromiseResolver> m_resolver;
|
| };
|
|
|
| -void LoadFontPromiseResolver::loaded()
|
| +void LoadFontPromiseResolver::loadFonts(ExecutionContext* context)
|
| +{
|
| + if (!m_numLoading) {
|
| + m_resolver->resolve(m_fontFaces);
|
| + return;
|
| + }
|
| +
|
| + for (size_t i = 0; i < m_fontFaces.size(); i++)
|
| + m_fontFaces[i]->loadWithCallback(this, context);
|
| +}
|
| +
|
| +void LoadFontPromiseResolver::notifyLoaded(FontFace* fontFace)
|
| {
|
| m_numLoading--;
|
| - if (m_numLoading)
|
| + if (m_numLoading || m_errorOccured)
|
| return;
|
|
|
| ScriptScope scope(m_scriptState);
|
| - if (m_errorOccured)
|
| - m_resolver->reject(ScriptValue::createNull());
|
| - else
|
| - m_resolver->resolve(ScriptValue::createNull());
|
| + m_resolver->resolve(m_fontFaces);
|
| }
|
|
|
| -void LoadFontPromiseResolver::error()
|
| +void LoadFontPromiseResolver::notifyError(FontFace* fontFace)
|
| {
|
| - m_errorOccured = true;
|
| - loaded();
|
| + m_numLoading--;
|
| + if (!m_errorOccured) {
|
| + m_errorOccured = true;
|
| + ScriptScope scope(m_scriptState);
|
| + m_resolver->reject(fontFace->error());
|
| + }
|
| }
|
|
|
| class FontsReadyPromiseResolver {
|
| @@ -423,30 +434,30 @@ static const String& nullToSpace(const String& s)
|
| return s.isNull() ? space : s;
|
| }
|
|
|
| -ScriptPromise FontFaceSet::load(const String& fontString, const String& text, ExceptionState& exceptionState)
|
| +ScriptPromise FontFaceSet::load(const String& fontString, const String& text)
|
| {
|
| if (!inActiveDocumentContext())
|
| return ScriptPromise();
|
|
|
| Font font;
|
| if (!resolveFontStyle(fontString, font)) {
|
| - exceptionState.throwDOMException(SyntaxError, "Could not resolve '" + fontString + "' as a font.");
|
| - return ScriptPromise();
|
| + RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(executionContext());
|
| + ScriptPromise promise = resolver->promise();
|
| + resolver->reject(DOMError::create(SyntaxError, "Could not resolve '" + fontString + "' as a font."));
|
| + return promise;
|
| }
|
|
|
| - CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
|
| - FontFaceCache* fontFaceCache = fontSelector->fontFaceCache();
|
| - RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(font.fontDescription().family(), executionContext());
|
| - ScriptPromise promise = resolver->promise();
|
| + FontFaceCache* fontFaceCache = document()->styleEngine()->fontSelector()->fontFaceCache();
|
| + FontFaceArray faces;
|
| for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
|
| - CSSSegmentedFontFace* face = fontFaceCache->get(font.fontDescription(), f->family());
|
| - if (!face) {
|
| - resolver->error();
|
| - continue;
|
| - }
|
| - face->loadFont(font.fontDescription(), nullToSpace(text), resolver);
|
| + CSSSegmentedFontFace* segmentedFontFace = fontFaceCache->get(font.fontDescription(), f->family());
|
| + if (segmentedFontFace)
|
| + segmentedFontFace->match(nullToSpace(text), faces);
|
| }
|
| - fontSelector->loadPendingFonts();
|
| +
|
| + RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(faces, executionContext());
|
| + ScriptPromise promise = resolver->promise();
|
| + resolver->loadFonts(executionContext()); // After this, resolver->promise() may return null.
|
| return promise;
|
| }
|
|
|
|
|