void StyleBuilderFunctions::applyValueCSSPropertyWebkitAppRegion(StyleResolverState& state, CSSValue* value) { const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); state.style()->setDraggableRegionMode(primitiveValue->getValueID() == CSSValueDrag ? DraggableRegionDrag : DraggableRegionNoDrag); state.document().setHasAnnotatedRegions(true); }
PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::CSSPropertySpecificKeyframe::maybeCreateInterpolation(PropertyHandle propertyHandle, Keyframe::PropertySpecificKeyframe& end, Element* element, const ComputedStyle* baseStyle) const { CSSPropertyID property = propertyHandle.cssProperty(); const Vector<const InterpolationType*>* applicableTypes = applicableTypesForProperty(property); if (applicableTypes) return InvalidatableStyleInterpolation::create(*applicableTypes, *this, toCSSPropertySpecificKeyframe(end)); // TODO(alancutter): Remove the remainder of this function. // FIXME: Refactor this into a generic piece that lives in InterpolationEffect, and a template parameter specific converter. CSSValue* fromCSSValue = m_value.get(); CSSValue* toCSSValue = toCSSPropertySpecificKeyframe(end).value(); InterpolationRange range = RangeAll; // FIXME: Remove this flag once we can rely on legacy's behaviour being correct. bool forceDefaultInterpolation = false; // FIXME: Remove this check once neutral keyframes are implemented in StringKeyframes. if (!fromCSSValue || !toCSSValue) return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSValue, property); ASSERT(fromCSSValue && toCSSValue); if (!CSSPropertyMetadata::isInterpolableProperty(property)) { if (fromCSSValue == toCSSValue) return ConstantStyleInterpolation::create(fromCSSValue, property); return nullptr; } if (fromCSSValue->isCSSWideKeyword() || toCSSValue->isCSSWideKeyword()) return createLegacyStyleInterpolation(property, end, element, baseStyle); switch (property) { case CSSPropertyLineHeight: if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyleInterpolation::canCreateFrom(*toCSSValue)) return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, RangeNonNegative); if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyleInterpolation::canCreateFrom(*toCSSValue)) return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, true, RangeNonNegative); break; case CSSPropertyBorderBottomWidth: case CSSPropertyBorderLeftWidth: case CSSPropertyBorderRightWidth: case CSSPropertyBorderTopWidth: case CSSPropertyFlexBasis: case CSSPropertyFontSize: case CSSPropertyHeight: case CSSPropertyMaxHeight: case CSSPropertyMaxWidth: case CSSPropertyMinHeight: case CSSPropertyMinWidth: case CSSPropertyOutlineWidth: case CSSPropertyPaddingBottom: case CSSPropertyPaddingLeft: case CSSPropertyPaddingRight: case CSSPropertyPaddingTop: case CSSPropertyPerspective: case CSSPropertyR: case CSSPropertyRx: case CSSPropertyRy: case CSSPropertyShapeMargin: case CSSPropertyStrokeWidth: case CSSPropertyWebkitBorderHorizontalSpacing: case CSSPropertyWebkitBorderVerticalSpacing: case CSSPropertyWebkitColumnGap: case CSSPropertyWebkitColumnWidth: case CSSPropertyWidth: range = RangeNonNegative; // Fall through case CSSPropertyBaselineShift: case CSSPropertyBottom: case CSSPropertyCx: case CSSPropertyCy: case CSSPropertyLeft: case CSSPropertyLetterSpacing: case CSSPropertyMarginBottom: case CSSPropertyMarginLeft: case CSSPropertyMarginRight: case CSSPropertyMarginTop: case CSSPropertyMotionOffset: case CSSPropertyOutlineOffset: case CSSPropertyRight: case CSSPropertyStrokeDashoffset: case CSSPropertyTop: case CSSPropertyVerticalAlign: case CSSPropertyWordSpacing: case CSSPropertyWebkitColumnRuleWidth: case CSSPropertyWebkitPerspectiveOriginX: case CSSPropertyWebkitPerspectiveOriginY: case CSSPropertyWebkitTransformOriginX: case CSSPropertyWebkitTransformOriginY: case CSSPropertyWebkitTransformOriginZ: case CSSPropertyX: case CSSPropertyY: if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue, property) && LengthStyleInterpolation::canCreateFrom(*toCSSValue, property)) return LengthStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, range); // FIXME: Handle keywords e.g. 'smaller', 'larger'. if (property == CSSPropertyFontSize) return createLegacyStyleInterpolation(property, end, element, baseStyle); // FIXME: Handle keywords e.g. 'baseline', 'sub'. if (property == CSSPropertyBaselineShift) return createLegacyStyleInterpolation(property, end, element, baseStyle); break; case CSSPropertyOrphans: case CSSPropertyWidows: case CSSPropertyZIndex: case CSSPropertyWebkitColumnCount: case CSSPropertyShapeImageThreshold: case CSSPropertyFillOpacity: case CSSPropertyFloodOpacity: case CSSPropertyFontSizeAdjust: case CSSPropertyOpacity: case CSSPropertyStopOpacity: case CSSPropertyStrokeOpacity: case CSSPropertyStrokeMiterlimit: if (DoubleStyleInterpolation::canCreateFrom(*fromCSSValue) && DoubleStyleInterpolation::canCreateFrom(*toCSSValue)) return DoubleStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, toCSSPrimitiveValue(fromCSSValue)->isNumber(), setRange(property)); break; case CSSPropertyMotionRotation: { RefPtrWillBeRawPtr<Interpolation> interpolation = DoubleStyleInterpolation::maybeCreateFromMotionRotation(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); break; } case CSSPropertyVisibility: if (VisibilityStyleInterpolation::canCreateFrom(*fromCSSValue) && VisibilityStyleInterpolation::canCreateFrom(*toCSSValue) && (VisibilityStyleInterpolation::isVisible(*fromCSSValue) || VisibilityStyleInterpolation::isVisible(*toCSSValue))) return VisibilityStyleInterpolation::create(*fromCSSValue, *toCSSValue, property); break; case CSSPropertyBackgroundColor: case CSSPropertyBorderBottomColor: case CSSPropertyBorderLeftColor: case CSSPropertyBorderRightColor: case CSSPropertyBorderTopColor: case CSSPropertyColor: case CSSPropertyFill: case CSSPropertyFloodColor: case CSSPropertyLightingColor: case CSSPropertyOutlineColor: case CSSPropertyStopColor: case CSSPropertyStroke: case CSSPropertyTextDecorationColor: case CSSPropertyWebkitColumnRuleColor: case CSSPropertyWebkitTextStrokeColor: { RefPtrWillBeRawPtr<Interpolation> interpolation = ColorStyleInterpolation::maybeCreateFromColor(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); // Current color should use LegacyStyleInterpolation if (ColorStyleInterpolation::shouldUseLegacyStyleInterpolation(*fromCSSValue, *toCSSValue)) return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } case CSSPropertyBorderImageSource: case CSSPropertyListStyleImage: case CSSPropertyWebkitMaskBoxImageSource: if (fromCSSValue == toCSSValue) return ConstantStyleInterpolation::create(fromCSSValue, property); if (ImageStyleInterpolation::canCreateFrom(*fromCSSValue) && ImageStyleInterpolation::canCreateFrom(*toCSSValue)) return ImageStyleInterpolation::create(*fromCSSValue, *toCSSValue, property); forceDefaultInterpolation = true; break; case CSSPropertyBorderBottomLeftRadius: case CSSPropertyBorderBottomRightRadius: case CSSPropertyBorderTopLeftRadius: case CSSPropertyBorderTopRightRadius: range = RangeNonNegative; // Fall through case CSSPropertyObjectPosition: if (LengthPairStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthPairStyleInterpolation::canCreateFrom(*toCSSValue)) return LengthPairStyleInterpolation::create(*fromCSSValue, *toCSSValue, property, range); break; case CSSPropertyPerspectiveOrigin: case CSSPropertyTransformOrigin: { RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation<LengthStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, property, range); if (interpolation) return interpolation.release(); // FIXME: Handle keywords: top, right, left, center, bottom return createLegacyStyleInterpolation(property, end, element, baseStyle); } case CSSPropertyBoxShadow: case CSSPropertyTextShadow: { RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation<ShadowStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); // FIXME: AnimatableShadow incorrectly animates between inset and non-inset values so it will never indicate it needs default interpolation if (ShadowStyleInterpolation::usesDefaultStyleInterpolation(*fromCSSValue, *toCSSValue)) { forceDefaultInterpolation = true; break; } // FIXME: Handle interpolation from/to none, unspecified color values return createLegacyStyleInterpolation(property, end, element, baseStyle); } case CSSPropertyClip: { if (LengthBoxStyleInterpolation::usesDefaultInterpolation(*fromCSSValue, *toCSSValue)) { forceDefaultInterpolation = true; break; } RefPtrWillBeRawPtr<Interpolation> interpolation = LengthBoxStyleInterpolation::maybeCreateFrom(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); break; } case CSSPropertyBorderImageSlice: case CSSPropertyWebkitMaskBoxImageSlice: { RefPtrWillBeRawPtr<Interpolation> interpolation = ImageSliceStyleInterpolation::maybeCreate(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); if (ImageSliceStyleInterpolation::usesDefaultInterpolation(*fromCSSValue, *toCSSValue)) forceDefaultInterpolation = true; break; } case CSSPropertyStrokeDasharray: { RefPtrWillBeRawPtr<Interpolation> interpolation = SVGStrokeDasharrayStyleInterpolation::maybeCreate(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); break; } case CSSPropertyWebkitFilter: { RefPtrWillBeRawPtr<Interpolation> interpolation = FilterStyleInterpolation::maybeCreateList(*fromCSSValue, *toCSSValue, property); if (interpolation) return interpolation.release(); // FIXME: Support drop shadow interpolation. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } case CSSPropertyTranslate: { RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation<LengthStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, property, range); if (interpolation) return interpolation.release(); // TODO(soonm): Legacy mode is used when from and to cssvaluelist length does not match. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } case CSSPropertyScale: { RefPtrWillBeRawPtr<Interpolation> interpolation = ListStyleInterpolation<DoubleStyleInterpolation>::maybeCreateFromList(*fromCSSValue, *toCSSValue, property, range); if (interpolation) return interpolation.release(); // TODO(soonm): Legacy mode is used when from and to cssvaluelist length does not match. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } default: // Fall back to LegacyStyleInterpolation. return createLegacyStyleInterpolation(property, end, element, baseStyle); break; } if (fromCSSValue == toCSSValue) return ConstantStyleInterpolation::create(fromCSSValue, property); if (!forceDefaultInterpolation) { ASSERT(AnimatableValue::usesDefaultInterpolation( StyleResolver::createAnimatableValueSnapshot(*element, baseStyle, property, fromCSSValue).get(), StyleResolver::createAnimatableValueSnapshot(*element, baseStyle, property, toCSSValue).get())); } return nullptr; }
// FIXME: Have to pass RenderStyles here for calc/computed values. This shouldn't be neecessary. void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, const RenderStyle* rootElementStyle) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); FontDescriptionChangeScope scope(this); scope.fontDescription().setKeywordSize(0); float parentSize = 0; bool parentIsAbsoluteSize = false; float size = 0; // FIXME: Find out when parentStyle could be 0? if (parentStyle) { parentSize = parentStyle->fontDescription().specifiedSize(); parentIsAbsoluteSize = parentStyle->fontDescription().isAbsoluteSize(); } if (CSSValueID valueID = primitiveValue->getValueID()) { switch (valueID) { case CSSValueXxSmall: case CSSValueXSmall: case CSSValueSmall: case CSSValueMedium: case CSSValueLarge: case CSSValueXLarge: case CSSValueXxLarge: case CSSValueWebkitXxxLarge: size = FontSize::fontSizeForKeyword(m_document, valueID, scope.fontDescription().useFixedDefaultSize()); scope.fontDescription().setKeywordSize(valueID - CSSValueXxSmall + 1); break; case CSSValueLarger: size = largerFontSize(parentSize); break; case CSSValueSmaller: size = smallerFontSize(parentSize); break; default: return; } scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize && (valueID == CSSValueLarger || valueID == CSSValueSmaller)); } else { scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize || !(primitiveValue->isPercentage() || primitiveValue->isFontRelativeLength())); if (primitiveValue->isPercentage()) { size = (primitiveValue->getFloatValue() * parentSize) / 100.0f; } else { // If we have viewport units the conversion will mark the parent style as having viewport units. bool parentHasViewportUnits = parentStyle->hasViewportUnits(); parentStyle->setHasViewportUnits(false); CSSToLengthConversionData conversionData(parentStyle, rootElementStyle, m_document->renderView(), 1.0f, true); if (primitiveValue->isLength()) size = primitiveValue->computeLength<float>(conversionData); else if (primitiveValue->isCalculatedPercentageWithLength()) size = primitiveValue->cssCalcValue()->toCalcValue(conversionData)->evaluate(parentSize); else ASSERT_NOT_REACHED(); m_fontSizehasViewportUnits = parentStyle->hasViewportUnits(); parentStyle->setHasViewportUnits(parentHasViewportUnits); } } if (size < 0) return; // Overly large font sizes will cause crashes on some platforms (such as Windows). // Cap font size here to make sure that doesn't happen. size = std::min(maximumAllowedFontSize, size); scope.fontDescription().setSpecifiedSize(size); }
bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CSSToLengthConversionData& unadjustedConversionData, FilterOperations& outOperations, StyleResolverState& state) { ASSERT(outOperations.isEmpty()); if (!inValue) return false; if (inValue->isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(inValue); if (primitiveValue->getValueID() == CSSValueNone) return true; } if (!inValue->isValueList()) return false; float zoomFactor = unadjustedConversionData.zoom() * state.elementStyleResources().deviceScaleFactor(); const CSSToLengthConversionData& conversionData = unadjustedConversionData.copyWithAdjustedZoom(zoomFactor); FilterOperations operations; for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) { CSSValue* currValue = i.value(); if (!currValue->isFilterValue()) continue; CSSFilterValue* filterValue = toCSSFilterValue(i.value()); FilterOperation::OperationType operationType = filterOperationForType(filterValue->operationType()); if (operationType == FilterOperation::VALIDATED_CUSTOM) { // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle. ASSERT_NOT_REACHED(); continue; } if (operationType == FilterOperation::CUSTOM) { RefPtr<CustomFilterOperation> operation = createCustomFilterOperation(filterValue, state); if (!operation) return false; operations.operations().append(operation); continue; } if (operationType == FilterOperation::REFERENCE) { if (filterValue->length() != 1) continue; CSSValue* argument = filterValue->itemWithoutBoundsCheck(0); if (!argument->isSVGDocumentValue()) continue; CSSSVGDocumentValue* svgDocumentValue = toCSSSVGDocumentValue(argument); KURL url = state.document().completeURL(svgDocumentValue->url()); RefPtr<ReferenceFilterOperation> operation = ReferenceFilterOperation::create(svgDocumentValue->url(), url.fragmentIdentifier()); if (SVGURIReference::isExternalURIReference(svgDocumentValue->url(), state.document())) { if (!svgDocumentValue->loadRequested()) state.elementStyleResources().addPendingSVGDocument(operation.get(), svgDocumentValue); else if (svgDocumentValue->cachedSVGDocument()) ReferenceFilterBuilder::setDocumentResourceReference(operation.get(), adoptPtr(new DocumentResourceReference(svgDocumentValue->cachedSVGDocument()))); } operations.operations().append(operation); continue; } // Check that all parameters are primitive values, with the // exception of drop shadow which has a CSSShadowValue parameter. if (operationType != FilterOperation::DROP_SHADOW) { bool haveNonPrimitiveValue = false; for (unsigned j = 0; j < filterValue->length(); ++j) { if (!filterValue->itemWithoutBoundsCheck(j)->isPrimitiveValue()) { haveNonPrimitiveValue = true; break; } } if (haveNonPrimitiveValue) continue; } CSSPrimitiveValue* firstValue = filterValue->length() && filterValue->itemWithoutBoundsCheck(0)->isPrimitiveValue() ? toCSSPrimitiveValue(filterValue->itemWithoutBoundsCheck(0)) : 0; switch (filterValue->operationType()) { case CSSFilterValue::GrayscaleFilterOperation: case CSSFilterValue::SepiaFilterOperation: case CSSFilterValue::SaturateFilterOperation: { double amount = 1; if (filterValue->length() == 1) { amount = firstValue->getDoubleValue(); if (firstValue->isPercentage()) amount /= 100; } operations.operations().append(BasicColorMatrixFilterOperation::create(amount, operationType)); break; } case CSSFilterValue::HueRotateFilterOperation: { double angle = 0; if (filterValue->length() == 1) angle = firstValue->computeDegrees(); operations.operations().append(BasicColorMatrixFilterOperation::create(angle, operationType)); break; } case CSSFilterValue::InvertFilterOperation: case CSSFilterValue::BrightnessFilterOperation: case CSSFilterValue::ContrastFilterOperation: case CSSFilterValue::OpacityFilterOperation: { double amount = (filterValue->operationType() == CSSFilterValue::BrightnessFilterOperation) ? 0 : 1; if (filterValue->length() == 1) { amount = firstValue->getDoubleValue(); if (firstValue->isPercentage()) amount /= 100; } operations.operations().append(BasicComponentTransferFilterOperation::create(amount, operationType)); break; } case CSSFilterValue::BlurFilterOperation: { Length stdDeviation = Length(0, Fixed); if (filterValue->length() >= 1) stdDeviation = firstValue->convertToLength<FixedConversion | PercentConversion>(conversionData); if (stdDeviation.isUndefined()) return false; operations.operations().append(BlurFilterOperation::create(stdDeviation)); break; } case CSSFilterValue::DropShadowFilterOperation: { if (filterValue->length() != 1) return false; CSSValue* cssValue = filterValue->itemWithoutBoundsCheck(0); if (!cssValue->isShadowValue()) continue; CSSShadowValue* item = toCSSShadowValue(cssValue); IntPoint location(item->x->computeLength<int>(conversionData), item->y->computeLength<int>(conversionData)); int blur = item->blur ? item->blur->computeLength<int>(conversionData) : 0; Color shadowColor; if (item->color) shadowColor = state.document().textLinkColors().colorFromPrimitiveValue(item->color.get(), state.style()->color()); operations.operations().append(DropShadowFilterOperation::create(location, blur, shadowColor.isValid() ? shadowColor : Color::transparent)); break; } case CSSFilterValue::UnknownFilterOperation: default: ASSERT_NOT_REACHED(); break; } } outOperations = operations; return true; }
PassOwnPtrWillBeRawPtr<InterpolableValue> DoubleStyleInterpolation::doubleToInterpolableValue(const CSSValue& value) { ASSERT(canCreateFrom(value)); const CSSPrimitiveValue& primitive = toCSSPrimitiveValue(value); return InterpolableNumber::create(primitive.getDoubleValue()); }
FilterOperations FilterOperationResolver::createFilterOperations(StyleResolverState& state, const CSSValue& inValue) { FilterOperations operations; if (inValue.isPrimitiveValue()) { ASSERT(toCSSPrimitiveValue(inValue).getValueID() == CSSValueNone); return operations; } const CSSToLengthConversionData& conversionData = state.cssToLengthConversionData(); for (auto& currValue : toCSSValueList(inValue)) { const CSSFunctionValue* filterValue = toCSSFunctionValue(currValue.get()); FilterOperation::OperationType operationType = filterOperationForType(filterValue->functionType()); countFilterUse(operationType, state.document()); ASSERT(filterValue->length() <= 1); if (operationType == FilterOperation::REFERENCE) { const CSSSVGDocumentValue& svgDocumentValue = toCSSSVGDocumentValue(filterValue->item(0)); KURL url = state.document().completeURL(svgDocumentValue.url()); ReferenceFilterOperation* operation = ReferenceFilterOperation::create(svgDocumentValue.url(), AtomicString(url.fragmentIdentifier())); if (SVGURIReference::isExternalURIReference(svgDocumentValue.url(), state.document())) { if (!svgDocumentValue.loadRequested()) state.elementStyleResources().addPendingSVGDocument(operation, &svgDocumentValue); else if (svgDocumentValue.cachedSVGDocument()) ReferenceFilterBuilder::setDocumentResourceReference(operation, new DocumentResourceReference(svgDocumentValue.cachedSVGDocument())); } operations.operations().append(operation); continue; } const CSSPrimitiveValue* firstValue = filterValue->length() && filterValue->item(0).isPrimitiveValue() ? &toCSSPrimitiveValue(filterValue->item(0)) : nullptr; switch (filterValue->functionType()) { case CSSValueGrayscale: case CSSValueSepia: case CSSValueSaturate: { double amount = 1; if (filterValue->length() == 1) { amount = firstValue->getDoubleValue(); if (firstValue->isPercentage()) amount /= 100; } operations.operations().append(BasicColorMatrixFilterOperation::create(amount, operationType)); break; } case CSSValueHueRotate: { double angle = 0; if (filterValue->length() == 1) angle = firstValue->computeDegrees(); operations.operations().append(BasicColorMatrixFilterOperation::create(angle, operationType)); break; } case CSSValueInvert: case CSSValueBrightness: case CSSValueContrast: case CSSValueOpacity: { double amount = (filterValue->functionType() == CSSValueBrightness) ? 0 : 1; if (filterValue->length() == 1) { amount = firstValue->getDoubleValue(); if (firstValue->isPercentage()) amount /= 100; } operations.operations().append(BasicComponentTransferFilterOperation::create(amount, operationType)); break; } case CSSValueBlur: { Length stdDeviation = Length(0, Fixed); if (filterValue->length() >= 1) stdDeviation = firstValue->convertToLength(conversionData); operations.operations().append(BlurFilterOperation::create(stdDeviation)); break; } case CSSValueDropShadow: { const CSSShadowValue& item = toCSSShadowValue(filterValue->item(0)); IntPoint location(item.x->computeLength<int>(conversionData), item.y->computeLength<int>(conversionData)); int blur = item.blur ? item.blur->computeLength<int>(conversionData) : 0; Color shadowColor = Color::black; if (item.color) shadowColor = state.document().textLinkColors().colorFromCSSValue(*item.color, state.style()->color()); operations.operations().append(DropShadowFilterOperation::create(location, blur, shadowColor)); break; } default: ASSERT_NOT_REACHED(); break; } } return operations; }
void StyleResolver::applySVGProperty(CSSPropertyID id, CSSValue* value) { ASSERT(value); CSSPrimitiveValue* primitiveValue = 0; if (value->isPrimitiveValue()) primitiveValue = toCSSPrimitiveValue(value); const State& 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->getValueID()) { switch (primitiveValue->getValueID()) { 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 = toSVGPaint(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 = toSVGPaint(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 = toCSSValueList(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 = toCSSPrimitiveValue(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(toSVGColor(value), state.style()->color())); break; } case CSSPropertyLightingColor: { HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor); if (value->isSVGColor()) svgStyle.setLightingColor(colorFromSVGColorCSSValue(toSVGColor(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(toSVGColor(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->getValueID() == 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(state.parentStyle()->svgStyle().shadow() ? std::make_unique<ShadowData>(*state.parentStyle()->svgStyle().shadow()) : nullptr); if (isInitial || primitiveValue) // initial | none return svgStyle.setShadow(nullptr); if (!value->isValueList()) return; CSSValueList* list = toCSSValueList(value); if (!list->length()) return; CSSValue* firstValue = list->itemWithoutBoundsCheck(0); if (!firstValue->isShadowValue()) return; CSSShadowValue* item = toCSSShadowValue(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); auto shadowData = std::make_unique<ShadowData>(location, blur, 0, Normal, false, color.isValid() ? color : Color::transparent); svgStyle.setShadow(std::move(shadowData)); 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 StyleBuilderFunctions::applyValueCSSPropertyWebkitTextOrientation(StyleResolverState& state, CSSValue* value) { if (value->isPrimitiveValue()) state.setTextOrientation(*toCSSPrimitiveValue(value)); }
double CSSToStyleMap::mapAnimationDuration(CSSValue* value) { if (value->isInitialValue()) return CSSTimingData::initialDuration(); return toCSSPrimitiveValue(value)->computeSeconds(); }
void StyleBuilderFunctions::applyValueCSSPropertyOutlineStyle(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); state.style()->setOutlineStyleIsAuto(*primitiveValue); state.style()->setOutlineStyle(*primitiveValue); }
void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value) { state.style()->resetPageSizeType(); Length width; Length height; PageSizeType pageSizeType = PAGE_SIZE_AUTO; CSSValueListInspector inspector(value); switch (inspector.length()) { case 2: { // <length>{2} | <page-size> <orientation> if (!inspector.first()->isPrimitiveValue() || !inspector.second()->isPrimitiveValue()) return; CSSPrimitiveValue* first = toCSSPrimitiveValue(inspector.first()); CSSPrimitiveValue* second = toCSSPrimitiveValue(inspector.second()); if (first->isLength()) { // <length>{2} if (!second->isLength()) return; width = first->computeLength<Length>(state.cssToLengthConversionData()); height = second->computeLength<Length>(state.cssToLengthConversionData()); } else { // <page-size> <orientation> // The value order is guaranteed. See BisonCSSParser::parseSizeParameter. if (!getPageSizeFromName(first, second, width, height)) return; } pageSizeType = PAGE_SIZE_RESOLVED; break; } case 1: { // <length> | auto | <page-size> | [ portrait | landscape] if (!inspector.first()->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(inspector.first()); if (primitiveValue->isLength()) { // <length> pageSizeType = PAGE_SIZE_RESOLVED; width = height = primitiveValue->computeLength<Length>(state.cssToLengthConversionData()); } else { switch (primitiveValue->getValueID()) { case 0: return; 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; if (!getPageSizeFromName(primitiveValue, 0, width, height)) return; } } break; } default: return; } state.style()->setPageSizeType(pageSizeType); state.style()->setPageSize(LengthSize(width, height)); }
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; }
bool TransformBuilder::createTransformOperations(CSSValue* inValue, const CSSToLengthConversionData& conversionData, TransformOperations& outOperations) { if (!inValue || !inValue->isValueList()) { outOperations.clear(); return false; } TransformOperations operations; for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) { CSSValue* currValue = i.value(); if (!currValue->isTransformValue()) continue; CSSTransformValue* transformValue = toCSSTransformValue(i.value()); if (!transformValue->length()) continue; bool haveNonPrimitiveValue = false; for (unsigned j = 0; j < transformValue->length(); ++j) { if (!transformValue->item(j)->isPrimitiveValue()) { haveNonPrimitiveValue = true; break; } } if (haveNonPrimitiveValue) continue; CSSPrimitiveValue* firstValue = toCSSPrimitiveValue(transformValue->item(0)); switch (transformValue->operationType()) { case CSSTransformValue::ScaleTransformOperation: case CSSTransformValue::ScaleXTransformOperation: case CSSTransformValue::ScaleYTransformOperation: { double sx = 1.0; double sy = 1.0; if (transformValue->operationType() == CSSTransformValue::ScaleYTransformOperation) sy = firstValue->getDoubleValue(); else { sx = firstValue->getDoubleValue(); if (transformValue->operationType() != CSSTransformValue::ScaleXTransformOperation) { if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); sy = secondValue->getDoubleValue(); } else sy = sx; } } operations.operations().append(ScaleTransformOperation::create(sx, sy, 1.0, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::ScaleZTransformOperation: case CSSTransformValue::Scale3DTransformOperation: { double sx = 1.0; double sy = 1.0; double sz = 1.0; if (transformValue->operationType() == CSSTransformValue::ScaleZTransformOperation) sz = firstValue->getDoubleValue(); else if (transformValue->operationType() == CSSTransformValue::ScaleYTransformOperation) sy = firstValue->getDoubleValue(); else { sx = firstValue->getDoubleValue(); if (transformValue->operationType() != CSSTransformValue::ScaleXTransformOperation) { if (transformValue->length() > 2) { CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->item(2)); sz = thirdValue->getDoubleValue(); } if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); sy = secondValue->getDoubleValue(); } else sy = sx; } } operations.operations().append(ScaleTransformOperation::create(sx, sy, sz, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::TranslateTransformOperation: case CSSTransformValue::TranslateXTransformOperation: case CSSTransformValue::TranslateYTransformOperation: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); if (transformValue->operationType() == CSSTransformValue::TranslateYTransformOperation) ty = convertToFloatLength(firstValue, conversionData); else { tx = convertToFloatLength(firstValue, conversionData); if (transformValue->operationType() != CSSTransformValue::TranslateXTransformOperation) { if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); ty = convertToFloatLength(secondValue, conversionData); } } } operations.operations().append(TranslateTransformOperation::create(tx, ty, 0, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::TranslateZTransformOperation: case CSSTransformValue::Translate3DTransformOperation: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); double tz = 0; if (transformValue->operationType() == CSSTransformValue::TranslateZTransformOperation) tz = firstValue->computeLength<double>(conversionData); else if (transformValue->operationType() == CSSTransformValue::TranslateYTransformOperation) ty = convertToFloatLength(firstValue, conversionData); else { tx = convertToFloatLength(firstValue, conversionData); if (transformValue->operationType() != CSSTransformValue::TranslateXTransformOperation) { if (transformValue->length() > 2) { CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->item(2)); tz = thirdValue->computeLength<double>(conversionData); } if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); ty = convertToFloatLength(secondValue, conversionData); } } } operations.operations().append(TranslateTransformOperation::create(tx, ty, tz, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::RotateTransformOperation: { double angle = firstValue->computeDegrees(); operations.operations().append(RotateTransformOperation::create(0, 0, 1, angle, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::RotateXTransformOperation: case CSSTransformValue::RotateYTransformOperation: case CSSTransformValue::RotateZTransformOperation: { double x = 0; double y = 0; double z = 0; double angle = firstValue->computeDegrees(); if (transformValue->operationType() == CSSTransformValue::RotateXTransformOperation) x = 1; else if (transformValue->operationType() == CSSTransformValue::RotateYTransformOperation) y = 1; else z = 1; operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::Rotate3DTransformOperation: { if (transformValue->length() < 4) break; CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->item(2)); CSSPrimitiveValue* fourthValue = toCSSPrimitiveValue(transformValue->item(3)); double x = firstValue->getDoubleValue(); double y = secondValue->getDoubleValue(); double z = thirdValue->getDoubleValue(); double angle = fourthValue->computeDegrees(); operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::SkewTransformOperation: case CSSTransformValue::SkewXTransformOperation: case CSSTransformValue::SkewYTransformOperation: { double angleX = 0; double angleY = 0; double angle = firstValue->computeDegrees(); if (transformValue->operationType() == CSSTransformValue::SkewYTransformOperation) angleY = angle; else { angleX = angle; if (transformValue->operationType() == CSSTransformValue::SkewTransformOperation) { if (transformValue->length() > 1) { CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->item(1)); angleY = secondValue->computeDegrees(); } } } operations.operations().append(SkewTransformOperation::create(angleX, angleY, getTransformOperationType(transformValue->operationType()))); break; } case CSSTransformValue::MatrixTransformOperation: { if (transformValue->length() < 6) break; double a = firstValue->getDoubleValue(); double b = toCSSPrimitiveValue(transformValue->item(1))->getDoubleValue(); double c = toCSSPrimitiveValue(transformValue->item(2))->getDoubleValue(); double d = toCSSPrimitiveValue(transformValue->item(3))->getDoubleValue(); double e = toCSSPrimitiveValue(transformValue->item(4))->getDoubleValue(); double f = toCSSPrimitiveValue(transformValue->item(5))->getDoubleValue(); operations.operations().append(MatrixTransformOperation::create(a, b, c, d, e, f)); break; } case CSSTransformValue::Matrix3DTransformOperation: { if (transformValue->length() < 16) break; TransformationMatrix matrix(toCSSPrimitiveValue(transformValue->item(0))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(1))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(2))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(3))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(4))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(5))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(6))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(7))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(8))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(9))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(10))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(11))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(12))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(13))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(14))->getDoubleValue(), toCSSPrimitiveValue(transformValue->item(15))->getDoubleValue()); operations.operations().append(Matrix3DTransformOperation::create(matrix)); break; } case CSSTransformValue::PerspectiveTransformOperation: { double p; if (firstValue->isLength()) p = firstValue->computeLength<double>(conversionData); else { // This is a quirk that should go away when 3d transforms are finalized. double val = firstValue->getDoubleValue(); if (val < 0) return false; p = clampToPositiveInteger(val); } operations.operations().append(PerspectiveTransformOperation::create(p)); break; } case CSSTransformValue::UnknownTransformOperation: ASSERT_NOT_REACHED(); break; } } outOperations = operations; return true; }
void StyleBuilderFunctions::applyValueCSSPropertyWebkitWritingMode(StyleResolverState& state, CSSValue* value) { state.setWritingMode(*toCSSPrimitiveValue(value)); }
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); }
float ViewportStyleResolver::getViewportArgumentValue(CSSPropertyID id) const { float defaultValue = ViewportArguments::ValueAuto; // UserZoom default value is CSSValueZoom, which maps to true, meaning that // yes, it is user scalable. When the value is set to CSSValueFixed, we // return false. if (id == CSSPropertyUserZoom) defaultValue = 1; RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id); if (!value || !value->isPrimitiveValue()) return defaultValue; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get()); if (primitiveValue->isNumber() || primitiveValue->isPx()) return primitiveValue->getFloatValue(); if (primitiveValue->isFontRelativeLength()) return primitiveValue->getFloatValue() * m_document->documentElement()->renderStyle()->fontDescription().computedSize(); if (primitiveValue->isPercentage()) { float percentValue = primitiveValue->getFloatValue() / 100.0f; switch (id) { case CSSPropertyMaxHeight: case CSSPropertyMinHeight: ASSERT(m_document->initialViewportSize().height() > 0); return percentValue * m_document->initialViewportSize().height(); case CSSPropertyMaxWidth: case CSSPropertyMinWidth: ASSERT(m_document->initialViewportSize().width() > 0); return percentValue * m_document->initialViewportSize().width(); case CSSPropertyMaxZoom: case CSSPropertyMinZoom: case CSSPropertyZoom: return percentValue; default: ASSERT_NOT_REACHED(); break; } } switch (primitiveValue->getIdent()) { case CSSValueAuto: return defaultValue; case CSSValueDeviceHeight: return ViewportArguments::ValueDeviceHeight; case CSSValueDeviceWidth: return ViewportArguments::ValueDeviceWidth; case CSSValueLandscape: return ViewportArguments::ValueLandscape; case CSSValuePortrait: return ViewportArguments::ValuePortrait; case CSSValueZoom: return defaultValue; case CSSValueFixed: return 0; default: return defaultValue; } }
InterpolationValue FilterInterpolationFunctions::maybeConvertCSSFilter( const CSSValue& value) { if (value.isURIValue()) return nullptr; const CSSFunctionValue& filter = toCSSFunctionValue(value); DCHECK_LE(filter.length(), 1u); FilterOperation::OperationType type = FilterOperationResolver::filterOperationForType(filter.functionType()); InterpolationValue result = nullptr; switch (type) { case FilterOperation::BRIGHTNESS: case FilterOperation::CONTRAST: case FilterOperation::GRAYSCALE: case FilterOperation::INVERT: case FilterOperation::OPACITY: case FilterOperation::SATURATE: case FilterOperation::SEPIA: { double amount = defaultParameter(type); if (filter.length() == 1) { const CSSPrimitiveValue& firstValue = toCSSPrimitiveValue(filter.item(0)); amount = firstValue.getDoubleValue(); if (firstValue.isPercentage()) amount /= 100; } result.interpolableValue = InterpolableNumber::create(amount); break; } case FilterOperation::HUE_ROTATE: { double angle = defaultParameter(type); if (filter.length() == 1) angle = toCSSPrimitiveValue(filter.item(0)).computeDegrees(); result.interpolableValue = InterpolableNumber::create(angle); break; } case FilterOperation::BLUR: { if (filter.length() == 0) result.interpolableValue = LengthInterpolationFunctions::createNeutralInterpolableValue(); else result = LengthInterpolationFunctions::maybeConvertCSSValue(filter.item(0)); break; } case FilterOperation::DROP_SHADOW: { result = ShadowInterpolationFunctions::maybeConvertCSSValue(filter.item(0)); break; } default: NOTREACHED(); return nullptr; } if (!result) return nullptr; result.nonInterpolableValue = FilterNonInterpolableValue::create( type, result.nonInterpolableValue.release()); return result; }
String CSSValue::cssText() const { if (m_isTextClone) { ASSERT(isCSSOMSafe()); return static_cast<const TextCloneCSSValue*>(this)->cssText(); } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: return toCSSAspectRatioValue(this)->customCSSText(); case BorderImageSliceClass: return toCSSBorderImageSliceValue(this)->customCSSText(); case CanvasClass: return toCSSCanvasValue(this)->customCSSText(); case CursorImageClass: return toCSSCursorImageValue(this)->customCSSText(); #if ENABLE(CSS_FILTERS) case FilterImageClass: return toCSSFilterImageValue(this)->customCSSText(); #endif case FontClass: return toCSSFontValue(this)->customCSSText(); case FontFaceSrcClass: return toCSSFontFaceSrcValue(this)->customCSSText(); case FontFeatureClass: return toCSSFontFeatureValue(this)->customCSSText(); case FunctionClass: return toCSSFunctionValue(this)->customCSSText(); case LinearGradientClass: return toCSSLinearGradientValue(this)->customCSSText(); case RadialGradientClass: return toCSSRadialGradientValue(this)->customCSSText(); case CrossfadeClass: return toCSSCrossfadeValue(this)->customCSSText(); case ImageClass: return toCSSImageValue(this)->customCSSText(); case InheritedClass: return toCSSInheritedValue(this)->customCSSText(); case InitialClass: return toCSSInitialValue(this)->customCSSText(); #if ENABLE(CSS_GRID_LAYOUT) case GridLineNamesClass: return toCSSGridLineNamesValue(this)->customCSSText(); case GridTemplateAreasClass: return toCSSGridTemplateAreasValue(this)->customCSSText(); #endif case PrimitiveClass: return toCSSPrimitiveValue(this)->customCSSText(); case ReflectClass: return toCSSReflectValue(this)->customCSSText(); case ShadowClass: return toCSSShadowValue(this)->customCSSText(); case CubicBezierTimingFunctionClass: return toCSSCubicBezierTimingFunctionValue(this)->customCSSText(); case StepsTimingFunctionClass: return toCSSStepsTimingFunctionValue(this)->customCSSText(); case UnicodeRangeClass: return toCSSUnicodeRangeValue(this)->customCSSText(); case ValueListClass: return toCSSValueList(this)->customCSSText(); case WebKitCSSTransformClass: return toWebKitCSSTransformValue(this)->customCSSText(); case LineBoxContainClass: return toCSSLineBoxContainValue(this)->customCSSText(); case CalculationClass: return toCSSCalcValue(this)->customCSSText(); #if ENABLE(CSS_IMAGE_SET) case ImageSetClass: return toCSSImageSetValue(this)->customCSSText(); #endif #if ENABLE(CSS_FILTERS) case WebKitCSSFilterClass: return toWebKitCSSFilterValue(this)->customCSSText(); #endif case SVGColorClass: return toSVGColor(this)->customCSSText(); case SVGPaintClass: return toSVGPaint(this)->customCSSText(); } ASSERT_NOT_REACHED(); return String(); }
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())->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 (toCSSPrimitiveValue(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 = toCSSValueList(fontVariant.get()); unsigned numVariants = variantList->length(); if (!numVariants) return; for (unsigned i = 0; i < numVariants; ++i) { switch (toCSSPrimitiveValue(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) { RefPtr<CSSFontFaceRule> rule; // FIXME: https://bugs.webkit.org/show_bug.cgi?id=112116 - This CSSFontFaceRule has no parent. if (RuntimeEnabledFeatures::fontLoadEventsEnabled()) rule = static_pointer_cast<CSSFontFaceRule>(fontFaceRule->createCSSOMWrapper()); 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->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).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; } }
PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> AnimatableLength::toCSSCalcExpressionNode() const { if (isCalc()) return m_calcExpression; return CSSCalcValue::createExpressionNode(toCSSPrimitiveValue(AllValues), m_lengthValue == trunc(m_lengthValue)); }
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); }
PassRefPtrWillBeRawPtr<CSSValue> AnimatableLength::toCSSValue(NumberRange range) const { return toCSSPrimitiveValue(range); }
static void testPrimitiveValue(RefPtrWillBeRawPtr<CSSValue> value, double doubleValue, CSSPrimitiveValue::UnitType unitType) { EXPECT_TRUE(value->isPrimitiveValue()); EXPECT_EQ(doubleValue, toCSSPrimitiveValue(value.get())->getDoubleValue()); EXPECT_EQ(unitType, toCSSPrimitiveValue(value.get())->primitiveType()); }
InterpolationValue CSSNumberInterpolationType::maybeConvertValue(const CSSValue& value, const StyleResolverState&, ConversionCheckers&) const { if (!value.isPrimitiveValue() || !toCSSPrimitiveValue(value).isNumber()) return nullptr; return createNumberValue(toCSSPrimitiveValue(value).getDoubleValue()); }
bool DoubleStyleInterpolation::canCreateFrom(const CSSValue& value) { return value.isPrimitiveValue() && toCSSPrimitiveValue(value).isNumber(); }
void CSSValue::destroy() { if (m_isTextClone) { ASSERT(isCSSOMSafe()); delete toTextCloneCSSValue(this); return; } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: delete toCSSAspectRatioValue(this); return; case BorderImageSliceClass: delete toCSSBorderImageSliceValue(this); return; case CanvasClass: delete toCSSCanvasValue(this); return; case CursorImageClass: delete toCSSCursorImageValue(this); return; case FontClass: delete toCSSFontValue(this); return; case FontFaceSrcClass: delete toCSSFontFaceSrcValue(this); return; case FontFeatureClass: delete toCSSFontFeatureValue(this); return; case FunctionClass: delete toCSSFunctionValue(this); return; case LinearGradientClass: delete toCSSLinearGradientValue(this); return; case RadialGradientClass: delete toCSSRadialGradientValue(this); return; case CrossfadeClass: delete toCSSCrossfadeValue(this); return; case ImageClass: delete toCSSImageValue(this); return; case InheritedClass: delete toCSSInheritedValue(this); return; case InitialClass: delete toCSSInitialValue(this); return; case PrimitiveClass: delete toCSSPrimitiveValue(this); return; case ShadowClass: delete toCSSShadowValue(this); return; case CubicBezierTimingFunctionClass: delete toCSSCubicBezierTimingFunctionValue(this); return; case StepsTimingFunctionClass: delete toCSSStepsTimingFunctionValue(this); return; case UnicodeRangeClass: delete toCSSUnicodeRangeValue(this); return; case ValueListClass: delete toCSSValueList(this); return; case CSSTransformClass: delete toCSSTransformValue(this); return; case LineBoxContainClass: delete toCSSLineBoxContainValue(this); return; case CalculationClass: delete toCSSCalcValue(this); return; case ImageSetClass: delete toCSSImageSetValue(this); return; case CSSFilterClass: delete toCSSFilterValue(this); return; } ASSERT_NOT_REACHED(); }
// FIXME: I am not convinced FontBuilder needs to know anything about CSSValues. void FontBuilder::setFontFamilyValue(CSSValue* value) { FontDescriptionChangeScope scope(this); if (!value->isValueList()) return; FontFamily& firstFamily = scope.fontDescription().firstFamily(); FontFamily* currFamily = 0; // Before mapping in a new font-family property, we should reset the generic family. bool oldFamilyUsedFixedDefaultSize = scope.fontDescription().useFixedDefaultSize(); scope.fontDescription().setGenericFamily(FontDescription::NoFamily); for (CSSValueListIterator i = value; i.hasMore(); i.advance()) { CSSValue* item = i.value(); if (!item->isPrimitiveValue()) continue; CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item); AtomicString face; Settings* settings = m_document->settings(); if (contentValue->isString()) { face = AtomicString(contentValue->getStringValue()); } else if (settings) { switch (contentValue->getValueID()) { case CSSValueWebkitBody: face = settings->genericFontFamilySettings().standard(); break; case CSSValueSerif: face = FontFamilyNames::webkit_serif; scope.fontDescription().setGenericFamily(FontDescription::SerifFamily); break; case CSSValueSansSerif: face = FontFamilyNames::webkit_sans_serif; scope.fontDescription().setGenericFamily(FontDescription::SansSerifFamily); break; case CSSValueCursive: face = FontFamilyNames::webkit_cursive; scope.fontDescription().setGenericFamily(FontDescription::CursiveFamily); break; case CSSValueFantasy: face = FontFamilyNames::webkit_fantasy; scope.fontDescription().setGenericFamily(FontDescription::FantasyFamily); break; case CSSValueMonospace: face = FontFamilyNames::webkit_monospace; scope.fontDescription().setGenericFamily(FontDescription::MonospaceFamily); break; case CSSValueWebkitPictograph: face = FontFamilyNames::webkit_pictograph; scope.fontDescription().setGenericFamily(FontDescription::PictographFamily); break; default: break; } } if (!face.isEmpty()) { if (!currFamily) { // Filling in the first family. firstFamily.setFamily(face); firstFamily.appendFamily(nullptr); // Remove any inherited family-fallback list. currFamily = &firstFamily; } else { RefPtr<SharedFontFamily> newFamily = SharedFontFamily::create(); newFamily->setFamily(face); currFamily->appendFamily(newFamily); currFamily = newFamily.get(); } } } // We can't call useFixedDefaultSize() until all new font families have been added // If currFamily is non-zero then we set at least one family on this description. if (!currFamily) return; if (scope.fontDescription().keywordSize() && scope.fontDescription().useFixedDefaultSize() != oldFamilyUsedFixedDefaultSize) scope.fontDescription().setSpecifiedSize(FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, !oldFamilyUsedFixedDefaultSize)); }
void CSSValue::destroy() { if (m_isTextClone) { ASSERT(isCSSOMSafe()); delete static_cast<TextCloneCSSValue*>(this); return; } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: delete toCSSAspectRatioValue(this); return; case BorderImageSliceClass: delete toCSSBorderImageSliceValue(this); return; case CanvasClass: delete toCSSCanvasValue(this); return; case CursorImageClass: delete toCSSCursorImageValue(this); return; case FontClass: delete toCSSFontValue(this); return; case FontFaceSrcClass: delete toCSSFontFaceSrcValue(this); return; case FontFeatureClass: delete toCSSFontFeatureValue(this); return; case FunctionClass: delete toCSSFunctionValue(this); return; case LinearGradientClass: delete toCSSLinearGradientValue(this); return; case RadialGradientClass: delete toCSSRadialGradientValue(this); return; case CrossfadeClass: delete toCSSCrossfadeValue(this); return; case ImageClass: delete toCSSImageValue(this); return; case InheritedClass: delete toCSSInheritedValue(this); return; case InitialClass: delete toCSSInitialValue(this); return; case GridTemplateClass: delete toCSSGridTemplateValue(this); return; case PrimitiveClass: delete toCSSPrimitiveValue(this); return; case ReflectClass: delete toCSSReflectValue(this); return; case ShadowClass: delete toCSSShadowValue(this); return; case CubicBezierTimingFunctionClass: delete toCSSCubicBezierTimingFunctionValue(this); return; case StepsTimingFunctionClass: delete toCSSStepsTimingFunctionValue(this); return; case UnicodeRangeClass: delete toCSSUnicodeRangeValue(this); return; case ValueListClass: delete toCSSValueList(this); return; case WebKitCSSTransformClass: delete toWebKitCSSTransformValue(this); return; case LineBoxContainClass: delete toCSSLineBoxContainValue(this); return; case CalculationClass: delete toCSSCalcValue(this); return; #if ENABLE(CSS_IMAGE_SET) case ImageSetClass: delete toCSSImageSetValue(this); return; #endif #if ENABLE(CSS_FILTERS) case FilterImageClass: delete toCSSFilterImageValue(this); return; case WebKitCSSFilterClass: delete toWebKitCSSFilterValue(this); return; #if ENABLE(CSS_SHADERS) case WebKitCSSArrayFunctionValueClass: delete toWebKitCSSArrayFunctionValue(this); return; case WebKitCSSMatFunctionValueClass: delete toWebKitCSSMatFunctionValue(this); return; case WebKitCSSMixFunctionValueClass: delete toWebKitCSSMixFunctionValue(this); return; case WebKitCSSShaderClass: delete toWebKitCSSShaderValue(this); return; #endif #endif #if ENABLE(SVG) case SVGColorClass: delete toSVGColor(this); return; case SVGPaintClass: delete toSVGPaint(this); return; case WebKitCSSSVGDocumentClass: delete toWebKitCSSSVGDocumentValue(this); return; #endif } ASSERT_NOT_REACHED(); }
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->item(i))->getValueID()) { case CSSValueNormal: variant = FontVariantNormal; break; case CSSValueSmallCaps: variant = FontVariantSmallCaps; break; default: break; } } } return FontTraits(style, variant, weight, FontStretchNormal); }
void StyleBuilderFunctions::applyValueCSSPropertyContent(StyleResolverState& state, CSSValue* value) { // list of string, uri, counter, attr, i bool didSet = false; for (auto& item : toCSSValueList(*value)) { if (item->isImageGeneratorValue()) { state.style()->setContent(StyleGeneratedImage::create(toCSSImageGeneratorValue(item.get())), didSet); didSet = true; } else if (item->isImageSetValue()) { state.style()->setContent(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item.get())), didSet); didSet = true; } if (item->isImageValue()) { state.style()->setContent(state.elementStyleResources().cachedOrPendingFromValue(state.document(), CSSPropertyContent, toCSSImageValue(item.get())), didSet); didSet = true; continue; } if (item->isCounterValue()) { CSSCounterValue* counterValue = toCSSCounterValue(item.get()); EListStyleType listStyleType = NoneListStyle; CSSValueID listStyleIdent = counterValue->listStyle(); if (listStyleIdent != CSSValueNone) listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc); OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(AtomicString(counterValue->identifier()), listStyleType, AtomicString(counterValue->separator()))); state.style()->setContent(counter.release(), didSet); didSet = true; } if (item->isFunctionValue()) { CSSFunctionValue* functionValue = toCSSFunctionValue(item.get()); ASSERT(functionValue->functionType() == CSSValueAttr); // FIXME: Can a namespace be specified for an attr(foo)? if (state.style()->styleType() == NOPSEUDO) state.style()->setUnique(); else state.parentStyle()->setUnique(); QualifiedName attr(nullAtom, AtomicString(toCSSPrimitiveValue(functionValue->item(0))->getStringValue()), nullAtom); const AtomicString& value = state.element()->getAttribute(attr); state.style()->setContent(value.isNull() ? emptyString() : value.string(), didSet); didSet = true; } if (!item->isPrimitiveValue()) continue; CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item.get()); if (contentValue->isString()) { state.style()->setContent(contentValue->getStringValue().impl(), didSet); didSet = true; } else { switch (contentValue->getValueID()) { case CSSValueOpenQuote: state.style()->setContent(OPEN_QUOTE, didSet); didSet = true; break; case CSSValueCloseQuote: state.style()->setContent(CLOSE_QUOTE, didSet); didSet = true; break; case CSSValueNoOpenQuote: state.style()->setContent(NO_OPEN_QUOTE, didSet); didSet = true; break; case CSSValueNoCloseQuote: state.style()->setContent(NO_CLOSE_QUOTE, didSet); didSet = true; break; default: // normal and none do not have any effect. { } } } } if (!didSet) state.style()->clearContent(); }