summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp304
1 files changed, 8 insertions, 296 deletions
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp
index 37706e6818d..fdb2e957ab4 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp
@@ -30,23 +30,12 @@
#include "core/css/resolver/FilterOperationResolver.h"
#include "core/css/CSSFilterValue.h"
-#include "core/css/CSSMixFunctionValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSPrimitiveValueMappings.h"
-#include "core/css/CSSShaderValue.h"
#include "core/css/CSSShadowValue.h"
#include "core/css/resolver/TransformBuilder.h"
-#include "core/rendering/style/StyleCustomFilterProgram.h"
-#include "core/rendering/style/StyleShader.h"
#include "core/rendering/svg/ReferenceFilterBuilder.h"
#include "core/svg/SVGURIReference.h"
-#include "platform/graphics/filters/custom/CustomFilterArrayParameter.h"
-#include "platform/graphics/filters/custom/CustomFilterConstants.h"
-#include "platform/graphics/filters/custom/CustomFilterNumberParameter.h"
-#include "platform/graphics/filters/custom/CustomFilterOperation.h"
-#include "platform/graphics/filters/custom/CustomFilterParameter.h"
-#include "platform/graphics/filters/custom/CustomFilterProgramInfo.h"
-#include "platform/graphics/filters/custom/CustomFilterTransformParameter.h"
namespace WebCore {
@@ -75,277 +64,12 @@ static FilterOperation::OperationType filterOperationForType(CSSFilterValue::Fil
return FilterOperation::BLUR;
case CSSFilterValue::DropShadowFilterOperation:
return FilterOperation::DROP_SHADOW;
- case CSSFilterValue::CustomFilterOperation:
- return FilterOperation::CUSTOM;
case CSSFilterValue::UnknownFilterOperation:
return FilterOperation::NONE;
}
return FilterOperation::NONE;
}
-static StyleShader* styleShader(CSSValue* value)
-{
- if (value->isShaderValue())
- return toCSSShaderValue(value)->cachedOrPendingShader();
- return 0;
-}
-
-static PassRefPtr<CustomFilterParameter> parseCustomFilterArrayParameter(const String& name, CSSValueList* values)
-{
- RefPtr<CustomFilterArrayParameter> arrayParameter = CustomFilterArrayParameter::create(name);
- for (unsigned i = 0, length = values->length(); i < length; ++i) {
- CSSValue* value = values->itemWithoutBoundsCheck(i);
- if (!value->isPrimitiveValue())
- return 0;
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
- return 0;
- arrayParameter->addValue(primitiveValue->getDoubleValue());
- }
- return arrayParameter.release();
-}
-
-static PassRefPtr<CustomFilterParameter> parseCustomFilterNumberParameter(const String& name, CSSValueList* values)
-{
- RefPtr<CustomFilterNumberParameter> numberParameter = CustomFilterNumberParameter::create(name);
- for (unsigned i = 0; i < values->length(); ++i) {
- CSSValue* value = values->itemWithoutBoundsCheck(i);
- if (!value->isPrimitiveValue())
- return 0;
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
- return 0;
- numberParameter->addValue(primitiveValue->getDoubleValue());
- }
- return numberParameter.release();
-}
-
-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();
-}
-
-static PassRefPtr<CustomFilterParameter> parseCustomFilterParameter(const String& name, CSSValue* parameterValue, StyleResolverState& state)
-{
- // FIXME: Implement other parameters types parsing.
- // booleans: https://bugs.webkit.org/show_bug.cgi?id=76438
- // textures: https://bugs.webkit.org/show_bug.cgi?id=71442
- // mat2, mat3, mat4: https://bugs.webkit.org/show_bug.cgi?id=71444
- // Number parameters are wrapped inside a CSSValueList and all
- // the other functions values inherit from CSSValueList.
- if (!parameterValue->isValueList())
- return 0;
-
- CSSValueList* values = toCSSValueList(parameterValue);
- if (!values->length())
- return 0;
-
- if (parameterValue->isArrayFunctionValue())
- return parseCustomFilterArrayParameter(name, values);
-
- // If the first value of the list is a transform function,
- // then we could safely assume that all the remaining items
- // are transforms. parseCustomFilterTransformParameter will
- // return 0 if that assumption is incorrect.
- if (values->itemWithoutBoundsCheck(0)->isTransformValue())
- return parseCustomFilterTransformParameter(name, values, state);
-
- // We can have only arrays of booleans or numbers, so use the first value to choose between those two.
- // We need up to 4 values (all booleans or all numbers).
- if (!values->itemWithoutBoundsCheck(0)->isPrimitiveValue() || values->length() > 4)
- return 0;
-
- CSSPrimitiveValue* firstPrimitiveValue = toCSSPrimitiveValue(values->itemWithoutBoundsCheck(0));
- if (firstPrimitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
- return parseCustomFilterNumberParameter(name, values);
-
- // FIXME: Implement the boolean array parameter here.
- // https://bugs.webkit.org/show_bug.cgi?id=76438
-
- return 0;
-}
-
-static bool parseCustomFilterParameterList(CSSValue* parametersValue, CustomFilterParameterList& parameterList, StyleResolverState& state)
-{
- HashSet<String> knownParameterNames;
- CSSValueListIterator parameterIterator(parametersValue);
- for (; parameterIterator.hasMore(); parameterIterator.advance()) {
- if (!parameterIterator.value()->isValueList())
- return false;
- CSSValueListIterator iterator(parameterIterator.value());
- if (!iterator.isPrimitiveValue())
- return false;
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value());
- if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_STRING)
- return false;
-
- String name = primitiveValue->getStringValue();
- // Do not allow duplicate parameter names.
- if (!knownParameterNames.add(name).isNewEntry)
- return false;
-
- iterator.advance();
-
- if (!iterator.hasMore())
- return false;
-
- RefPtr<CustomFilterParameter> parameter = parseCustomFilterParameter(name, iterator.value(), state);
- if (!parameter)
- return false;
- parameterList.append(parameter.release());
- }
-
- // Make sure we sort the parameters before passing them down to the CustomFilterOperation.
- parameterList.sortParametersByName();
-
- return true;
-}
-
-static PassRefPtr<CustomFilterOperation> createCustomFilterOperationWithAtRuleReferenceSyntax(CSSFilterValue*)
-{
- // FIXME: Implement style resolution for the custom filter at-rule reference syntax.
- return 0;
-}
-
-static PassRefPtr<CustomFilterProgram> createCustomFilterProgram(CSSShaderValue* vertexShader, CSSShaderValue* fragmentShader,
- CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType,
- StyleResolverState& state)
-{
- ResourceFetcher* fetcher = state.document().fetcher();
- KURL vertexShaderURL = vertexShader ? vertexShader->completeURL(fetcher) : KURL();
- KURL fragmentShaderURL = fragmentShader ? fragmentShader->completeURL(fetcher) : KURL();
- // We re-resolve the custom filter style after the shaders are loaded.
- // We always create a StyleCustomFilterProgram here, and later replace it with a program from the StyleCustomFilterProgramCache, if available.
- StyleShader* styleVertexShader = vertexShader ? styleShader(vertexShader) : 0;
- StyleShader* styleFragmentShader = fragmentShader ? styleShader(fragmentShader) : 0;
- RefPtr<StyleCustomFilterProgram> program = StyleCustomFilterProgram::create(vertexShaderURL, styleVertexShader,
- fragmentShaderURL, styleFragmentShader, programType, mixSettings, meshType);
- state.elementStyleResources().setHasNewCustomFilterProgram(true);
- return program.release();
-}
-
-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);
-}
-
-static PassRefPtr<CustomFilterOperation> createCustomFilterOperation(CSSFilterValue* filterValue, StyleResolverState& state)
-{
- ASSERT(filterValue->length());
- bool isAtRuleReferenceSyntax = filterValue->itemWithoutBoundsCheck(0)->isPrimitiveValue();
- return isAtRuleReferenceSyntax ? createCustomFilterOperationWithAtRuleReferenceSyntax(filterValue) : createCustomFilterOperationWithInlineSyntax(filterValue, state);
-}
-
-
bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CSSToLengthConversionData& unadjustedConversionData, FilterOperations& outOperations, StyleResolverState& state)
{
ASSERT(outOperations.isEmpty());
@@ -362,7 +86,11 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
if (!inValue->isValueList())
return false;
+#ifdef BLINK_SCALE_FILTERS_AT_RECORD_TIME
float zoomFactor = unadjustedConversionData.zoom() * state.elementStyleResources().deviceScaleFactor();
+#else
+ float zoomFactor = unadjustedConversionData.zoom();
+#endif
const CSSToLengthConversionData& conversionData = unadjustedConversionData.copyWithAdjustedZoom(zoomFactor);
FilterOperations operations;
for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) {
@@ -373,19 +101,6 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
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;
@@ -397,7 +112,7 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
CSSSVGDocumentValue* svgDocumentValue = toCSSSVGDocumentValue(argument);
KURL url = state.document().completeURL(svgDocumentValue->url());
- RefPtr<ReferenceFilterOperation> operation = ReferenceFilterOperation::create(svgDocumentValue->url(), url.fragmentIdentifier());
+ RefPtr<ReferenceFilterOperation> operation = ReferenceFilterOperation::create(svgDocumentValue->url(), AtomicString(url.fragmentIdentifier()));
if (SVGURIReference::isExternalURIReference(svgDocumentValue->url(), state.document())) {
if (!svgDocumentValue->loadRequested())
state.elementStyleResources().addPendingSVGDocument(operation.get(), svgDocumentValue);
@@ -463,9 +178,6 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
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;
}
@@ -480,11 +192,11 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
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;
+ Color shadowColor = Color::transparent;
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));
+ operations.operations().append(DropShadowFilterOperation::create(location, blur, shadowColor));
break;
}
case CSSFilterValue::UnknownFilterOperation: