KCDashArray KSVGPainterFactory::dashArrayFromRenderingStyle(const RenderStyle* style) { KCDashArray 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->item(i)); if (!dash) continue; array.append(dash->computeLengthFloat(const_cast<RenderStyle*>(style))); } } return array; }
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 StyleBuilderFunctions::applyValueCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state, CSSValue* value) { if (value->isValueList()) { CSSValueList* list = toCSSValueList(value); ASSERT(list->length() == 2); if (list->length() != 2) return; for (unsigned i = 0; i < 2; ++i) { CSSValue* item = list->item(i); if (!item->isPrimitiveValue()) continue; CSSPrimitiveValue* value = toCSSPrimitiveValue(item); if (value->getValueID() == CSSValueFilled || value->getValueID() == CSSValueOpen) state.style()->setTextEmphasisFill(*value); else state.style()->setTextEmphasisMark(*value); } state.style()->setTextEmphasisCustomMark(nullAtom); return; } if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->isString()) { state.style()->setTextEmphasisFill(TextEmphasisFillFilled); state.style()->setTextEmphasisMark(TextEmphasisMarkCustom); state.style()->setTextEmphasisCustomMark(AtomicString(primitiveValue->getStringValue())); return; } state.style()->setTextEmphasisCustomMark(nullAtom); if (primitiveValue->getValueID() == CSSValueFilled || primitiveValue->getValueID() == CSSValueOpen) { state.style()->setTextEmphasisFill(*primitiveValue); state.style()->setTextEmphasisMark(TextEmphasisMarkAuto); } else { state.style()->setTextEmphasisFill(TextEmphasisFillFilled); state.style()->setTextEmphasisMark(*primitiveValue); } }
void StyleBuilderFunctions::applyValueCSSPropertyPerspectiveOrigin(StyleResolverState& state, CSSValue* value) { CSSValueList* list = toCSSValueList(value); ASSERT(list->length() == 2); CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0)); if (primitiveValue->isValueID()) { switch (primitiveValue->getValueID()) { case CSSValueLeft: state.style()->setPerspectiveOriginX(Length(0, Percent)); break; case CSSValueRight: state.style()->setPerspectiveOriginX(Length(100, Percent)); break; case CSSValueCenter: state.style()->setPerspectiveOriginX(Length(50, Percent)); break; default: ASSERT_NOT_REACHED(); } } else { state.style()->setPerspectiveOriginX(StyleBuilderConverter::convertLength(state, primitiveValue)); } primitiveValue = toCSSPrimitiveValue(list->item(1)); if (primitiveValue->isValueID()) { switch (primitiveValue->getValueID()) { case CSSValueTop: state.style()->setPerspectiveOriginY(Length(0, Percent)); break; case CSSValueBottom: state.style()->setPerspectiveOriginY(Length(100, Percent)); break; case CSSValueCenter: state.style()->setPerspectiveOriginY(Length(50, Percent)); break; default: ASSERT_NOT_REACHED(); } } else { state.style()->setPerspectiveOriginY(StyleBuilderConverter::convertLength(state, primitiveValue)); } }
void SVGFontFaceElement::rebuildFontFace() { if (!inDocument()) { ASSERT(!m_fontElement); return; } bool describesParentFont = isSVGFontElement(*parentNode()); RefPtrWillBeRawPtr<CSSValueList> list = nullptr; if (describesParentFont) { m_fontElement = toSVGFontElement(parentNode()); list = CSSValueList::createCommaSeparated(); list->append(CSSFontFaceSrcValue::createLocal(fontFamily())); } else { m_fontElement = nullptr; // we currently ignore all but the last src element, alternatively we could concat them if (SVGFontFaceSrcElement* element = Traversal<SVGFontFaceSrcElement>::lastChild(*this)) list = element->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. RefPtrWillBeRawPtr<CSSValue> src = m_fontFaceRule->properties().getPropertyCSSValue(CSSPropertySrc); CSSValueList* srcList = toCSSValueList(src.get()); unsigned srcLength = srcList ? srcList->length() : 0; for (unsigned i = 0; i < srcLength; i++) { if (CSSFontFaceSrcValue* item = toCSSFontFaceSrcValue(srcList->item(i))) item->setSVGFontFaceElement(this); } } document().styleResolverChanged(); }
void StyleBuilderFunctions::applyValueCSSPropertyCursor(StyleResolverState& state, CSSValue* value) { state.style()->clearCursorList(); if (value->isValueList()) { CSSValueList* list = toCSSValueList(value); int len = list->length(); state.style()->setCursor(CURSOR_AUTO); for (int i = 0; i < len; i++) { CSSValue* item = list->item(i); if (item->isCursorImageValue()) { CSSCursorImageValue* image = toCSSCursorImageValue(item); state.style()->addCursor(state.styleImage(CSSPropertyCursor, image), image->hotSpot()); } else { state.style()->setCursor(*toCSSPrimitiveValue(item)); } } } else { state.style()->setCursor(*toCSSPrimitiveValue(value)); } }
static CSSValueList* parseSimpleTransformList(const CharType* chars, unsigned length) { if (!transformCanLikelyUseFastPath(chars, length)) return nullptr; const CharType*& pos = chars; const CharType* end = chars + length; CSSValueList* transformList = nullptr; while (pos < end) { while (pos < end && isCSSSpace(*pos)) ++pos; if (pos >= end) break; CSSFunctionValue* transformValue = parseSimpleTransformValue(pos, end); if (!transformValue) return nullptr; if (!transformList) transformList = CSSValueList::createSpaceSeparated(); transformList->append(*transformValue); } return transformList; }
PassRefPtr<SVGLengthList> StyleBuilderConverter::convertStrokeDasharray(StyleResolverState&, CSSValue* value) { if (!value->isValueList()) { return SVGRenderStyle::initialStrokeDashArray(); } CSSValueList* dashes = toCSSValueList(value); RefPtr<SVGLengthList> array = SVGLengthList::create(); size_t length = dashes->length(); for (size_t i = 0; i < length; ++i) { CSSValue* currValue = dashes->item(i); if (!currValue->isPrimitiveValue()) continue; CSSPrimitiveValue* dash = toCSSPrimitiveValue(dashes->item(i)); array->append(SVGLength::fromCSSPrimitiveValue(dash)); } return array.release(); }
void FontFace::initCSSFontFace(Document* document, CSSValue* src) { m_cssFontFace = createCSSFontFace(this, m_unicodeRange.get()); if (m_error) return; // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace. ASSERT(src); ASSERT(src->isValueList()); CSSValueList* srcList = toCSSValueList(src); int srcLength = srcList->length(); 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->item(i)); CSSFontFaceSource* source = nullptr; if (!item->isLocal()) { const Settings* settings = document ? document->settings() : nullptr; bool allowDownloading = settings && settings->downloadableBinaryFontsEnabled(); if (allowDownloading && item->isSupportedFormat() && document) { FontResource* fetched = item->fetch(document); if (fetched) { CSSFontSelector* fontSelector = document->styleEngine().fontSelector(); source = new RemoteFontFaceSource(fetched, fontSelector, CSSValueToFontDisplay(m_display.get())); } } } else { source = new LocalFontFaceSource(item->resource()); } if (source) m_cssFontFace->addSource(source); } if (m_display) { DEFINE_STATIC_LOCAL(EnumerationHistogram, fontDisplayHistogram, ("WebFont.FontDisplayValue", FontDisplayEnumMax)); fontDisplayHistogram.count(CSSValueToFontDisplay(m_display.get())); } }
static bool parseAspectRatio(CSSValue* value, int& a, int& b) { if (value->isValueList()){ CSSValueList* valueList = static_cast<CSSValueList*>(value); if (valueList->length() == 3) { CSSValue* i0 = valueList->item(0); CSSValue* i1 = valueList->item(1); CSSValue* i2 = valueList->item(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] == DeprecatedChar('/')) { a = (int) static_cast<CSSPrimitiveValue*>(i0)->getFloatValue(CSSPrimitiveValue::CSS_NUMBER); b = (int) static_cast<CSSPrimitiveValue*>(i2)->getFloatValue(CSSPrimitiveValue::CSS_NUMBER); return true; } } } } return false; }
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; }
void StyleBuilderFunctions::applyValueCSSPropertyCursor(StyleResolverState& state, CSSValue* value) { state.style()->clearCursorList(); if (value->isValueList()) { CSSValueList* list = toCSSValueList(value); int len = list->length(); state.style()->setCursor(CURSOR_AUTO); for (int i = 0; i < len; i++) { CSSValue* item = list->item(i); if (item->isCursorImageValue()) { CSSCursorImageValue* image = toCSSCursorImageValue(item); if (image->updateIfSVGCursorIsUsed(state.element())) // Elements with SVG cursors are not allowed to share style. state.style()->setUnique(); state.style()->addCursor(state.styleImage(CSSPropertyCursor, image), image->hotSpotSpecified(), image->hotSpot()); } else { state.style()->setCursor(*toCSSPrimitiveValue(item)); } } } else { state.style()->setCursor(*toCSSPrimitiveValue(value)); } }
JSValue* JSCSSValueListPrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) { if (!thisObj->inherits(&JSCSSValueList::info)) return throwError(exec, TypeError); CSSValueList* imp = static_cast<CSSValueList*>(static_cast<JSCSSValueList*>(thisObj)->impl()); switch (id) { case JSCSSValueList::ItemFuncNum: { bool indexOk; unsigned index = args[0]->toInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); } KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->item(index))); return result; } } return 0; }
void PageSerializer::retrieveResourcesForCSSValue(CSSValue* cssValue, Document* document) { if (cssValue->isImageValue()) { CSSImageValue* imageValue = toCSSImageValue(cssValue); StyleImage* styleImage = imageValue->cachedOrPendingImage(); // Non cached-images are just place-holders and do not contain data. if (!styleImage || !styleImage->isImageResource()) return; addImageToResources(styleImage->cachedImage(), 0, styleImage->cachedImage()->url()); } else if (cssValue->isFontFaceSrcValue()) { CSSFontFaceSrcValue* fontFaceSrcValue = toCSSFontFaceSrcValue(cssValue); if (fontFaceSrcValue->isLocal()) { return; } addFontToResources(fontFaceSrcValue->fetch(document)); } else if (cssValue->isValueList()) { CSSValueList* cssValueList = toCSSValueList(cssValue); for (unsigned i = 0; i < cssValueList->length(); i++) retrieveResourcesForCSSValue(cssValueList->item(i), document); } }
void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value) { state.style()->resetPageSizeType(); FloatSize size; PageSizeType pageSizeType = PAGE_SIZE_AUTO; CSSValueList* list = toCSSValueList(value); if (list->length() == 2) { // <length>{2} | <page-size> <orientation> CSSPrimitiveValue* first = toCSSPrimitiveValue(list->item(0)); CSSPrimitiveValue* second = toCSSPrimitiveValue(list->item(1)); if (first->isLength()) { // <length>{2} size = FloatSize(first->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0)), second->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0))); } else { // <page-size> <orientation> size = getPageSizeFromName(first); ASSERT(second->getValueID() == CSSValueLandscape || second->getValueID() == CSSValuePortrait); if (second->getValueID() == CSSValueLandscape) size = size.transposedSize(); } pageSizeType = PAGE_SIZE_RESOLVED; } else { ASSERT(list->length() == 1); // <length> | auto | <page-size> | [ portrait | landscape] CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0)); if (primitiveValue->isLength()) { // <length> pageSizeType = PAGE_SIZE_RESOLVED; float width = primitiveValue->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0)); size = FloatSize(width, width); } else { switch (primitiveValue->getValueID()) { case CSSValueAuto: pageSizeType = PAGE_SIZE_AUTO; break; case CSSValuePortrait: pageSizeType = PAGE_SIZE_AUTO_PORTRAIT; break; case CSSValueLandscape: pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE; break; default: // <page-size> pageSizeType = PAGE_SIZE_RESOLVED; size = getPageSizeFromName(primitiveValue); } } } state.style()->setPageSizeType(pageSizeType); state.style()->setPageSize(size); }
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; }
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; } }
FontTraits FontFace::traits() const { FontStretch stretch = FontStretchNormal; if (m_stretch) { if (!m_stretch->isPrimitiveValue()) return 0; switch (toCSSPrimitiveValue(m_stretch.get())->getValueID()) { case CSSValueUltraCondensed: stretch = FontStretchUltraCondensed; break; case CSSValueExtraCondensed: stretch = FontStretchExtraCondensed; break; case CSSValueCondensed: stretch = FontStretchCondensed; break; case CSSValueSemiCondensed: stretch = FontStretchSemiCondensed; break; case CSSValueSemiExpanded: stretch = FontStretchSemiExpanded; break; case CSSValueExpanded: stretch = FontStretchExpanded; break; case CSSValueExtraExpanded: stretch = FontStretchExtraExpanded; break; case CSSValueUltraExpanded: stretch = FontStretchUltraExpanded; break; default: break; } } FontStyle style = FontStyleNormal; if (m_style) { if (!m_style->isPrimitiveValue()) return 0; switch (toCSSPrimitiveValue(m_style.get())->getValueID()) { case CSSValueNormal: style = FontStyleNormal; break; case CSSValueOblique: style = FontStyleOblique; break; case CSSValueItalic: 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 CSSValue100: weight = FontWeight100; break; // Although 'lighter' and 'bolder' are valid keywords for font-weights, they are invalid // inside font-face rules so they are ignored. Reference: http://www.w3.org/TR/css3-fonts/#descdef-font-weight. case CSSValueLighter: case CSSValueBolder: 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->item(i))->getValueID()) { case CSSValueNormal: variant = FontVariantNormal; break; case CSSValueSmallCaps: variant = FontVariantSmallCaps; break; default: break; } } } return FontTraits(style, variant, weight, stretch); }
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; } }
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); }
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); } }
String CSSMutableStyleDeclaration::getLayeredShorthandValue(const int* properties, size_t size) const { String res; // Begin by collecting the properties into an array. Vector< RefPtr<CSSValue> > values(size); size_t numLayers = 0; for (size_t i = 0; i < size; ++i) { values[i] = getPropertyCSSValue(properties[i]); if (values[i]) { if (values[i]->isValueList()) { CSSValueList* valueList = static_cast<CSSValueList*>(values[i].get()); numLayers = max(valueList->length(), numLayers); } else numLayers = max<size_t>(1U, numLayers); } } // Now stitch the properties together. Implicit initial values are flagged as such and // can safely be omitted. for (size_t i = 0; i < numLayers; i++) { String layerRes; bool useRepeatXShorthand = false; bool useRepeatYShorthand = false; bool useSingleWordShorthand = false; for (size_t j = 0; j < size; j++) { RefPtr<CSSValue> value; if (values[j]) { if (values[j]->isValueList()) value = static_cast<CSSValueList*>(values[j].get())->item(i); else { value = values[j]; // Color only belongs in the last layer. if (properties[j] == CSSPropertyBackgroundColor) { if (i != numLayers - 1) value = 0; } else if (i != 0) // Other singletons only belong in the first layer. value = 0; } } // We need to report background-repeat as it was written in the CSS. If the property is implicit, // then it was written with only one value. Here we figure out which value that was so we can // report back correctly. if (properties[j] == CSSPropertyBackgroundRepeatX && isPropertyImplicit(properties[j])) { // BUG 49055: make sure the value was not reset in the layer check just above. if (j < size - 1 && properties[j + 1] == CSSPropertyBackgroundRepeatY && value) { RefPtr<CSSValue> yValue; RefPtr<CSSValue> nextValue = values[j + 1]; if (nextValue->isValueList()) yValue = static_cast<CSSValueList*>(nextValue.get())->itemWithoutBoundsCheck(i); else yValue = nextValue; int xId = static_cast<CSSPrimitiveValue*>(value.get())->getIdent(); int yId = static_cast<CSSPrimitiveValue*>(yValue.get())->getIdent(); if (xId != yId) { if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { useRepeatXShorthand = true; ++j; } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { useRepeatYShorthand = true; continue; } } else { useSingleWordShorthand = true; ++j; } } } if (value && !value->isImplicitInitialValue()) { if (!layerRes.isNull()) layerRes += " "; if (useRepeatXShorthand) { useRepeatXShorthand = false; layerRes += getValueName(CSSValueRepeatX); } else if (useRepeatYShorthand) { useRepeatYShorthand = false; layerRes += getValueName(CSSValueRepeatY); } else if (useSingleWordShorthand) { useSingleWordShorthand = false; layerRes += value->cssText(); } else layerRes += value->cssText(); } } if (!layerRes.isNull()) { if (!res.isNull()) res += ", "; res += layerRes; } } return res; }
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); }
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 CSSToStyleMap::mapNinePieceImage(CSSPropertyID property, CSSValue* value, NinePieceImage& image) { // If we're not a value list, then we are "none" and don't need to alter the empty image at all. if (!value || !value->isValueList()) return; // Retrieve the border image value. CSSValueList* borderImage = static_cast<CSSValueList*>(value); // Set the image (this kicks off the load). CSSPropertyID imageProperty; if (property == CSSPropertyWebkitBorderImage) imageProperty = CSSPropertyBorderImageSource; else if (property == CSSPropertyWebkitMaskBoxImage) imageProperty = CSSPropertyWebkitMaskBoxImageSource; else imageProperty = property; for (unsigned i = 0 ; i < borderImage->length() ; ++i) { CSSValue* current = borderImage->item(i); if (current->isImageValue() || current->isImageGeneratorValue() #if ENABLE(CSS_IMAGE_SET) || current->isImageSetValue() #endif ) image.setImage(styleImage(imageProperty, current)); else if (current->isBorderImageSliceValue()) mapNinePieceImageSlice(current, image); else if (current->isValueList()) { CSSValueList* slashList = static_cast<CSSValueList*>(current); // Map in the image slices. if (slashList->item(0) && slashList->item(0)->isBorderImageSliceValue()) mapNinePieceImageSlice(slashList->item(0), image); // Map in the border slices. if (slashList->item(1)) image.setBorderSlices(mapNinePieceImageQuad(slashList->item(1))); // Map in the outset. if (slashList->item(2)) image.setOutset(mapNinePieceImageQuad(slashList->item(2))); } else if (current->isPrimitiveValue()) { // Set the appropriate rules for stretch/round/repeat of the slices. mapNinePieceImageRepeat(current, image); } } if (property == CSSPropertyWebkitBorderImage) { // We have to preserve the legacy behavior of -webkit-border-image and make the border slices // also set the border widths. We don't need to worry about percentages, since we don't even support // those on real borders yet. if (image.borderSlices().top().isFixed()) style()->setBorderTopWidth(image.borderSlices().top().value()); if (image.borderSlices().right().isFixed()) style()->setBorderRightWidth(image.borderSlices().right().value()); if (image.borderSlices().bottom().isFixed()) style()->setBorderBottomWidth(image.borderSlices().bottom().value()); if (image.borderSlices().left().isFixed()) style()->setBorderLeftWidth(image.borderSlices().left().value()); } }
String StylePropertySet::getLayeredShorthandValue(const StylePropertyShorthand& shorthand) const { StringBuilder result; const unsigned size = shorthand.length(); // Begin by collecting the properties into an array. Vector< RefPtr<CSSValue> > values(size); size_t numLayers = 0; for (unsigned i = 0; i < size; ++i) { values[i] = getPropertyCSSValue(shorthand.properties()[i]); if (values[i]) { if (values[i]->isBaseValueList()) { CSSValueList* valueList = static_cast<CSSValueList*>(values[i].get()); numLayers = max(valueList->length(), numLayers); } else numLayers = max<size_t>(1U, numLayers); } } String commonValue; bool commonValueInitialized = false; // Now stitch the properties together. Implicit initial values are flagged as such and // can safely be omitted. for (size_t i = 0; i < numLayers; i++) { StringBuilder layerResult; bool useRepeatXShorthand = false; bool useRepeatYShorthand = false; bool useSingleWordShorthand = false; bool foundPositionYCSSProperty = false; for (unsigned j = 0; j < size; j++) { RefPtr<CSSValue> value; if (values[j]) { if (values[j]->isBaseValueList()) value = static_cast<CSSValueList*>(values[j].get())->item(i); else { value = values[j]; // Color only belongs in the last layer. if (shorthand.properties()[j] == CSSPropertyBackgroundColor) { if (i != numLayers - 1) value = 0; } else if (i != 0) // Other singletons only belong in the first layer. value = 0; } } // We need to report background-repeat as it was written in the CSS. If the property is implicit, // then it was written with only one value. Here we figure out which value that was so we can // report back correctly. if ((shorthand.properties()[j] == CSSPropertyBackgroundRepeatX && isPropertyImplicit(shorthand.properties()[j])) || (shorthand.properties()[j] == CSSPropertyWebkitMaskRepeatX && isPropertyImplicit(shorthand.properties()[j]))) { // BUG 49055: make sure the value was not reset in the layer check just above. if ((j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyBackgroundRepeatY && value) || (j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyWebkitMaskRepeatY && value)) { RefPtr<CSSValue> yValue; RefPtr<CSSValue> nextValue = values[j + 1]; if (nextValue->isValueList()) yValue = static_cast<CSSValueList*>(nextValue.get())->itemWithoutBoundsCheck(i); else yValue = nextValue; int xId = static_cast<CSSPrimitiveValue*>(value.get())->getIdent(); int yId = static_cast<CSSPrimitiveValue*>(yValue.get())->getIdent(); if (xId != yId) { if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) { useRepeatXShorthand = true; ++j; } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) { useRepeatYShorthand = true; continue; } } else { useSingleWordShorthand = true; ++j; } } } String valueText; if (value && !value->isImplicitInitialValue()) { if (!layerResult.isEmpty()) layerResult.append(' '); if (foundPositionYCSSProperty && (shorthand.properties()[j] == CSSPropertyBackgroundSize || shorthand.properties()[j] == CSSPropertyWebkitMaskSize)) layerResult.appendLiteral("/ "); if (!foundPositionYCSSProperty && (shorthand.properties()[j] == CSSPropertyBackgroundSize || shorthand.properties()[j] == CSSPropertyWebkitMaskSize)) continue; if (useRepeatXShorthand) { useRepeatXShorthand = false; layerResult.append(getValueName(CSSValueRepeatX)); } else if (useRepeatYShorthand) { useRepeatYShorthand = false; layerResult.append(getValueName(CSSValueRepeatY)); } else { if (useSingleWordShorthand) useSingleWordShorthand = false; valueText = value->cssText(); layerResult.append(valueText); } if (shorthand.properties()[j] == CSSPropertyBackgroundPositionY || shorthand.properties()[j] == CSSPropertyWebkitMaskPositionY) { foundPositionYCSSProperty = true; // background-position is a special case: if only the first offset is specified, // the second one defaults to "center", not the same value. if (commonValueInitialized && commonValue != "initial" && commonValue != "inherit") commonValue = String(); } } if (!commonValueInitialized) { commonValue = valueText; commonValueInitialized = true; } else if (!commonValue.isNull() && commonValue != valueText) commonValue = String(); } if (!layerResult.isEmpty()) { if (!result.isEmpty()) result.appendLiteral(", "); result.append(layerResult); } } if (isInitialOrInherit(commonValue)) return commonValue; if (result.isEmpty()) return String(); return result.toString(); }
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; }