diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/css/FontFace.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/core/css/FontFace.cpp | 393 |
1 files changed, 246 insertions, 147 deletions
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFace.cpp b/chromium/third_party/WebKit/Source/core/css/FontFace.cpp index 3b35cbca0fb..9590053c590 100644 --- a/chromium/third_party/WebKit/Source/core/css/FontFace.cpp +++ b/chromium/third_party/WebKit/Source/core/css/FontFace.cpp @@ -31,134 +31,161 @@ #include "config.h" #include "core/css/FontFace.h" -#include "CSSValueKeywords.h" -#include "FontFamilyNames.h" #include "bindings/v8/Dictionary.h" #include "bindings/v8/ExceptionState.h" -#include "bindings/v8/ScriptPromiseResolver.h" -#include "bindings/v8/ScriptScope.h" +#include "bindings/v8/ScriptPromiseResolverWithContext.h" #include "bindings/v8/ScriptState.h" +#include "core/CSSValueKeywords.h" +#include "core/css/BinaryDataFontFaceSource.h" #include "core/css/CSSFontFace.h" #include "core/css/CSSFontFaceSrcValue.h" -#include "core/css/CSSParser.h" +#include "core/css/CSSFontSelector.h" #include "core/css/CSSPrimitiveValue.h" #include "core/css/CSSUnicodeRangeValue.h" #include "core/css/CSSValueList.h" +#include "core/css/LocalFontFaceSource.h" +#include "core/css/RemoteFontFaceSource.h" #include "core/css/StylePropertySet.h" #include "core/css/StyleRule.h" +#include "core/css/parser/BisonCSSParser.h" #include "core/dom/DOMError.h" #include "core/dom/Document.h" #include "core/dom/ExceptionCode.h" -#include "core/frame/Frame.h" +#include "core/dom/StyleEngine.h" +#include "core/frame/LocalFrame.h" #include "core/frame/Settings.h" #include "core/svg/SVGFontFaceElement.h" -#include "platform/fonts/FontDescription.h" -#include "platform/fonts/FontTraitsMask.h" -#include "platform/fonts/SimpleFontData.h" +#include "core/svg/SVGFontFaceSource.h" +#include "core/svg/SVGRemoteFontFaceSource.h" +#include "platform/FontFamilyNames.h" +#include "platform/SharedBuffer.h" namespace WebCore { class FontFaceReadyPromiseResolver { public: - static PassOwnPtr<FontFaceReadyPromiseResolver> create(ScriptPromise promise, ExecutionContext* context) + static PassOwnPtr<FontFaceReadyPromiseResolver> create(ScriptState* scriptState) { - return adoptPtr(new FontFaceReadyPromiseResolver(promise, context)); + return adoptPtr(new FontFaceReadyPromiseResolver(scriptState)); } - void resolve(PassRefPtr<FontFace> fontFace) + void resolve(PassRefPtrWillBeRawPtr<FontFace> fontFace) { - ScriptScope scope(m_scriptState); switch (fontFace->loadStatus()) { case FontFace::Loaded: m_resolver->resolve(fontFace); break; case FontFace::Error: - m_resolver->reject(DOMError::create(NetworkError)); + m_resolver->reject(fontFace->error()); break; default: ASSERT_NOT_REACHED(); } } + ScriptPromise promise() { return m_resolver->promise(); } + private: - FontFaceReadyPromiseResolver(ScriptPromise promise, ExecutionContext* context) - : m_scriptState(ScriptState::current()) - , m_resolver(ScriptPromiseResolver::create(promise, context)) - { } - ScriptState* m_scriptState; - RefPtr<ScriptPromiseResolver> m_resolver; + FontFaceReadyPromiseResolver(ScriptState* scriptState) + : m_resolver(ScriptPromiseResolverWithContext::create(scriptState)) + { + } + + RefPtr<ScriptPromiseResolverWithContext> m_resolver; }; -static PassRefPtr<CSSValue> parseCSSValue(const String& s, CSSPropertyID propertyID) +static PassRefPtrWillBeRawPtr<CSSValue> parseCSSValue(const Document* document, const String& s, CSSPropertyID propertyID) { if (s.isEmpty()) - return 0; - RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::create(); - CSSParser::parseValue(parsedStyle.get(), propertyID, s, true, HTMLStandardMode, 0); + return nullptr; + RefPtrWillBeRawPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::create(); + BisonCSSParser::parseValue(parsedStyle.get(), propertyID, s, true, *document); return parsedStyle->getPropertyCSSValue(propertyID); } -PassRefPtr<FontFace> FontFace::create(const AtomicString& family, const String& source, const Dictionary& descriptors, ExceptionState& exceptionState) +static bool initFontFace(FontFace* fontFace, ExecutionContext* context, const AtomicString& family, const Dictionary& descriptors, ExceptionState& exceptionState) { - RefPtr<CSSValue> src = parseCSSValue(source, CSSPropertySrc); - if (!src || !src->isValueList()) { - exceptionState.throwUninformativeAndGenericDOMException(SyntaxError); - return 0; - } - - RefPtr<FontFace> fontFace = adoptRef<FontFace>(new FontFace(src)); - fontFace->setFamily(family, exceptionState); + fontFace->setFamily(context, family, exceptionState); if (exceptionState.hadException()) - return 0; + return false; String value; if (descriptors.get("style", value)) { - fontFace->setStyle(value, exceptionState); + fontFace->setStyle(context, value, exceptionState); if (exceptionState.hadException()) - return 0; + return false; } if (descriptors.get("weight", value)) { - fontFace->setWeight(value, exceptionState); + fontFace->setWeight(context, value, exceptionState); if (exceptionState.hadException()) - return 0; + return false; } if (descriptors.get("stretch", value)) { - fontFace->setStretch(value, exceptionState); + fontFace->setStretch(context, value, exceptionState); if (exceptionState.hadException()) - return 0; + return false; } if (descriptors.get("unicodeRange", value)) { - fontFace->setUnicodeRange(value, exceptionState); + fontFace->setUnicodeRange(context, value, exceptionState); if (exceptionState.hadException()) - return 0; + return false; } if (descriptors.get("variant", value)) { - fontFace->setVariant(value, exceptionState); + fontFace->setVariant(context, value, exceptionState); if (exceptionState.hadException()) - return 0; + return false; } if (descriptors.get("featureSettings", value)) { - fontFace->setFeatureSettings(value, exceptionState); + fontFace->setFeatureSettings(context, value, exceptionState); if (exceptionState.hadException()) - return 0; + return false; + } + return true; +} + +PassRefPtrWillBeRawPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, const String& source, const Dictionary& descriptors, ExceptionState& exceptionState) +{ + RefPtrWillBeRawPtr<CSSValue> src = parseCSSValue(toDocument(context), source, CSSPropertySrc); + if (!src || !src->isValueList()) { + exceptionState.throwDOMException(SyntaxError, "The source provided ('" + source + "') could not be parsed as a value list."); + return nullptr; } - return fontFace; + RefPtrWillBeRawPtr<FontFace> fontFace = adoptRefWillBeNoop(new FontFace()); + if (initFontFace(fontFace.get(), context, family, descriptors, exceptionState)) + fontFace->initCSSFontFace(toDocument(context), src); + return fontFace.release(); } -PassRefPtr<FontFace> FontFace::create(const StyleRuleFontFace* fontFaceRule) +PassRefPtrWillBeRawPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, PassRefPtr<ArrayBuffer> source, const Dictionary& descriptors, ExceptionState& exceptionState) { - const StylePropertySet* properties = fontFaceRule->properties(); + RefPtrWillBeRawPtr<FontFace> fontFace = adoptRefWillBeNoop(new FontFace()); + if (initFontFace(fontFace.get(), context, family, descriptors, exceptionState)) + fontFace->initCSSFontFace(static_cast<const unsigned char*>(source->data()), source->byteLength()); + return fontFace.release(); +} + +PassRefPtrWillBeRawPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, PassRefPtr<ArrayBufferView> source, const Dictionary& descriptors, ExceptionState& exceptionState) +{ + RefPtrWillBeRawPtr<FontFace> fontFace = adoptRefWillBeNoop(new FontFace()); + if (initFontFace(fontFace.get(), context, family, descriptors, exceptionState)) + fontFace->initCSSFontFace(static_cast<const unsigned char*>(source->baseAddress()), source->byteLength()); + return fontFace.release(); +} + +PassRefPtrWillBeRawPtr<FontFace> FontFace::create(Document* document, const StyleRuleFontFace* fontFaceRule) +{ + const StylePropertySet& properties = fontFaceRule->properties(); // Obtain the font-family property and the src property. Both must be defined. - RefPtr<CSSValue> family = properties->getPropertyCSSValue(CSSPropertyFontFamily); + RefPtrWillBeRawPtr<CSSValue> family = properties.getPropertyCSSValue(CSSPropertyFontFamily); if (!family || !family->isValueList()) - return 0; - RefPtr<CSSValue> src = properties->getPropertyCSSValue(CSSPropertySrc); + return nullptr; + RefPtrWillBeRawPtr<CSSValue> src = properties.getPropertyCSSValue(CSSPropertySrc); if (!src || !src->isValueList()) - return 0; + return nullptr; - RefPtr<FontFace> fontFace = adoptRef<FontFace>(new FontFace(src)); + RefPtrWillBeRawPtr<FontFace> fontFace = adoptRefWillBeNoop(new FontFace()); if (fontFace->setFamilyValue(toCSSValueList(family.get())) && fontFace->setPropertyFromStyle(properties, CSSPropertyFontStyle) @@ -166,15 +193,17 @@ PassRefPtr<FontFace> FontFace::create(const StyleRuleFontFace* fontFaceRule) && fontFace->setPropertyFromStyle(properties, CSSPropertyFontStretch) && fontFace->setPropertyFromStyle(properties, CSSPropertyUnicodeRange) && fontFace->setPropertyFromStyle(properties, CSSPropertyFontVariant) - && fontFace->setPropertyFromStyle(properties, CSSPropertyWebkitFontFeatureSettings)) - return fontFace; - return 0; + && fontFace->setPropertyFromStyle(properties, CSSPropertyWebkitFontFeatureSettings) + && !fontFace->family().isEmpty() + && fontFace->traits().mask()) { + fontFace->initCSSFontFace(document, src); + return fontFace.release(); + } + return nullptr; } -FontFace::FontFace(PassRefPtr<CSSValue> src) - : m_src(src) - , m_status(Unloaded) - , m_cssFontFace(0) +FontFace::FontFace() + : m_status(Unloaded) { } @@ -212,49 +241,49 @@ String FontFace::featureSettings() const return m_featureSettings ? m_featureSettings->cssText() : "normal"; } -void FontFace::setStyle(const String& s, ExceptionState& exceptionState) +void FontFace::setStyle(ExecutionContext* context, const String& s, ExceptionState& exceptionState) { - setPropertyFromString(s, CSSPropertyFontStyle, exceptionState); + setPropertyFromString(toDocument(context), s, CSSPropertyFontStyle, exceptionState); } -void FontFace::setWeight(const String& s, ExceptionState& exceptionState) +void FontFace::setWeight(ExecutionContext* context, const String& s, ExceptionState& exceptionState) { - setPropertyFromString(s, CSSPropertyFontWeight, exceptionState); + setPropertyFromString(toDocument(context), s, CSSPropertyFontWeight, exceptionState); } -void FontFace::setStretch(const String& s, ExceptionState& exceptionState) +void FontFace::setStretch(ExecutionContext* context, const String& s, ExceptionState& exceptionState) { - setPropertyFromString(s, CSSPropertyFontStretch, exceptionState); + setPropertyFromString(toDocument(context), s, CSSPropertyFontStretch, exceptionState); } -void FontFace::setUnicodeRange(const String& s, ExceptionState& exceptionState) +void FontFace::setUnicodeRange(ExecutionContext* context, const String& s, ExceptionState& exceptionState) { - setPropertyFromString(s, CSSPropertyUnicodeRange, exceptionState); + setPropertyFromString(toDocument(context), s, CSSPropertyUnicodeRange, exceptionState); } -void FontFace::setVariant(const String& s, ExceptionState& exceptionState) +void FontFace::setVariant(ExecutionContext* context, const String& s, ExceptionState& exceptionState) { - setPropertyFromString(s, CSSPropertyFontVariant, exceptionState); + setPropertyFromString(toDocument(context), s, CSSPropertyFontVariant, exceptionState); } -void FontFace::setFeatureSettings(const String& s, ExceptionState& exceptionState) +void FontFace::setFeatureSettings(ExecutionContext* context, const String& s, ExceptionState& exceptionState) { - setPropertyFromString(s, CSSPropertyWebkitFontFeatureSettings, exceptionState); + setPropertyFromString(toDocument(context), s, CSSPropertyWebkitFontFeatureSettings, exceptionState); } -void FontFace::setPropertyFromString(const String& s, CSSPropertyID propertyID, ExceptionState& exceptionState) +void FontFace::setPropertyFromString(const Document* document, const String& s, CSSPropertyID propertyID, ExceptionState& exceptionState) { - RefPtr<CSSValue> value = parseCSSValue(s, propertyID); + RefPtrWillBeRawPtr<CSSValue> value = parseCSSValue(document, s, propertyID); if (!value || !setPropertyValue(value, propertyID)) - exceptionState.throwUninformativeAndGenericDOMException(SyntaxError); + exceptionState.throwDOMException(SyntaxError, "Failed to set '" + s + "' as a property value."); } -bool FontFace::setPropertyFromStyle(const StylePropertySet* properties, CSSPropertyID propertyID) +bool FontFace::setPropertyFromStyle(const StylePropertySet& properties, CSSPropertyID propertyID) { - return setPropertyValue(properties->getPropertyCSSValue(propertyID), propertyID); + return setPropertyValue(properties.getPropertyCSSValue(propertyID), propertyID); } -bool FontFace::setPropertyValue(PassRefPtr<CSSValue> value, CSSPropertyID propertyID) +bool FontFace::setPropertyValue(PassRefPtrWillBeRawPtr<CSSValue> value, CSSPropertyID propertyID) { switch (propertyID) { case CSSPropertyFontStyle: @@ -344,38 +373,62 @@ String FontFace::status() const void FontFace::setLoadStatus(LoadStatus status) { m_status = status; - if (m_status == Loaded || m_status == Error) + if (m_status == Error) + m_error = DOMError::create(NetworkError); + if (m_status == Loaded || m_status == Error) { resolveReadyPromises(); -} - -void FontFace::load() -{ - // FIXME: This does not load FontFace created by JavaScript, since m_cssFontFace is null. - if (m_status != Unloaded || !m_cssFontFace) - return; - - FontDescription fontDescription; - FontFamily fontFamily; - fontFamily.setFamily(m_family); - fontDescription.setFamily(fontFamily); - fontDescription.setTraitsMask(static_cast<FontTraitsMask>(traitsMask())); - RefPtr<SimpleFontData> fontData = m_cssFontFace->getFontData(fontDescription); - if (fontData && fontData->customFontData()) - fontData->customFontData()->beginLoadIfNeeded(); + WillBeHeapVector<RefPtrWillBeMember<LoadFontCallback> > callbacks; + m_callbacks.swap(callbacks); + for (size_t i = 0; i < callbacks.size(); ++i) { + if (m_status == Loaded) + callbacks[i]->notifyLoaded(this); + else + callbacks[i]->notifyError(this); + } + } } -ScriptPromise FontFace::ready(ExecutionContext* context) +ScriptPromise FontFace::fontStatusPromise(ScriptState* scriptState) { - ScriptPromise promise = ScriptPromise::createPending(context); - OwnPtr<FontFaceReadyPromiseResolver> resolver = FontFaceReadyPromiseResolver::create(promise, context); + // Since we cannot hold a ScriptPromise as a member of FontFace (that will + // cause a circular reference), this creates new Promise every time. + OwnPtr<FontFaceReadyPromiseResolver> resolver = FontFaceReadyPromiseResolver::create(scriptState); + ScriptPromise promise = resolver->promise(); if (m_status == Loaded || m_status == Error) resolver->resolve(this); else m_readyResolvers.append(resolver.release()); + return promise; } +ScriptPromise FontFace::load(ScriptState* scriptState) +{ + loadInternal(scriptState->executionContext()); + return fontStatusPromise(scriptState); +} + +void FontFace::loadWithCallback(PassRefPtrWillBeRawPtr<LoadFontCallback> callback, ExecutionContext* context) +{ + loadInternal(context); + if (m_status == Loaded) + callback->notifyLoaded(this); + else if (m_status == Error) + callback->notifyError(this); + else + m_callbacks.append(callback); +} + +void FontFace::loadInternal(ExecutionContext* context) +{ + if (m_status != Unloaded) + return; + + m_cssFontFace->load(); + toDocument(context)->styleEngine()->fontSelector()->fontLoader()->loadPendingFonts(); +} + void FontFace::resolveReadyPromises() { for (size_t i = 0; i < m_readyResolvers.size(); i++) @@ -383,29 +436,27 @@ void FontFace::resolveReadyPromises() m_readyResolvers.clear(); } -unsigned FontFace::traitsMask() const +FontTraits FontFace::traits() const { - unsigned traitsMask = 0; - + FontStyle style = FontStyleNormal; if (m_style) { if (!m_style->isPrimitiveValue()) return 0; switch (toCSSPrimitiveValue(m_style.get())->getValueID()) { case CSSValueNormal: - traitsMask |= FontStyleNormalMask; + style = FontStyleNormal; break; case CSSValueItalic: case CSSValueOblique: - traitsMask |= FontStyleItalicMask; + style = FontStyleItalic; break; default: break; } - } else { - traitsMask |= FontStyleNormalMask; } + FontWeight weight = FontWeight400; if (m_weight) { if (!m_weight->isPrimitiveValue()) return 0; @@ -413,44 +464,45 @@ unsigned FontFace::traitsMask() const switch (toCSSPrimitiveValue(m_weight.get())->getValueID()) { case CSSValueBold: case CSSValue700: - traitsMask |= FontWeight700Mask; + weight = FontWeight700; break; case CSSValueNormal: case CSSValue400: - traitsMask |= FontWeight400Mask; + weight = FontWeight400; break; case CSSValue900: - traitsMask |= FontWeight900Mask; + weight = FontWeight900; break; case CSSValue800: - traitsMask |= FontWeight800Mask; + weight = FontWeight800; break; case CSSValue600: - traitsMask |= FontWeight600Mask; + weight = FontWeight600; break; case CSSValue500: - traitsMask |= FontWeight500Mask; + weight = FontWeight500; break; case CSSValue300: - traitsMask |= FontWeight300Mask; + weight = FontWeight300; break; case CSSValue200: - traitsMask |= FontWeight200Mask; + weight = FontWeight200; break; + case CSSValueLighter: case CSSValue100: - traitsMask |= FontWeight100Mask; + weight = FontWeight100; break; default: + ASSERT_NOT_REACHED(); break; } - } else { - traitsMask |= FontWeight400Mask; } - if (RefPtr<CSSValue> fontVariant = m_variant) { + FontVariant variant = FontVariantNormal; + if (RefPtrWillBeRawPtr<CSSValue> fontVariant = m_variant) { // font-variant descriptor can be a value list. if (fontVariant->isPrimitiveValue()) { - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); list->append(fontVariant); fontVariant = list; } else if (!fontVariant->isValueList()) { @@ -465,31 +517,40 @@ unsigned FontFace::traitsMask() const for (unsigned i = 0; i < numVariants; ++i) { switch (toCSSPrimitiveValue(variantList->itemWithoutBoundsCheck(i))->getValueID()) { case CSSValueNormal: - traitsMask |= FontVariantNormalMask; + variant = FontVariantNormal; break; case CSSValueSmallCaps: - traitsMask |= FontVariantSmallCapsMask; + variant = FontVariantSmallCaps; break; default: break; } } - } else { - traitsMask |= FontVariantNormalMask; } - return traitsMask; + + return FontTraits(style, variant, weight, FontStretchNormal); } -PassRefPtr<CSSFontFace> FontFace::createCSSFontFace(Document* document) +static PassOwnPtrWillBeRawPtr<CSSFontFace> createCSSFontFace(FontFace* fontFace, CSSValue* unicodeRange) { - if (m_cssFontFace) - return m_cssFontFace; + Vector<CSSFontFace::UnicodeRange> ranges; + if (CSSValueList* rangeList = toCSSValueList(unicodeRange)) { + unsigned numRanges = rangeList->length(); + for (unsigned i = 0; i < numRanges; i++) { + CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->itemWithoutBoundsCheck(i)); + ranges.append(CSSFontFace::UnicodeRange(range->from(), range->to())); + } + } - RefPtr<CSSFontFace> cssFontFace = CSSFontFace::create(this); - m_cssFontFace = cssFontFace.get(); + return adoptPtrWillBeNoop(new CSSFontFace(fontFace, ranges)); +} + +void FontFace::initCSSFontFace(Document* document, PassRefPtrWillBeRawPtr<CSSValue> src) +{ + m_cssFontFace = createCSSFontFace(this, m_unicodeRange.get()); // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace. - CSSValueList* srcList = toCSSValueList(m_src.get()); + CSSValueList* srcList = toCSSValueList(src.get()); int srcLength = srcList->length(); bool foundSVGFont = false; @@ -497,7 +558,7 @@ PassRefPtr<CSSFontFace> FontFace::createCSSFontFace(Document* document) for (int i = 0; i < srcLength; i++) { // An item in the list either specifies a string (local font name) or a URL (remote font to download). CSSFontFaceSrcValue* item = toCSSFontFaceSrcValue(srcList->itemWithoutBoundsCheck(i)); - OwnPtr<CSSFontFaceSource> source; + OwnPtrWillBeRawPtr<CSSFontFaceSource> source = nullptr; #if ENABLE(SVG_FONTS) foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement(); @@ -508,33 +569,71 @@ PassRefPtr<CSSFontFace> FontFace::createCSSFontFace(Document* document) if (allowDownloading && item->isSupportedFormat() && document) { FontResource* fetched = item->fetch(document); if (fetched) { - source = adoptPtr(new CSSFontFaceSource(item->resource(), fetched)); + FontLoader* fontLoader = document->styleEngine()->fontSelector()->fontLoader(); + #if ENABLE(SVG_FONTS) - if (foundSVGFont) - source->setHasExternalSVGFont(true); + if (foundSVGFont) { + source = adoptPtrWillBeNoop(new SVGRemoteFontFaceSource(item->resource(), fetched, fontLoader)); + } else #endif + { + source = adoptPtrWillBeNoop(new RemoteFontFaceSource(fetched, fontLoader)); + } } } } else { - source = adoptPtr(new CSSFontFaceSource(item->resource())); - } - - if (source) { #if ENABLE(SVG_FONTS) - source->setSVGFontFaceElement(item->svgFontFaceElement()); + if (item->svgFontFaceElement()) { + RefPtrWillBeRawPtr<SVGFontFaceElement> fontfaceElement = item->svgFontFaceElement(); + // SVGFontFaceSource assumes that it is the case where <font-face> element resides in the same document. + // We put a RELEASE_ASSERT here as it will cause UAF if the assumption is false. + RELEASE_ASSERT(fontfaceElement->inDocument()); + RELEASE_ASSERT(fontfaceElement->document() == document); + source = adoptPtrWillBeNoop(new SVGFontFaceSource(fontfaceElement.get())); + } else #endif - cssFontFace->addSource(source.release()); + { + source = adoptPtrWillBeNoop(new LocalFontFaceSource(item->resource())); + } } + + if (source) + m_cssFontFace->addSource(source.release()); } +} - if (CSSValueList* rangeList = toCSSValueList(m_unicodeRange.get())) { - unsigned numRanges = rangeList->length(); - for (unsigned i = 0; i < numRanges; i++) { - CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->itemWithoutBoundsCheck(i)); - cssFontFace->ranges().add(range->from(), range->to()); - } +void FontFace::initCSSFontFace(const unsigned char* data, unsigned size) +{ + m_cssFontFace = createCSSFontFace(this, m_unicodeRange.get()); + + RefPtr<SharedBuffer> buffer = SharedBuffer::create(data, size); + OwnPtrWillBeRawPtr<BinaryDataFontFaceSource> source = adoptPtrWillBeNoop(new BinaryDataFontFaceSource(buffer.get())); + if (source->isValid()) { + m_status = Loaded; + } else { + m_status = Error; + m_error = DOMError::create(SyntaxError, "Invalid font data in ArrayBuffer."); } - return cssFontFace; + m_cssFontFace->addSource(source.release()); +} + +void FontFace::trace(Visitor* visitor) +{ + visitor->trace(m_src); + visitor->trace(m_style); + visitor->trace(m_weight); + visitor->trace(m_stretch); + visitor->trace(m_unicodeRange); + visitor->trace(m_variant); + visitor->trace(m_featureSettings); + visitor->trace(m_error); + visitor->trace(m_cssFontFace); + visitor->trace(m_callbacks); +} + +bool FontFace::hadBlankText() const +{ + return m_cssFontFace->hadBlankText(); } } // namespace WebCore |