diff options
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.cpp | 304 |
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: |