diff options
Diffstat (limited to 'WebCore/platform/graphics/filters')
33 files changed, 255 insertions, 244 deletions
diff --git a/WebCore/platform/graphics/filters/FEBlend.cpp b/WebCore/platform/graphics/filters/FEBlend.cpp index 4185f61..1a40027 100644 --- a/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/WebCore/platform/graphics/filters/FEBlend.cpp @@ -98,13 +98,13 @@ void FEBlend::apply(Filter* filter) if (m_mode == FEBLEND_MODE_UNKNOWN) return; - if (!effectContext()) + if (!effectContext(filter)) return; - IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates()); + IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); - IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates()); + IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data()); IntRect imageRect(IntPoint(), resultImage()->size()); diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp index 86c37c2..b41d5ad 100644 --- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -160,11 +160,11 @@ void FEColorMatrix::apply(Filter* filter) if (!in->resultImage()) return; - GraphicsContext* filterContext = effectContext(); + GraphicsContext* filterContext = effectContext(filter); if (!filterContext) return; - filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates())); + filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); IntRect imageRect(IntPoint(), resultImage()->size()); PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect)); diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp index 6fe38e4..08d0b1f 100644 --- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp +++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp @@ -154,7 +154,7 @@ void FEComponentTransfer::apply(Filter* filter) if (!in->resultImage()) return; - if (!effectContext()) + if (!effectContext(filter)) return; unsigned char rValues[256], gValues[256], bValues[256], aValues[256]; @@ -167,7 +167,7 @@ void FEComponentTransfer::apply(Filter* filter) for (unsigned channel = 0; channel < 4; channel++) (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]); - IntRect drawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates()); + IntRect drawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<ImageData> imageData(in->resultImage()->getUnmultipliedImageData(drawingRect)); CanvasPixelArray* srcPixelArray(imageData->data()); diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp index 94e2524..2326966 100644 --- a/WebCore/platform/graphics/filters/FEComposite.cpp +++ b/WebCore/platform/graphics/filters/FEComposite.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> * Copyright (C) 2005 Eric Seidel <eric@webkit.org> * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> + * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -112,6 +113,27 @@ inline void arithmetic(const RefPtr<CanvasPixelArray>& srcPixelArrayA, CanvasPix } } } + +void FEComposite::determineAbsolutePaintRect(Filter* filter) +{ + switch (m_type) { + case FECOMPOSITE_OPERATOR_IN: + case FECOMPOSITE_OPERATOR_ATOP: + // For In and Atop the first effect just influences the result of + // the second effect. So just use the absolute paint rect of the second effect here. + setAbsolutePaintRect(inputEffect(1)->absolutePaintRect()); + return; + case FECOMPOSITE_OPERATOR_ARITHMETIC: + // Arithmetic may influnce the compele filter primitive region. So we can't + // optimize the paint region here. + setAbsolutePaintRect(maxEffectRect()); + return; + default: + // Take the union of both input effects. + FilterEffect::determineAbsolutePaintRect(filter); + return; + } +} void FEComposite::apply(Filter* filter) { @@ -122,39 +144,39 @@ void FEComposite::apply(Filter* filter) if (!in->resultImage() || !in2->resultImage()) return; - GraphicsContext* filterContext = effectContext(); + GraphicsContext* filterContext = effectContext(filter); if (!filterContext) return; FloatRect srcRect = FloatRect(0, 0, -1, -1); switch (m_type) { case FECOMPOSITE_OPERATOR_OVER: - filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates())); - filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates())); + filterContext->drawImageBuffer(in2->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); + filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); break; case FECOMPOSITE_OPERATOR_IN: filterContext->save(); - filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates())); - filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates())); + filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2->absolutePaintRect())); + filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); filterContext->restore(); break; case FECOMPOSITE_OPERATOR_OUT: - filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates())); - filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()), srcRect, CompositeDestinationOut); + filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); + filterContext->drawImageBuffer(in2->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()), srcRect, CompositeDestinationOut); break; case FECOMPOSITE_OPERATOR_ATOP: - filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates())); - filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()), srcRect, CompositeSourceAtop); + filterContext->drawImageBuffer(in2->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); + filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeSourceAtop); break; case FECOMPOSITE_OPERATOR_XOR: - filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates())); - filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()), srcRect, CompositeXOR); + filterContext->drawImageBuffer(in2->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); + filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeXOR); break; case FECOMPOSITE_OPERATOR_ARITHMETIC: { - IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates()); + IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); - IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates()); + IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); RefPtr<ImageData> imageData(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)); CanvasPixelArray* srcPixelArrayB(imageData->data()); diff --git a/WebCore/platform/graphics/filters/FEComposite.h b/WebCore/platform/graphics/filters/FEComposite.h index 82a3b06..ecdb037 100644 --- a/WebCore/platform/graphics/filters/FEComposite.h +++ b/WebCore/platform/graphics/filters/FEComposite.h @@ -61,6 +61,8 @@ public: virtual void apply(Filter*); virtual void dump(); + + virtual void determineAbsolutePaintRect(Filter*); virtual TextStream& externalRepresentation(TextStream&, int indention) const; diff --git a/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp b/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp index dd66c6a..d487a47 100644 --- a/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp +++ b/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp @@ -377,11 +377,11 @@ void FEConvolveMatrix::apply(Filter* filter) if (!in->resultImage()) return; - if (!effectContext()) + if (!effectContext(filter)) return; IntRect imageRect(IntPoint(), resultImage()->size()); - IntRect effectDrawingRect = requestedRegionOfInputImageData(in->filterPrimitiveSubregion()); + IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<CanvasPixelArray> srcPixelArray; if (m_preserveAlpha) diff --git a/WebCore/platform/graphics/filters/FEConvolveMatrix.h b/WebCore/platform/graphics/filters/FEConvolveMatrix.h index 2fe634f..8d3439e 100644 --- a/WebCore/platform/graphics/filters/FEConvolveMatrix.h +++ b/WebCore/platform/graphics/filters/FEConvolveMatrix.h @@ -75,6 +75,8 @@ public: virtual void apply(Filter*); virtual void dump(); + virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } + virtual TextStream& externalRepresentation(TextStream&, int indention) const; private: diff --git a/WebCore/platform/graphics/filters/FEDisplacementMap.cpp b/WebCore/platform/graphics/filters/FEDisplacementMap.cpp index 6b5dbaa..0c53241 100644 --- a/WebCore/platform/graphics/filters/FEDisplacementMap.cpp +++ b/WebCore/platform/graphics/filters/FEDisplacementMap.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> * Copyright (C) 2005 Eric Seidel <eric@webkit.org> * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> + * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -88,13 +89,13 @@ void FEDisplacementMap::apply(Filter* filter) if (m_xChannelSelector == CHANNEL_UNKNOWN || m_yChannelSelector == CHANNEL_UNKNOWN) return; - if (!effectContext()) + if (!effectContext(filter)) return; - IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates()); + IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); - IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates()); + IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect)->data()); IntRect imageRect(IntPoint(), resultImage()->size()); @@ -102,10 +103,10 @@ void FEDisplacementMap::apply(Filter* filter) ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length()); - float scaleX = m_scale / 255.f * filter->filterResolution().width(); - float scaleY = m_scale / 255.f * filter->filterResolution().height(); - float scaleAdjustmentX = (0.5f - 0.5f * m_scale) * filter->filterResolution().width(); - float scaleAdjustmentY = (0.5f - 0.5f * m_scale) * filter->filterResolution().height(); + float scaleX = filter->applyHorizontalScale(m_scale / 255); + float scaleY = filter->applyVerticalScale(m_scale / 255); + float scaleAdjustmentX = filter->applyHorizontalScale(0.5f - 0.5f * m_scale); + float scaleAdjustmentY = filter->applyVerticalScale(0.5f - 0.5f * m_scale); int stride = imageRect.width() * 4; for (int y = 0; y < imageRect.height(); ++y) { int line = y * stride; diff --git a/WebCore/platform/graphics/filters/FEDisplacementMap.h b/WebCore/platform/graphics/filters/FEDisplacementMap.h index dc87b90..c5b97a7 100644 --- a/WebCore/platform/graphics/filters/FEDisplacementMap.h +++ b/WebCore/platform/graphics/filters/FEDisplacementMap.h @@ -53,6 +53,8 @@ public: virtual void apply(Filter*); virtual void dump(); + virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } + virtual TextStream& externalRepresentation(TextStream&, int indention) const; private: diff --git a/WebCore/platform/graphics/filters/FEFlood.cpp b/WebCore/platform/graphics/filters/FEFlood.cpp index 7804d89..b51a422 100644 --- a/WebCore/platform/graphics/filters/FEFlood.cpp +++ b/WebCore/platform/graphics/filters/FEFlood.cpp @@ -62,14 +62,14 @@ void FEFlood::setFloodOpacity(float floodOpacity) m_floodOpacity = floodOpacity; } -void FEFlood::apply(Filter*) +void FEFlood::apply(Filter* filter) { - GraphicsContext* filterContext = effectContext(); + GraphicsContext* filterContext = effectContext(filter); if (!filterContext) return; Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity()); - filterContext->fillRect(FloatRect(FloatPoint(), repaintRectInLocalCoordinates().size()), color, DeviceColorSpace); + filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, ColorSpaceDeviceRGB); } void FEFlood::dump() diff --git a/WebCore/platform/graphics/filters/FEFlood.h b/WebCore/platform/graphics/filters/FEFlood.h index b615531..e6a9574 100644 --- a/WebCore/platform/graphics/filters/FEFlood.h +++ b/WebCore/platform/graphics/filters/FEFlood.h @@ -42,6 +42,8 @@ public: virtual void apply(Filter*); virtual void dump(); + virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } + virtual TextStream& externalRepresentation(TextStream&, int indention) const; private: diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp index fd9a3d8..1f36ba7 100644 --- a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp +++ b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp @@ -4,6 +4,7 @@ * Copyright (C) 2005 Eric Seidel <eric@webkit.org> * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> * Copyright (C) 2010 Igalia, S.L. + * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -34,7 +35,8 @@ using std::max; -static const float gGaussianKernelFactor = (3 * sqrtf(2 * piFloat) / 4.f); +static const float gGaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat); +static const unsigned gMaxKernelSize = 1000; namespace WebCore { @@ -97,7 +99,7 @@ static void boxBlur(CanvasPixelArray*& srcPixelArray, CanvasPixelArray*& dstPixe } } -void FEGaussianBlur::kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight) +inline void kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight) { // check http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement for details switch (boxBlur) { @@ -125,6 +127,41 @@ void FEGaussianBlur::kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& } } +inline void calculateKernelSize(Filter* filter, unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY) +{ + stdX = filter->applyHorizontalScale(stdX); + stdY = filter->applyVerticalScale(stdY); + + kernelSizeX = 0; + if (stdX) + kernelSizeX = max<unsigned>(2, static_cast<unsigned>(floorf(stdX * gGaussianKernelFactor + 0.5f))); + kernelSizeY = 0; + if (stdY) + kernelSizeY = max<unsigned>(2, static_cast<unsigned>(floorf(stdY * gGaussianKernelFactor + 0.5f))); + + // Limit the kernel size to 1000. A bigger radius won't make a big difference for the result image but + // inflates the absolute paint rect to much. This is compatible with Firefox' behavior. + if (kernelSizeX > gMaxKernelSize) + kernelSizeX = gMaxKernelSize; + if (kernelSizeY > gMaxKernelSize) + kernelSizeY = gMaxKernelSize; +} + +void FEGaussianBlur::determineAbsolutePaintRect(Filter* filter) +{ + FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); + absolutePaintRect.intersect(maxEffectRect()); + + unsigned kernelSizeX = 0; + unsigned kernelSizeY = 0; + calculateKernelSize(filter, kernelSizeX, kernelSizeY, m_stdX, m_stdY); + + // We take the half kernel size and multiply it with three, because we run box blur three times. + absolutePaintRect.inflateX(3 * kernelSizeX * 0.5f); + absolutePaintRect.inflateY(3 * kernelSizeY * 0.5f); + setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); +} + void FEGaussianBlur::apply(Filter* filter) { FilterEffect* in = inputEffect(0); @@ -132,12 +169,12 @@ void FEGaussianBlur::apply(Filter* filter) if (!in->resultImage()) return; - if (!effectContext()) + if (!effectContext(filter)) return; setIsAlphaImage(in->isAlphaImage()); - IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates()); + IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<ImageData> srcImageData(in->resultImage()->getPremultipliedImageData(effectDrawingRect)); IntRect imageRect(IntPoint(), resultImage()->size()); @@ -147,12 +184,8 @@ void FEGaussianBlur::apply(Filter* filter) } unsigned kernelSizeX = 0; - if (m_stdX) - kernelSizeX = max(2U, static_cast<unsigned>(floor(m_stdX * filter->filterResolution().width() * gGaussianKernelFactor + 0.5f))); - unsigned kernelSizeY = 0; - if (m_stdY) - kernelSizeY = max(2U, static_cast<unsigned>(floor(m_stdY * filter->filterResolution().height() * gGaussianKernelFactor + 0.5f))); + calculateKernelSize(filter, kernelSizeX, kernelSizeY, m_stdX, m_stdY); CanvasPixelArray* srcPixelArray(srcImageData->data()); RefPtr<ImageData> tmpImageData = ImageData::create(imageRect.width(), imageRect.height()); diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.h b/WebCore/platform/graphics/filters/FEGaussianBlur.h index 745bcc8..50fc610 100644 --- a/WebCore/platform/graphics/filters/FEGaussianBlur.h +++ b/WebCore/platform/graphics/filters/FEGaussianBlur.h @@ -42,12 +42,13 @@ public: virtual void apply(Filter*); virtual void dump(); + + virtual void determineAbsolutePaintRect(Filter*); virtual TextStream& externalRepresentation(TextStream&, int indention) const; private: FEGaussianBlur(float, float); - static void kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight); float m_stdX; float m_stdY; diff --git a/WebCore/platform/graphics/filters/FELighting.cpp b/WebCore/platform/graphics/filters/FELighting.cpp index f49b67d..e1df580 100644 --- a/WebCore/platform/graphics/filters/FELighting.cpp +++ b/WebCore/platform/graphics/filters/FELighting.cpp @@ -247,12 +247,12 @@ void FELighting::apply(Filter* filter) if (!in->resultImage()) return; - if (!effectContext()) + if (!effectContext(filter)) return; setIsAlphaImage(false); - IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates()); + IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<ImageData> srcImageData(in->resultImage()->getUnmultipliedImageData(effectDrawingRect)); CanvasPixelArray* srcPixelArray(srcImageData->data()); @@ -261,8 +261,9 @@ void FELighting::apply(Filter* filter) // output for various kernelUnitLengths, and I am not sure they are reliable. // Anyway, feConvolveMatrix should also use the implementation - if (drawLighting(srcPixelArray, effectDrawingRect.width(), effectDrawingRect.height())) - resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint()); + IntSize absolutePaintSize = absolutePaintRect().size(); + if (drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height())) + resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), absolutePaintSize), IntPoint()); } } // namespace WebCore diff --git a/WebCore/platform/graphics/filters/FELighting.h b/WebCore/platform/graphics/filters/FELighting.h index 28c00c4..bd56cee 100644 --- a/WebCore/platform/graphics/filters/FELighting.h +++ b/WebCore/platform/graphics/filters/FELighting.h @@ -44,6 +44,8 @@ class FELighting : public FilterEffect { public: virtual void apply(Filter*); + virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } + protected: enum LightingType { DiffuseLighting, diff --git a/WebCore/platform/graphics/filters/FEMerge.cpp b/WebCore/platform/graphics/filters/FEMerge.cpp index 19c832a..b136af3 100644 --- a/WebCore/platform/graphics/filters/FEMerge.cpp +++ b/WebCore/platform/graphics/filters/FEMerge.cpp @@ -50,13 +50,13 @@ void FEMerge::apply(Filter* filter) return; } - GraphicsContext* filterContext = effectContext(); + GraphicsContext* filterContext = effectContext(filter); if (!filterContext) return; for (unsigned i = 0; i < size; ++i) { FilterEffect* in = inputEffect(i); - filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates())); + filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); } } diff --git a/WebCore/platform/graphics/filters/FEMorphology.cpp b/WebCore/platform/graphics/filters/FEMorphology.cpp index 7329e1e..ac26441 100644 --- a/WebCore/platform/graphics/filters/FEMorphology.cpp +++ b/WebCore/platform/graphics/filters/FEMorphology.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> * Copyright (C) 2005 Eric Seidel <eric@webkit.org> * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> + * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -74,6 +75,15 @@ float FEMorphology::radiusY() const return m_radiusY; } +void FEMorphology::determineAbsolutePaintRect(Filter* filter) +{ + FloatRect paintRect = inputEffect(0)->absolutePaintRect(); + paintRect.inflateX(filter->applyHorizontalScale(m_radiusX)); + paintRect.inflateY(filter->applyVerticalScale(m_radiusY)); + paintRect.intersect(maxEffectRect()); + setAbsolutePaintRect(enclosingIntRect(paintRect)); +} + void FEMorphology::setRadiusY(float radiusY) { m_radiusY = radiusY; @@ -86,18 +96,18 @@ void FEMorphology::apply(Filter* filter) if (!in->resultImage()) return; - if (!effectContext()) + if (!effectContext(filter)) return; setIsAlphaImage(in->isAlphaImage()); - - int radiusX = static_cast<int>(m_radiusX * filter->filterResolution().width()); - int radiusY = static_cast<int>(m_radiusY * filter->filterResolution().height()); - if (radiusX <= 0 || radiusY <= 0) + if (m_radiusX <= 0 || m_radiusY <= 0) return; + int radiusX = static_cast<int>(floorf(filter->applyHorizontalScale(m_radiusX))); + int radiusY = static_cast<int>(floorf(filter->applyVerticalScale(m_radiusY))); + IntRect imageRect(IntPoint(), resultImage()->size()); - IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates()); + IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<CanvasPixelArray> srcPixelArray(in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data()); RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height()); diff --git a/WebCore/platform/graphics/filters/FEMorphology.h b/WebCore/platform/graphics/filters/FEMorphology.h index c8ce058..913671d 100644 --- a/WebCore/platform/graphics/filters/FEMorphology.h +++ b/WebCore/platform/graphics/filters/FEMorphology.h @@ -49,6 +49,8 @@ public: virtual void apply(Filter*); virtual void dump(); + virtual void determineAbsolutePaintRect(Filter*); + virtual TextStream& externalRepresentation(TextStream&, int indention) const; private: diff --git a/WebCore/platform/graphics/filters/FEOffset.cpp b/WebCore/platform/graphics/filters/FEOffset.cpp index ea84cf0..6ca56aa 100644 --- a/WebCore/platform/graphics/filters/FEOffset.cpp +++ b/WebCore/platform/graphics/filters/FEOffset.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> * Copyright (C) 2005 Eric Seidel <eric@webkit.org> * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> + * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -62,6 +63,14 @@ void FEOffset::setDy(float dy) m_dy = dy; } +void FEOffset::determineAbsolutePaintRect(Filter* filter) +{ + FloatRect paintRect = inputEffect(0)->absolutePaintRect(); + paintRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); + paintRect.intersect(maxEffectRect()); + setAbsolutePaintRect(enclosingIntRect(paintRect)); +} + void FEOffset::apply(Filter* filter) { FilterEffect* in = inputEffect(0); @@ -69,28 +78,15 @@ void FEOffset::apply(Filter* filter) if (!in->resultImage()) return; - GraphicsContext* filterContext = effectContext(); + GraphicsContext* filterContext = effectContext(filter); if (!filterContext) return; setIsAlphaImage(in->isAlphaImage()); - FloatRect sourceImageRect = filter->sourceImageRect(); - sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); - - if (filter->effectBoundingBoxMode()) { - m_dx *= sourceImageRect.width(); - m_dy *= sourceImageRect.height(); - } - m_dx *= filter->filterResolution().width(); - m_dy *= filter->filterResolution().height(); - - FloatRect dstRect = FloatRect(m_dx + in->repaintRectInLocalCoordinates().x() - repaintRectInLocalCoordinates().x(), - m_dy + in->repaintRectInLocalCoordinates().y() - repaintRectInLocalCoordinates().y(), - in->repaintRectInLocalCoordinates().width(), - in->repaintRectInLocalCoordinates().height()); - - filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, dstRect); + FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); + drawingRegion.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); + filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegion); } void FEOffset::dump() diff --git a/WebCore/platform/graphics/filters/FEOffset.h b/WebCore/platform/graphics/filters/FEOffset.h index 052ba74..36575c5 100644 --- a/WebCore/platform/graphics/filters/FEOffset.h +++ b/WebCore/platform/graphics/filters/FEOffset.h @@ -40,6 +40,8 @@ public: virtual void apply(Filter*); virtual void dump(); + + virtual void determineAbsolutePaintRect(Filter*); virtual TextStream& externalRepresentation(TextStream&, int indention) const; diff --git a/WebCore/platform/graphics/filters/FETile.cpp b/WebCore/platform/graphics/filters/FETile.cpp index 41abd34..a695d3b 100644 --- a/WebCore/platform/graphics/filters/FETile.cpp +++ b/WebCore/platform/graphics/filters/FETile.cpp @@ -27,6 +27,7 @@ #include "Filter.h" #include "GraphicsContext.h" #include "Pattern.h" +#include "SVGImageBufferTools.h" namespace WebCore { @@ -44,45 +45,51 @@ FloatRect FETile::determineFilterPrimitiveSubregion(Filter* filter) { inputEffect(0)->determineFilterPrimitiveSubregion(filter); - filter->determineFilterPrimitiveSubregion(this, filter->filterRegion()); + filter->determineFilterPrimitiveSubregion(this, filter->filterRegionInUserSpace()); return filterPrimitiveSubregion(); } void FETile::apply(Filter* filter) { +// FIXME: See bug 47315. This is a hack to work around a compile failure, but is incorrect behavior otherwise. +#if ENABLE(SVG) FilterEffect* in = inputEffect(0); in->apply(filter); if (!in->resultImage()) return; - GraphicsContext* filterContext = effectContext(); + GraphicsContext* filterContext = effectContext(filter); if (!filterContext) return; setIsAlphaImage(in->isAlphaImage()); - IntRect tileRect = enclosingIntRect(in->repaintRectInLocalCoordinates()); - // Source input needs more attention. It has the size of the filterRegion but gives the // size of the cutted sourceImage back. This is part of the specification and optimization. - if (in->isSourceInput()) { - FloatRect filterRegion = filter->filterRegion(); - filterRegion.scale(filter->filterResolution().width(), filter->filterResolution().height()); - tileRect = enclosingIntRect(filterRegion); + FloatRect tileRect = in->maxEffectRect(); + FloatPoint inMaxEffectLocation = tileRect.location(); + FloatPoint maxEffectLocation = maxEffectRect().location(); + if (in->filterEffectType() == FilterEffectTypeSourceInput) { + tileRect = filter->filterRegion(); + tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); } - OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(tileRect.size()); + OwnPtr<ImageBuffer> tileImage; + if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, ColorSpaceDeviceRGB)) + return; + GraphicsContext* tileImageContext = tileImage->context(); - tileImageContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, IntPoint()); - RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true); + tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y()); + tileImageContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, in->absolutePaintRect().location()); - AffineTransform matrix; - matrix.translate(in->repaintRectInLocalCoordinates().x() - repaintRectInLocalCoordinates().x(), - in->repaintRectInLocalCoordinates().y() - repaintRectInLocalCoordinates().y()); - pattern.get()->setPatternSpaceTransform(matrix); + RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true); + AffineTransform patternTransform; + patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y()); + pattern->setPatternSpaceTransform(patternTransform); filterContext->setFillPattern(pattern); - filterContext->fillRect(FloatRect(FloatPoint(), repaintRectInLocalCoordinates().size())); + filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size())); +#endif } void FETile::dump() @@ -103,4 +110,3 @@ TextStream& FETile::externalRepresentation(TextStream& ts, int indent) const } // namespace WebCore #endif // ENABLE(FILTERS) - diff --git a/WebCore/platform/graphics/filters/FETile.h b/WebCore/platform/graphics/filters/FETile.h index 20efbcd..8562c90 100644 --- a/WebCore/platform/graphics/filters/FETile.h +++ b/WebCore/platform/graphics/filters/FETile.h @@ -35,6 +35,8 @@ public: virtual void apply(Filter*); virtual void dump(); + virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } + virtual TextStream& externalRepresentation(TextStream&, int indention) const; virtual FloatRect determineFilterPrimitiveSubregion(Filter*); diff --git a/WebCore/platform/graphics/filters/FETurbulence.cpp b/WebCore/platform/graphics/filters/FETurbulence.cpp index bb24362..b1494a5 100644 --- a/WebCore/platform/graphics/filters/FETurbulence.cpp +++ b/WebCore/platform/graphics/filters/FETurbulence.cpp @@ -321,7 +321,7 @@ unsigned char FETurbulence::calculateTurbulenceValueForPoint(PaintingData& paint void FETurbulence::apply(Filter* filter) { - if (!effectContext()) + if (!effectContext(filter)) return; IntRect imageRect(IntPoint(), resultImage()->size()); @@ -329,10 +329,10 @@ void FETurbulence::apply(Filter* filter) return; RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height()); - PaintingData paintingData(m_seed, imageRect.size()); + PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size())); initPaint(paintingData); - FloatRect filterRegion = filter->filterRegion(); + FloatRect filterRegion = absolutePaintRect(); FloatPoint point; point.setY(filterRegion.y()); int indexOfPixelChannel = 0; @@ -342,7 +342,7 @@ void FETurbulence::apply(Filter* filter) for (int x = 0; x < imageRect.width(); ++x) { point.setX(point.x() + 1); for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel) - imageData->data()->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, point)); + imageData->data()->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, filter->mapAbsolutePointToLocalPoint(point))); } } resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint()); diff --git a/WebCore/platform/graphics/filters/FETurbulence.h b/WebCore/platform/graphics/filters/FETurbulence.h index 1a5a28a..c15d7d1 100644 --- a/WebCore/platform/graphics/filters/FETurbulence.h +++ b/WebCore/platform/graphics/filters/FETurbulence.h @@ -60,6 +60,8 @@ public: virtual void apply(Filter*); virtual void dump(); + + virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } virtual TextStream& externalRepresentation(TextStream&, int indention) const; diff --git a/WebCore/platform/graphics/filters/Filter.h b/WebCore/platform/graphics/filters/Filter.h index bce4be3..121e389 100644 --- a/WebCore/platform/graphics/filters/Filter.h +++ b/WebCore/platform/graphics/filters/Filter.h @@ -44,11 +44,18 @@ namespace WebCore { FloatSize filterResolution() const { return m_filterResolution; } void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; } + virtual float applyHorizontalScale(float value) const { return value * m_filterResolution.width(); } + virtual float applyVerticalScale(float value) const { return value * m_filterResolution.height(); } + virtual FloatRect sourceImageRect() const = 0; virtual FloatRect filterRegion() const = 0; + + virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint&) const { return FloatPoint(); } // SVG specific virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&) { } + + virtual FloatRect filterRegionInUserSpace() const { return FloatRect(); } virtual FloatSize maxImageSize() const = 0; virtual bool effectBoundingBoxMode() const = 0; diff --git a/WebCore/platform/graphics/filters/FilterEffect.cpp b/WebCore/platform/graphics/filters/FilterEffect.cpp index 461b22a..121b921 100644 --- a/WebCore/platform/graphics/filters/FilterEffect.cpp +++ b/WebCore/platform/graphics/filters/FilterEffect.cpp @@ -46,7 +46,7 @@ FloatRect FilterEffect::determineFilterPrimitiveSubregion(Filter* filter) // FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect. if (!size) - uniteRect = filter->filterRegion(); + uniteRect = filter->filterRegionInUserSpace(); else { for (unsigned i = 0; i < size; ++i) uniteRect.unite(m_inputEffects.at(i)->determineFilterPrimitiveSubregion(filter)); @@ -56,18 +56,29 @@ FloatRect FilterEffect::determineFilterPrimitiveSubregion(Filter* filter) return m_filterPrimitiveSubregion; } -IntRect FilterEffect::requestedRegionOfInputImageData(const FloatRect& effectRect) const +void FilterEffect::determineAbsolutePaintRect(Filter*) +{ + m_absolutePaintRect = IntRect(); + unsigned size = m_inputEffects.size(); + for (unsigned i = 0; i < size; ++i) + m_absolutePaintRect.unite(m_inputEffects.at(i)->absolutePaintRect()); + + // SVG specification wants us to clip to primitive subregion. + m_absolutePaintRect.intersect(m_maxEffectRect); +} + +IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect) const { ASSERT(m_effectBuffer); - FloatPoint location = m_repaintRectInLocalCoordinates.location(); + IntPoint location = m_absolutePaintRect.location(); location.move(-effectRect.x(), -effectRect.y()); - return IntRect(roundedIntPoint(location), m_effectBuffer->size()); + return IntRect(location, m_effectBuffer->size()); } -FloatRect FilterEffect::drawingRegionOfInputImage(const FloatRect& srcRect) const +IntRect FilterEffect::drawingRegionOfInputImage(const IntRect& srcRect) const { - return FloatRect(FloatPoint(srcRect.x() - m_repaintRectInLocalCoordinates.x(), - srcRect.y() - m_repaintRectInLocalCoordinates.y()), srcRect.size()); + return IntRect(IntPoint(srcRect.x() - m_absolutePaintRect.x(), + srcRect.y() - m_absolutePaintRect.y()), srcRect.size()); } FilterEffect* FilterEffect::inputEffect(unsigned number) const @@ -76,10 +87,12 @@ FilterEffect* FilterEffect::inputEffect(unsigned number) const return m_inputEffects.at(number).get(); } -GraphicsContext* FilterEffect::effectContext() +GraphicsContext* FilterEffect::effectContext(Filter* filter) { - IntRect bufferRect = enclosingIntRect(m_repaintRectInLocalCoordinates); - m_effectBuffer = ImageBuffer::create(bufferRect.size(), LinearRGB); + determineAbsolutePaintRect(filter); + if (m_absolutePaintRect.isEmpty()) + return 0; + m_effectBuffer = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB); if (!m_effectBuffer) return 0; return m_effectBuffer->context(); diff --git a/WebCore/platform/graphics/filters/FilterEffect.h b/WebCore/platform/graphics/filters/FilterEffect.h index ebe1880..a614b59 100644 --- a/WebCore/platform/graphics/filters/FilterEffect.h +++ b/WebCore/platform/graphics/filters/FilterEffect.h @@ -39,6 +39,13 @@ namespace WebCore { typedef Vector<RefPtr<FilterEffect> > FilterEffectVector; +enum FilterEffectType { + FilterEffectTypeUnknown, + FilterEffectTypeImage, + FilterEffectTypeTile, + FilterEffectTypeSourceInput +}; + class FilterEffect : public RefCounted<FilterEffect> { public: virtual ~FilterEffect(); @@ -49,26 +56,31 @@ public: // Creates the ImageBuffer for the current filter primitive result in the size of the // repaintRect. Gives back the GraphicsContext of the own ImageBuffer. - GraphicsContext* effectContext(); + GraphicsContext* effectContext(Filter*); FilterEffectVector& inputEffects() { return m_inputEffects; } FilterEffect* inputEffect(unsigned) const; unsigned numberOfEffectInputs() const { return m_inputEffects.size(); } - FloatRect drawingRegionOfInputImage(const FloatRect&) const; - IntRect requestedRegionOfInputImageData(const FloatRect&) const; + IntRect drawingRegionOfInputImage(const IntRect&) const; + IntRect requestedRegionOfInputImageData(const IntRect&) const; // Solid black image with different alpha values. bool isAlphaImage() const { return m_alphaImage; } void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; } - FloatRect repaintRectInLocalCoordinates() const { return m_repaintRectInLocalCoordinates; } - void setRepaintRectInLocalCoordinates(const FloatRect& repaintRectInLocalCoordinates) { m_repaintRectInLocalCoordinates = repaintRectInLocalCoordinates; } + IntRect absolutePaintRect() const { return m_absolutePaintRect; } + void setAbsolutePaintRect(const IntRect& absolutePaintRect) { m_absolutePaintRect = absolutePaintRect; } + + IntRect maxEffectRect() const { return m_maxEffectRect; } + void setMaxEffectRect(const IntRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; } virtual void apply(Filter*) = 0; virtual void dump() = 0; - virtual bool isSourceInput() const { return false; } + virtual void determineAbsolutePaintRect(Filter*); + + virtual FilterEffectType filterEffectType() const { return FilterEffectTypeUnknown; } virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const; @@ -87,7 +99,7 @@ public: bool hasHeight() const { return m_hasHeight; } void setHasHeight(bool value) { m_hasHeight = value; } - // FIXME: Pseudo primitives like SourceGraphic and SourceAlpha as well as FETile still need special handling. + // FIXME: FETile still needs special handling. virtual FloatRect determineFilterPrimitiveSubregion(Filter*); FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; } @@ -105,8 +117,11 @@ private: bool m_alphaImage; - // FIXME: Should be the paint region of the filter primitive, instead of the scaled subregion on use of filterRes. - FloatRect m_repaintRectInLocalCoordinates; + IntRect m_absolutePaintRect; + + // The maximum size of a filter primitive. In SVG this is the primitive subregion in absolute coordinate space. + // The absolute paint rect should never be bigger than m_maxEffectRect. + IntRect m_maxEffectRect; private: // The following member variables are SVG specific and will move to RenderSVGResourceFilterPrimitive. diff --git a/WebCore/platform/graphics/filters/ImageBufferFilter.cpp b/WebCore/platform/graphics/filters/ImageBufferFilter.cpp deleted file mode 100644 index 12407f8..0000000 --- a/WebCore/platform/graphics/filters/ImageBufferFilter.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> - * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#if ENABLE(FILTERS) -#include "ImageBufferFilter.h" - -#include "FloatSize.h" - -namespace WebCore { - -ImageBufferFilter::ImageBufferFilter() - : Filter() -{ - setFilterResolution(FloatSize(1.f, 1.f)); -} - -PassRefPtr<ImageBufferFilter> ImageBufferFilter::create() -{ - return adoptRef(new ImageBufferFilter()); -} - -} // namespace WebCore - -#endif // ENABLE(FILTERS) diff --git a/WebCore/platform/graphics/filters/ImageBufferFilter.h b/WebCore/platform/graphics/filters/ImageBufferFilter.h deleted file mode 100644 index cd4bc2f..0000000 --- a/WebCore/platform/graphics/filters/ImageBufferFilter.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> - * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef ImageBufferFilter_h -#define ImageBufferFilter_h - -#if ENABLE(FILTERS) -#include "Filter.h" -#include "FilterEffect.h" -#include "FloatRect.h" -#include "FloatSize.h" - -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> - -namespace WebCore { - -class ImageBufferFilter : public Filter { -public: - static PassRefPtr<ImageBufferFilter> create(); - - virtual FloatRect filterRegion() const { return FloatRect(); } - virtual FloatRect sourceImageRect() const { return FloatRect(); } - - // SVG specific - virtual bool effectBoundingBoxMode() const { return false; } - - virtual FloatSize maxImageSize() const { return FloatSize(); } - virtual void calculateEffectSubRegion(FilterEffect*) { } - -private: - ImageBufferFilter(); -}; - -} // namespace WebCore - -#endif // ENABLE(FILTERS) - -#endif // ImageBufferFilter_h diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp index beaf2e7..7dc56d9 100644 --- a/WebCore/platform/graphics/filters/SourceAlpha.cpp +++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp @@ -42,31 +42,25 @@ const AtomicString& SourceAlpha::effectName() return s_effectName; } -FloatRect SourceAlpha::determineFilterPrimitiveSubregion(Filter* filter) +void SourceAlpha::determineAbsolutePaintRect(Filter* filter) { - FloatRect clippedSourceRect = filter->sourceImageRect(); - if (filter->sourceImageRect().x() < filter->filterRegion().x()) - clippedSourceRect.setX(filter->filterRegion().x()); - if (filter->sourceImageRect().y() < filter->filterRegion().y()) - clippedSourceRect.setY(filter->filterRegion().y()); - setFilterPrimitiveSubregion(clippedSourceRect); - clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); - setRepaintRectInLocalCoordinates(clippedSourceRect); - return filter->filterRegion(); + FloatRect paintRect = filter->sourceImageRect(); + paintRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); + setAbsolutePaintRect(enclosingIntRect(paintRect)); } void SourceAlpha::apply(Filter* filter) { - GraphicsContext* filterContext = effectContext(); - if (!filterContext) + GraphicsContext* filterContext = effectContext(filter); + if (!filterContext || !filter->sourceImage()) return; setIsAlphaImage(true); - FloatRect imageRect(FloatPoint(), filter->sourceImage()->size()); + FloatRect imageRect(FloatPoint(), absolutePaintRect().size()); filterContext->save(); filterContext->clipToImageBuffer(filter->sourceImage(), imageRect); - filterContext->fillRect(imageRect, Color::black, DeviceColorSpace); + filterContext->fillRect(imageRect, Color::black, ColorSpaceDeviceRGB); filterContext->restore(); } diff --git a/WebCore/platform/graphics/filters/SourceAlpha.h b/WebCore/platform/graphics/filters/SourceAlpha.h index f0fa319..83704e5 100644 --- a/WebCore/platform/graphics/filters/SourceAlpha.h +++ b/WebCore/platform/graphics/filters/SourceAlpha.h @@ -34,12 +34,12 @@ public: static const AtomicString& effectName(); - virtual FloatRect determineFilterPrimitiveSubregion(Filter*); - virtual void apply(Filter*); virtual void dump(); - virtual bool isSourceInput() const { return true; } + virtual void determineAbsolutePaintRect(Filter*); + + virtual FilterEffectType filterEffectType() const { return FilterEffectTypeSourceInput; } virtual TextStream& externalRepresentation(TextStream&, int indention) const; diff --git a/WebCore/platform/graphics/filters/SourceGraphic.cpp b/WebCore/platform/graphics/filters/SourceGraphic.cpp index c014e68..fbb711a 100644 --- a/WebCore/platform/graphics/filters/SourceGraphic.cpp +++ b/WebCore/platform/graphics/filters/SourceGraphic.cpp @@ -41,26 +41,20 @@ const AtomicString& SourceGraphic::effectName() return s_effectName; } -FloatRect SourceGraphic::determineFilterPrimitiveSubregion(Filter* filter) +void SourceGraphic::determineAbsolutePaintRect(Filter* filter) { - FloatRect clippedSourceRect = filter->sourceImageRect(); - if (filter->sourceImageRect().x() < filter->filterRegion().x()) - clippedSourceRect.setX(filter->filterRegion().x()); - if (filter->sourceImageRect().y() < filter->filterRegion().y()) - clippedSourceRect.setY(filter->filterRegion().y()); - setFilterPrimitiveSubregion(clippedSourceRect); - clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); - setRepaintRectInLocalCoordinates(clippedSourceRect); - return filter->filterRegion(); + FloatRect paintRect = filter->sourceImageRect(); + paintRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); + setAbsolutePaintRect(enclosingIntRect(paintRect)); } void SourceGraphic::apply(Filter* filter) { - GraphicsContext* filterContext = effectContext(); - if (!filterContext) + GraphicsContext* filterContext = effectContext(filter); + if (!filterContext || !filter->sourceImage()) return; - filterContext->drawImageBuffer(filter->sourceImage(), DeviceColorSpace, IntPoint()); + filterContext->drawImageBuffer(filter->sourceImage(), ColorSpaceDeviceRGB, IntPoint()); } void SourceGraphic::dump() diff --git a/WebCore/platform/graphics/filters/SourceGraphic.h b/WebCore/platform/graphics/filters/SourceGraphic.h index 2378798..a13337d 100644 --- a/WebCore/platform/graphics/filters/SourceGraphic.h +++ b/WebCore/platform/graphics/filters/SourceGraphic.h @@ -35,12 +35,12 @@ public: static const AtomicString& effectName(); - virtual FloatRect determineFilterPrimitiveSubregion(Filter*); - virtual void apply(Filter*); virtual void dump(); - virtual bool isSourceInput() const { return true; } + virtual void determineAbsolutePaintRect(Filter*); + + virtual FilterEffectType filterEffectType() const { return FilterEffectTypeSourceInput; } virtual TextStream& externalRepresentation(TextStream&, int indention) const; |