diff options
9 files changed, 41 insertions, 11 deletions
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-filter-width-height-expected.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-filter-width-height-expected.html new file mode 100644 index 0000000..0e23e3f --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-filter-width-height-expected.html @@ -0,0 +1,7 @@ +<canvas id="canvas" width="100" height="100"></canvas> +<script> +var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +ctx.fillStyle = '#0f0'; +ctx.fillRect(0, 0, 50, 40); +</script> diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-filter-width-height.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-filter-width-height.html new file mode 100644 index 0000000..1185895 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-filter-width-height.html @@ -0,0 +1,17 @@ +<svg style="display: block; width: 0; height: 0"> + <defs> + <filter id="crop" primitiveUnits="objectBoundingBox"> + <femerge x="0" y="0" width="50%" height="40%"> + <femergenode in="SourceGraphic"></femergenode> + </femerge> + </filter> + </defs> +</svg> +<canvas id="canvas" width="100" height="100"></canvas> +<script> +var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +ctx.filter = 'url(#crop)'; +ctx.fillStyle = '#0f0'; +ctx.fillRect(0, 0, 90, 90); +</script> diff --git a/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.cpp b/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.cpp index 1f2ea90..ddba2fb 100644 --- a/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.cpp +++ b/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.cpp @@ -69,7 +69,7 @@ void ReferenceFilterBuilder::clearDocumentResourceReference(const FilterOperatio } #endif -PassRefPtrWillBeRawPtr<Filter> ReferenceFilterBuilder::build(float zoom, Element* element, FilterEffect* previousEffect, const ReferenceFilterOperation& filterOperation, const SkPaint* fillPaint, const SkPaint* strokePaint) +PassRefPtrWillBeRawPtr<Filter> ReferenceFilterBuilder::build(float zoom, Element* element, FilterEffect* previousEffect, const ReferenceFilterOperation& filterOperation, const FloatSize* referenceBoxSize, const SkPaint* fillPaint, const SkPaint* strokePaint) { TreeScope* treeScope = &element->treeScope(); @@ -101,8 +101,12 @@ PassRefPtrWillBeRawPtr<Filter> ReferenceFilterBuilder::build(float zoom, Element FloatRect referenceBox; if (element->inDocument() && element->layoutObject() && element->layoutObject()->enclosingLayer()) { - FloatSize size(element->layoutObject()->enclosingLayer()->physicalBoundingBoxIncludingReflectionAndStackingChildren(LayoutPoint()).size()); - referenceBox = FloatRect(FloatPoint(), size); + if (referenceBoxSize) { + referenceBox = FloatRect(FloatPoint(), *referenceBoxSize); + } else { + FloatSize size(element->layoutObject()->enclosingLayer()->physicalBoundingBoxIncludingReflectionAndStackingChildren(LayoutPoint()).size()); + referenceBox = FloatRect(FloatPoint(), size); + } } referenceBox.scale(1.0f / zoom); FloatRect filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement>(&filterElement, filterElement.filterUnits()->currentValue()->enumValue(), referenceBox); diff --git a/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.h b/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.h index 521e7fa..8212c0d 100644 --- a/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.h +++ b/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.h @@ -44,6 +44,7 @@ class Element; class Filter; class FilterEffect; class FilterOperation; +class FloatSize; class ReferenceFilterOperation; class ReferenceFilterBuilder { @@ -55,7 +56,7 @@ public: static void clearDocumentResourceReference(const FilterOperation*); #endif - static PassRefPtrWillBeRawPtr<Filter> build(float zoom, Element*, FilterEffect* previousEffect, const ReferenceFilterOperation&, const SkPaint* fillPaint = nullptr, const SkPaint* strokePaint = nullptr); + static PassRefPtrWillBeRawPtr<Filter> build(float zoom, Element*, FilterEffect* previousEffect, const ReferenceFilterOperation&, const FloatSize* referenceBoxSize = nullptr, const SkPaint* fillPaint = nullptr, const SkPaint* strokePaint = nullptr); }; } diff --git a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp index faabeec..f183593 100644 --- a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp +++ b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp @@ -130,7 +130,7 @@ DEFINE_TRACE(FilterEffectBuilder) visitor->trace(m_referenceFilters); } -bool FilterEffectBuilder::build(Element* element, const FilterOperations& operations, float zoom, const SkPaint* fillPaint, const SkPaint* strokePaint) +bool FilterEffectBuilder::build(Element* element, const FilterOperations& operations, float zoom, const FloatSize* referenceBoxSize, const SkPaint* fillPaint, const SkPaint* strokePaint) { // Create a parent filter for shorthand filters. These have already been scaled by the CSS code for page zoom, so scale is 1.0 here. RefPtrWillBeRawPtr<Filter> parentFilter = Filter::create(1.0f); @@ -140,7 +140,7 @@ bool FilterEffectBuilder::build(Element* element, const FilterOperations& operat FilterOperation* filterOperation = operations.operations().at(i).get(); switch (filterOperation->type()) { case FilterOperation::REFERENCE: { - RefPtrWillBeRawPtr<Filter> referenceFilter = ReferenceFilterBuilder::build(zoom, element, previousEffect.get(), toReferenceFilterOperation(*filterOperation), fillPaint, strokePaint); + RefPtrWillBeRawPtr<Filter> referenceFilter = ReferenceFilterBuilder::build(zoom, element, previousEffect.get(), toReferenceFilterOperation(*filterOperation), referenceBoxSize, fillPaint, strokePaint); if (referenceFilter) { effect = referenceFilter->lastEffect(); m_referenceFilters.append(referenceFilter); diff --git a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.h b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.h index 6e8da7b..9022ddf 100644 --- a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.h +++ b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.h @@ -53,7 +53,7 @@ public: virtual ~FilterEffectBuilder(); DECLARE_TRACE(); - bool build(Element*, const FilterOperations&, float zoom, const SkPaint* fillPaint = nullptr, const SkPaint* strokePaint = nullptr); + bool build(Element*, const FilterOperations&, float zoom, const FloatSize* referenceBoxSize = nullptr, const SkPaint* fillPaint = nullptr, const SkPaint* strokePaint = nullptr); PassRefPtrWillBeRawPtr<FilterEffect> lastEffect() const { diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp index 8cf6c19..c2b01b6 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp @@ -828,7 +828,7 @@ static bool isFullCanvasCompositeMode(SkXfermode::Mode op) template<typename DrawFunc> void CanvasRenderingContext2D::compositedDraw(const DrawFunc& drawFunc, SkCanvas* c, CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::ImageType imageType) { - SkImageFilter* filter = state().getFilter(canvas(), accessFont()); + SkImageFilter* filter = state().getFilter(canvas(), accessFont(), canvas()->size()); ASSERT(isFullCanvasCompositeMode(state().globalComposite()) || filter); SkMatrix ctm = c->getTotalMatrix(); c->resetMatrix(); diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.cpp index 71f1564..09b50bd 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.cpp @@ -341,7 +341,7 @@ void CanvasRenderingContext2DState::resetTransform() m_isTransformInvertible = true; } -SkImageFilter* CanvasRenderingContext2DState::getFilter(Element* styleResolutionHost, const Font& font) const +SkImageFilter* CanvasRenderingContext2DState::getFilter(Element* styleResolutionHost, const Font& font, IntSize canvasSize) const { if (!m_filterValue) return nullptr; @@ -365,8 +365,9 @@ SkImageFilter* CanvasRenderingContext2DState::getFilter(Element* styleResolution m_strokeStyle->applyToPaint(strokePaintForFilter); fillPaintForFilter.setColor(m_fillStyle->paintColor()); strokePaintForFilter.setColor(m_strokeStyle->paintColor()); + FloatSize floatCanvasSize(canvasSize); const double effectiveZoom = 1.0; // Deliberately ignore zoom on the canvas element - filterEffectBuilder->build(styleResolutionHost, filterStyle->filter(), effectiveZoom, &fillPaintForFilter, &strokePaintForFilter); + filterEffectBuilder->build(styleResolutionHost, filterStyle->filter(), effectiveZoom, &floatCanvasSize, &fillPaintForFilter, &strokePaintForFilter); SkiaImageFilterBuilder imageFilterBuilder; RefPtrWillBeRawPtr<FilterEffect> lastEffect = filterEffectBuilder->lastEffect(); diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.h b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.h index 326700a..df13ac9 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.h +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.h @@ -84,7 +84,7 @@ public: void setFilter(PassRefPtrWillBeRawPtr<CSSValue>); void setUnparsedFilter(const String& filterString) { m_unparsedFilter = filterString; } const String& unparsedFilter() const { return m_unparsedFilter; } - SkImageFilter* getFilter(Element*, const Font&) const; + SkImageFilter* getFilter(Element*, const Font&, IntSize canvasSize) const; bool hasFilter() const { return m_filterValue; } void setStrokeStyle(CanvasStyle*); |