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

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
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 ScriptPromise promise() { return m_resolver->promise(); }
66 void resolve();
72 private: 67 private:
73 LoadFontCallback(int numLoading, PassRefPtr<VoidCallback> loadCallback, Pass RefPtr<VoidCallback> errorCallback) 68 LoadFontPromiseResolver(int numLoading, ScriptExecutionContext* context)
74 : m_numLoading(numLoading) 69 : m_numLoading(numLoading)
75 , m_errorOccured(false) 70 , m_errorOccured(false)
76 , m_loadCallback(loadCallback) 71 , m_scriptState(ScriptState::current())
77 , m_errorCallback(errorCallback) 72 , m_resolver(ScriptPromiseResolver::create(context))
78 { } 73 { }
79 74
80 int m_numLoading; 75 int m_numLoading;
81 bool m_errorOccured; 76 bool m_errorOccured;
82 RefPtr<VoidCallback> m_loadCallback; 77 ScriptState* m_scriptState;
83 RefPtr<VoidCallback> m_errorCallback; 78 RefPtr<ScriptPromiseResolver> m_resolver;
84 }; 79 };
85 80
86 void LoadFontCallback::loaded(Document* document) 81 void LoadFontPromiseResolver::loaded(Document* document)
87 { 82 {
88 m_numLoading--; 83 m_numLoading--;
89 if (m_numLoading || !document) 84 if (m_numLoading || !document)
90 return; 85 return;
91 86
92 if (m_errorOccured) { 87 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 } 88 }
100 89
101 void LoadFontCallback::error(Document* document) 90 void LoadFontPromiseResolver::error(Document* document)
102 { 91 {
103 m_errorOccured = true; 92 m_errorOccured = true;
104 loaded(document); 93 loaded(document);
105 } 94 }
106 95
107 void LoadFontCallback::notifyLoaded(CSSSegmentedFontFace* face) 96 void LoadFontPromiseResolver::notifyLoaded(CSSSegmentedFontFace* face)
108 { 97 {
109 loaded(face->fontSelector()->document()); 98 loaded(face->fontSelector()->document());
110 } 99 }
111 100
112 void LoadFontCallback::notifyError(CSSSegmentedFontFace* face) 101 void LoadFontPromiseResolver::notifyError(CSSSegmentedFontFace* face)
113 { 102 {
114 error(face->fontSelector()->document()); 103 error(face->fontSelector()->document());
115 } 104 }
116 105
106 void LoadFontPromiseResolver::resolve()
107 {
108 ScriptScope scope(m_scriptState);
109 if (m_errorOccured)
110 m_resolver->reject(ScriptValue::createNull());
111 else
112 m_resolver->fulfill(ScriptValue::createNull());
113 }
114
115 class FontsReadyPromiseResolver {
116 public:
117 static PassOwnPtr<FontsReadyPromiseResolver> create(ScriptExecutionContext* context)
118 {
119 return adoptPtr(new FontsReadyPromiseResolver(context));
120 }
121
122 void call(PassRefPtr<FontFaceSet> fontFaceSet)
123 {
124 ScriptScope scope(m_scriptState);
125 m_resolver->fulfill(fontFaceSet);
126 }
127
128 ScriptPromise promise() { return m_resolver->promise(); }
129
130 private:
131 FontsReadyPromiseResolver(ScriptExecutionContext* context)
132 : m_scriptState(ScriptState::current())
133 , m_resolver(ScriptPromiseResolver::create(context))
134 { }
135 ScriptState* m_scriptState;
136 RefPtr<ScriptPromiseResolver> m_resolver;
137 };
138
117 FontFaceSet::FontFaceSet(Document* document) 139 FontFaceSet::FontFaceSet(Document* document)
118 : ActiveDOMObject(document) 140 : ActiveDOMObject(document)
119 , m_loadingCount(0) 141 , m_loadingCount(0)
120 , m_shouldFireDoneEvent(false) 142 , m_shouldFireDoneEvent(false)
121 , m_timer(this, &FontFaceSet::timerFired) 143 , m_timer(this, &FontFaceSet::timerFired)
122 { 144 {
123 suspendIfNeeded(); 145 suspendIfNeeded();
124 } 146 }
125 147
126 FontFaceSet::~FontFaceSet() 148 FontFaceSet::~FontFaceSet()
(...skipping 25 matching lines...) Expand all
152 return ActiveDOMObject::scriptExecutionContext(); 174 return ActiveDOMObject::scriptExecutionContext();
153 } 175 }
154 176
155 void FontFaceSet::didLayout() 177 void FontFaceSet::didLayout()
156 { 178 {
157 Document* d = document(); 179 Document* d = document();
158 if (d->page() && d->page()->mainFrame() == d->frame()) 180 if (d->page() && d->page()->mainFrame() == d->frame())
159 m_histogram.record(); 181 m_histogram.record();
160 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled()) 182 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
161 return; 183 return;
162 if (m_loadingCount || (!m_shouldFireDoneEvent && m_fontsReadyCallbacks.isEmp ty())) 184 if (m_loadingCount || (!m_shouldFireDoneEvent && m_readyPromises.isEmpty()))
163 return; 185 return;
164 if (!m_timer.isActive()) 186 if (!m_timer.isActive())
165 m_timer.startOneShot(0); 187 m_timer.startOneShot(0);
166 } 188 }
167 189
168 void FontFaceSet::timerFired(Timer<FontFaceSet>*) 190 void FontFaceSet::timerFired(Timer<FontFaceSet>*)
169 { 191 {
170 firePendingEvents(); 192 firePendingEvents();
171 firePendingCallbacks(); 193 resolvePendingLoadPromises();
172 fireDoneEventIfPossible(); 194 fireDoneEventIfPossible();
173 } 195 }
174 196
175 void FontFaceSet::scheduleEvent(PassRefPtr<Event> event) 197 void FontFaceSet::scheduleEvent(PassRefPtr<Event> event)
176 { 198 {
177 m_pendingEvents.append(event); 199 m_pendingEvents.append(event);
178 if (!m_timer.isActive()) 200 if (!m_timer.isActive())
179 m_timer.startOneShot(0); 201 m_timer.startOneShot(0);
180 } 202 }
181 203
182 void FontFaceSet::firePendingEvents() 204 void FontFaceSet::firePendingEvents()
183 { 205 {
184 if (m_pendingEvents.isEmpty()) 206 if (m_pendingEvents.isEmpty())
185 return; 207 return;
186 208
187 Vector<RefPtr<Event> > pendingEvents; 209 Vector<RefPtr<Event> > pendingEvents;
188 m_pendingEvents.swap(pendingEvents); 210 m_pendingEvents.swap(pendingEvents);
189 for (size_t index = 0; index < pendingEvents.size(); ++index) 211 for (size_t index = 0; index < pendingEvents.size(); ++index)
190 dispatchEvent(pendingEvents[index].release()); 212 dispatchEvent(pendingEvents[index].release());
191 } 213 }
192 214
193 void FontFaceSet::scheduleCallback(PassRefPtr<VoidCallback> callback) 215 void FontFaceSet::scheduleResolve(LoadFontPromiseResolver* resolver)
194 { 216 {
195 m_pendingCallbacks.append(callback); 217 m_pendingLoadPromises.append(resolver);
196 if (!m_timer.isActive()) 218 if (!m_timer.isActive())
197 m_timer.startOneShot(0); 219 m_timer.startOneShot(0);
198 } 220 }
199 221
200 void FontFaceSet::firePendingCallbacks() 222 void FontFaceSet::resolvePendingLoadPromises()
201 { 223 {
202 if (m_pendingCallbacks.isEmpty()) 224 if (m_pendingLoadPromises.isEmpty())
203 return; 225 return;
204 226
205 Vector<RefPtr<VoidCallback> > pendingCallbacks; 227 Vector<RefPtr<LoadFontPromiseResolver> > resolvers;
206 m_pendingCallbacks.swap(pendingCallbacks); 228 m_pendingLoadPromises.swap(resolvers);
207 for (size_t index = 0; index < pendingCallbacks.size(); ++index) 229 for (size_t index = 0; index < resolvers.size(); ++index)
208 pendingCallbacks[index]->handleEvent(); 230 resolvers[index]->resolve();
209 } 231 }
210 232
211 void FontFaceSet::beginFontLoading(FontFace* fontFace) 233 void FontFaceSet::beginFontLoading(FontFace* fontFace)
212 { 234 {
213 m_histogram.incrementCount(); 235 m_histogram.incrementCount();
214 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled()) 236 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
215 return; 237 return;
216 238
217 ++m_loadingCount; 239 ++m_loadingCount;
218 if (m_loadingCount == 1 && !m_shouldFireDoneEvent) 240 if (m_loadingCount == 1 && !m_shouldFireDoneEvent)
(...skipping 22 matching lines...) Expand all
241 ASSERT(m_loadingCount > 0); 263 ASSERT(m_loadingCount > 0);
242 --m_loadingCount; 264 --m_loadingCount;
243 if (!m_loadingCount) { 265 if (!m_loadingCount) {
244 ASSERT(!m_shouldFireDoneEvent); 266 ASSERT(!m_shouldFireDoneEvent);
245 m_shouldFireDoneEvent = true; 267 m_shouldFireDoneEvent = true;
246 if (!m_timer.isActive()) 268 if (!m_timer.isActive())
247 m_timer.startOneShot(0); 269 m_timer.startOneShot(0);
248 } 270 }
249 } 271 }
250 272
251 void FontFaceSet::notifyWhenFontsReady(PassRefPtr<VoidCallback> callback) 273 ScriptPromise FontFaceSet::ready()
252 { 274 {
253 m_fontsReadyCallbacks.append(callback); 275 OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::crea te(scriptExecutionContext());
276 ScriptPromise promise = resolver->promise();
yhirano 2013/09/18 11:49:45 You should call ScriptPromiseResolver::detachPromi
Kunihiko Sakamoto 2013/09/19 01:14:26 Changed FontsReadyPromiseResolver::promise() detac
277 m_readyPromises.append(resolver.release());
254 if (!m_timer.isActive()) 278 if (!m_timer.isActive())
255 m_timer.startOneShot(0); 279 m_timer.startOneShot(0);
280 return promise;
256 } 281 }
257 282
258 void FontFaceSet::fireDoneEventIfPossible() 283 void FontFaceSet::fireDoneEventIfPossible()
259 { 284 {
260 if (!m_pendingEvents.isEmpty() || !m_pendingCallbacks.isEmpty()) 285 if (!m_pendingEvents.isEmpty() || !m_pendingLoadPromises.isEmpty())
261 return; 286 return;
262 if (m_loadingCount || (!m_shouldFireDoneEvent && m_fontsReadyCallbacks.isEmp ty())) 287 if (m_loadingCount || (!m_shouldFireDoneEvent && m_readyPromises.isEmpty()))
263 return; 288 return;
264 289
265 // If the layout was invalidated in between when we thought layout 290 // 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 291 // was updated and when we're ready to fire the event, just wait
267 // until after the next layout before firing events. 292 // until after the next layout before firing events.
268 Document* d = document(); 293 Document* d = document();
269 if (!d->view() || d->view()->needsLayout()) 294 if (!d->view() || d->view()->needsLayout())
270 return; 295 return;
271 296
272 if (m_shouldFireDoneEvent) { 297 if (m_shouldFireDoneEvent) {
273 m_shouldFireDoneEvent = false; 298 m_shouldFireDoneEvent = false;
274 RefPtr<CSSFontFaceLoadEvent> doneEvent; 299 RefPtr<CSSFontFaceLoadEvent> doneEvent;
275 RefPtr<CSSFontFaceLoadEvent> errorEvent; 300 RefPtr<CSSFontFaceLoadEvent> errorEvent;
276 doneEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().loadin gdoneEvent, m_loadedFonts); 301 doneEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().loadin gdoneEvent, m_loadedFonts);
277 m_loadedFonts.clear(); 302 m_loadedFonts.clear();
278 if (!m_failedFonts.isEmpty()) { 303 if (!m_failedFonts.isEmpty()) {
279 errorEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().l oadingerrorEvent, m_failedFonts); 304 errorEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().l oadingerrorEvent, m_failedFonts);
280 m_failedFonts.clear(); 305 m_failedFonts.clear();
281 } 306 }
282 dispatchEvent(doneEvent); 307 dispatchEvent(doneEvent);
283 if (errorEvent) 308 if (errorEvent)
284 dispatchEvent(errorEvent); 309 dispatchEvent(errorEvent);
285 } 310 }
286 311
287 if (!m_fontsReadyCallbacks.isEmpty()) { 312 if (!m_readyPromises.isEmpty()) {
288 Vector<RefPtr<VoidCallback> > callbacks; 313 Vector<OwnPtr<FontsReadyPromiseResolver> > resolvers;
289 m_fontsReadyCallbacks.swap(callbacks); 314 m_readyPromises.swap(resolvers);
290 for (size_t index = 0; index < callbacks.size(); ++index) 315 for (size_t index = 0; index < resolvers.size(); ++index)
291 callbacks[index]->handleEvent(); 316 resolvers[index]->call(this);
292 } 317 }
293 } 318 }
294 319
295 void FontFaceSet::loadFont(const Dictionary& params) 320 Vector<RefPtr<FontFace> > FontFaceSet::match(const String& fontString, const Str ing&, ExceptionState& es)
296 { 321 {
297 // FIXME: The text member of params is ignored. 322 // FIXME: The second parameter (text) is ignored.
298 String fontString; 323 Vector<RefPtr<FontFace> > matchedFonts;
299 if (!params.get("font", fontString)) 324
300 return;
301 Font font; 325 Font font;
302 if (!resolveFontStyle(fontString, font)) 326 if (!resolveFontStyle(fontString, font)) {
303 return; 327 es.throwDOMException(SyntaxError);
304 RefPtr<LoadFontCallback> callback = LoadFontCallback::createFromParams(param s, font.family()); 328 return matchedFonts;
329 }
305 330
306 for (const FontFamily* f = &font.family(); f; f = f->next()) { 331 for (const FontFamily* f = &font.family(); f; f = f->next()) {
332 CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector() ->getFontFace(font.fontDescription(), f->family());
333 if (face)
334 matchedFonts.append(face->fontFaces());
335 }
336 return matchedFonts;
337 }
338
339 ScriptPromise FontFaceSet::load(const String& fontString, const String&, Excepti onState& es)
340 {
341 // FIXME: The second parameter (text) is ignored.
342 Font font;
343 if (!resolveFontStyle(fontString, font)) {
344 es.throwDOMException(SyntaxError);
345 return ScriptPromise();
346 }
347
348 RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(f ont.family(), scriptExecutionContext());
349 for (const FontFamily* f = &font.family(); f; f = f->next()) {
307 Document* d = document(); 350 Document* d = document();
308 CSSSegmentedFontFace* face = d->styleResolver()->fontSelector()->getFont Face(font.fontDescription(), f->family()); 351 CSSSegmentedFontFace* face = d->styleResolver()->fontSelector()->getFont Face(font.fontDescription(), f->family());
309 if (!face) { 352 if (!face) {
310 if (callback) 353 resolver->error(d);
311 callback->error(d);
312 continue; 354 continue;
313 } 355 }
314 face->loadFont(font.fontDescription(), callback); 356 face->loadFont(font.fontDescription(), resolver);
315 } 357 }
yhirano 2013/09/18 11:49:45 What happens if face == NULL for all f in the loop
Kunihiko Sakamoto 2013/09/19 01:14:26 Then FontFaceSet::scheduleResolve is called inside
358 return resolver->promise();
yhirano 2013/09/18 11:49:45 You should call ScriptPromiseResolver::detachPromi
Kunihiko Sakamoto 2013/09/19 01:14:26 Now LoadFontPromiseResolver::promise() does that.
316 } 359 }
317 360
318 bool FontFaceSet::checkFont(const String& fontString, const String&) 361 bool FontFaceSet::check(const String& fontString, const String&, ExceptionState& es)
319 { 362 {
320 // FIXME: The second parameter (text) is ignored. 363 // FIXME: The second parameter (text) is ignored.
321 Font font; 364 Font font;
322 if (!resolveFontStyle(fontString, font)) 365 if (!resolveFontStyle(fontString, font)) {
366 es.throwDOMException(SyntaxError);
323 return false; 367 return false;
368 }
369
324 for (const FontFamily* f = &font.family(); f; f = f->next()) { 370 for (const FontFamily* f = &font.family(); f; f = f->next()) {
325 CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector() ->getFontFace(font.fontDescription(), f->family()); 371 CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector() ->getFontFace(font.fontDescription(), f->family());
326 if (!face || !face->checkFont()) 372 if (!face || !face->checkFont())
327 return false; 373 return false;
328 } 374 }
329 return true; 375 return true;
330 } 376 }
331 377
332 bool FontFaceSet::resolveFontStyle(const String& fontString, Font& font) 378 bool FontFaceSet::resolveFontStyle(const String& fontString, Font& font)
333 { 379 {
380 if (fontString.isEmpty())
381 return false;
382
334 // Interpret fontString in the same way as the 'font' attribute of CanvasRen deringContext2D. 383 // Interpret fontString in the same way as the 'font' attribute of CanvasRen deringContext2D.
335 RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::creat e(); 384 RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::creat e();
336 CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, CSSStrictMode, 0); 385 CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, CSSStrictMode, 0);
337 if (parsedStyle->isEmpty()) 386 if (parsedStyle->isEmpty())
338 return false; 387 return false;
339 388
340 String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont); 389 String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont);
341 if (fontValue == "inherit" || fontValue == "initial") 390 if (fontValue == "inherit" || fontValue == "initial")
342 return false; 391 return false;
343 392
(...skipping 30 matching lines...) Expand all
374 423
375 void FontFaceSet::FontLoadHistogram::record() 424 void FontFaceSet::FontLoadHistogram::record()
376 { 425 {
377 if (m_recorded) 426 if (m_recorded)
378 return; 427 return;
379 m_recorded = true; 428 m_recorded = true;
380 HistogramSupport::histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1 , 100, 50); 429 HistogramSupport::histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1 , 100, 50);
381 } 430 }
382 431
383 } // namespace WebCore 432 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698