Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "core/svg/SVGLengthContext.h" | 31 #include "core/svg/SVGLengthContext.h" |
| 32 #include "core/svg/graphics/filters/SVGFilterBuilder.h" | 32 #include "core/svg/graphics/filters/SVGFilterBuilder.h" |
| 33 #include "platform/LengthFunctions.h" | 33 #include "platform/LengthFunctions.h" |
| 34 #include "platform/graphics/ColorSpace.h" | 34 #include "platform/graphics/ColorSpace.h" |
| 35 #include "platform/graphics/filters/FEBoxReflect.h" | 35 #include "platform/graphics/filters/FEBoxReflect.h" |
| 36 #include "platform/graphics/filters/FEColorMatrix.h" | 36 #include "platform/graphics/filters/FEColorMatrix.h" |
| 37 #include "platform/graphics/filters/FEComponentTransfer.h" | 37 #include "platform/graphics/filters/FEComponentTransfer.h" |
| 38 #include "platform/graphics/filters/FEDropShadow.h" | 38 #include "platform/graphics/filters/FEDropShadow.h" |
| 39 #include "platform/graphics/filters/FEGaussianBlur.h" | 39 #include "platform/graphics/filters/FEGaussianBlur.h" |
| 40 #include "platform/graphics/filters/Filter.h" | 40 #include "platform/graphics/filters/Filter.h" |
| 41 #include "platform/graphics/filters/FilterEffect.h" | |
| 41 #include "platform/graphics/filters/FilterOperations.h" | 42 #include "platform/graphics/filters/FilterOperations.h" |
| 42 #include "platform/graphics/filters/SourceGraphic.h" | 43 #include "platform/graphics/filters/SourceGraphic.h" |
| 43 #include "wtf/MathExtras.h" | 44 #include "wtf/MathExtras.h" |
| 44 #include <algorithm> | 45 #include <algorithm> |
| 45 | 46 |
| 46 namespace blink { | 47 namespace blink { |
| 47 | 48 |
| 48 namespace { | 49 namespace { |
| 49 | 50 |
| 50 inline void endMatrixRow(Vector<float>& matrix) | 51 inline void endMatrixRow(Vector<float>& matrix) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 matrix.uncheckedAppend(clampTo<float>(0.534 - 0.534 * oneMinusAmount)); | 114 matrix.uncheckedAppend(clampTo<float>(0.534 - 0.534 * oneMinusAmount)); |
| 114 matrix.uncheckedAppend(clampTo<float>(0.131 + 0.869 * oneMinusAmount)); | 115 matrix.uncheckedAppend(clampTo<float>(0.131 + 0.869 * oneMinusAmount)); |
| 115 endMatrixRow(matrix); | 116 endMatrixRow(matrix); |
| 116 | 117 |
| 117 lastMatrixRow(matrix); | 118 lastMatrixRow(matrix); |
| 118 return matrix; | 119 return matrix; |
| 119 } | 120 } |
| 120 | 121 |
| 121 } // namespace | 122 } // namespace |
| 122 | 123 |
| 123 FilterEffectBuilder::FilterEffectBuilder() | 124 FilterEffectBuilder::FilterEffectBuilder( |
| 125 Element* target, | |
| 126 const FloatRect& zoomedReferenceBox, float zoom, | |
| 127 const SkPaint* fillPaint, const SkPaint* strokePaint) | |
| 128 : m_targetContext(target) | |
| 129 , m_referenceBox(zoomedReferenceBox) | |
| 130 , m_zoom(zoom) | |
| 131 , m_fillPaint(fillPaint) | |
| 132 , m_strokePaint(strokePaint) | |
| 124 { | 133 { |
| 134 if (m_zoom != 1) | |
| 135 m_referenceBox.scale(1 / m_zoom); | |
| 125 } | 136 } |
| 126 | 137 |
| 127 FilterEffectBuilder::~FilterEffectBuilder() | 138 FilterEffect* FilterEffectBuilder::buildFilterEffect(const FilterOperations& ope rations) const |
| 128 { | |
| 129 } | |
| 130 | |
| 131 DEFINE_TRACE(FilterEffectBuilder) | |
| 132 { | |
| 133 visitor->trace(m_lastEffect); | |
| 134 } | |
| 135 | |
| 136 bool FilterEffectBuilder::build(Element* element, const FilterOperations& operat ions, float zoom, const FloatRect& zoomedReferenceBox, const SkPaint* fillPaint, const SkPaint* strokePaint) | |
| 137 { | 139 { |
| 138 // Create a parent filter for shorthand filters. These have already been sca led by the CSS code for page zoom, so scale is 1.0 here. | 140 // Create a parent filter for shorthand filters. These have already been sca led by the CSS code for page zoom, so scale is 1.0 here. |
| 139 Filter* parentFilter = Filter::create(1.0f); | 141 Filter* parentFilter = Filter::create(1.0f); |
| 140 FilterEffect* previousEffect = parentFilter->getSourceGraphic(); | 142 FilterEffect* previousEffect = parentFilter->getSourceGraphic(); |
| 141 for (size_t i = 0; i < operations.operations().size(); ++i) { | 143 for (size_t i = 0; i < operations.operations().size(); ++i) { |
| 142 FilterEffect* effect = nullptr; | 144 FilterEffect* effect = nullptr; |
| 143 FilterOperation* filterOperation = operations.operations().at(i).get(); | 145 FilterOperation* filterOperation = operations.operations().at(i).get(); |
| 144 switch (filterOperation->type()) { | 146 switch (filterOperation->type()) { |
| 145 case FilterOperation::REFERENCE: { | 147 case FilterOperation::REFERENCE: { |
| 146 Filter* referenceFilter = buildReferenceFilter(toReferenceFilterOper ation(*filterOperation), zoomedReferenceBox, fillPaint, strokePaint, *element, p reviousEffect, zoom); | 148 Filter* referenceFilter = buildReferenceFilter(toReferenceFilterOper ation(*filterOperation), previousEffect); |
| 147 if (referenceFilter) | 149 if (referenceFilter) |
| 148 effect = referenceFilter->lastEffect(); | 150 effect = referenceFilter->lastEffect(); |
| 149 break; | 151 break; |
| 150 } | 152 } |
| 151 case FilterOperation::GRAYSCALE: { | 153 case FilterOperation::GRAYSCALE: { |
| 152 Vector<float> inputParameters = grayscaleMatrix(toBasicColorMatrixFi lterOperation(filterOperation)->amount()); | 154 Vector<float> inputParameters = grayscaleMatrix(toBasicColorMatrixFi lterOperation(filterOperation)->amount()); |
| 153 effect = FEColorMatrix::create(parentFilter, FECOLORMATRIX_TYPE_MATR IX, inputParameters); | 155 effect = FEColorMatrix::create(parentFilter, FECOLORMATRIX_TYPE_MATR IX, inputParameters); |
| 154 break; | 156 break; |
| 155 } | 157 } |
| 156 case FilterOperation::SEPIA: { | 158 case FilterOperation::SEPIA: { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 // Unlike SVG, filters applied here should not clip to their pri mitive subregions. | 245 // Unlike SVG, filters applied here should not clip to their pri mitive subregions. |
| 244 effect->setClipsToBounds(false); | 246 effect->setClipsToBounds(false); |
| 245 effect->setOperatingColorSpace(ColorSpaceDeviceRGB); | 247 effect->setOperatingColorSpace(ColorSpaceDeviceRGB); |
| 246 effect->inputEffects().append(previousEffect); | 248 effect->inputEffects().append(previousEffect); |
| 247 } | 249 } |
| 248 if (previousEffect->originTainted()) | 250 if (previousEffect->originTainted()) |
| 249 effect->setOriginTainted(); | 251 effect->setOriginTainted(); |
| 250 previousEffect = effect; | 252 previousEffect = effect; |
| 251 } | 253 } |
| 252 } | 254 } |
| 253 | 255 return previousEffect; |
| 254 // We need to keep the old effects alive until this point, so that SVG refer ence filters | |
| 255 // can share cached resources across frames. | |
| 256 m_lastEffect = previousEffect; | |
| 257 | |
| 258 // If we didn't make any effects, tell our caller we are not valid | |
| 259 if (!m_lastEffect.get()) | |
| 260 return false; | |
| 261 | |
| 262 return true; | |
| 263 } | 256 } |
| 264 | 257 |
| 265 Filter* FilterEffectBuilder::buildReferenceFilter( | 258 Filter* FilterEffectBuilder::buildReferenceFilter( |
|
Stephen White
2016/09/19 14:59:36
I wonder if we should now just have two constructo
fs
2016/09/20 08:17:28
My plan is one constructor and one buildReferenceF
| |
| 266 const ReferenceFilterOperation& referenceOperation, | 259 const ReferenceFilterOperation& referenceOperation, |
| 267 const FloatRect& zoomedReferenceBox, | 260 FilterEffect* previousEffect) const |
| 268 const SkPaint* fillPaint, | |
| 269 const SkPaint* strokePaint, | |
| 270 Element& element, | |
| 271 FilterEffect* previousEffect, | |
| 272 float zoom) | |
| 273 { | 261 { |
| 274 SVGFilterElement* filterElement = ReferenceFilterBuilder::resolveFilterRefer ence(referenceOperation, element); | 262 DCHECK(m_targetContext); |
| 263 SVGFilterElement* filterElement = ReferenceFilterBuilder::resolveFilterRefer ence(referenceOperation, *m_targetContext); | |
| 275 if (!filterElement) | 264 if (!filterElement) |
| 276 return nullptr; | 265 return nullptr; |
| 277 FloatRect referenceBox = zoomedReferenceBox; | 266 return buildReferenceFilter(*filterElement, previousEffect); |
| 278 referenceBox.scale(1.0f / zoom); | |
| 279 return buildReferenceFilter(*filterElement, referenceBox, fillPaint, strokeP aint, previousEffect, zoom); | |
| 280 } | 267 } |
| 281 | 268 |
| 282 Filter* FilterEffectBuilder::buildReferenceFilter( | 269 Filter* FilterEffectBuilder::buildReferenceFilter( |
| 283 SVGFilterElement& filterElement, | 270 SVGFilterElement& filterElement, |
| 284 const FloatRect& referenceBox, | |
| 285 const SkPaint* fillPaint, | |
| 286 const SkPaint* strokePaint, | |
| 287 FilterEffect* previousEffect, | 271 FilterEffect* previousEffect, |
| 288 float zoom, | 272 SVGFilterGraphNodeMap* nodeMap) const |
| 289 SVGFilterGraphNodeMap* nodeMap) | |
| 290 { | 273 { |
| 291 FloatRect filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement >(&filterElement, filterElement.filterUnits()->currentValue()->enumValue(), refe renceBox); | 274 FloatRect filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement >(&filterElement, filterElement.filterUnits()->currentValue()->enumValue(), m_re ferenceBox); |
| 292 // TODO(fs): We rely on the presence of a node map here to opt-in to the | 275 // TODO(fs): We rely on the presence of a node map here to opt-in to the |
| 293 // check for an empty filter region. The reason for this is that we lack a | 276 // check for an empty filter region. The reason for this is that we lack a |
| 294 // viewport to resolve against for HTML content. This is crbug.com/512453. | 277 // viewport to resolve against for HTML content. This is crbug.com/512453. |
| 295 if (nodeMap && filterRegion.isEmpty()) | 278 if (nodeMap && filterRegion.isEmpty()) |
| 296 return nullptr; | 279 return nullptr; |
| 297 | 280 |
| 298 bool primitiveBoundingBoxMode = filterElement.primitiveUnits()->currentValue ()->enumValue() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox; | 281 bool primitiveBoundingBoxMode = filterElement.primitiveUnits()->currentValue ()->enumValue() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox; |
| 299 Filter::UnitScaling unitScaling = primitiveBoundingBoxMode ? Filter::Boundin gBox : Filter::UserSpace; | 282 Filter::UnitScaling unitScaling = primitiveBoundingBoxMode ? Filter::Boundin gBox : Filter::UserSpace; |
| 300 Filter* result = Filter::create(referenceBox, filterRegion, zoom, unitScalin g); | 283 Filter* result = Filter::create(m_referenceBox, filterRegion, m_zoom, unitSc aling); |
| 301 if (!previousEffect) | 284 if (!previousEffect) |
| 302 previousEffect = result->getSourceGraphic(); | 285 previousEffect = result->getSourceGraphic(); |
| 303 SVGFilterBuilder builder(previousEffect, nodeMap, fillPaint, strokePaint); | 286 SVGFilterBuilder builder(previousEffect, nodeMap, m_fillPaint, m_strokePaint ); |
| 304 builder.buildGraph(result, filterElement, referenceBox); | 287 builder.buildGraph(result, filterElement, m_referenceBox); |
| 305 result->setLastEffect(builder.lastEffect()); | 288 result->setLastEffect(builder.lastEffect()); |
| 306 return result; | 289 return result; |
| 307 } | 290 } |
| 308 | 291 |
| 309 } // namespace blink | 292 } // namespace blink |
| 310 | 293 |
| OLD | NEW |