String CSSFontFaceSet::familyNameFromPrimitive(const CSSPrimitiveValue& value) { if (value.isFontFamily()) return value.fontFamily().familyName; if (!value.isValueID()) return { }; // 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 (value.getValueID()) { case CSSValueSerif: return serifFamily; case CSSValueSansSerif: return sansSerifFamily; case CSSValueCursive: return cursiveFamily; case CSSValueFantasy: return fantasyFamily; case CSSValueMonospace: return monospaceFamily; case CSSValueWebkitPictograph: return pictographFamily; default: return { }; } }
void StyleBuilderFunctions::applyValueCSSPropertyTransformOrigin(StyleResolverState& state, CSSValue* value) { CSSValueList* list = toCSSValueList(value); ASSERT(list->length() == 3); CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0)); if (primitiveValue->isValueID()) { switch (primitiveValue->getValueID()) { case CSSValueLeft: state.style()->setTransformOriginX(Length(0, Percent)); break; case CSSValueRight: state.style()->setTransformOriginX(Length(100, Percent)); break; case CSSValueCenter: state.style()->setTransformOriginX(Length(50, Percent)); break; default: ASSERT_NOT_REACHED(); } } else { state.style()->setTransformOriginX(StyleBuilderConverter::convertLength(state, primitiveValue)); } primitiveValue = toCSSPrimitiveValue(list->item(1)); if (primitiveValue->isValueID()) { switch (primitiveValue->getValueID()) { case CSSValueTop: state.style()->setTransformOriginY(Length(0, Percent)); break; case CSSValueBottom: state.style()->setTransformOriginY(Length(100, Percent)); break; case CSSValueCenter: state.style()->setTransformOriginY(Length(50, Percent)); break; default: ASSERT_NOT_REACHED(); } } else { state.style()->setTransformOriginY(StyleBuilderConverter::convertLength(state, primitiveValue)); } primitiveValue = toCSSPrimitiveValue(list->item(2)); state.style()->setTransformOriginZ(StyleBuilderConverter::convertComputedLength<float>(state, primitiveValue)); }
void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent) state.style()->setTextAlign(*primitiveValue); else if (state.parentStyle()->textAlign() == TASTART) state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT); else if (state.parentStyle()->textAlign() == TAEND) state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT); else state.style()->setTextAlign(state.parentStyle()->textAlign()); }
static bool positionFromThreeOrFourValues(CSSPrimitiveValue** values, CSSValue*& resultX, CSSValue*& resultY) { CSSPrimitiveValue* center = nullptr; for (int i = 0; values[i]; i++) { CSSPrimitiveValue* currentValue = values[i]; if (!currentValue->isValueID()) return false; CSSValueID id = currentValue->getValueID(); if (id == CSSValueCenter) { if (center) return false; center = currentValue; continue; } CSSValue* result = nullptr; if (values[i + 1] && !values[i + 1]->isValueID()) { result = CSSValuePair::create(currentValue, values[++i], CSSValuePair::KeepIdenticalValues); } else { result = currentValue; } if (id == CSSValueLeft || id == CSSValueRight) { if (resultX) return false; resultX = result; } else { ASSERT(id == CSSValueTop || id == CSSValueBottom); if (resultY) return false; resultY = result; } } if (center) { ASSERT(resultX || resultY); if (resultX && resultY) return false; if (!resultX) resultX = center; else resultY = center; } ASSERT(resultX && resultY); return true; }
void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); // FIXME : Per http://www.w3.org/TR/css3-text/#text-align0 can now take <string> but this is not implemented in the // rendering code. if (primitiveValue->isString()) return; if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent) state.style()->setTextAlign(*primitiveValue); else if (state.parentStyle()->textAlign() == TASTART) state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT); else if (state.parentStyle()->textAlign() == TAEND) state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT); else state.style()->setTextAlign(state.parentStyle()->textAlign()); }
bool FontFace::setFamilyValue(CSSValueList* familyList) { // The font-family descriptor has to have exactly one family name. if (familyList->length() != 1) return false; CSSPrimitiveValue* familyValue = toCSSPrimitiveValue(familyList->itemWithoutBoundsCheck(0)); AtomicString family; if (familyValue->isString()) { family = AtomicString(familyValue->getStringValue()); } else if (familyValue->isValueID()) { // 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 (familyValue->getValueID()) { case CSSValueSerif: family = FontFamilyNames::webkit_serif; break; case CSSValueSansSerif: family = FontFamilyNames::webkit_sans_serif; break; case CSSValueCursive: family = FontFamilyNames::webkit_cursive; break; case CSSValueFantasy: family = FontFamilyNames::webkit_fantasy; break; case CSSValueMonospace: family = FontFamilyNames::webkit_monospace; break; case CSSValueWebkitPictograph: family = FontFamilyNames::webkit_pictograph; break; default: return false; } } m_family = family; return true; }
void StyleBuilderFunctions::applyValueCSSPropertyBaselineShift(StyleResolverState& state, CSSValue* value) { SVGComputedStyle& svgStyle = state.style()->accessSVGStyle(); CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (!primitiveValue->isValueID()) { svgStyle.setBaselineShift(BS_LENGTH); svgStyle.setBaselineShiftValue(StyleBuilderConverter::convertLength(state, primitiveValue)); return; } switch (primitiveValue->getValueID()) { case CSSValueBaseline: svgStyle.setBaselineShift(BS_LENGTH); svgStyle.setBaselineShiftValue(Length(Fixed)); return; case CSSValueSub: svgStyle.setBaselineShift(BS_SUB); return; case CSSValueSuper: svgStyle.setBaselineShift(BS_SUPER); return; default: ASSERT_NOT_REACHED(); } }
static bool isVerticalPositionKeywordOnly(const CSSPrimitiveValue& value) { return value.isValueID() && (value.getValueID() == CSSValueTop || value.getValueID() == CSSValueBottom); }
static bool isHorizontalPositionKeywordOnly(const CSSPrimitiveValue& value) { return value.isValueID() && (value.getValueID() == CSSValueLeft || value.getValueID() == CSSValueRight); }
void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule) { // Obtain the font-family property and the src property. Both must be defined. const StylePropertySet& style = fontFaceRule->properties(); 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 = toCSSValueList(fontFamily.get()); if (!familyList->length()) return; CSSValueList* srcList = toCSSValueList(src.get()); if (!srcList->length()) return; CSSValueList* rangeList = toCSSValueList(unicodeRange.get()); unsigned traitsMask = 0; if (RefPtr<CSSValue> fontStyle = style.getPropertyCSSValue(CSSPropertyFontStyle)) { if (!fontStyle->isPrimitiveValue()) return; switch (toCSSPrimitiveValue(fontStyle.get())->getValueID()) { 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 (toCSSPrimitiveValue(fontWeight.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 = 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 = toCSSValueList(fontVariant.get()); unsigned numVariants = variantList->length(); if (!numVariants) return; 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 |= 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 = toCSSFontFaceSrcValue(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) { 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()); #endif fontFace = CSSFontFace::create(static_cast<FontTraitsMask>(traitsMask), rule); } 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 = toCSSPrimitiveValue(familyList->itemWithoutBoundsCheck(i)); String familyName; if (item->isString()) { familyName = item->getStringValue(); } else if (item->isValueID()) { // 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->getValueID()) { 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).iterator->value; 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]), 0, true); locallyInstalledFontFace->addSource(adoptPtr(new CSSFontFaceSource(familyName))); ASSERT(locallyInstalledFontFace->isValid()); familyLocallyInstalledFaces->append(locallyInstalledFontFace); } m_locallyInstalledFontFaces.set(familyName, familyLocallyInstalledFaces.release()); } } familyFontFaces->append(fontFace); ++m_version; } }