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 14 matching lines...) Expand all Loading... |
25 */ | 25 */ |
26 | 26 |
27 #include "core/paint/FilterEffectBuilder.h" | 27 #include "core/paint/FilterEffectBuilder.h" |
28 | 28 |
29 #include "core/layout/svg/ReferenceFilterBuilder.h" | 29 #include "core/layout/svg/ReferenceFilterBuilder.h" |
30 #include "core/svg/SVGFilterElement.h" | 30 #include "core/svg/SVGFilterElement.h" |
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/CompositorFilterOperations.h" |
35 #include "platform/graphics/filters/FEBoxReflect.h" | 36 #include "platform/graphics/filters/FEBoxReflect.h" |
36 #include "platform/graphics/filters/FEColorMatrix.h" | 37 #include "platform/graphics/filters/FEColorMatrix.h" |
37 #include "platform/graphics/filters/FEComponentTransfer.h" | 38 #include "platform/graphics/filters/FEComponentTransfer.h" |
38 #include "platform/graphics/filters/FEDropShadow.h" | 39 #include "platform/graphics/filters/FEDropShadow.h" |
39 #include "platform/graphics/filters/FEGaussianBlur.h" | 40 #include "platform/graphics/filters/FEGaussianBlur.h" |
40 #include "platform/graphics/filters/Filter.h" | 41 #include "platform/graphics/filters/Filter.h" |
41 #include "platform/graphics/filters/FilterEffect.h" | 42 #include "platform/graphics/filters/FilterEffect.h" |
42 #include "platform/graphics/filters/FilterOperations.h" | 43 #include "platform/graphics/filters/FilterOperations.h" |
| 44 #include "platform/graphics/filters/SkiaImageFilterBuilder.h" |
43 #include "platform/graphics/filters/SourceGraphic.h" | 45 #include "platform/graphics/filters/SourceGraphic.h" |
| 46 #include "public/platform/WebPoint.h" |
44 #include "wtf/MathExtras.h" | 47 #include "wtf/MathExtras.h" |
45 #include <algorithm> | 48 #include <algorithm> |
46 | 49 |
47 namespace blink { | 50 namespace blink { |
48 | 51 |
49 namespace { | 52 namespace { |
50 | 53 |
51 inline void endMatrixRow(Vector<float>& matrix) | 54 inline void endMatrixRow(Vector<float>& matrix) |
52 { | 55 { |
53 matrix.uncheckedAppend(0); | 56 matrix.uncheckedAppend(0); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 matrix.uncheckedAppend(clampTo<float>(0.131 + 0.869 * oneMinusAmount)); | 118 matrix.uncheckedAppend(clampTo<float>(0.131 + 0.869 * oneMinusAmount)); |
116 endMatrixRow(matrix); | 119 endMatrixRow(matrix); |
117 | 120 |
118 lastMatrixRow(matrix); | 121 lastMatrixRow(matrix); |
119 return matrix; | 122 return matrix; |
120 } | 123 } |
121 | 124 |
122 } // namespace | 125 } // namespace |
123 | 126 |
124 FilterEffectBuilder::FilterEffectBuilder( | 127 FilterEffectBuilder::FilterEffectBuilder( |
125 Element* target, | 128 Node* target, |
126 const FloatRect& zoomedReferenceBox, float zoom, | 129 const FloatRect& zoomedReferenceBox, float zoom, |
127 const SkPaint* fillPaint, const SkPaint* strokePaint) | 130 const SkPaint* fillPaint, const SkPaint* strokePaint) |
128 : m_targetContext(target) | 131 : m_targetContext(target) |
129 , m_referenceBox(zoomedReferenceBox) | 132 , m_referenceBox(zoomedReferenceBox) |
130 , m_zoom(zoom) | 133 , m_zoom(zoom) |
131 , m_fillPaint(fillPaint) | 134 , m_fillPaint(fillPaint) |
132 , m_strokePaint(strokePaint) | 135 , m_strokePaint(strokePaint) |
133 { | 136 { |
134 if (m_zoom != 1) | 137 if (m_zoom != 1) |
135 m_referenceBox.scale(1 / m_zoom); | 138 m_referenceBox.scale(1 / m_zoom); |
136 } | 139 } |
137 | 140 |
138 FilterEffect* FilterEffectBuilder::buildFilterEffect(const FilterOperations& ope
rations) const | 141 FilterEffect* FilterEffectBuilder::buildFilterEffect(const FilterOperations& ope
rations) const |
139 { | 142 { |
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. | 143 // 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. |
141 Filter* parentFilter = Filter::create(1.0f); | 144 Filter* parentFilter = Filter::create(1.0f); |
142 FilterEffect* previousEffect = parentFilter->getSourceGraphic(); | 145 FilterEffect* previousEffect = parentFilter->getSourceGraphic(); |
143 for (size_t i = 0; i < operations.operations().size(); ++i) { | 146 for (FilterOperation* filterOperation : operations.operations()) { |
144 FilterEffect* effect = nullptr; | 147 FilterEffect* effect = nullptr; |
145 FilterOperation* filterOperation = operations.operations().at(i).get(); | |
146 switch (filterOperation->type()) { | 148 switch (filterOperation->type()) { |
147 case FilterOperation::REFERENCE: { | 149 case FilterOperation::REFERENCE: { |
148 Filter* referenceFilter = buildReferenceFilter(toReferenceFilterOper
ation(*filterOperation), previousEffect); | 150 ReferenceFilterOperation& referenceOperation = toReferenceFilterOper
ation(*filterOperation); |
149 if (referenceFilter) | 151 if (Filter* referenceFilter = buildReferenceFilter(referenceOperatio
n, previousEffect)) { |
| 152 // TODO(fs): This is essentially only needed for the |
| 153 // side-effects (mapRect). The filter differs from the one |
| 154 // computed just above in what the SourceGraphic is, and how |
| 155 // it's connected to the filter-chain. |
| 156 referenceOperation.setFilter(buildReferenceFilter(referenceOpera
tion, nullptr)); |
150 effect = referenceFilter->lastEffect(); | 157 effect = referenceFilter->lastEffect(); |
| 158 } |
151 break; | 159 break; |
152 } | 160 } |
153 case FilterOperation::GRAYSCALE: { | 161 case FilterOperation::GRAYSCALE: { |
154 Vector<float> inputParameters = grayscaleMatrix(toBasicColorMatrixFi
lterOperation(filterOperation)->amount()); | 162 Vector<float> inputParameters = grayscaleMatrix(toBasicColorMatrixFi
lterOperation(filterOperation)->amount()); |
155 effect = FEColorMatrix::create(parentFilter, FECOLORMATRIX_TYPE_MATR
IX, inputParameters); | 163 effect = FEColorMatrix::create(parentFilter, FECOLORMATRIX_TYPE_MATR
IX, inputParameters); |
156 break; | 164 break; |
157 } | 165 } |
158 case FilterOperation::SEPIA: { | 166 case FilterOperation::SEPIA: { |
159 Vector<float> inputParameters = sepiaMatrix(toBasicColorMatrixFilter
Operation(filterOperation)->amount()); | 167 Vector<float> inputParameters = sepiaMatrix(toBasicColorMatrixFilter
Operation(filterOperation)->amount()); |
160 effect = FEColorMatrix::create(parentFilter, FECOLORMATRIX_TYPE_MATR
IX, inputParameters); | 168 effect = FEColorMatrix::create(parentFilter, FECOLORMATRIX_TYPE_MATR
IX, inputParameters); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 effect->inputEffects().append(previousEffect); | 256 effect->inputEffects().append(previousEffect); |
249 } | 257 } |
250 if (previousEffect->originTainted()) | 258 if (previousEffect->originTainted()) |
251 effect->setOriginTainted(); | 259 effect->setOriginTainted(); |
252 previousEffect = effect; | 260 previousEffect = effect; |
253 } | 261 } |
254 } | 262 } |
255 return previousEffect; | 263 return previousEffect; |
256 } | 264 } |
257 | 265 |
| 266 CompositorFilterOperations FilterEffectBuilder::buildFilterOperations(const Filt
erOperations& operations) const |
| 267 { |
| 268 ColorSpace currentColorSpace = ColorSpaceDeviceRGB; |
| 269 |
| 270 CompositorFilterOperations filters; |
| 271 for (FilterOperation* op : operations.operations()) { |
| 272 switch (op->type()) { |
| 273 case FilterOperation::REFERENCE: { |
| 274 ReferenceFilterOperation& referenceOperation = toReferenceFilterOper
ation(*op); |
| 275 Filter* referenceFilter = buildReferenceFilter(referenceOperation, n
ullptr); |
| 276 if (referenceFilter && referenceFilter->lastEffect()) { |
| 277 referenceOperation.setFilter(referenceFilter); |
| 278 SkiaImageFilterBuilder::populateSourceGraphicImageFilters(refere
nceFilter->getSourceGraphic(), nullptr, currentColorSpace); |
| 279 |
| 280 FilterEffect* filterEffect = referenceFilter->lastEffect(); |
| 281 currentColorSpace = filterEffect->operatingColorSpace(); |
| 282 filters.appendReferenceFilter(SkiaImageFilterBuilder::build(filt
erEffect, currentColorSpace)); |
| 283 } |
| 284 break; |
| 285 } |
| 286 case FilterOperation::GRAYSCALE: |
| 287 case FilterOperation::SEPIA: |
| 288 case FilterOperation::SATURATE: |
| 289 case FilterOperation::HUE_ROTATE: { |
| 290 float amount = toBasicColorMatrixFilterOperation(*op).amount(); |
| 291 switch (op->type()) { |
| 292 case FilterOperation::GRAYSCALE: |
| 293 filters.appendGrayscaleFilter(amount); |
| 294 break; |
| 295 case FilterOperation::SEPIA: |
| 296 filters.appendSepiaFilter(amount); |
| 297 break; |
| 298 case FilterOperation::SATURATE: |
| 299 filters.appendSaturateFilter(amount); |
| 300 break; |
| 301 case FilterOperation::HUE_ROTATE: |
| 302 filters.appendHueRotateFilter(amount); |
| 303 break; |
| 304 default: |
| 305 NOTREACHED(); |
| 306 } |
| 307 break; |
| 308 } |
| 309 case FilterOperation::INVERT: |
| 310 case FilterOperation::OPACITY: |
| 311 case FilterOperation::BRIGHTNESS: |
| 312 case FilterOperation::CONTRAST: { |
| 313 float amount = toBasicComponentTransferFilterOperation(*op).amount()
; |
| 314 switch (op->type()) { |
| 315 case FilterOperation::INVERT: |
| 316 filters.appendInvertFilter(amount); |
| 317 break; |
| 318 case FilterOperation::OPACITY: |
| 319 filters.appendOpacityFilter(amount); |
| 320 break; |
| 321 case FilterOperation::BRIGHTNESS: |
| 322 filters.appendBrightnessFilter(amount); |
| 323 break; |
| 324 case FilterOperation::CONTRAST: |
| 325 filters.appendContrastFilter(amount); |
| 326 break; |
| 327 default: |
| 328 NOTREACHED(); |
| 329 } |
| 330 break; |
| 331 } |
| 332 case FilterOperation::BLUR: { |
| 333 float pixelRadius = toBlurFilterOperation(*op).stdDeviation().getFlo
atValue(); |
| 334 filters.appendBlurFilter(pixelRadius); |
| 335 break; |
| 336 } |
| 337 case FilterOperation::DROP_SHADOW: { |
| 338 const DropShadowFilterOperation& drop = toDropShadowFilterOperation(
*op); |
| 339 filters.appendDropShadowFilter(WebPoint(drop.x(), drop.y()), drop.st
dDeviation(), drop.getColor().rgb()); |
| 340 break; |
| 341 } |
| 342 case FilterOperation::BOX_REFLECT: { |
| 343 // TODO(jbroman): Consider explaining box reflect to the compositor, |
| 344 // instead of calling this a "reference filter". |
| 345 const auto& reflection = toBoxReflectFilterOperation(*op).reflection
(); |
| 346 filters.appendReferenceFilter(SkiaImageFilterBuilder::buildBoxReflec
tFilter(reflection, nullptr)); |
| 347 break; |
| 348 } |
| 349 case FilterOperation::NONE: |
| 350 break; |
| 351 } |
| 352 } |
| 353 if (currentColorSpace != ColorSpaceDeviceRGB) { |
| 354 // Transform to device color space at the end of processing, if required
. |
| 355 sk_sp<SkImageFilter> filter = SkiaImageFilterBuilder::transformColorSpac
e(nullptr, currentColorSpace, ColorSpaceDeviceRGB); |
| 356 filters.appendReferenceFilter(std::move(filter)); |
| 357 } |
| 358 return filters; |
| 359 } |
| 360 |
258 Filter* FilterEffectBuilder::buildReferenceFilter( | 361 Filter* FilterEffectBuilder::buildReferenceFilter( |
259 const ReferenceFilterOperation& referenceOperation, | 362 const ReferenceFilterOperation& referenceOperation, |
260 FilterEffect* previousEffect) const | 363 FilterEffect* previousEffect) const |
261 { | 364 { |
262 DCHECK(m_targetContext); | 365 DCHECK(m_targetContext && m_targetContext->isElementNode()); |
263 SVGFilterElement* filterElement = ReferenceFilterBuilder::resolveFilterRefer
ence(referenceOperation, *m_targetContext); | 366 SVGFilterElement* filterElement = ReferenceFilterBuilder::resolveFilterRefer
ence(referenceOperation, toElement(*m_targetContext)); |
264 if (!filterElement) | 367 if (!filterElement) |
265 return nullptr; | 368 return nullptr; |
266 return buildReferenceFilter(*filterElement, previousEffect); | 369 return buildReferenceFilter(*filterElement, previousEffect); |
267 } | 370 } |
268 | 371 |
269 Filter* FilterEffectBuilder::buildReferenceFilter( | 372 Filter* FilterEffectBuilder::buildReferenceFilter( |
270 SVGFilterElement& filterElement, | 373 SVGFilterElement& filterElement, |
271 FilterEffect* previousEffect, | 374 FilterEffect* previousEffect, |
272 SVGFilterGraphNodeMap* nodeMap) const | 375 SVGFilterGraphNodeMap* nodeMap) const |
273 { | 376 { |
(...skipping 10 matching lines...) Expand all Loading... |
284 if (!previousEffect) | 387 if (!previousEffect) |
285 previousEffect = result->getSourceGraphic(); | 388 previousEffect = result->getSourceGraphic(); |
286 SVGFilterBuilder builder(previousEffect, nodeMap, m_fillPaint, m_strokePaint
); | 389 SVGFilterBuilder builder(previousEffect, nodeMap, m_fillPaint, m_strokePaint
); |
287 builder.buildGraph(result, filterElement, m_referenceBox); | 390 builder.buildGraph(result, filterElement, m_referenceBox); |
288 result->setLastEffect(builder.lastEffect()); | 391 result->setLastEffect(builder.lastEffect()); |
289 return result; | 392 return result; |
290 } | 393 } |
291 | 394 |
292 } // namespace blink | 395 } // namespace blink |
293 | 396 |
OLD | NEW |