void FontBuilder::setFontVariantLigaturesValue(CSSValue* value) { FontDescriptionChangeScope scope(this); FontDescription::LigaturesState commonLigaturesState = FontDescription::NormalLigaturesState; FontDescription::LigaturesState discretionaryLigaturesState = FontDescription::NormalLigaturesState; FontDescription::LigaturesState historicalLigaturesState = FontDescription::NormalLigaturesState; FontDescription::LigaturesState contextualLigaturesState = FontDescription::NormalLigaturesState; if (value->isValueList()) { CSSValueList* valueList = toCSSValueList(value); for (size_t i = 0; i < valueList->length(); ++i) { CSSValue* item = valueList->itemWithoutBoundsCheck(i); ASSERT(item->isPrimitiveValue()); if (item->isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item); switch (primitiveValue->getValueID()) { case CSSValueNoCommonLigatures: commonLigaturesState = FontDescription::DisabledLigaturesState; break; case CSSValueCommonLigatures: commonLigaturesState = FontDescription::EnabledLigaturesState; break; case CSSValueNoDiscretionaryLigatures: discretionaryLigaturesState = FontDescription::DisabledLigaturesState; break; case CSSValueDiscretionaryLigatures: discretionaryLigaturesState = FontDescription::EnabledLigaturesState; break; case CSSValueNoHistoricalLigatures: historicalLigaturesState = FontDescription::DisabledLigaturesState; break; case CSSValueHistoricalLigatures: historicalLigaturesState = FontDescription::EnabledLigaturesState; break; case CSSValueNoContextual: contextualLigaturesState = FontDescription::DisabledLigaturesState; break; case CSSValueContextual: contextualLigaturesState = FontDescription::EnabledLigaturesState; break; default: ASSERT_NOT_REACHED(); break; } } } } #if ASSERT_ENABLED else { ASSERT_WITH_SECURITY_IMPLICATION(value->isPrimitiveValue()); ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal); } #endif scope.fontDescription().setCommonLigaturesState(commonLigaturesState); scope.fontDescription().setDiscretionaryLigaturesState(discretionaryLigaturesState); scope.fontDescription().setHistoricalLigaturesState(historicalLigaturesState); scope.fontDescription().setContextualLigaturesState(contextualLigaturesState); }
virtual void applyValue(CSSStyleSelector* selector, CSSValue* value) const { FillLayer* currChild = (selector->style()->*m_accessLayers)(); FillLayer* prevChild = 0; if (value->isValueList()) { /* Walk each value and put it into a layer, creating new layers as needed. */ CSSValueList* valueList = static_cast<CSSValueList*>(value); for (unsigned int i = 0; i < valueList->length(); i++) { if (!currChild) { /* Need to make a new layer to hold this value */ currChild = new FillLayer(m_fillLayerType); prevChild->setNext(currChild); } (selector->*m_mapFill)(m_propertyId, currChild, valueList->itemWithoutBoundsCheck(i)); prevChild = currChild; currChild = currChild->next(); } } else { (selector->*m_mapFill)(m_propertyId, currChild, value); currChild = currChild->next(); } while (currChild) { /* Reset all remaining layers to not have the property set. */ (currChild->*m_clear)(); currChild = currChild->next(); } }
void SVGFontFaceElement::rebuildFontFace() { ASSERT(inDocument()); // we currently ignore all but the first src element, alternatively we could concat them SVGFontFaceSrcElement* srcElement = 0; SVGDefinitionSrcElement* definitionSrc = 0; for (Node* child = firstChild(); child; child = child->nextSibling()) { if (child->hasTagName(font_face_srcTag) && !srcElement) srcElement = static_cast<SVGFontFaceSrcElement*>(child); else if (child->hasTagName(definition_srcTag) && !definitionSrc) definitionSrc = static_cast<SVGDefinitionSrcElement*>(child); } #if 0 // @font-face (CSSFontFace) does not yet support definition-src, as soon as it does this code should do the trick! if (definitionSrc) m_styleDeclaration->setProperty(CSSPropertyDefinitionSrc, definitionSrc->getAttribute(XLinkNames::hrefAttr), false); #endif bool describesParentFont = parentNode()->hasTagName(fontTag); RefPtr<CSSValueList> list; if (describesParentFont) { m_fontElement = static_cast<SVGFontElement*>(parentNode()); list = CSSValueList::createCommaSeparated(); list->append(CSSFontFaceSrcValue::createLocal(fontFamily())); } else { m_fontElement = 0; if (srcElement) list = srcElement->srcValue(); } if (!list) return; // Parse in-memory CSS rules CSSProperty srcProperty(CSSPropertySrc, list); const CSSProperty* srcPropertyRef = &srcProperty; m_styleDeclaration->addParsedProperties(&srcPropertyRef, 1); if (describesParentFont) { // Traverse parsed CSS values and associate CSSFontFaceSrcValue elements with ourselves. RefPtr<CSSValue> src = m_styleDeclaration->getPropertyCSSValue(CSSPropertySrc); CSSValueList* srcList = static_cast<CSSValueList*>(src.get()); unsigned srcLength = srcList ? srcList->length() : 0; for (unsigned i = 0; i < srcLength; i++) { if (CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->itemWithoutBoundsCheck(i))) item->setSVGFontFaceElement(this); } } document()->updateStyleSelector(); }
PassRefPtr<CSSFontFace> FontFace::createCSSFontFace(Document* document) { RefPtr<CSSFontFace> cssFontFace = CSSFontFace::create(this); // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace. CSSValueList* srcList = toCSSValueList(m_src.get()); int srcLength = srcList->length(); bool foundSVGFont = false; 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; #if ENABLE(SVG_FONTS) foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement(); #endif if (!item->isLocal()) { Settings* settings = document ? document->frame() ? document->frame()->settings() : 0 : 0; bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled()); if (allowDownloading && item->isSupportedFormat() && document) { FontResource* fetched = item->fetch(document); if (fetched) { source = adoptPtr(new CSSFontFaceSource(item->resource(), fetched)); #if ENABLE(SVG_FONTS) if (foundSVGFont) source->setHasExternalSVGFont(true); #endif } } } else { source = adoptPtr(new CSSFontFaceSource(item->resource())); } if (source) { #if ENABLE(SVG_FONTS) source->setSVGFontFaceElement(item->svgFontFaceElement()); #endif 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()); } } return cssFontFace; }
static PassRefPtr<CustomFilterParameter> parseCustomFilterParameter(const String& name, CSSValue* parameterValue, StyleResolverState& state) { // FIXME: Implement other parameters types parsing. // booleans: https://bugs.webkit.org/show_bug.cgi?id=76438 // textures: https://bugs.webkit.org/show_bug.cgi?id=71442 // mat2, mat3, mat4: https://bugs.webkit.org/show_bug.cgi?id=71444 // Number parameters are wrapped inside a CSSValueList and all // the other functions values inherit from CSSValueList. if (!parameterValue->isValueList()) return 0; CSSValueList* values = toCSSValueList(parameterValue); if (!values->length()) return 0; if (parameterValue->isArrayFunctionValue()) return parseCustomFilterArrayParameter(name, values); // If the first value of the list is a transform function, // then we could safely assume that all the remaining items // are transforms. parseCustomFilterTransformParameter will // return 0 if that assumption is incorrect. if (values->itemWithoutBoundsCheck(0)->isTransformValue()) return parseCustomFilterTransformParameter(name, values, state); // We can have only arrays of booleans or numbers, so use the first value to choose between those two. // We need up to 4 values (all booleans or all numbers). if (!values->itemWithoutBoundsCheck(0)->isPrimitiveValue() || values->length() > 4) return 0; CSSPrimitiveValue* firstPrimitiveValue = toCSSPrimitiveValue(values->itemWithoutBoundsCheck(0)); if (firstPrimitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) return parseCustomFilterNumberParameter(name, values); // FIXME: Implement the boolean array parameter here. // https://bugs.webkit.org/show_bug.cgi?id=76438 return 0; }
static bool parseAspectRatio(CSSValue* value, int& h, int& v) { if (value->isValueList()) { CSSValueList* valueList = static_cast<CSSValueList*>(value); if (valueList->length() == 3) { CSSValue* i0 = valueList->itemWithoutBoundsCheck(0); CSSValue* i1 = valueList->itemWithoutBoundsCheck(1); CSSValue* i2 = valueList->itemWithoutBoundsCheck(2); if (i0->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i0)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER && i1->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i1)->primitiveType() == CSSPrimitiveValue::CSS_STRING && i2->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i2)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) { String str = static_cast<CSSPrimitiveValue*>(i1)->getStringValue(); if (!str.isNull() && str.length() == 1 && str[0] == '/') { h = static_cast<CSSPrimitiveValue*>(i0)->getIntValue(CSSPrimitiveValue::CSS_NUMBER); v = static_cast<CSSPrimitiveValue*>(i2)->getIntValue(CSSPrimitiveValue::CSS_NUMBER); return true; } } } } return false; }
static Ref<CSSFontFace> createFontFace(CSSValueList& srcList, FontTraitsMask traitsMask, Document* document, const StyleRuleFontFace& fontFaceRule, bool isInitiatingElementInUserAgentShadowTree) { RefPtr<CSSFontFaceRule> rule; #if ENABLE(FONT_LOAD_EVENTS) // FIXME: https://bugs.webkit.org/show_bug.cgi?id=112116 - This CSSFontFaceRule has no parent. if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled()) rule = static_pointer_cast<CSSFontFaceRule>(fontFaceRule.createCSSOMWrapper()); #else UNUSED_PARAM(fontFaceRule); #endif Ref<CSSFontFace> fontFace = CSSFontFace::create(traitsMask, WTF::move(rule)); int srcLength = srcList.length(); bool foundSVGFont = false; 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 = downcast<CSSFontFaceSrcValue>(*srcList.itemWithoutBoundsCheck(i)); std::unique_ptr<CSSFontFaceSource> source; #if ENABLE(SVG_FONTS) foundSVGFont = item.isSVGFontFaceSrc() || item.svgFontFaceElement(); #endif if (!item.isLocal()) { Settings* settings = document ? document->settings() : nullptr; bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled()); if (allowDownloading && item.isSupportedFormat() && document) { CachedFont* cachedFont = item.cachedFont(document, foundSVGFont, isInitiatingElementInUserAgentShadowTree); if (cachedFont) { source = std::make_unique<CSSFontFaceSource>(item.resource(), cachedFont); #if ENABLE(SVG_FONTS) if (foundSVGFont) source->setHasExternalSVGFont(); #endif } } } else { source = std::make_unique<CSSFontFaceSource>(item.resource()); } if (source) { #if ENABLE(SVG_FONTS) source->setSVGFontFaceElement(item.svgFontFaceElement()); #endif fontFace->addSource(WTF::move(source)); } } return fontFace; }
void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace& fontFaceRule, bool isInitiatingElementInUserAgentShadowTree) { const StyleProperties& style = fontFaceRule.properties(); RefPtr<CSSValue> fontFamily = style.getPropertyCSSValue(CSSPropertyFontFamily); RefPtr<CSSValue> src = style.getPropertyCSSValue(CSSPropertySrc); RefPtr<CSSValue> unicodeRange = style.getPropertyCSSValue(CSSPropertyUnicodeRange); if (!is<CSSValueList>(fontFamily.get()) || !is<CSSValueList>(src.get()) || (unicodeRange && !is<CSSValueList>(*unicodeRange))) return; CSSValueList& familyList = downcast<CSSValueList>(*fontFamily); if (!familyList.length()) return; CSSValueList& srcList = downcast<CSSValueList>(*src); if (!srcList.length()) return; CSSValueList* rangeList = downcast<CSSValueList>(unicodeRange.get()); auto computedTraitsMask = computeTraitsMask(style); if (!computedTraitsMask) return; auto traitsMask = computedTraitsMask.value(); Ref<CSSFontFace> fontFace = createFontFace(srcList, traitsMask, m_document, fontFaceRule, isInitiatingElementInUserAgentShadowTree); if (!fontFace->isValid()) return; if (rangeList) { unsigned numRanges = rangeList->length(); for (unsigned i = 0; i < numRanges; i++) { CSSUnicodeRangeValue& range = downcast<CSSUnicodeRangeValue>(*rangeList->itemWithoutBoundsCheck(i)); fontFace->addRange(range.from(), range.to()); } } for (auto& item : familyList) { String familyName = familyNameFromPrimitive(downcast<CSSPrimitiveValue>(item.get())); if (familyName.isEmpty()) continue; auto addResult = m_fontFaces.add(familyName, Vector<Ref<CSSFontFace>>()); auto& familyFontFaces = addResult.iterator->value; if (addResult.isNewEntry) familyFontFaces = constructFamilyFontFaces(familyName, m_locallyInstalledFontFaces); familyFontFaces.append(fontFace.copyRef()); ++m_version; } }
void SVGFontFaceElement::rebuildFontFace() { if (!inDocument()) { ASSERT(!m_fontElement); return; } // we currently ignore all but the first src element, alternatively we could concat them SVGFontFaceSrcElement* srcElement = 0; for (Node* child = firstChild(); child && !srcElement; child = child->nextSibling()) { if (child->hasTagName(font_face_srcTag)) srcElement = static_cast<SVGFontFaceSrcElement*>(child); } bool describesParentFont = parentNode()->hasTagName(SVGNames::fontTag); RefPtr<CSSValueList> list; if (describesParentFont) { m_fontElement = static_cast<SVGFontElement*>(parentNode()); list = CSSValueList::createCommaSeparated(); list->append(CSSFontFaceSrcValue::createLocal(fontFamily())); } else { m_fontElement = 0; if (srcElement) list = srcElement->srcValue(); } if (!list || !list->length()) return; // Parse in-memory CSS rules m_fontFaceRule->mutableProperties()->addParsedProperty(CSSProperty(CSSPropertySrc, list)); if (describesParentFont) { // Traverse parsed CSS values and associate CSSFontFaceSrcValue elements with ourselves. RefPtr<CSSValue> src = m_fontFaceRule->properties()->getPropertyCSSValue(CSSPropertySrc); CSSValueList* srcList = static_cast<CSSValueList*>(src.get()); unsigned srcLength = srcList ? srcList->length() : 0; for (unsigned i = 0; i < srcLength; i++) { if (CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->itemWithoutBoundsCheck(i))) item->setSVGFontFaceElement(this); } } document()->styleResolverChanged(DeferRecalcStyle); }
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(src.get()); int srcLength = srcList->length(); bool foundSVGFont = false; 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; #if ENABLE(SVG_FONTS) foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement(); #endif if (!item->isLocal()) { Settings* settings = document ? document->frame() ? document->frame()->settings() : 0 : 0; bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled()); if (allowDownloading && item->isSupportedFormat() && document) { FontResource* fetched = item->fetch(document); if (fetched) { #if ENABLE(SVG_FONTS) if (foundSVGFont) { source = adoptPtr(new SVGRemoteFontFaceSource(item->resource(), fetched)); } else #endif { source = adoptPtr(new RemoteFontFaceSource(fetched)); } } } } else { #if ENABLE(SVG_FONTS) if (item->svgFontFaceElement()) { source = adoptPtr(new SVGFontFaceSource(item->svgFontFaceElement())); } else #endif { source = adoptPtr(new LocalFontFaceSource(item->resource())); } } if (source) m_cssFontFace->addSource(source.release()); } }
void FontBuilder::setFeatureSettingsValue(CSSValue* value) { FontDescriptionChangeScope scope(this); CSSValueList* list = toCSSValueList(value); RefPtr<FontFeatureSettings> settings = FontFeatureSettings::create(); int len = list->length(); for (int i = 0; i < len; ++i) { CSSValue* item = list->itemWithoutBoundsCheck(i); if (!item->isFontFeatureValue()) continue; CSSFontFeatureValue* feature = toCSSFontFeatureValue(item); settings->append(FontFeature(feature->tag(), feature->value())); } scope.fontDescription().setFeatureSettings(settings.release()); }
void SVGFontFaceElement::rebuildFontFace() { if (!inDocument()) { ASSERT(!m_fontElement); return; } // we currently ignore all but the first src element, alternatively we could concat them auto srcElement = childrenOfType<SVGFontFaceSrcElement>(*this).first(); bool describesParentFont = is<SVGFontElement>(*parentNode()); RefPtr<CSSValueList> list; if (describesParentFont) { m_fontElement = downcast<SVGFontElement>(parentNode()); list = CSSValueList::createCommaSeparated(); list->append(CSSFontFaceSrcValue::createLocal(fontFamily())); } else { m_fontElement = nullptr; if (srcElement) list = srcElement->srcValue(); } if (!list || !list->length()) return; // Parse in-memory CSS rules m_fontFaceRule->mutableProperties().addParsedProperty(CSSProperty(CSSPropertySrc, list)); if (describesParentFont) { // Traverse parsed CSS values and associate CSSFontFaceSrcValue elements with ourselves. RefPtr<CSSValue> src = m_fontFaceRule->properties().getPropertyCSSValue(CSSPropertySrc); CSSValueList* srcList = downcast<CSSValueList>(src.get()); unsigned srcLength = srcList ? srcList->length() : 0; for (unsigned i = 0; i < srcLength; ++i) { if (CSSFontFaceSrcValue* item = downcast<CSSFontFaceSrcValue>(srcList->itemWithoutBoundsCheck(i))) item->setSVGFontFaceElement(this); } } document().styleResolverChanged(DeferRecalcStyle); }
DashArray dashArrayFromRenderingStyle(const RenderStyle* style, RenderStyle* rootStyle) { DashArray array; CSSValueList* dashes = style->svgStyle()->strokeDashArray(); if (dashes) { CSSPrimitiveValue* dash = 0; unsigned long len = dashes->length(); for (unsigned long i = 0; i < len; i++) { dash = static_cast<CSSPrimitiveValue*>(dashes->itemWithoutBoundsCheck(i)); if (!dash) continue; array.append((float) dash->computeLengthFloat(const_cast<RenderStyle*>(style), rootStyle)); } } return array; }
void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule) { // Obtain the font-family property and the src property. Both must be defined. const StylePropertySet* style = fontFaceRule->declaration(); RefPtr<CSSValue> fontFamily = style->getPropertyCSSValue(CSSPropertyFontFamily); RefPtr<CSSValue> src = style->getPropertyCSSValue(CSSPropertySrc); RefPtr<CSSValue> unicodeRange = style->getPropertyCSSValue(CSSPropertyUnicodeRange); if (!fontFamily || !src || !fontFamily->isValueList() || !src->isValueList() || (unicodeRange && !unicodeRange->isValueList())) return; CSSValueList* familyList = static_cast<CSSValueList*>(fontFamily.get()); if (!familyList->length()) return; CSSValueList* srcList = static_cast<CSSValueList*>(src.get()); if (!srcList->length()) return; CSSValueList* rangeList = static_cast<CSSValueList*>(unicodeRange.get()); unsigned traitsMask = 0; if (RefPtr<CSSValue> fontStyle = style->getPropertyCSSValue(CSSPropertyFontStyle)) { if (!fontStyle->isPrimitiveValue()) return; switch (static_cast<CSSPrimitiveValue*>(fontStyle.get())->getIdent()) { case CSSValueNormal: traitsMask |= FontStyleNormalMask; break; case CSSValueItalic: case CSSValueOblique: traitsMask |= FontStyleItalicMask; break; default: break; } } else traitsMask |= FontStyleNormalMask; if (RefPtr<CSSValue> fontWeight = style->getPropertyCSSValue(CSSPropertyFontWeight)) { if (!fontWeight->isPrimitiveValue()) return; switch (static_cast<CSSPrimitiveValue*>(fontWeight.get())->getIdent()) { case CSSValueBold: case CSSValue700: traitsMask |= FontWeight700Mask; break; case CSSValueNormal: case CSSValue400: traitsMask |= FontWeight400Mask; break; case CSSValue900: traitsMask |= FontWeight900Mask; break; case CSSValue800: traitsMask |= FontWeight800Mask; break; case CSSValue600: traitsMask |= FontWeight600Mask; break; case CSSValue500: traitsMask |= FontWeight500Mask; break; case CSSValue300: traitsMask |= FontWeight300Mask; break; case CSSValue200: traitsMask |= FontWeight200Mask; break; case CSSValue100: traitsMask |= FontWeight100Mask; break; default: break; } } else traitsMask |= FontWeight400Mask; if (RefPtr<CSSValue> fontVariant = style->getPropertyCSSValue(CSSPropertyFontVariant)) { // font-variant descriptor can be a value list. if (fontVariant->isPrimitiveValue()) { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); list->append(fontVariant); fontVariant = list; } else if (!fontVariant->isValueList()) return; CSSValueList* variantList = static_cast<CSSValueList*>(fontVariant.get()); unsigned numVariants = variantList->length(); if (!numVariants) return; for (unsigned i = 0; i < numVariants; ++i) { switch (static_cast<CSSPrimitiveValue*>(variantList->itemWithoutBoundsCheck(i))->getIdent()) { case CSSValueNormal: traitsMask |= FontVariantNormalMask; break; case CSSValueSmallCaps: traitsMask |= FontVariantSmallCapsMask; break; default: break; } } } else traitsMask |= FontVariantMask; // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace. RefPtr<CSSFontFace> fontFace; int srcLength = srcList->length(); bool foundSVGFont = false; 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 = static_cast<CSSFontFaceSrcValue*>(srcList->itemWithoutBoundsCheck(i)); OwnPtr<CSSFontFaceSource> source; #if ENABLE(SVG_FONTS) foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement(); #endif if (!item->isLocal()) { Settings* settings = m_document ? m_document->frame() ? m_document->frame()->settings() : 0 : 0; bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled()); if (allowDownloading && item->isSupportedFormat() && m_document) { CachedFont* cachedFont = item->cachedFont(m_document); if (cachedFont) { source = adoptPtr(new CSSFontFaceSource(item->resource(), cachedFont)); #if ENABLE(SVG_FONTS) if (foundSVGFont) source->setHasExternalSVGFont(true); #endif } } } else { source = adoptPtr(new CSSFontFaceSource(item->resource())); } if (!fontFace) fontFace = CSSFontFace::create(static_cast<FontTraitsMask>(traitsMask)); if (source) { #if ENABLE(SVG_FONTS) source->setSVGFontFaceElement(item->svgFontFaceElement()); #endif fontFace->addSource(source.release()); } } ASSERT(fontFace); if (fontFace && !fontFace->isValid()) return; if (rangeList) { unsigned numRanges = rangeList->length(); for (unsigned i = 0; i < numRanges; i++) { CSSUnicodeRangeValue* range = static_cast<CSSUnicodeRangeValue*>(rangeList->itemWithoutBoundsCheck(i)); fontFace->addRange(range->from(), range->to()); } } // Hash under every single family name. int familyLength = familyList->length(); for (int i = 0; i < familyLength; i++) { CSSPrimitiveValue* item = static_cast<CSSPrimitiveValue*>(familyList->itemWithoutBoundsCheck(i)); String familyName; if (item->isString()) familyName = item->getStringValue(); else if (item->isIdent()) { // We need to use the raw text for all the generic family types, since @font-face is a way of actually // defining what font to use for those types. switch (item->getIdent()) { case CSSValueSerif: familyName = serifFamily; break; case CSSValueSansSerif: familyName = sansSerifFamily; break; case CSSValueCursive: familyName = cursiveFamily; break; case CSSValueFantasy: familyName = fantasyFamily; break; case CSSValueMonospace: familyName = monospaceFamily; break; case CSSValueWebkitPictograph: familyName = pictographFamily; break; default: break; } } if (familyName.isEmpty()) continue; OwnPtr<Vector<RefPtr<CSSFontFace> > >& familyFontFaces = m_fontFaces.add(familyName, nullptr).first->second; if (!familyFontFaces) { familyFontFaces = adoptPtr(new Vector<RefPtr<CSSFontFace> >); ASSERT(!m_locallyInstalledFontFaces.contains(familyName)); Vector<unsigned> locallyInstalledFontsTraitsMasks; fontCache()->getTraitsInFamily(familyName, locallyInstalledFontsTraitsMasks); if (unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsMasks.size()) { OwnPtr<Vector<RefPtr<CSSFontFace> > > familyLocallyInstalledFaces = adoptPtr(new Vector<RefPtr<CSSFontFace> >); for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) { RefPtr<CSSFontFace> locallyInstalledFontFace = CSSFontFace::create(static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i]), true); locallyInstalledFontFace->addSource(adoptPtr(new CSSFontFaceSource(familyName))); ASSERT(locallyInstalledFontFace->isValid()); familyLocallyInstalledFaces->append(locallyInstalledFontFace); } m_locallyInstalledFontFaces.set(familyName, familyLocallyInstalledFaces.release()); } } familyFontFaces->append(fontFace); ++m_version; } }
void StyleResolver::applySVGProperty(CSSPropertyID id, CSSValue* value) { ASSERT(value); CSSPrimitiveValue* primitiveValue = 0; if (value->isPrimitiveValue()) primitiveValue = static_cast<CSSPrimitiveValue*>(value); const StyleResolverState& state = m_state; SVGRenderStyle* svgstyle = state.style()->accessSVGStyle(); bool isInherit = state.parentNode() && value->isInheritedValue(); bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue()); // What follows is a list that maps the CSS properties into their // corresponding front-end RenderStyle values. Shorthands(e.g. border, // background) occur in this list as well and are only hit when mapping // "inherit" or "initial" into front-end values. switch (id) { // ident only properties case CSSPropertyAlignmentBaseline: { HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline) if (!primitiveValue) break; svgstyle->setAlignmentBaseline(*primitiveValue); break; } case CSSPropertyBaselineShift: { HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift); if (!primitiveValue) break; if (primitiveValue->getIdent()) { switch (primitiveValue->getIdent()) { case CSSValueBaseline: svgstyle->setBaselineShift(BS_BASELINE); break; case CSSValueSub: svgstyle->setBaselineShift(BS_SUB); break; case CSSValueSuper: svgstyle->setBaselineShift(BS_SUPER); break; default: break; } } else { svgstyle->setBaselineShift(BS_LENGTH); svgstyle->setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue)); } break; } case CSSPropertyKerning: { HANDLE_INHERIT_AND_INITIAL(kerning, Kerning); if (primitiveValue) svgstyle->setKerning(SVGLength::fromCSSPrimitiveValue(primitiveValue)); break; } case CSSPropertyDominantBaseline: { HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline) if (primitiveValue) svgstyle->setDominantBaseline(*primitiveValue); break; } case CSSPropertyColorInterpolation: { HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation) if (primitiveValue) svgstyle->setColorInterpolation(*primitiveValue); break; } case CSSPropertyColorInterpolationFilters: { HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters) if (primitiveValue) svgstyle->setColorInterpolationFilters(*primitiveValue); break; } case CSSPropertyColorProfile: { // Not implemented. break; } case CSSPropertyColorRendering: { HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering) if (primitiveValue) svgstyle->setColorRendering(*primitiveValue); break; } case CSSPropertyClipRule: { HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule) if (primitiveValue) svgstyle->setClipRule(*primitiveValue); break; } case CSSPropertyFillRule: { HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule) if (primitiveValue) svgstyle->setFillRule(*primitiveValue); break; } case CSSPropertyStrokeLinejoin: { HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle) if (primitiveValue) svgstyle->setJoinStyle(*primitiveValue); break; } case CSSPropertyShapeRendering: { HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering) if (primitiveValue) svgstyle->setShapeRendering(*primitiveValue); break; } // end of ident only properties case CSSPropertyFill: { if (isInherit) { const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle(); svgstyle->setFillPaint(svgParentStyle->fillPaintType(), svgParentStyle->fillPaintColor(), svgParentStyle->fillPaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); return; } if (isInitial) { svgstyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); return; } if (value->isSVGPaint()) { SVGPaint* svgPaint = static_cast<SVGPaint*>(value); svgstyle->setFillPaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); } break; } case CSSPropertyStroke: { if (isInherit) { const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle(); svgstyle->setStrokePaint(svgParentStyle->strokePaintType(), svgParentStyle->strokePaintColor(), svgParentStyle->strokePaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); return; } if (isInitial) { svgstyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); return; } if (value->isSVGPaint()) { SVGPaint* svgPaint = static_cast<SVGPaint*>(value); svgstyle->setStrokePaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle()); } break; } case CSSPropertyStrokeWidth: { HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth) if (primitiveValue) svgstyle->setStrokeWidth(SVGLength::fromCSSPrimitiveValue(primitiveValue)); break; } case CSSPropertyStrokeDasharray: { HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray) if (!value->isValueList()) { svgstyle->setStrokeDashArray(SVGRenderStyle::initialStrokeDashArray()); break; } CSSValueList* dashes = static_cast<CSSValueList*>(value); Vector<SVGLength> array; size_t length = dashes->length(); for (size_t i = 0; i < length; ++i) { CSSValue* currValue = dashes->itemWithoutBoundsCheck(i); if (!currValue->isPrimitiveValue()) continue; CSSPrimitiveValue* dash = static_cast<CSSPrimitiveValue*>(dashes->itemWithoutBoundsCheck(i)); array.append(SVGLength::fromCSSPrimitiveValue(dash)); } svgstyle->setStrokeDashArray(array); break; } case CSSPropertyStrokeDashoffset: { HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset) if (primitiveValue) svgstyle->setStrokeDashOffset(SVGLength::fromCSSPrimitiveValue(primitiveValue)); break; } case CSSPropertyFillOpacity: { HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setFillOpacity(f); break; } case CSSPropertyStrokeOpacity: { HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setStrokeOpacity(f); break; } case CSSPropertyStopOpacity: { HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setStopOpacity(f); break; } case CSSPropertyMarkerStart: { HANDLE_INHERIT_AND_INITIAL(markerStartResource, MarkerStartResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgstyle->setMarkerStartResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyMarkerMid: { HANDLE_INHERIT_AND_INITIAL(markerMidResource, MarkerMidResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgstyle->setMarkerMidResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyMarkerEnd: { HANDLE_INHERIT_AND_INITIAL(markerEndResource, MarkerEndResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgstyle->setMarkerEndResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyStrokeLinecap: { HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle) if (primitiveValue) svgstyle->setCapStyle(*primitiveValue); break; } case CSSPropertyStrokeMiterlimit: { HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setStrokeMiterLimit(f); break; } case CSSPropertyFilter: { HANDLE_INHERIT_AND_INITIAL(filterResource, FilterResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgstyle->setFilterResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyMask: { HANDLE_INHERIT_AND_INITIAL(maskerResource, MaskerResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgstyle->setMaskerResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyClipPath: { HANDLE_INHERIT_AND_INITIAL(clipperResource, ClipperResource) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); svgstyle->setClipperResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document())); break; } case CSSPropertyTextAnchor: { HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor) if (primitiveValue) svgstyle->setTextAnchor(*primitiveValue); break; } case CSSPropertyWritingMode: { HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode) if (primitiveValue) svgstyle->setWritingMode(*primitiveValue); break; } case CSSPropertyStopColor: { HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor); if (value->isSVGColor()) svgstyle->setStopColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), state.style()->color())); break; } case CSSPropertyLightingColor: { HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor); if (value->isSVGColor()) svgstyle->setLightingColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), state.style()->color())); break; } case CSSPropertyFloodOpacity: { HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setFloodOpacity(f); break; } case CSSPropertyFloodColor: { HANDLE_INHERIT_AND_INITIAL(floodColor, FloodColor); if (value->isSVGColor()) svgstyle->setFloodColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), state.style()->color())); break; } case CSSPropertyGlyphOrientationHorizontal: { HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal) if (!primitiveValue) return; if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) { int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue()); ASSERT(orientation != -1); svgstyle->setGlyphOrientationHorizontal((EGlyphOrientation) orientation); } break; } case CSSPropertyGlyphOrientationVertical: { HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical) if (!primitiveValue) return; if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) { int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue()); ASSERT(orientation != -1); svgstyle->setGlyphOrientationVertical((EGlyphOrientation) orientation); } else if (primitiveValue->getIdent() == CSSValueAuto) svgstyle->setGlyphOrientationVertical(GO_AUTO); break; } case CSSPropertyEnableBackground: // Silently ignoring this property for now // http://bugs.webkit.org/show_bug.cgi?id=6022 break; case CSSPropertyWebkitSvgShadow: { if (isInherit) return svgstyle->setShadow(adoptPtr(state.parentStyle()->svgStyle()->shadow() ? new ShadowData(*state.parentStyle()->svgStyle()->shadow()) : 0)); if (isInitial || primitiveValue) // initial | none return svgstyle->setShadow(nullptr); if (!value->isValueList()) return; CSSValueList *list = static_cast<CSSValueList*>(value); if (!list->length()) return; CSSValue* firstValue = list->itemWithoutBoundsCheck(0); if (!firstValue->isShadowValue()) return; ShadowValue* item = static_cast<ShadowValue*>(firstValue); IntPoint location(item->x->computeLength<int>(state.style(), state.rootElementStyle()), item->y->computeLength<int>(state.style(), state.rootElementStyle())); int blur = item->blur ? item->blur->computeLength<int>(state.style(), state.rootElementStyle()) : 0; Color color; if (item->color) color = colorFromPrimitiveValue(item->color.get()); // -webkit-svg-shadow does should not have a spread or style ASSERT(!item->spread); ASSERT(!item->style); OwnPtr<ShadowData> shadowData = adoptPtr(new ShadowData(location, blur, 0, Normal, false, color.isValid() ? color : Color::transparent)); svgstyle->setShadow(shadowData.release()); return; } case CSSPropertyVectorEffect: { HANDLE_INHERIT_AND_INITIAL(vectorEffect, VectorEffect) if (!primitiveValue) break; svgstyle->setVectorEffect(*primitiveValue); break; } case CSSPropertyBufferedRendering: { HANDLE_INHERIT_AND_INITIAL(bufferedRendering, BufferedRendering) if (!primitiveValue) break; svgstyle->setBufferedRendering(*primitiveValue); break; } case CSSPropertyMaskType: { HANDLE_INHERIT_AND_INITIAL(maskType, MaskType) if (!primitiveValue) break; svgstyle->setMaskType(*primitiveValue); break; } default: // If you crash here, it's because you added a css property and are not handling it // in either this switch statement or the one in StyleResolver::applyProperty ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id); return; } }
void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) { ASSERT(value); CSSPrimitiveValue* primitiveValue = 0; if (value->isPrimitiveValue()) primitiveValue = static_cast<CSSPrimitiveValue*>(value); SVGRenderStyle* svgstyle = m_style->accessSVGStyle(); unsigned short valueType = value->cssValueType(); bool isInherit = m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT; bool isInitial = valueType == CSSPrimitiveValue::CSS_INITIAL || (!m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT); // What follows is a list that maps the CSS properties into their // corresponding front-end RenderStyle values. Shorthands(e.g. border, // background) occur in this list as well and are only hit when mapping // "inherit" or "initial" into front-end values. switch (id) { // ident only properties case CSSPropertyAlignmentBaseline: { HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline) if (!primitiveValue) break; svgstyle->setAlignmentBaseline(*primitiveValue); break; } case CSSPropertyBaselineShift: { HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift); if (!primitiveValue) break; if (primitiveValue->getIdent()) { switch (primitiveValue->getIdent()) { case CSSValueBaseline: svgstyle->setBaselineShift(BS_BASELINE); break; case CSSValueSub: svgstyle->setBaselineShift(BS_SUB); break; case CSSValueSuper: svgstyle->setBaselineShift(BS_SUPER); break; default: break; } } else { svgstyle->setBaselineShift(BS_LENGTH); svgstyle->setBaselineShiftValue(primitiveValue); } break; } case CSSPropertyKerning: { HANDLE_INHERIT_AND_INITIAL(kerning, Kerning); svgstyle->setKerning(primitiveValue); break; } case CSSPropertyDominantBaseline: { HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline) if (primitiveValue) svgstyle->setDominantBaseline(*primitiveValue); break; } case CSSPropertyColorInterpolation: { HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation) if (primitiveValue) svgstyle->setColorInterpolation(*primitiveValue); break; } case CSSPropertyColorInterpolationFilters: { HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters) if (primitiveValue) svgstyle->setColorInterpolationFilters(*primitiveValue); break; } case CSSPropertyColorRendering: { HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering) if (primitiveValue) svgstyle->setColorRendering(*primitiveValue); break; } case CSSPropertyClipRule: { HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule) if (primitiveValue) svgstyle->setClipRule(*primitiveValue); break; } case CSSPropertyFillRule: { HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule) if (primitiveValue) svgstyle->setFillRule(*primitiveValue); break; } case CSSPropertyStrokeLinejoin: { HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle) if (primitiveValue) svgstyle->setJoinStyle(*primitiveValue); break; } case CSSPropertyImageRendering: { HANDLE_INHERIT_AND_INITIAL(imageRendering, ImageRendering) if (primitiveValue) svgstyle->setImageRendering(*primitiveValue); break; } case CSSPropertyShapeRendering: { HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering) if (primitiveValue) svgstyle->setShapeRendering(*primitiveValue); break; } // end of ident only properties case CSSPropertyFill: { HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint) if (value->isSVGPaint()) svgstyle->setFillPaint(static_cast<SVGPaint*>(value)); break; } case CSSPropertyStroke: { HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint) if (value->isSVGPaint()) svgstyle->setStrokePaint(static_cast<SVGPaint*>(value)); break; } case CSSPropertyStrokeWidth: { HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth) if (primitiveValue) svgstyle->setStrokeWidth(primitiveValue); break; } case CSSPropertyStrokeDasharray: { HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray) if (value->isValueList()) svgstyle->setStrokeDashArray(static_cast<CSSValueList*>(value)); break; } case CSSPropertyStrokeDashoffset: { HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset) if (primitiveValue) svgstyle->setStrokeDashOffset(primitiveValue); break; } case CSSPropertyFillOpacity: { HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setFillOpacity(f); break; } case CSSPropertyStrokeOpacity: { HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setStrokeOpacity(f); break; } case CSSPropertyStopOpacity: { HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setStopOpacity(f); break; } case CSSPropertyMarkerStart: { HANDLE_INHERIT_AND_INITIAL(startMarker, StartMarker) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); else return; svgstyle->setStartMarker(SVGURIReference::getTarget(s)); break; } case CSSPropertyMarkerMid: { HANDLE_INHERIT_AND_INITIAL(midMarker, MidMarker) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); else return; svgstyle->setMidMarker(SVGURIReference::getTarget(s)); break; } case CSSPropertyMarkerEnd: { HANDLE_INHERIT_AND_INITIAL(endMarker, EndMarker) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); else return; svgstyle->setEndMarker(SVGURIReference::getTarget(s)); break; } case CSSPropertyStrokeLinecap: { HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle) if (primitiveValue) svgstyle->setCapStyle(*primitiveValue); break; } case CSSPropertyStrokeMiterlimit: { HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setStrokeMiterLimit(f); break; } case CSSPropertyFilter: { HANDLE_INHERIT_AND_INITIAL(filter, Filter) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); else return; svgstyle->setFilter(SVGURIReference::getTarget(s)); break; } case CSSPropertyMask: { HANDLE_INHERIT_AND_INITIAL(maskElement, MaskElement) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); else return; svgstyle->setMaskElement(SVGURIReference::getTarget(s)); break; } case CSSPropertyClipPath: { HANDLE_INHERIT_AND_INITIAL(clipPath, ClipPath) if (!primitiveValue) return; String s; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); else return; svgstyle->setClipPath(SVGURIReference::getTarget(s)); break; } case CSSPropertyTextAnchor: { HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor) if (primitiveValue) svgstyle->setTextAnchor(*primitiveValue); break; } case CSSPropertyWritingMode: { HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode) if (primitiveValue) svgstyle->setWritingMode(*primitiveValue); break; } case CSSPropertyStopColor: { HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor); svgstyle->setStopColor(colorFromSVGColorCSSValue(value, m_style.get())); break; } case CSSPropertyLightingColor: { HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor); svgstyle->setLightingColor(colorFromSVGColorCSSValue(value, m_style.get())); break; } case CSSPropertyFloodOpacity: { HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity) if (!primitiveValue) return; float f = 0.0f; int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_PERCENTAGE) f = primitiveValue->getFloatValue() / 100.0f; else if (type == CSSPrimitiveValue::CSS_NUMBER) f = primitiveValue->getFloatValue(); else return; svgstyle->setFloodOpacity(f); break; } case CSSPropertyFloodColor: { if (isInitial) { svgstyle->setFloodColor(SVGRenderStyle::initialFloodColor()); return; } svgstyle->setFloodColor(colorFromSVGColorCSSValue(value, m_style.get())); break; } case CSSPropertyGlyphOrientationHorizontal: { HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal) if (!primitiveValue) return; if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) { int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue()); ASSERT(orientation != -1); svgstyle->setGlyphOrientationHorizontal((EGlyphOrientation) orientation); } break; } case CSSPropertyGlyphOrientationVertical: { HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical) if (!primitiveValue) return; if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) { int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue()); ASSERT(orientation != -1); svgstyle->setGlyphOrientationVertical((EGlyphOrientation) orientation); } else if (primitiveValue->getIdent() == CSSValueAuto) svgstyle->setGlyphOrientationVertical(GO_AUTO); break; } case CSSPropertyEnableBackground: // Silently ignoring this property for now // http://bugs.webkit.org/show_bug.cgi?id=6022 break; case CSSPropertyWebkitSvgShadow: { if (isInherit) return svgstyle->setShadow(m_parentStyle->svgStyle()->shadow() ? new ShadowData(*m_parentStyle->svgStyle()->shadow()) : 0); if (isInitial || primitiveValue) // initial | none return svgstyle->setShadow(0); if (!value->isValueList()) return; float zoomFactor = m_style->effectiveZoom(); CSSValueList *list = static_cast<CSSValueList*>(value); ASSERT(list->length() == 1); ShadowValue* item = static_cast<ShadowValue*>(list->itemWithoutBoundsCheck(0)); int x = item->x->computeLengthInt(style(), m_rootElementStyle, zoomFactor); int y = item->y->computeLengthInt(style(), m_rootElementStyle, zoomFactor); int blur = item->blur ? item->blur->computeLengthInt(style(), m_rootElementStyle, zoomFactor) : 0; Color color; if (item->color) color = getColorFromPrimitiveValue(item->color.get()); // -webkit-svg-shadow does should not have a spread or style ASSERT(!item->spread); ASSERT(!item->style); ShadowData* shadowData = new ShadowData(x, y, blur, 0, Normal, color.isValid() ? color : Color::transparent); svgstyle->setShadow(shadowData); return; } default: // If you crash here, it's because you added a css property and are not handling it // in either this switch statement or the one in CSSStyleSelector::applyProperty ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id); return; } }
void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule) { // Obtain the font-family property and the src property. Both must be defined. const CSSMutableStyleDeclaration* style = fontFaceRule->style(); RefPtr<CSSValue> fontFamily = style->getPropertyCSSValue(CSSPropertyFontFamily); RefPtr<CSSValue> src = style->getPropertyCSSValue(CSSPropertySrc); RefPtr<CSSValue> unicodeRange = style->getPropertyCSSValue(CSSPropertyUnicodeRange); if (!fontFamily || !src || !fontFamily->isValueList() || !src->isValueList() || unicodeRange && !unicodeRange->isValueList()) return; CSSValueList* familyList = static_cast<CSSValueList*>(fontFamily.get()); if (!familyList->length()) return; CSSValueList* srcList = static_cast<CSSValueList*>(src.get()); if (!srcList->length()) return; CSSValueList* rangeList = static_cast<CSSValueList*>(unicodeRange.get()); unsigned traitsMask = 0; if (RefPtr<CSSValue> fontStyle = style->getPropertyCSSValue(CSSPropertyFontStyle)) { if (fontStyle->isPrimitiveValue()) { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); list->append(fontStyle); fontStyle = list; } else if (!fontStyle->isValueList()) return; CSSValueList* styleList = static_cast<CSSValueList*>(fontStyle.get()); unsigned numStyles = styleList->length(); if (!numStyles) return; for (unsigned i = 0; i < numStyles; ++i) { switch (static_cast<CSSPrimitiveValue*>(styleList->itemWithoutBoundsCheck(i))->getIdent()) { case CSSValueAll: traitsMask |= FontStyleMask; break; case CSSValueNormal: traitsMask |= FontStyleNormalMask; break; case CSSValueItalic: case CSSValueOblique: traitsMask |= FontStyleItalicMask; break; default: break; } } } else traitsMask |= FontStyleMask; if (RefPtr<CSSValue> fontWeight = style->getPropertyCSSValue(CSSPropertyFontWeight)) { if (fontWeight->isPrimitiveValue()) { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); list->append(fontWeight); fontWeight = list; } else if (!fontWeight->isValueList()) return; CSSValueList* weightList = static_cast<CSSValueList*>(fontWeight.get()); unsigned numWeights = weightList->length(); if (!numWeights) return; for (unsigned i = 0; i < numWeights; ++i) { switch (static_cast<CSSPrimitiveValue*>(weightList->itemWithoutBoundsCheck(i))->getIdent()) { case CSSValueAll: traitsMask |= FontWeightMask; break; case CSSValueBolder: case CSSValueBold: case CSSValue700: traitsMask |= FontWeight700Mask; break; case CSSValueNormal: case CSSValue400: traitsMask |= FontWeight400Mask; break; case CSSValue900: traitsMask |= FontWeight900Mask; break; case CSSValue800: traitsMask |= FontWeight800Mask; break; case CSSValue600: traitsMask |= FontWeight600Mask; break; case CSSValue500: traitsMask |= FontWeight500Mask; break; case CSSValue300: traitsMask |= FontWeight300Mask; break; case CSSValueLighter: case CSSValue200: traitsMask |= FontWeight200Mask; break; case CSSValue100: traitsMask |= FontWeight100Mask; break; default: break; } } } else traitsMask |= FontWeightMask; if (RefPtr<CSSValue> fontVariant = style->getPropertyCSSValue(CSSPropertyFontVariant)) { if (fontVariant->isPrimitiveValue()) { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); list->append(fontVariant); fontVariant = list; } else if (!fontVariant->isValueList()) return; CSSValueList* variantList = static_cast<CSSValueList*>(fontVariant.get()); unsigned numVariants = variantList->length(); if (!numVariants) return; for (unsigned i = 0; i < numVariants; ++i) { switch (static_cast<CSSPrimitiveValue*>(variantList->itemWithoutBoundsCheck(i))->getIdent()) { case CSSValueAll: traitsMask |= FontVariantMask; break; case CSSValueNormal: traitsMask |= FontVariantNormalMask; break; case CSSValueSmallCaps: traitsMask |= FontVariantSmallCapsMask; break; default: break; } } } else traitsMask |= FontVariantNormalMask; // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace. RefPtr<CSSFontFace> fontFace; int srcLength = srcList->length(); bool foundLocal = false; #if ENABLE(SVG_FONTS) bool foundSVGFont = false; #endif 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 = static_cast<CSSFontFaceSrcValue*>(srcList->itemWithoutBoundsCheck(i)); CSSFontFaceSource* source = 0; #if ENABLE(SVG_FONTS) foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement(); #endif if (!item->isLocal()) { if (item->isSupportedFormat() && m_document) { CachedFont* cachedFont = m_document->docLoader()->requestFont(item->resource()); if (cachedFont) { #if ENABLE(SVG_FONTS) if (foundSVGFont) cachedFont->setSVGFont(true); #endif source = new CSSFontFaceSource(item->resource(), cachedFont); } } } else { source = new CSSFontFaceSource(item->resource()); foundLocal = true; } if (!fontFace) fontFace = CSSFontFace::create(static_cast<FontTraitsMask>(traitsMask)); if (source) { #if ENABLE(SVG_FONTS) source->setSVGFontFaceElement(item->svgFontFaceElement()); #endif fontFace->addSource(source); } } ASSERT(fontFace); if (fontFace && !fontFace->isValid()) return; if (rangeList) { unsigned numRanges = rangeList->length(); for (unsigned i = 0; i < numRanges; i++) { CSSUnicodeRangeValue* range = static_cast<CSSUnicodeRangeValue*>(rangeList->itemWithoutBoundsCheck(i)); fontFace->addRange(range->from(), range->to()); } } // Hash under every single family name. int familyLength = familyList->length(); for (int i = 0; i < familyLength; i++) { CSSPrimitiveValue* item = static_cast<CSSPrimitiveValue*>(familyList->itemWithoutBoundsCheck(i)); String familyName; if (item->primitiveType() == CSSPrimitiveValue::CSS_STRING) familyName = static_cast<FontFamilyValue*>(item)->familyName(); else if (item->primitiveType() == CSSPrimitiveValue::CSS_IDENT) { // We need to use the raw text for all the generic family types, since @font-face is a way of actually // defining what font to use for those types. String familyName; switch (item->getIdent()) { case CSSValueSerif: familyName = "-webkit-serif"; break; case CSSValueSansSerif: familyName = "-webkit-sans-serif"; break; case CSSValueCursive: familyName = "-webkit-cursive"; break; case CSSValueFantasy: familyName = "-webkit-fantasy"; break; case CSSValueMonospace: familyName = "-webkit-monospace"; break; default: break; } } if (familyName.isEmpty()) continue; #if ENABLE(SVG_FONTS) // SVG allows several <font> elements with the same font-family, differing only // in ie. font-variant. Be sure to pick up the right one - in getFontData below. if (foundSVGFont && (traitsMask & FontVariantSmallCapsMask)) familyName += "-webkit-svg-small-caps"; #endif Vector<RefPtr<CSSFontFace> >* familyFontFaces = m_fontFaces.get(familyName); if (!familyFontFaces) { familyFontFaces = new Vector<RefPtr<CSSFontFace> >; m_fontFaces.set(familyName, familyFontFaces); ASSERT(!m_locallyInstalledFontFaces.contains(familyName)); Vector<RefPtr<CSSFontFace> >* familyLocallyInstalledFaces; Vector<unsigned> locallyInstalledFontsTraitsMasks; FontCache::getTraitsInFamily(familyName, locallyInstalledFontsTraitsMasks); unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsMasks.size(); if (numLocallyInstalledFaces) { familyLocallyInstalledFaces = new Vector<RefPtr<CSSFontFace> >; m_locallyInstalledFontFaces.set(familyName, familyLocallyInstalledFaces); for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) { RefPtr<CSSFontFace> locallyInstalledFontFace = CSSFontFace::create(static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i])); locallyInstalledFontFace->addSource(new CSSFontFaceSource(familyName)); ASSERT(locallyInstalledFontFace->isValid()); familyLocallyInstalledFaces->append(locallyInstalledFontFace); } } } familyFontFaces->append(fontFace); } }
FontTraits FontFace::traits() const { FontStyle style = FontStyleNormal; if (m_style) { if (!m_style->isPrimitiveValue()) return 0; switch (toCSSPrimitiveValue(m_style.get())->getValueID()) { case CSSValueNormal: style = FontStyleNormal; break; case CSSValueItalic: case CSSValueOblique: style = FontStyleItalic; break; default: break; } } FontWeight weight = FontWeight400; if (m_weight) { if (!m_weight->isPrimitiveValue()) return 0; switch (toCSSPrimitiveValue(m_weight.get())->getValueID()) { case CSSValueBold: case CSSValue700: weight = FontWeight700; break; case CSSValueNormal: case CSSValue400: weight = FontWeight400; break; case CSSValue900: weight = FontWeight900; break; case CSSValue800: weight = FontWeight800; break; case CSSValue600: weight = FontWeight600; break; case CSSValue500: weight = FontWeight500; break; case CSSValue300: weight = FontWeight300; break; case CSSValue200: weight = FontWeight200; break; case CSSValueLighter: case CSSValue100: weight = FontWeight100; break; default: ASSERT_NOT_REACHED(); break; } } FontVariant variant = FontVariantNormal; if (RefPtrWillBeRawPtr<CSSValue> fontVariant = m_variant) { // font-variant descriptor can be a value list. if (fontVariant->isPrimitiveValue()) { RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); list->append(fontVariant); fontVariant = list; } else if (!fontVariant->isValueList()) { return 0; } CSSValueList* variantList = toCSSValueList(fontVariant.get()); unsigned numVariants = variantList->length(); if (!numVariants) return 0; for (unsigned i = 0; i < numVariants; ++i) { switch (toCSSPrimitiveValue(variantList->itemWithoutBoundsCheck(i))->getValueID()) { case CSSValueNormal: variant = FontVariantNormal; break; case CSSValueSmallCaps: variant = FontVariantSmallCaps; break; default: break; } } } return FontTraits(style, variant, weight, FontStretchNormal); }
static PassRefPtr<CustomFilterOperation> createCustomFilterOperationWithInlineSyntax(CSSFilterValue* filterValue, StyleResolverState& state) { CSSValue* shadersValue = filterValue->itemWithoutBoundsCheck(0); ASSERT_WITH_SECURITY_IMPLICATION(shadersValue->isValueList()); CSSValueList* shadersList = toCSSValueList(shadersValue); unsigned shadersListLength = shadersList->length(); ASSERT(shadersListLength); CSSShaderValue* vertexShader = 0; CSSShaderValue* fragmentShader = 0; if (shadersList->itemWithoutBoundsCheck(0)->isShaderValue()) vertexShader = toCSSShaderValue(shadersList->itemWithoutBoundsCheck(0)); CustomFilterProgramType programType = ProgramTypeBlendsElementTexture; CustomFilterProgramMixSettings mixSettings; if (shadersListLength > 1) { CSSValue* fragmentShaderOrMixFunction = shadersList->itemWithoutBoundsCheck(1); if (fragmentShaderOrMixFunction->isMixFunctionValue()) { CSSMixFunctionValue* mixFunction = toCSSMixFunctionValue(fragmentShaderOrMixFunction); CSSValueListIterator iterator(mixFunction); ASSERT(mixFunction->length()); if (iterator.value()->isShaderValue()) fragmentShader = toCSSShaderValue(iterator.value()); iterator.advance(); ASSERT(mixFunction->length() <= 3); while (iterator.hasMore()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value()); if (CSSParser::isBlendMode(primitiveValue->getValueID())) mixSettings.blendMode = *primitiveValue; else if (CSSParser::isCompositeOperator(primitiveValue->getValueID())) mixSettings.compositeOperator = *primitiveValue; else ASSERT_NOT_REACHED(); iterator.advance(); } } else { programType = ProgramTypeNoElementTexture; if (fragmentShaderOrMixFunction->isShaderValue()) fragmentShader = toCSSShaderValue(fragmentShaderOrMixFunction); } } if (!vertexShader && !fragmentShader) return 0; unsigned meshRows = 1; unsigned meshColumns = 1; CustomFilterMeshType meshType = MeshTypeAttached; CSSValue* parametersValue = 0; if (filterValue->length() > 1) { CSSValueListIterator iterator(filterValue->itemWithoutBoundsCheck(1)); // The second value might be the mesh box or the list of parameters: // If it starts with a number or any of the mesh-box identifiers it is // the mesh-box list, if not it means it is the parameters list. if (iterator.hasMore() && iterator.isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value()); if (primitiveValue->isNumber()) { // If only one integer value is specified, it will set both // the rows and the columns. meshColumns = meshRows = primitiveValue->getIntValue(); iterator.advance(); // Try to match another number for the rows. if (iterator.hasMore() && iterator.isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value()); if (primitiveValue->isNumber()) { meshRows = primitiveValue->getIntValue(); iterator.advance(); } } } } if (iterator.hasMore() && iterator.isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value()); if (primitiveValue->getValueID() == CSSValueDetached) { meshType = MeshTypeDetached; iterator.advance(); } } if (!iterator.index()) { // If no value was consumed from the mesh value, then it is just a parameter list, meaning that we end up // having just two CSSListValues: list of shaders and list of parameters. ASSERT(filterValue->length() == 2); parametersValue = filterValue->itemWithoutBoundsCheck(1); } } if (filterValue->length() > 2 && !parametersValue) parametersValue = filterValue->itemWithoutBoundsCheck(2); CustomFilterParameterList parameterList; if (parametersValue && !parseCustomFilterParameterList(parametersValue, parameterList, state)) return 0; RefPtr<CustomFilterProgram> program = createCustomFilterProgram(vertexShader, fragmentShader, programType, mixSettings, meshType, state); return CustomFilterOperation::create(program.release(), parameterList, meshRows, meshColumns, meshType); }
unsigned FontFace::traitsMask() const { unsigned traitsMask = 0; if (m_style) { if (!m_style->isPrimitiveValue()) return 0; switch (toCSSPrimitiveValue(m_style.get())->getValueID()) { case CSSValueNormal: traitsMask |= FontStyleNormalMask; break; case CSSValueItalic: case CSSValueOblique: traitsMask |= FontStyleItalicMask; break; default: break; } } else { traitsMask |= FontStyleNormalMask; } if (m_weight) { if (!m_weight->isPrimitiveValue()) return 0; switch (toCSSPrimitiveValue(m_weight.get())->getValueID()) { case CSSValueBold: case CSSValue700: traitsMask |= FontWeight700Mask; break; case CSSValueNormal: case CSSValue400: traitsMask |= FontWeight400Mask; break; case CSSValue900: traitsMask |= FontWeight900Mask; break; case CSSValue800: traitsMask |= FontWeight800Mask; break; case CSSValue600: traitsMask |= FontWeight600Mask; break; case CSSValue500: traitsMask |= FontWeight500Mask; break; case CSSValue300: traitsMask |= FontWeight300Mask; break; case CSSValue200: traitsMask |= FontWeight200Mask; break; case CSSValue100: traitsMask |= FontWeight100Mask; break; default: break; } } else { traitsMask |= FontWeight400Mask; } if (RefPtr<CSSValue> fontVariant = m_variant) { // font-variant descriptor can be a value list. if (fontVariant->isPrimitiveValue()) { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); list->append(fontVariant); fontVariant = list; } else if (!fontVariant->isValueList()) { return 0; } CSSValueList* variantList = toCSSValueList(fontVariant.get()); unsigned numVariants = variantList->length(); if (!numVariants) return 0; for (unsigned i = 0; i < numVariants; ++i) { switch (toCSSPrimitiveValue(variantList->itemWithoutBoundsCheck(i))->getValueID()) { case CSSValueNormal: traitsMask |= FontVariantNormalMask; break; case CSSValueSmallCaps: traitsMask |= FontVariantSmallCapsMask; break; default: break; } } } else { traitsMask |= FontVariantNormalMask; } return traitsMask; }