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

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

Issue 23717059: [Font Load Events] Implement FontFaceSet methods (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 3 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
« no previous file with comments | « Source/core/css/FontFaceSet.h ('k') | Source/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 "config.h" 26 #include "config.h"
27 #include "core/css/FontFaceSet.h" 27 #include "core/css/FontFaceSet.h"
28 28
29 #include "RuntimeEnabledFeatures.h" 29 #include "RuntimeEnabledFeatures.h"
30 #include "V8FontFaceSet.h"
30 #include "bindings/v8/Dictionary.h" 31 #include "bindings/v8/Dictionary.h"
32 #include "bindings/v8/ScriptPromiseResolver.h"
33 #include "bindings/v8/ScriptScope.h"
34 #include "bindings/v8/ScriptState.h"
31 #include "core/css/CSSFontFaceLoadEvent.h" 35 #include "core/css/CSSFontFaceLoadEvent.h"
32 #include "core/css/CSSFontFaceSource.h" 36 #include "core/css/CSSFontFaceSource.h"
33 #include "core/css/CSSFontSelector.h" 37 #include "core/css/CSSFontSelector.h"
34 #include "core/css/CSSParser.h" 38 #include "core/css/CSSParser.h"
35 #include "core/css/CSSSegmentedFontFace.h" 39 #include "core/css/CSSSegmentedFontFace.h"
36 #include "core/css/StylePropertySet.h" 40 #include "core/css/StylePropertySet.h"
37 #include "core/css/resolver/StyleResolver.h" 41 #include "core/css/resolver/StyleResolver.h"
38 #include "core/dom/Document.h" 42 #include "core/dom/Document.h"
39 #include "core/page/FrameView.h" 43 #include "core/page/FrameView.h"
40 #include "core/platform/HistogramSupport.h" 44 #include "core/platform/HistogramSupport.h"
41 45
42 namespace WebCore { 46 namespace WebCore {
43 47
44 static const int defaultFontSize = 10; 48 static const int defaultFontSize = 10;
45 static const char* const defaultFontFamily = "sans-serif"; 49 static const char* const defaultFontFamily = "sans-serif";
46 50
47 class LoadFontCallback : public CSSSegmentedFontFace::LoadFontCallback { 51 class LoadFontPromiseResolver : public CSSSegmentedFontFace::LoadFontCallback {
48 public: 52 public:
49 static PassRefPtr<LoadFontCallback> create(int numLoading, PassRefPtr<VoidCa llback> loadCallback, PassRefPtr<VoidCallback> errorCallback) 53 static PassRefPtr<LoadFontPromiseResolver> create(const FontFamily& family, ScriptExecutionContext* context)
50 { 54 {
51 return adoptRef<LoadFontCallback>(new LoadFontCallback(numLoading, loadC allback, errorCallback));
52 }
53
54 static PassRefPtr<LoadFontCallback> createFromParams(const Dictionary& param s, const FontFamily& family)
55 {
56 RefPtr<VoidCallback> onsuccess;
57 RefPtr<VoidCallback> onerror;
58 params.get("onsuccess", onsuccess);
59 params.get("onerror", onerror);
60 if (!onsuccess && !onerror)
61 return 0;
62 int numFamilies = 0; 55 int numFamilies = 0;
63 for (const FontFamily* f = &family; f; f = f->next()) 56 for (const FontFamily* f = &family; f; f = f->next())
64 numFamilies++; 57 numFamilies++;
65 return LoadFontCallback::create(numFamilies, onsuccess, onerror); 58 return adoptRef<LoadFontPromiseResolver>(new LoadFontPromiseResolver(num Families, context));
66 } 59 }
67 60
68 virtual void notifyLoaded(CSSSegmentedFontFace*) OVERRIDE; 61 virtual void notifyLoaded(CSSSegmentedFontFace*) OVERRIDE;
69 virtual void notifyError(CSSSegmentedFontFace*) OVERRIDE; 62 virtual void notifyError(CSSSegmentedFontFace*) OVERRIDE;
70 void loaded(Document*); 63 void loaded(Document*);
71 void error(Document*); 64 void error(Document*);
65 void resolve();
66
67 ScriptPromise promise()
68 {
69 ScriptPromise promise = m_resolver->promise();
70 m_resolver->detachPromise();
71 return promise;
72 }
73
72 private: 74 private:
73 LoadFontCallback(int numLoading, PassRefPtr<VoidCallback> loadCallback, Pass RefPtr<VoidCallback> errorCallback) 75 LoadFontPromiseResolver(int numLoading, ScriptExecutionContext* context)
74 : m_numLoading(numLoading) 76 : m_numLoading(numLoading)
75 , m_errorOccured(false) 77 , m_errorOccured(false)
76 , m_loadCallback(loadCallback) 78 , m_scriptState(ScriptState::current())
77 , m_errorCallback(errorCallback) 79 , m_resolver(ScriptPromiseResolver::create(context))
78 { } 80 { }
79 81
80 int m_numLoading; 82 int m_numLoading;
81 bool m_errorOccured; 83 bool m_errorOccured;
82 RefPtr<VoidCallback> m_loadCallback; 84 ScriptState* m_scriptState;
83 RefPtr<VoidCallback> m_errorCallback; 85 RefPtr<ScriptPromiseResolver> m_resolver;
84 }; 86 };
85 87
86 void LoadFontCallback::loaded(Document* document) 88 void LoadFontPromiseResolver::loaded(Document* document)
87 { 89 {
88 m_numLoading--; 90 m_numLoading--;
89 if (m_numLoading || !document) 91 if (m_numLoading || !document)
90 return; 92 return;
91 93
92 if (m_errorOccured) { 94 document->fonts()->scheduleResolve(this);
93 if (m_errorCallback)
94 document->fonts()->scheduleCallback(m_errorCallback.release());
95 } else {
96 if (m_loadCallback)
97 document->fonts()->scheduleCallback(m_loadCallback.release());
98 }
99 } 95 }
100 96
101 void LoadFontCallback::error(Document* document) 97 void LoadFontPromiseResolver::error(Document* document)
102 { 98 {
103 m_errorOccured = true; 99 m_errorOccured = true;
104 loaded(document); 100 loaded(document);
105 } 101 }
106 102
107 void LoadFontCallback::notifyLoaded(CSSSegmentedFontFace* face) 103 void LoadFontPromiseResolver::notifyLoaded(CSSSegmentedFontFace* face)
108 { 104 {
109 loaded(face->fontSelector()->document()); 105 loaded(face->fontSelector()->document());
110 } 106 }
111 107
112 void LoadFontCallback::notifyError(CSSSegmentedFontFace* face) 108 void LoadFontPromiseResolver::notifyError(CSSSegmentedFontFace* face)
113 { 109 {
114 error(face->fontSelector()->document()); 110 error(face->fontSelector()->document());
115 } 111 }
116 112
113 void LoadFontPromiseResolver::resolve()
114 {
115 ScriptScope scope(m_scriptState);
116 if (m_errorOccured)
117 m_resolver->reject(ScriptValue::createNull());
118 else
119 m_resolver->fulfill(ScriptValue::createNull());
120 }
121
122 class FontsReadyPromiseResolver {
123 public:
124 static PassOwnPtr<FontsReadyPromiseResolver> create(ScriptExecutionContext* context)
125 {
126 return adoptPtr(new FontsReadyPromiseResolver(context));
127 }
128
129 void call(PassRefPtr<FontFaceSet> fontFaceSet)
130 {
131 ScriptScope scope(m_scriptState);
132 m_resolver->fulfill(fontFaceSet);
133 }
134
135 ScriptPromise promise()
136 {
137 ScriptPromise promise = m_resolver->promise();
138 m_resolver->detachPromise();
139 return promise;
140 }
141
142 private:
143 FontsReadyPromiseResolver(ScriptExecutionContext* context)
144 : m_scriptState(ScriptState::current())
145 , m_resolver(ScriptPromiseResolver::create(context))
146 { }
147 ScriptState* m_scriptState;
148 RefPtr<ScriptPromiseResolver> m_resolver;
149 };
150
117 FontFaceSet::FontFaceSet(Document* document) 151 FontFaceSet::FontFaceSet(Document* document)
118 : ActiveDOMObject(document) 152 : ActiveDOMObject(document)
119 , m_loadingCount(0) 153 , m_loadingCount(0)
120 , m_shouldFireDoneEvent(false) 154 , m_shouldFireDoneEvent(false)
121 , m_timer(this, &FontFaceSet::timerFired) 155 , m_timer(this, &FontFaceSet::timerFired)
122 { 156 {
123 suspendIfNeeded(); 157 suspendIfNeeded();
124 } 158 }
125 159
126 FontFaceSet::~FontFaceSet() 160 FontFaceSet::~FontFaceSet()
(...skipping 18 matching lines...) Expand all
145 const AtomicString& FontFaceSet::interfaceName() const 179 const AtomicString& FontFaceSet::interfaceName() const
146 { 180 {
147 return eventNames().interfaceForFontFaceSet; 181 return eventNames().interfaceForFontFaceSet;
148 } 182 }
149 183
150 ScriptExecutionContext* FontFaceSet::scriptExecutionContext() const 184 ScriptExecutionContext* FontFaceSet::scriptExecutionContext() const
151 { 185 {
152 return ActiveDOMObject::scriptExecutionContext(); 186 return ActiveDOMObject::scriptExecutionContext();
153 } 187 }
154 188
189 AtomicString FontFaceSet::status() const
190 {
191 DEFINE_STATIC_LOCAL(AtomicString, loading, ("loading", AtomicString::Constru ctFromLiteral));
192 DEFINE_STATIC_LOCAL(AtomicString, loaded, ("loaded", AtomicString::Construct FromLiteral));
193 return (m_loadingCount > 0 || m_shouldFireDoneEvent) ? loading : loaded;
194 }
195
155 void FontFaceSet::didLayout() 196 void FontFaceSet::didLayout()
156 { 197 {
157 Document* d = document(); 198 Document* d = document();
158 if (d->page() && d->page()->mainFrame() == d->frame()) 199 if (d->page() && d->page()->mainFrame() == d->frame())
159 m_histogram.record(); 200 m_histogram.record();
160 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled()) 201 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
161 return; 202 return;
162 if (m_loadingCount || (!m_shouldFireDoneEvent && m_fontsReadyCallbacks.isEmp ty())) 203 if (m_loadingCount || (!m_shouldFireDoneEvent && m_readyResolvers.isEmpty()) )
163 return; 204 return;
164 if (!m_timer.isActive()) 205 if (!m_timer.isActive())
165 m_timer.startOneShot(0); 206 m_timer.startOneShot(0);
166 } 207 }
167 208
168 void FontFaceSet::timerFired(Timer<FontFaceSet>*) 209 void FontFaceSet::timerFired(Timer<FontFaceSet>*)
169 { 210 {
170 firePendingEvents(); 211 firePendingEvents();
171 firePendingCallbacks(); 212 resolvePendingLoadPromises();
172 fireDoneEventIfPossible(); 213 fireDoneEventIfPossible();
173 } 214 }
174 215
175 void FontFaceSet::scheduleEvent(PassRefPtr<Event> event) 216 void FontFaceSet::scheduleEvent(PassRefPtr<Event> event)
176 { 217 {
177 m_pendingEvents.append(event); 218 m_pendingEvents.append(event);
178 if (!m_timer.isActive()) 219 if (!m_timer.isActive())
179 m_timer.startOneShot(0); 220 m_timer.startOneShot(0);
180 } 221 }
181 222
182 void FontFaceSet::firePendingEvents() 223 void FontFaceSet::firePendingEvents()
183 { 224 {
184 if (m_pendingEvents.isEmpty()) 225 if (m_pendingEvents.isEmpty())
185 return; 226 return;
186 227
187 Vector<RefPtr<Event> > pendingEvents; 228 Vector<RefPtr<Event> > pendingEvents;
188 m_pendingEvents.swap(pendingEvents); 229 m_pendingEvents.swap(pendingEvents);
189 for (size_t index = 0; index < pendingEvents.size(); ++index) 230 for (size_t index = 0; index < pendingEvents.size(); ++index)
190 dispatchEvent(pendingEvents[index].release()); 231 dispatchEvent(pendingEvents[index].release());
191 } 232 }
192 233
193 void FontFaceSet::scheduleCallback(PassRefPtr<VoidCallback> callback) 234 void FontFaceSet::scheduleResolve(LoadFontPromiseResolver* resolver)
194 { 235 {
195 m_pendingCallbacks.append(callback); 236 m_pendingLoadResolvers.append(resolver);
196 if (!m_timer.isActive()) 237 if (!m_timer.isActive())
197 m_timer.startOneShot(0); 238 m_timer.startOneShot(0);
198 } 239 }
199 240
200 void FontFaceSet::firePendingCallbacks() 241 void FontFaceSet::resolvePendingLoadPromises()
201 { 242 {
202 if (m_pendingCallbacks.isEmpty()) 243 if (m_pendingLoadResolvers.isEmpty())
203 return; 244 return;
204 245
205 Vector<RefPtr<VoidCallback> > pendingCallbacks; 246 Vector<RefPtr<LoadFontPromiseResolver> > resolvers;
206 m_pendingCallbacks.swap(pendingCallbacks); 247 m_pendingLoadResolvers.swap(resolvers);
207 for (size_t index = 0; index < pendingCallbacks.size(); ++index) 248 for (size_t index = 0; index < resolvers.size(); ++index)
208 pendingCallbacks[index]->handleEvent(); 249 resolvers[index]->resolve();
209 } 250 }
210 251
211 void FontFaceSet::beginFontLoading(FontFace* fontFace) 252 void FontFaceSet::beginFontLoading(FontFace* fontFace)
212 { 253 {
213 m_histogram.incrementCount(); 254 m_histogram.incrementCount();
214 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled()) 255 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
215 return; 256 return;
216 257
217 ++m_loadingCount; 258 ++m_loadingCount;
218 if (m_loadingCount == 1 && !m_shouldFireDoneEvent) 259 if (m_loadingCount == 1 && !m_shouldFireDoneEvent)
(...skipping 22 matching lines...) Expand all
241 ASSERT(m_loadingCount > 0); 282 ASSERT(m_loadingCount > 0);
242 --m_loadingCount; 283 --m_loadingCount;
243 if (!m_loadingCount) { 284 if (!m_loadingCount) {
244 ASSERT(!m_shouldFireDoneEvent); 285 ASSERT(!m_shouldFireDoneEvent);
245 m_shouldFireDoneEvent = true; 286 m_shouldFireDoneEvent = true;
246 if (!m_timer.isActive()) 287 if (!m_timer.isActive())
247 m_timer.startOneShot(0); 288 m_timer.startOneShot(0);
248 } 289 }
249 } 290 }
250 291
251 void FontFaceSet::notifyWhenFontsReady(PassRefPtr<VoidCallback> callback) 292 ScriptPromise FontFaceSet::ready()
252 { 293 {
253 m_fontsReadyCallbacks.append(callback); 294 OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::crea te(scriptExecutionContext());
295 ScriptPromise promise = resolver->promise();
296 m_readyResolvers.append(resolver.release());
254 if (!m_timer.isActive()) 297 if (!m_timer.isActive())
255 m_timer.startOneShot(0); 298 m_timer.startOneShot(0);
299 return promise;
256 } 300 }
257 301
258 void FontFaceSet::fireDoneEventIfPossible() 302 void FontFaceSet::fireDoneEventIfPossible()
259 { 303 {
260 if (!m_pendingEvents.isEmpty() || !m_pendingCallbacks.isEmpty()) 304 if (!m_pendingEvents.isEmpty() || !m_pendingLoadResolvers.isEmpty())
261 return; 305 return;
262 if (m_loadingCount || (!m_shouldFireDoneEvent && m_fontsReadyCallbacks.isEmp ty())) 306 if (m_loadingCount || (!m_shouldFireDoneEvent && m_readyResolvers.isEmpty()) )
263 return; 307 return;
264 308
265 // If the layout was invalidated in between when we thought layout 309 // If the layout was invalidated in between when we thought layout
266 // was updated and when we're ready to fire the event, just wait 310 // was updated and when we're ready to fire the event, just wait
267 // until after the next layout before firing events. 311 // until after the next layout before firing events.
268 Document* d = document(); 312 Document* d = document();
269 if (!d->view() || d->view()->needsLayout()) 313 if (!d->view() || d->view()->needsLayout())
270 return; 314 return;
271 315
272 if (m_shouldFireDoneEvent) { 316 if (m_shouldFireDoneEvent) {
273 m_shouldFireDoneEvent = false; 317 m_shouldFireDoneEvent = false;
274 RefPtr<CSSFontFaceLoadEvent> doneEvent; 318 RefPtr<CSSFontFaceLoadEvent> doneEvent;
275 RefPtr<CSSFontFaceLoadEvent> errorEvent; 319 RefPtr<CSSFontFaceLoadEvent> errorEvent;
276 doneEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().loadin gdoneEvent, m_loadedFonts); 320 doneEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().loadin gdoneEvent, m_loadedFonts);
277 m_loadedFonts.clear(); 321 m_loadedFonts.clear();
278 if (!m_failedFonts.isEmpty()) { 322 if (!m_failedFonts.isEmpty()) {
279 errorEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().l oadingerrorEvent, m_failedFonts); 323 errorEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().l oadingerrorEvent, m_failedFonts);
280 m_failedFonts.clear(); 324 m_failedFonts.clear();
281 } 325 }
282 dispatchEvent(doneEvent); 326 dispatchEvent(doneEvent);
283 if (errorEvent) 327 if (errorEvent)
284 dispatchEvent(errorEvent); 328 dispatchEvent(errorEvent);
285 } 329 }
286 330
287 if (!m_fontsReadyCallbacks.isEmpty()) { 331 if (!m_readyResolvers.isEmpty()) {
288 Vector<RefPtr<VoidCallback> > callbacks; 332 Vector<OwnPtr<FontsReadyPromiseResolver> > resolvers;
289 m_fontsReadyCallbacks.swap(callbacks); 333 m_readyResolvers.swap(resolvers);
290 for (size_t index = 0; index < callbacks.size(); ++index) 334 for (size_t index = 0; index < resolvers.size(); ++index)
291 callbacks[index]->handleEvent(); 335 resolvers[index]->call(this);
292 } 336 }
293 } 337 }
294 338
295 void FontFaceSet::loadFont(const Dictionary& params) 339 Vector<RefPtr<FontFace> > FontFaceSet::match(const String& fontString, const Str ing&, ExceptionState& es)
296 { 340 {
297 // FIXME: The text member of params is ignored. 341 // FIXME: The second parameter (text) is ignored.
298 String fontString; 342 Vector<RefPtr<FontFace> > matchedFonts;
299 if (!params.get("font", fontString)) 343
300 return;
301 Font font; 344 Font font;
302 if (!resolveFontStyle(fontString, font)) 345 if (!resolveFontStyle(fontString, font)) {
303 return; 346 es.throwDOMException(SyntaxError);
304 RefPtr<LoadFontCallback> callback = LoadFontCallback::createFromParams(param s, font.family()); 347 return matchedFonts;
348 }
305 349
306 for (const FontFamily* f = &font.family(); f; f = f->next()) { 350 for (const FontFamily* f = &font.family(); f; f = f->next()) {
307 Document* d = document(); 351 CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector() ->getFontFace(font.fontDescription(), f->family());
308 CSSSegmentedFontFace* face = d->styleResolver()->fontSelector()->getFont Face(font.fontDescription(), f->family()); 352 if (face)
309 if (!face) { 353 matchedFonts.append(face->fontFaces());
310 if (callback)
311 callback->error(d);
312 continue;
313 }
314 face->loadFont(font.fontDescription(), callback);
315 } 354 }
355 return matchedFonts;
316 } 356 }
317 357
318 bool FontFaceSet::checkFont(const String& fontString, const String&) 358 ScriptPromise FontFaceSet::load(const String& fontString, const String&, Excepti onState& es)
319 { 359 {
320 // FIXME: The second parameter (text) is ignored. 360 // FIXME: The second parameter (text) is ignored.
321 Font font; 361 Font font;
322 if (!resolveFontStyle(fontString, font)) 362 if (!resolveFontStyle(fontString, font)) {
363 es.throwDOMException(SyntaxError);
364 return ScriptPromise();
365 }
366
367 Document* d = document();
368 RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(f ont.family(), scriptExecutionContext());
369 for (const FontFamily* f = &font.family(); f; f = f->next()) {
370 CSSSegmentedFontFace* face = d->styleResolver()->fontSelector()->getFont Face(font.fontDescription(), f->family());
371 if (!face) {
372 resolver->error(d);
373 continue;
374 }
375 face->loadFont(font.fontDescription(), resolver);
376 }
377 return resolver->promise();
378 }
379
380 bool FontFaceSet::check(const String& fontString, const String&, ExceptionState& es)
381 {
382 // FIXME: The second parameter (text) is ignored.
383 Font font;
384 if (!resolveFontStyle(fontString, font)) {
385 es.throwDOMException(SyntaxError);
323 return false; 386 return false;
387 }
388
324 for (const FontFamily* f = &font.family(); f; f = f->next()) { 389 for (const FontFamily* f = &font.family(); f; f = f->next()) {
325 CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector() ->getFontFace(font.fontDescription(), f->family()); 390 CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector() ->getFontFace(font.fontDescription(), f->family());
326 if (!face || !face->checkFont()) 391 if (!face || !face->checkFont())
327 return false; 392 return false;
328 } 393 }
329 return true; 394 return true;
330 } 395 }
331 396
332 bool FontFaceSet::resolveFontStyle(const String& fontString, Font& font) 397 bool FontFaceSet::resolveFontStyle(const String& fontString, Font& font)
333 { 398 {
399 if (fontString.isEmpty())
400 return false;
401
334 // Interpret fontString in the same way as the 'font' attribute of CanvasRen deringContext2D. 402 // Interpret fontString in the same way as the 'font' attribute of CanvasRen deringContext2D.
335 RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::creat e(); 403 RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::creat e();
336 CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, CSSStrictMode, 0); 404 CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, CSSStrictMode, 0);
337 if (parsedStyle->isEmpty()) 405 if (parsedStyle->isEmpty())
338 return false; 406 return false;
339 407
340 String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont); 408 String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont);
341 if (fontValue == "inherit" || fontValue == "initial") 409 if (fontValue == "inherit" || fontValue == "initial")
342 return false; 410 return false;
343 411
(...skipping 30 matching lines...) Expand all
374 442
375 void FontFaceSet::FontLoadHistogram::record() 443 void FontFaceSet::FontLoadHistogram::record()
376 { 444 {
377 if (m_recorded) 445 if (m_recorded)
378 return; 446 return;
379 m_recorded = true; 447 m_recorded = true;
380 HistogramSupport::histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1 , 100, 50); 448 HistogramSupport::histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1 , 100, 50);
381 } 449 }
382 450
383 } // namespace WebCore 451 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/css/FontFaceSet.h ('k') | Source/core/css/FontFaceSet.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698