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

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 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 25 matching lines...) Expand all
152 return ActiveDOMObject::scriptExecutionContext(); 186 return ActiveDOMObject::scriptExecutionContext();
153 } 187 }
154 188
155 void FontFaceSet::didLayout() 189 void FontFaceSet::didLayout()
156 { 190 {
157 Document* d = document(); 191 Document* d = document();
158 if (d->page() && d->page()->mainFrame() == d->frame()) 192 if (d->page() && d->page()->mainFrame() == d->frame())
159 m_histogram.record(); 193 m_histogram.record();
160 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled()) 194 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
161 return; 195 return;
162 if (m_loadingCount || (!m_shouldFireDoneEvent && m_fontsReadyCallbacks.isEmp ty())) 196 if (m_loadingCount || (!m_shouldFireDoneEvent && m_readyResolvers.isEmpty()) )
163 return; 197 return;
164 if (!m_timer.isActive()) 198 if (!m_timer.isActive())
165 m_timer.startOneShot(0); 199 m_timer.startOneShot(0);
166 } 200 }
167 201
168 void FontFaceSet::timerFired(Timer<FontFaceSet>*) 202 void FontFaceSet::timerFired(Timer<FontFaceSet>*)
169 { 203 {
170 firePendingEvents(); 204 firePendingEvents();
171 firePendingCallbacks(); 205 resolvePendingLoadPromises();
172 fireDoneEventIfPossible(); 206 fireDoneEventIfPossible();
173 } 207 }
174 208
175 void FontFaceSet::scheduleEvent(PassRefPtr<Event> event) 209 void FontFaceSet::scheduleEvent(PassRefPtr<Event> event)
176 { 210 {
177 m_pendingEvents.append(event); 211 m_pendingEvents.append(event);
178 if (!m_timer.isActive()) 212 if (!m_timer.isActive())
179 m_timer.startOneShot(0); 213 m_timer.startOneShot(0);
180 } 214 }
181 215
182 void FontFaceSet::firePendingEvents() 216 void FontFaceSet::firePendingEvents()
183 { 217 {
184 if (m_pendingEvents.isEmpty()) 218 if (m_pendingEvents.isEmpty())
185 return; 219 return;
186 220
187 Vector<RefPtr<Event> > pendingEvents; 221 Vector<RefPtr<Event> > pendingEvents;
188 m_pendingEvents.swap(pendingEvents); 222 m_pendingEvents.swap(pendingEvents);
189 for (size_t index = 0; index < pendingEvents.size(); ++index) 223 for (size_t index = 0; index < pendingEvents.size(); ++index)
190 dispatchEvent(pendingEvents[index].release()); 224 dispatchEvent(pendingEvents[index].release());
191 } 225 }
192 226
193 void FontFaceSet::scheduleCallback(PassRefPtr<VoidCallback> callback) 227 void FontFaceSet::scheduleResolve(LoadFontPromiseResolver* resolver)
194 { 228 {
195 m_pendingCallbacks.append(callback); 229 m_pendingLoadResolvers.append(resolver);
196 if (!m_timer.isActive()) 230 if (!m_timer.isActive())
197 m_timer.startOneShot(0); 231 m_timer.startOneShot(0);
198 } 232 }
199 233
200 void FontFaceSet::firePendingCallbacks() 234 void FontFaceSet::resolvePendingLoadPromises()
201 { 235 {
202 if (m_pendingCallbacks.isEmpty()) 236 if (m_pendingLoadResolvers.isEmpty())
203 return; 237 return;
204 238
205 Vector<RefPtr<VoidCallback> > pendingCallbacks; 239 Vector<RefPtr<LoadFontPromiseResolver> > resolvers;
206 m_pendingCallbacks.swap(pendingCallbacks); 240 m_pendingLoadResolvers.swap(resolvers);
207 for (size_t index = 0; index < pendingCallbacks.size(); ++index) 241 for (size_t index = 0; index < resolvers.size(); ++index)
208 pendingCallbacks[index]->handleEvent(); 242 resolvers[index]->resolve();
209 } 243 }
210 244
211 void FontFaceSet::beginFontLoading(FontFace* fontFace) 245 void FontFaceSet::beginFontLoading(FontFace* fontFace)
212 { 246 {
213 m_histogram.incrementCount(); 247 m_histogram.incrementCount();
214 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled()) 248 if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
215 return; 249 return;
216 250
217 ++m_loadingCount; 251 ++m_loadingCount;
218 if (m_loadingCount == 1 && !m_shouldFireDoneEvent) 252 if (m_loadingCount == 1 && !m_shouldFireDoneEvent)
(...skipping 22 matching lines...) Expand all
241 ASSERT(m_loadingCount > 0); 275 ASSERT(m_loadingCount > 0);
242 --m_loadingCount; 276 --m_loadingCount;
243 if (!m_loadingCount) { 277 if (!m_loadingCount) {
244 ASSERT(!m_shouldFireDoneEvent); 278 ASSERT(!m_shouldFireDoneEvent);
245 m_shouldFireDoneEvent = true; 279 m_shouldFireDoneEvent = true;
246 if (!m_timer.isActive()) 280 if (!m_timer.isActive())
247 m_timer.startOneShot(0); 281 m_timer.startOneShot(0);
248 } 282 }
249 } 283 }
250 284
251 void FontFaceSet::notifyWhenFontsReady(PassRefPtr<VoidCallback> callback) 285 ScriptPromise FontFaceSet::ready()
252 { 286 {
253 m_fontsReadyCallbacks.append(callback); 287 OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::crea te(scriptExecutionContext());
288 ScriptPromise promise = resolver->promise();
289 m_readyResolvers.append(resolver.release());
254 if (!m_timer.isActive()) 290 if (!m_timer.isActive())
255 m_timer.startOneShot(0); 291 m_timer.startOneShot(0);
292 return promise;
256 } 293 }
257 294
258 void FontFaceSet::fireDoneEventIfPossible() 295 void FontFaceSet::fireDoneEventIfPossible()
259 { 296 {
260 if (!m_pendingEvents.isEmpty() || !m_pendingCallbacks.isEmpty()) 297 if (!m_pendingEvents.isEmpty() || !m_pendingLoadResolvers.isEmpty())
261 return; 298 return;
262 if (m_loadingCount || (!m_shouldFireDoneEvent && m_fontsReadyCallbacks.isEmp ty())) 299 if (m_loadingCount || (!m_shouldFireDoneEvent && m_readyResolvers.isEmpty()) )
263 return; 300 return;
264 301
265 // If the layout was invalidated in between when we thought layout 302 // 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 303 // was updated and when we're ready to fire the event, just wait
267 // until after the next layout before firing events. 304 // until after the next layout before firing events.
268 Document* d = document(); 305 Document* d = document();
269 if (!d->view() || d->view()->needsLayout()) 306 if (!d->view() || d->view()->needsLayout())
270 return; 307 return;
271 308
272 if (m_shouldFireDoneEvent) { 309 if (m_shouldFireDoneEvent) {
273 m_shouldFireDoneEvent = false; 310 m_shouldFireDoneEvent = false;
274 RefPtr<CSSFontFaceLoadEvent> doneEvent; 311 RefPtr<CSSFontFaceLoadEvent> doneEvent;
275 RefPtr<CSSFontFaceLoadEvent> errorEvent; 312 RefPtr<CSSFontFaceLoadEvent> errorEvent;
276 doneEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().loadin gdoneEvent, m_loadedFonts); 313 doneEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().loadin gdoneEvent, m_loadedFonts);
277 m_loadedFonts.clear(); 314 m_loadedFonts.clear();
278 if (!m_failedFonts.isEmpty()) { 315 if (!m_failedFonts.isEmpty()) {
279 errorEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().l oadingerrorEvent, m_failedFonts); 316 errorEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().l oadingerrorEvent, m_failedFonts);
280 m_failedFonts.clear(); 317 m_failedFonts.clear();
281 } 318 }
282 dispatchEvent(doneEvent); 319 dispatchEvent(doneEvent);
283 if (errorEvent) 320 if (errorEvent)
284 dispatchEvent(errorEvent); 321 dispatchEvent(errorEvent);
285 } 322 }
286 323
287 if (!m_fontsReadyCallbacks.isEmpty()) { 324 if (!m_readyResolvers.isEmpty()) {
288 Vector<RefPtr<VoidCallback> > callbacks; 325 Vector<OwnPtr<FontsReadyPromiseResolver> > resolvers;
289 m_fontsReadyCallbacks.swap(callbacks); 326 m_readyResolvers.swap(resolvers);
290 for (size_t index = 0; index < callbacks.size(); ++index) 327 for (size_t index = 0; index < resolvers.size(); ++index)
291 callbacks[index]->handleEvent(); 328 resolvers[index]->call(this);
292 } 329 }
293 } 330 }
294 331
295 void FontFaceSet::loadFont(const Dictionary& params) 332 Vector<RefPtr<FontFace> > FontFaceSet::match(const String& fontString, const Str ing&, ExceptionState& es)
296 { 333 {
297 // FIXME: The text member of params is ignored. 334 // FIXME: The second parameter (text) is ignored.
298 String fontString; 335 Vector<RefPtr<FontFace> > matchedFonts;
299 if (!params.get("font", fontString)) 336
300 return;
301 Font font; 337 Font font;
302 if (!resolveFontStyle(fontString, font)) 338 if (!resolveFontStyle(fontString, font)) {
303 return; 339 es.throwDOMException(SyntaxError);
304 RefPtr<LoadFontCallback> callback = LoadFontCallback::createFromParams(param s, font.family()); 340 return matchedFonts;
341 }
305 342
306 for (const FontFamily* f = &font.family(); f; f = f->next()) { 343 for (const FontFamily* f = &font.family(); f; f = f->next()) {
307 Document* d = document(); 344 CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector() ->getFontFace(font.fontDescription(), f->family());
308 CSSSegmentedFontFace* face = d->styleResolver()->fontSelector()->getFont Face(font.fontDescription(), f->family()); 345 if (face)
309 if (!face) { 346 matchedFonts.append(face->fontFaces());
310 if (callback)
311 callback->error(d);
312 continue;
313 }
314 face->loadFont(font.fontDescription(), callback);
315 } 347 }
348 return matchedFonts;
316 } 349 }
317 350
318 bool FontFaceSet::checkFont(const String& fontString, const String&) 351 ScriptPromise FontFaceSet::load(const String& fontString, const String&, Excepti onState& es)
319 { 352 {
320 // FIXME: The second parameter (text) is ignored. 353 // FIXME: The second parameter (text) is ignored.
321 Font font; 354 Font font;
322 if (!resolveFontStyle(fontString, font)) 355 if (!resolveFontStyle(fontString, font)) {
356 es.throwDOMException(SyntaxError);
357 return ScriptPromise();
358 }
359
360 Document* d = document();
361 RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(f ont.family(), scriptExecutionContext());
362 for (const FontFamily* f = &font.family(); f; f = f->next()) {
363 CSSSegmentedFontFace* face = d->styleResolver()->fontSelector()->getFont Face(font.fontDescription(), f->family());
364 if (!face) {
365 resolver->error(d);
366 continue;
367 }
368 face->loadFont(font.fontDescription(), resolver);
369 }
370 return resolver->promise();
371 }
372
373 bool FontFaceSet::check(const String& fontString, const String&, ExceptionState& es)
374 {
375 // FIXME: The second parameter (text) is ignored.
376 Font font;
377 if (!resolveFontStyle(fontString, font)) {
378 es.throwDOMException(SyntaxError);
323 return false; 379 return false;
380 }
381
324 for (const FontFamily* f = &font.family(); f; f = f->next()) { 382 for (const FontFamily* f = &font.family(); f; f = f->next()) {
325 CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector() ->getFontFace(font.fontDescription(), f->family()); 383 CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector() ->getFontFace(font.fontDescription(), f->family());
326 if (!face || !face->checkFont()) 384 if (!face || !face->checkFont())
327 return false; 385 return false;
328 } 386 }
329 return true; 387 return true;
330 } 388 }
331 389
332 bool FontFaceSet::resolveFontStyle(const String& fontString, Font& font) 390 bool FontFaceSet::resolveFontStyle(const String& fontString, Font& font)
333 { 391 {
392 if (fontString.isEmpty())
eseidel 2013/09/19 04:11:18 I believe (!fontString) is equivalent, but this is
Kunihiko Sakamoto 2013/09/19 04:49:31 !s is equivalent to !s.isNull(), but we don't want
393 return false;
394
334 // Interpret fontString in the same way as the 'font' attribute of CanvasRen deringContext2D. 395 // Interpret fontString in the same way as the 'font' attribute of CanvasRen deringContext2D.
335 RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::creat e(); 396 RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::creat e();
336 CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, CSSStrictMode, 0); 397 CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, CSSStrictMode, 0);
337 if (parsedStyle->isEmpty()) 398 if (parsedStyle->isEmpty())
338 return false; 399 return false;
339 400
340 String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont); 401 String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont);
341 if (fontValue == "inherit" || fontValue == "initial") 402 if (fontValue == "inherit" || fontValue == "initial")
342 return false; 403 return false;
343 404
(...skipping 30 matching lines...) Expand all
374 435
375 void FontFaceSet::FontLoadHistogram::record() 436 void FontFaceSet::FontLoadHistogram::record()
376 { 437 {
377 if (m_recorded) 438 if (m_recorded)
378 return; 439 return;
379 m_recorded = true; 440 m_recorded = true;
380 HistogramSupport::histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1 , 100, 50); 441 HistogramSupport::histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1 , 100, 50);
381 } 442 }
382 443
383 } // namespace WebCore 444 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698