Chromium Code Reviews| Index: third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp |
| diff --git a/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp b/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp |
| index 74458c84a2802d5bb634b2b560a8820d08d631a5..a7d537fc6f451cf75a93f29405e88c6e1b99ca88 100644 |
| --- a/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp |
| +++ b/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp |
| @@ -39,6 +39,9 @@ |
| namespace blink { |
| +static float kOffScreenCanvasEMFontSize = 10.0; |
| +static float kOffScreenCanvasREMFontSize = 16.0; |
| + |
| FilterOperation::OperationType FilterOperationResolver::filterOperationForType( |
| CSSValueID type) { |
| switch (type) { |
| @@ -63,7 +66,7 @@ FilterOperation::OperationType FilterOperationResolver::filterOperationForType( |
| case CSSValueDropShadow: |
| return FilterOperation::DROP_SHADOW; |
| default: |
| - ASSERT_NOT_REACHED(); |
| + NOTREACHED(); |
| // FIXME: We shouldn't have a type None since we never create them |
| return FilterOperation::NONE; |
| } |
| @@ -77,7 +80,7 @@ static void countFilterUse(FilterOperation::OperationType operationType, |
| switch (operationType) { |
| case FilterOperation::NONE: |
| case FilterOperation::BOX_REFLECT: |
| - ASSERT_NOT_REACHED(); |
| + NOTREACHED(); |
| return; |
| case FilterOperation::REFERENCE: |
| feature = UseCounter::CSSFilterReference; |
| @@ -128,6 +131,7 @@ FilterOperations FilterOperationResolver::createFilterOperations( |
| const CSSToLengthConversionData& conversionData = |
| state.cssToLengthConversionData(); |
| + |
| for (auto& currValue : toCSSValueList(inValue)) { |
| if (currValue->isURIValue()) { |
| countFilterUse(FilterOperation::REFERENCE, state.document()); |
| @@ -150,71 +154,137 @@ FilterOperations FilterOperationResolver::createFilterOperations( |
| filterValue->length() && filterValue->item(0).isPrimitiveValue() |
| ? &toCSSPrimitiveValue(filterValue->item(0)) |
| : nullptr; |
| + double firstNumber = |
| + StyleBuilderConverter::convertValueToNumber(filterValue, firstValue); |
| + |
| switch (filterValue->functionType()) { |
| case CSSValueGrayscale: |
| case CSSValueSepia: |
| - case CSSValueSaturate: { |
| - double amount = 1; |
| - if (filterValue->length() == 1) { |
| - amount = firstValue->getDoubleValue(); |
| - if (firstValue->isPercentage()) |
| - amount /= 100; |
| + case CSSValueSaturate: |
| + case CSSValueHueRotate: { |
| + operations.operations().push_back( |
| + BasicColorMatrixFilterOperation::create(firstNumber, |
| + operationType)); |
| + break; |
| + } |
| + case CSSValueInvert: |
| + case CSSValueBrightness: |
| + case CSSValueContrast: |
| + case CSSValueOpacity: { |
| + operations.operations().push_back( |
| + BasicComponentTransferFilterOperation::create(firstNumber, |
| + operationType)); |
| + break; |
| + } |
| + case CSSValueBlur: { |
| + Length stdDeviation = Length(0, Fixed); |
| + if (filterValue->length() >= 1) { |
| + stdDeviation = firstValue->convertToLength(conversionData); |
| } |
| - |
| operations.operations().push_back( |
| - BasicColorMatrixFilterOperation::create(amount, operationType)); |
| + BlurFilterOperation::create(stdDeviation)); |
| break; |
| } |
| - case CSSValueHueRotate: { |
| - double angle = 0; |
| - if (filterValue->length() == 1) |
| - angle = firstValue->computeDegrees(); |
| + case CSSValueDropShadow: { |
| + ShadowData shadow = StyleBuilderConverter::convertShadow( |
| + conversionData, &state, filterValue->item(0)); |
| + // TODO(fs): Resolve 'currentcolor' when constructing the filter chain. |
| + if (shadow.color().isCurrentColor()) { |
| + shadow.overrideColor(state.style()->color()); |
| + } |
| + operations.operations().push_back( |
| + DropShadowFilterOperation::create(shadow)); |
| + break; |
| + } |
| + default: |
| + NOTREACHED(); |
| + break; |
| + } |
| + } |
| + |
| + return operations; |
| +} |
| + |
| +FilterOperations FilterOperationResolver::createOffscreenFilterOperations( |
| + const CSSValue& inValue) { |
| + FilterOperations operations; |
| + |
| + if (inValue.isIdentifierValue()) { |
| + DCHECK_EQ(toCSSIdentifierValue(inValue).getValueID(), CSSValueNone); |
| + return operations; |
| + } |
| + |
| + FontDescription fontDescription; |
| + Font font(fontDescription); |
| + CSSToLengthConversionData::FontSizes fontSizes( |
| + kOffScreenCanvasEMFontSize, kOffScreenCanvasREMFontSize, &font); |
| + CSSToLengthConversionData::ViewportSize viewportSize(1024, 768); |
| + CSSToLengthConversionData conversionData(&ComputedStyle::initialStyle(), |
| + fontSizes, viewportSize, 1); |
| + |
| + for (auto& currValue : toCSSValueList(inValue)) { |
| + if (currValue->isURIValue()) |
| + continue; |
| + |
| + const CSSFunctionValue* filterValue = toCSSFunctionValue(currValue.get()); |
| + FilterOperation::OperationType operationType = |
| + filterOperationForType(filterValue->functionType()); |
| + // TODO(fserb): Take an ExecutionContext argument to this function, |
| + // so we can have workers using UseCounter as well. |
| + // countFilterUse(operationType, state.document()); |
| + DCHECK_LE(filterValue->length(), 1u); |
| + const CSSPrimitiveValue* firstValue = |
| + filterValue->length() && filterValue->item(0).isPrimitiveValue() |
| + ? &toCSSPrimitiveValue(filterValue->item(0)) |
| + : nullptr; |
| + double firstNumber = |
| + StyleBuilderConverter::convertValueToNumber(filterValue, firstValue); |
| + |
| + switch (filterValue->functionType()) { |
| + case CSSValueGrayscale: |
| + case CSSValueSepia: |
| + case CSSValueSaturate: |
| + case CSSValueHueRotate: { |
| operations.operations().push_back( |
| - BasicColorMatrixFilterOperation::create(angle, operationType)); |
| + BasicColorMatrixFilterOperation::create(firstNumber, |
| + 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().push_back( |
| - BasicComponentTransferFilterOperation::create(amount, |
| + BasicComponentTransferFilterOperation::create(firstNumber, |
| operationType)); |
| break; |
| } |
| case CSSValueBlur: { |
| Length stdDeviation = Length(0, Fixed); |
| - if (filterValue->length() >= 1) |
| + if (filterValue->length() >= 1) { |
| stdDeviation = firstValue->convertToLength(conversionData); |
| + } |
| operations.operations().push_back( |
| BlurFilterOperation::create(stdDeviation)); |
| break; |
| } |
| case CSSValueDropShadow: { |
| - ShadowData shadow = |
| - StyleBuilderConverter::convertShadow(state, filterValue->item(0)); |
| + ShadowData shadow = StyleBuilderConverter::convertShadow( |
| + conversionData, nullptr, filterValue->item(0)); |
| // TODO(fs): Resolve 'currentcolor' when constructing the filter chain. |
| - if (shadow.color().isCurrentColor()) |
| - shadow.overrideColor(state.style()->color()); |
| + if (shadow.color().isCurrentColor()) { |
| + shadow.overrideColor(Color::black); |
|
esprehn
2017/01/27 19:44:39
Is this a regression? It used to do ->color() and
fserb
2017/01/27 19:54:47
Well, on a regular document, you want the default
|
| + } |
| operations.operations().push_back( |
| DropShadowFilterOperation::create(shadow)); |
| break; |
| } |
| default: |
| - ASSERT_NOT_REACHED(); |
| + NOTREACHED(); |
| break; |
| } |
| } |
| - |
| return operations; |
| } |