PassRefPtr<ShadowList> StyleBuilderConverter::convertShadow(StyleResolverState& state, CSSValue* value) { if (value->isPrimitiveValue()) { ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone); return PassRefPtr<ShadowList>(); } const CSSValueList* valueList = toCSSValueList(value); size_t shadowCount = valueList->length(); ShadowDataVector shadows; for (size_t i = 0; i < shadowCount; ++i) { const CSSShadowValue* item = toCSSShadowValue(valueList->item(i)); float x = item->x->computeLength<float>(state.cssToLengthConversionData()); float y = item->y->computeLength<float>(state.cssToLengthConversionData()); float blur = item->blur ? item->blur->computeLength<float>(state.cssToLengthConversionData()) : 0; float spread = item->spread ? item->spread->computeLength<float>(state.cssToLengthConversionData()) : 0; ShadowStyle shadowStyle = item->style && item->style->getValueID() == CSSValueInset ? Inset : Normal; Color color; if (item->color) color = convertColor(state, item->color.get()); else color = state.style()->color(); shadows.append(ShadowData(FloatPoint(x, y), blur, spread, shadowStyle, color)); } return ShadowList::adopt(shadows); }
LengthPoint StyleBuilderConverter::convertLengthPoint(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Pair* pair = primitiveValue->getPairValue(); Length x = pair->first()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); Length y = pair->second()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); return LengthPoint(x, y); }
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); }
BorderImageLengthBox CSSToStyleMap::mapNinePieceImageQuad(StyleResolverState& state, CSSValue* value) { if (!value || !value->isPrimitiveValue()) return BorderImageLengthBox(Length(Auto)); Quad* slices = toCSSPrimitiveValue(value)->getQuadValue(); // Set up a border image length box to represent our image slices. return BorderImageLengthBox( toBorderImageLength(*slices->top(), state.cssToLengthConversionData()), toBorderImageLength(*slices->right(), state.cssToLengthConversionData()), toBorderImageLength(*slices->bottom(), state.cssToLengthConversionData()), toBorderImageLength(*slices->left(), state.cssToLengthConversionData())); }
BorderImageLengthBox CSSToStyleMap::mapNinePieceImageQuad(StyleResolverState& state, const CSSValue& value) { if (!value.isQuadValue()) return BorderImageLengthBox(Length(Auto)); const CSSQuadValue& slices = toCSSQuadValue(value); // Set up a border image length box to represent our image slices. return BorderImageLengthBox( toBorderImageLength(*slices.top(), state.cssToLengthConversionData()), toBorderImageLength(*slices.right(), state.cssToLengthConversionData()), toBorderImageLength(*slices.bottom(), state.cssToLengthConversionData()), toBorderImageLength(*slices.left(), state.cssToLengthConversionData())); }
InterpolationValue CSSTransformInterpolationType::maybeConvertValue( const CSSValue& value, const StyleResolverState& state, ConversionCheckers& conversionCheckers) const { if (value.isValueList()) { CSSLengthArray lengthArray; for (const CSSValue* item : toCSSValueList(value)) { const CSSFunctionValue& transformFunction = toCSSFunctionValue(*item); if (transformFunction.functionType() == CSSValueMatrix || transformFunction.functionType() == CSSValueMatrix3d) { lengthArray.typeFlags.set(CSSPrimitiveValue::UnitTypePixels); continue; } for (const CSSValue* argument : transformFunction) { const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(*argument); if (!primitiveValue.isLength()) continue; primitiveValue.accumulateLengthArray(lengthArray); } } std::unique_ptr<InterpolationType::ConversionChecker> lengthUnitsChecker = LengthUnitsChecker::maybeCreate(std::move(lengthArray), state); if (lengthUnitsChecker) conversionCheckers.append(std::move(lengthUnitsChecker)); } TransformOperations transform; TransformBuilder::createTransformOperations( value, state.cssToLengthConversionData(), transform); return convertTransform(std::move(transform)); }
float StyleBuilderConverter::convertSpacing(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID() == CSSValueNormal) return 0; return primitiveValue->computeLength<float>(state.cssToLengthConversionData()); }
void StyleBuilderFunctions::applyValueCSSPropertyBackdropFilter(StyleResolverState& state, CSSValue* value) { // FIXME: We should just make this a converter FilterOperations operations; FilterOperationResolver::createFilterOperations(*value, state.cssToLengthConversionData(), operations, state); state.style()->setBackdropFilter(operations); }
void StyleBuilderFunctions::applyValueCSSPropertyTransform(StyleResolverState& state, CSSValue* value) { // FIXME: We should just make this a converter TransformOperations operations; TransformBuilder::createTransformOperations(*value, state.cssToLengthConversionData(), operations); state.style()->setTransform(operations); }
static PassRefPtr<CustomFilterParameter> parseCustomFilterTransformParameter(const String& name, CSSValueList* values, StyleResolverState& state) { RefPtr<CustomFilterTransformParameter> transformParameter = CustomFilterTransformParameter::create(name); TransformOperations operations; TransformBuilder::createTransformOperations(values, state.cssToLengthConversionData(), operations); transformParameter->setOperations(operations); return transformParameter.release(); }
void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID()) state.style()->setVerticalAlign(*primitiveValue); else state.style()->setVerticalAlignLength(primitiveValue->convertToLength(state.cssToLengthConversionData())); }
float StyleBuilderConverter::convertTextStrokeWidth(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID()) { float multiplier = convertLineWidth<float>(state, value); return CSSPrimitiveValue::create(multiplier / 48, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(state.cssToLengthConversionData()); } return primitiveValue->computeLength<float>(state.cssToLengthConversionData()); }
void CSSToStyleMap::mapFillYPosition(StyleResolverState& state, FillLayer* layer, const CSSValue& value) { if (value.isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); return; } if (!value.isPrimitiveValue() && !value.isValuePair()) return; Length length; if (value.isValuePair()) length = toCSSPrimitiveValue(toCSSValuePair(value).second()).convertToLength(state.cssToLengthConversionData()); else length = toCSSPrimitiveValue(value).convertToLength(state.cssToLengthConversionData()); layer->setYPosition(length); if (value.isValuePair()) layer->setBackgroundYOrigin(toCSSPrimitiveValue(toCSSValuePair(value).first())); }
void CSSToStyleMap::mapFillSize(StyleResolverState& state, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setSizeType(FillLayer::initialFillSizeType(layer->type())); layer->setSizeLength(FillLayer::initialFillSizeLength(layer->type())); return; } if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID() == CSSValueContain) layer->setSizeType(Contain); else if (primitiveValue->getValueID() == CSSValueCover) layer->setSizeType(Cover); else layer->setSizeType(SizeLength); LengthSize b = FillLayer::initialFillSizeLength(layer->type()); if (primitiveValue->getValueID() == CSSValueContain || primitiveValue->getValueID() == CSSValueCover) { layer->setSizeLength(b); return; } Length firstLength; Length secondLength; if (Pair* pair = primitiveValue->getPairValue()) { firstLength = pair->first()->convertToLength<AnyConversion>(state.cssToLengthConversionData()); secondLength = pair->second()->convertToLength<AnyConversion>(state.cssToLengthConversionData()); } else { firstLength = primitiveValue->convertToLength<AnyConversion>(state.cssToLengthConversionData()); secondLength = Length(); } b.setWidth(firstLength); b.setHeight(secondLength); layer->setSizeLength(b); }
void StyleBuilderFunctions::applyValueCSSPropertyLineHeight(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Length lineHeight; if (primitiveValue->getValueID() == CSSValueNormal) { lineHeight = RenderStyle::initialLineHeight(); } else if (primitiveValue->isLength()) { lineHeight = primitiveValue->computeLength<Length>(state.cssToLengthConversionData()); } else if (primitiveValue->isPercentage()) { lineHeight = Length((state.style()->computedFontSize() * primitiveValue->getIntValue()) / 100.0, Fixed); } else if (primitiveValue->isNumber()) { lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent); } else if (primitiveValue->isCalculated()) { Length length = Length(primitiveValue->cssCalcValue()->toCalcValue(state.cssToLengthConversionData())); lineHeight = Length(valueForLength(length, state.style()->fontSize()), Fixed); } else { return; } state.style()->setLineHeight(lineHeight); }
void StyleBuilderFunctions::applyValueCSSPropertyPerspective(StyleResolverState& state, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID() == CSSValueNone) { state.style()->setPerspective(0); return; } if (!primitiveValue->isLength()) return; float perspectiveValue = primitiveValue->computeLength<float>(state.cssToLengthConversionData()); if (perspectiveValue >= 0.0f) state.style()->setPerspective(perspectiveValue); }
void CSSToStyleMap::mapFillYPosition(StyleResolverState& state, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); return; } if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Pair* pair = primitiveValue->getPairValue(); if (pair) primitiveValue = pair->second(); Length length = primitiveValue->convertToLength(state.cssToLengthConversionData()); layer->setYPosition(length); if (pair) layer->setBackgroundYOrigin(*(pair->first())); }
void StyleBuilderFunctions::applyValueCSSPropertyTextIndent(StyleResolverState& state, CSSValue* value) { Length lengthOrPercentageValue; TextIndentLine textIndentLineValue = ComputedStyle::initialTextIndentLine(); TextIndentType textIndentTypeValue = ComputedStyle::initialTextIndentType(); for (auto& listValue : toCSSValueList(*value)) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(listValue.get()); if (!primitiveValue->getValueID()) lengthOrPercentageValue = primitiveValue->convertToLength(state.cssToLengthConversionData()); else if (primitiveValue->getValueID() == CSSValueEachLine) textIndentLineValue = TextIndentEachLine; else if (primitiveValue->getValueID() == CSSValueHanging) textIndentTypeValue = TextIndentHanging; else ASSERT_NOT_REACHED(); } state.style()->setTextIndent(lengthOrPercentageValue); state.style()->setTextIndentLine(textIndentLineValue); state.style()->setTextIndentType(textIndentTypeValue); }
LengthSize StyleBuilderConverter::convertRadius(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Pair* pair = primitiveValue->getPairValue(); Length radiusWidth = pair->first()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); Length radiusHeight = pair->second()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); float width = radiusWidth.value(); float height = radiusHeight.value(); ASSERT(width >= 0 && height >= 0); if (width <= 0 || height <= 0) return LengthSize(Length(0, Fixed), Length(0, Fixed)); return LengthSize(radiusWidth, radiusHeight); }
Length StyleBuilderConverter::convertLengthOrAuto(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Length result = primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData()); result.setQuirk(primitiveValue->isQuirkValue()); return result; }
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 StyleBuilderFunctions::applyValueCSSPropertyTransform(StyleResolverState& state, CSSValue* value) { TransformOperations operations; TransformBuilder::createTransformOperations(value, state.cssToLengthConversionData(), operations); state.style()->setTransform(operations); }
void StyleBuilderFunctions::applyValueCSSPropertyTextIndent(StyleResolverState& state, CSSValue* value) { if (!value->isValueList()) return; Length lengthOrPercentageValue; TextIndentLine textIndentLineValue = RenderStyle::initialTextIndentLine(); TextIndentType textIndentTypeValue = RenderStyle::initialTextIndentType(); for (CSSValueListIterator i(value); i.hasMore(); i.advance()) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value()); if (!primitiveValue->getValueID()) lengthOrPercentageValue = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); else if (primitiveValue->getValueID() == CSSValueEachLine) textIndentLineValue = TextIndentEachLine; else if (primitiveValue->getValueID() == CSSValueHanging) textIndentTypeValue = TextIndentHanging; else ASSERT_NOT_REACHED(); } state.style()->setTextIndent(lengthOrPercentageValue); state.style()->setTextIndentLine(textIndentLineValue); state.style()->setTextIndentType(textIndentTypeValue); }
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)); }
static Length convertToLength(const StyleResolverState& state, CSSPrimitiveValue* value) { if (!value) return Length(0, Fixed); return value->convertToLength(state.cssToLengthConversionData()); }
PassRefPtr<StyleReflection> StyleBuilderConverter::convertBoxReflect(StyleResolverState& state, CSSValue* value) { if (value->isPrimitiveValue()) { ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone); return RenderStyle::initialBoxReflect(); } CSSReflectValue* reflectValue = toCSSReflectValue(value); RefPtr<StyleReflection> reflection = StyleReflection::create(); reflection->setDirection(*reflectValue->direction()); if (reflectValue->offset()) reflection->setOffset(reflectValue->offset()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData())); NinePieceImage mask; mask.setMaskDefaults(); state.styleMap().mapNinePieceImage(state.style(), CSSPropertyWebkitBoxReflect, reflectValue->mask(), mask); reflection->setMask(mask); return reflection.release(); }
void StyleBuilderFunctions::applyValueCSSPropertyFilter(StyleResolverState& state, CSSValue* value) { FilterOperations operations; if (FilterOperationResolver::createFilterOperations(value, state.cssToLengthConversionData(), operations, state)) state.style()->setFilter(operations); }
void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->getValueID()) { state.style()->setVerticalAlign(*primitiveValue); return; } state.style()->setVerticalAlignLength(primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData())); }
void StyleBuilderFunctions::applyValueCSSPropertyWebkitPerspective(StyleResolverState& state, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); if (primitiveValue->isNumber()) { float perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(state.cssToLengthConversionData()); if (perspectiveValue >= 0.0f) state.style()->setPerspective(perspectiveValue); } else { applyValueCSSPropertyPerspective(state, value); } }