InterpolationValue CSSPositionAxisListInterpolationType::convertPositionAxisCSSValue( const CSSValue& value) { if (value.isValuePair()) { const CSSValuePair& pair = toCSSValuePair(value); InterpolationValue result = LengthInterpolationFunctions::maybeConvertCSSValue(pair.second()); CSSValueID side = toCSSIdentifierValue(pair.first()).getValueID(); if (side == CSSValueRight || side == CSSValueBottom) LengthInterpolationFunctions::subtractFromOneHundredPercent(result); return result; } if (value.isPrimitiveValue()) return LengthInterpolationFunctions::maybeConvertCSSValue(value); if (!value.isIdentifierValue()) return nullptr; const CSSIdentifierValue& ident = toCSSIdentifierValue(value); switch (ident.getValueID()) { case CSSValueLeft: case CSSValueTop: return LengthInterpolationFunctions::createInterpolablePercent(0); case CSSValueRight: case CSSValueBottom: return LengthInterpolationFunctions::createInterpolablePercent(100); case CSSValueCenter: return LengthInterpolationFunctions::createInterpolablePercent(50); default: NOTREACHED(); return nullptr; } }
void CSSMatrix::setMatrixValue(const String& string, ExceptionState& exceptionState) { if (string.isEmpty()) return; if (const CSSValue* value = CSSParser::parseSingleValue(CSSPropertyTransform, string)) { // Check for a "none" transform. In these cases we can use the default // identity matrix. if (value->isIdentifierValue() && (toCSSIdentifierValue(value))->getValueID() == CSSValueNone) return; DEFINE_STATIC_REF(ComputedStyle, initialStyle, createInitialStyle()); TransformOperations operations = TransformBuilder::createTransformOperations( *value, CSSToLengthConversionData(initialStyle, initialStyle, LayoutViewItem(nullptr), 1.0f)); // Convert transform operations to a TransformationMatrix. This can fail // if a param has a percentage ('%') if (operations.dependsOnBoxSize()) exceptionState.throwDOMException(SyntaxError, "The transformation depends on the box " "size, which is not supported."); m_matrix = TransformationMatrix::create(); operations.apply(FloatSize(0, 0), *m_matrix); } else { // There is something there but parsing failed. exceptionState.throwDOMException(SyntaxError, "Failed to parse '" + string + "'."); } }
InterpolationValue CSSFilterListInterpolationType::maybeConvertValue( const CSSValue& value, const StyleResolverState&, ConversionCheckers&) const { if (value.isIdentifierValue() && toCSSIdentifierValue(value).getValueID() == CSSValueNone) return InterpolationValue(InterpolableList::create(0), NonInterpolableList::create()); if (!value.isBaseValueList()) return nullptr; const CSSValueList& list = toCSSValueList(value); size_t length = list.length(); std::unique_ptr<InterpolableList> interpolableList = InterpolableList::create(length); Vector<RefPtr<NonInterpolableValue>> nonInterpolableValues(length); for (size_t i = 0; i < length; i++) { InterpolationValue itemResult = FilterInterpolationFunctions::maybeConvertCSSFilter(list.item(i)); if (!itemResult) return nullptr; interpolableList->set(i, std::move(itemResult.interpolableValue)); nonInterpolableValues[i] = itemResult.nonInterpolableValue.release(); } return InterpolationValue( std::move(interpolableList), NonInterpolableList::create(std::move(nonInterpolableValues))); }
bool propertyMissingOrEqualToNone(StylePropertySet* style, CSSPropertyID propertyID) { if (!style) return false; const CSSValue* value = style->getPropertyCSSValue(propertyID); if (!value) return true; if (!value->isIdentifierValue()) return false; return toCSSIdentifierValue(value)->getValueID() == CSSValueNone; }
static BasicShapeCenterCoordinate convertToCenterCoordinate( const StyleResolverState& state, CSSValue* value) { BasicShapeCenterCoordinate::Direction direction; Length offset = Length(0, Fixed); CSSValueID keyword = CSSValueTop; if (!value) { keyword = CSSValueCenter; } else if (value->isIdentifierValue()) { keyword = toCSSIdentifierValue(value)->getValueID(); } else if (value->isValuePair()) { keyword = toCSSIdentifierValue(toCSSValuePair(value)->first()).getValueID(); offset = convertToLength( state, &toCSSPrimitiveValue(toCSSValuePair(value)->second())); } else { offset = convertToLength(state, toCSSPrimitiveValue(value)); } switch (keyword) { case CSSValueTop: case CSSValueLeft: direction = BasicShapeCenterCoordinate::TopLeft; break; case CSSValueRight: case CSSValueBottom: direction = BasicShapeCenterCoordinate::BottomRight; break; case CSSValueCenter: direction = BasicShapeCenterCoordinate::TopLeft; offset = Length(50, Percent); break; default: ASSERT_NOT_REACHED(); direction = BasicShapeCenterCoordinate::TopLeft; break; } return BasicShapeCenterCoordinate(direction, offset); }
InterpolationValue SizeInterpolationFunctions::maybeConvertCSSSizeSide( const CSSValue& value, bool convertWidth) { if (value.isValuePair()) { const CSSValuePair& pair = toCSSValuePair(value); const CSSValue& side = convertWidth ? pair.first() : pair.second(); if (side.isIdentifierValue() && toCSSIdentifierValue(side).getValueID() == CSSValueAuto) return convertKeyword(CSSValueAuto); return wrapConvertedLength( LengthInterpolationFunctions::maybeConvertCSSValue(side)); } if (!value.isIdentifierValue() && !value.isPrimitiveValue()) return nullptr; if (value.isIdentifierValue()) return convertKeyword(toCSSIdentifierValue(value).getValueID()); // A single length is equivalent to "<length> auto". if (convertWidth) return wrapConvertedLength( LengthInterpolationFunctions::maybeConvertCSSValue(value)); return convertKeyword(CSSValueAuto); }
static BasicShapeRadius cssValueToBasicShapeRadius( const StyleResolverState& state, const CSSValue* radius) { if (!radius) return BasicShapeRadius(BasicShapeRadius::ClosestSide); if (radius->isIdentifierValue()) { switch (toCSSIdentifierValue(radius)->getValueID()) { case CSSValueClosestSide: return BasicShapeRadius(BasicShapeRadius::ClosestSide); case CSSValueFarthestSide: return BasicShapeRadius(BasicShapeRadius::FarthestSide); default: ASSERT_NOT_REACHED(); break; } } return BasicShapeRadius(convertToLength(state, toCSSPrimitiveValue(radius))); }
TransformOperations TransformBuilder::createTransformOperations( const CSSValue& inValue, const CSSToLengthConversionData& conversionData) { TransformOperations operations; if (!inValue.isValueList()) { DCHECK_EQ(toCSSIdentifierValue(inValue).getValueID(), CSSValueNone); return operations; } float zoomFactor = conversionData.zoom(); for (auto& value : toCSSValueList(inValue)) { const CSSFunctionValue* transformValue = toCSSFunctionValue(value.get()); TransformOperation::OperationType transformType = getTransformOperationType(transformValue->functionType()); const CSSPrimitiveValue& firstValue = toCSSPrimitiveValue(transformValue->item(0)); switch (transformType) { case TransformOperation::Scale: case TransformOperation::ScaleX: case TransformOperation::ScaleY: { double sx = 1.0; double sy = 1.0; if (transformType == TransformOperation::ScaleY) { sy = firstValue.getDoubleValue(); } else { sx = firstValue.getDoubleValue(); if (transformType != TransformOperation::ScaleX) { if (transformValue->length() > 1) { const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); sy = secondValue.getDoubleValue(); } else { sy = sx; } } } operations.operations().append( ScaleTransformOperation::create(sx, sy, 1.0, transformType)); break; } case TransformOperation::ScaleZ: case TransformOperation::Scale3D: { double sx = 1.0; double sy = 1.0; double sz = 1.0; if (transformType == TransformOperation::ScaleZ) { sz = firstValue.getDoubleValue(); } else { sx = firstValue.getDoubleValue(); sy = toCSSPrimitiveValue(transformValue->item(1)).getDoubleValue(); sz = toCSSPrimitiveValue(transformValue->item(2)).getDoubleValue(); } operations.operations().append( ScaleTransformOperation::create(sx, sy, sz, transformType)); break; } case TransformOperation::Translate: case TransformOperation::TranslateX: case TransformOperation::TranslateY: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); if (transformType == TransformOperation::TranslateY) ty = convertToFloatLength(firstValue, conversionData); else { tx = convertToFloatLength(firstValue, conversionData); if (transformType != TransformOperation::TranslateX) { if (transformValue->length() > 1) { const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); ty = convertToFloatLength(secondValue, conversionData); } } } operations.operations().append( TranslateTransformOperation::create(tx, ty, 0, transformType)); break; } case TransformOperation::TranslateZ: case TransformOperation::Translate3D: { Length tx = Length(0, Fixed); Length ty = Length(0, Fixed); double tz = 0; if (transformType == TransformOperation::TranslateZ) { tz = firstValue.computeLength<double>(conversionData); } else { tx = convertToFloatLength(firstValue, conversionData); ty = convertToFloatLength( toCSSPrimitiveValue(transformValue->item(1)), conversionData); tz = toCSSPrimitiveValue(transformValue->item(2)) .computeLength<double>(conversionData); } operations.operations().append( TranslateTransformOperation::create(tx, ty, tz, transformType)); break; } case TransformOperation::RotateX: case TransformOperation::RotateY: case TransformOperation::RotateZ: { double angle = firstValue.computeDegrees(); if (transformValue->length() == 1) { double x = transformType == TransformOperation::RotateX; double y = transformType == TransformOperation::RotateY; double z = transformType == TransformOperation::RotateZ; operations.operations().append( RotateTransformOperation::create(x, y, z, angle, transformType)); } else { // For SVG 'transform' attributes we generate 3-argument rotate() // functions. DCHECK_EQ(transformValue->length(), 3u); const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); const CSSPrimitiveValue& thirdValue = toCSSPrimitiveValue(transformValue->item(2)); operations.operations().append( RotateAroundOriginTransformOperation::create( angle, secondValue.computeLength<double>(conversionData), thirdValue.computeLength<double>(conversionData))); } break; } case TransformOperation::Rotate3D: { const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); const CSSPrimitiveValue& thirdValue = toCSSPrimitiveValue(transformValue->item(2)); const 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, transformType)); break; } case TransformOperation::Skew: case TransformOperation::SkewX: case TransformOperation::SkewY: { double angleX = 0; double angleY = 0; double angle = firstValue.computeDegrees(); if (transformType == TransformOperation::SkewY) angleY = angle; else { angleX = angle; if (transformType == TransformOperation::Skew) { if (transformValue->length() > 1) { const CSSPrimitiveValue& secondValue = toCSSPrimitiveValue(transformValue->item(1)); angleY = secondValue.computeDegrees(); } } } operations.operations().append( SkewTransformOperation::create(angleX, angleY, transformType)); break; } case TransformOperation::Matrix: { 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 = zoomFactor * toCSSPrimitiveValue(transformValue->item(4)).getDoubleValue(); double f = zoomFactor * toCSSPrimitiveValue(transformValue->item(5)).getDoubleValue(); operations.operations().append( MatrixTransformOperation::create(a, b, c, d, e, f)); break; } case TransformOperation::Matrix3D: { 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()); matrix.zoom(zoomFactor); operations.operations().append( Matrix3DTransformOperation::create(matrix)); break; } case TransformOperation::Perspective: { double p = firstValue.computeLength<double>(conversionData); ASSERT(p >= 0); operations.operations().append( PerspectiveTransformOperation::create(p)); break; } default: ASSERT_NOT_REACHED(); break; } } return operations; }
static bool isCSSAuto(const CSSValue& value) { return value.isIdentifierValue() && toCSSIdentifierValue(value).getValueID() == CSSValueAuto; }
void CSSValue::finalizeGarbageCollectedObject() { switch (getClassType()) { case BasicShapeCircleClass: toCSSBasicShapeCircleValue(this)->~CSSBasicShapeCircleValue(); return; case BasicShapeEllipseClass: toCSSBasicShapeEllipseValue(this)->~CSSBasicShapeEllipseValue(); return; case BasicShapePolygonClass: toCSSBasicShapePolygonValue(this)->~CSSBasicShapePolygonValue(); return; case BasicShapeInsetClass: toCSSBasicShapeInsetValue(this)->~CSSBasicShapeInsetValue(); return; case BorderImageSliceClass: toCSSBorderImageSliceValue(this)->~CSSBorderImageSliceValue(); return; case ColorClass: toCSSColorValue(this)->~CSSColorValue(); return; case CounterClass: toCSSCounterValue(this)->~CSSCounterValue(); return; case CursorImageClass: toCSSCursorImageValue(this)->~CSSCursorImageValue(); return; case FontFaceSrcClass: toCSSFontFaceSrcValue(this)->~CSSFontFaceSrcValue(); return; case FontFamilyClass: toCSSFontFamilyValue(this)->~CSSFontFamilyValue(); return; case FontFeatureClass: toCSSFontFeatureValue(this)->~CSSFontFeatureValue(); return; case FunctionClass: toCSSFunctionValue(this)->~CSSFunctionValue(); return; case LinearGradientClass: toCSSLinearGradientValue(this)->~CSSLinearGradientValue(); return; case RadialGradientClass: toCSSRadialGradientValue(this)->~CSSRadialGradientValue(); return; case CrossfadeClass: toCSSCrossfadeValue(this)->~CSSCrossfadeValue(); return; case PaintClass: toCSSPaintValue(this)->~CSSPaintValue(); return; case CustomIdentClass: toCSSCustomIdentValue(this)->~CSSCustomIdentValue(); return; case ImageClass: toCSSImageValue(this)->~CSSImageValue(); return; case InheritedClass: toCSSInheritedValue(this)->~CSSInheritedValue(); return; case InitialClass: toCSSInitialValue(this)->~CSSInitialValue(); return; case UnsetClass: toCSSUnsetValue(this)->~CSSUnsetValue(); return; case GridAutoRepeatClass: toCSSGridAutoRepeatValue(this)->~CSSGridAutoRepeatValue(); return; case GridLineNamesClass: toCSSGridLineNamesValue(this)->~CSSGridLineNamesValue(); return; case GridTemplateAreasClass: toCSSGridTemplateAreasValue(this)->~CSSGridTemplateAreasValue(); return; case PathClass: toCSSPathValue(this)->~CSSPathValue(); return; case PrimitiveClass: toCSSPrimitiveValue(this)->~CSSPrimitiveValue(); return; case IdentifierClass: toCSSIdentifierValue(this)->~CSSIdentifierValue(); return; case QuadClass: toCSSQuadValue(this)->~CSSQuadValue(); return; case ReflectClass: toCSSReflectValue(this)->~CSSReflectValue(); return; case ShadowClass: toCSSShadowValue(this)->~CSSShadowValue(); return; case StringClass: toCSSStringValue(this)->~CSSStringValue(); return; case CubicBezierTimingFunctionClass: toCSSCubicBezierTimingFunctionValue(this) ->~CSSCubicBezierTimingFunctionValue(); return; case StepsTimingFunctionClass: toCSSStepsTimingFunctionValue(this)->~CSSStepsTimingFunctionValue(); return; case UnicodeRangeClass: toCSSUnicodeRangeValue(this)->~CSSUnicodeRangeValue(); return; case URIClass: toCSSURIValue(this)->~CSSURIValue(); return; case ValueListClass: toCSSValueList(this)->~CSSValueList(); return; case ValuePairClass: toCSSValuePair(this)->~CSSValuePair(); return; case ImageSetClass: toCSSImageSetValue(this)->~CSSImageSetValue(); return; case CSSContentDistributionClass: toCSSContentDistributionValue(this)->~CSSContentDistributionValue(); return; case VariableReferenceClass: toCSSVariableReferenceValue(this)->~CSSVariableReferenceValue(); return; case CustomPropertyDeclarationClass: toCSSCustomPropertyDeclaration(this)->~CSSCustomPropertyDeclaration(); return; case PendingSubstitutionValueClass: toCSSPendingSubstitutionValue(this)->~CSSPendingSubstitutionValue(); return; } ASSERT_NOT_REACHED(); }