#ifndef FilterEffect_h
#define FilterEffect_h
#include "platform/PlatformExport.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntRect.h"
#include "platform/graphics/Color.h"
#include "platform/graphics/ColorSpace.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
#include "wtf/Uint8ClampedArray.h"
#include "wtf/Vector.h"
namespace WebCore {
class Filter;
class FilterEffect;
class ImageBuffer;
class TextStream;
class SkiaImageFilterBuilder;
typedef Vector<RefPtr<FilterEffect> > FilterEffectVector;
enum FilterEffectType {
FilterEffectTypeUnknown,
FilterEffectTypeImage,
FilterEffectTypeTile,
FilterEffectTypeSourceInput
};
enum DetermineSubregionFlag {
DetermineSubregionNone = 0,
MapRectForward = 1,
ClipToFilterRegion = 1 << 1
};
typedef int DetermineSubregionFlags;
class PLATFORM_EXPORT FilterEffect : public RefCounted<FilterEffect> {
public:
virtual ~FilterEffect();
static bool isFilterSizeValid(const FloatRect&);
static float maxFilterArea();
void clearResult();
void clearResultsRecursive();
ImageBuffer* asImageBuffer();
PassRefPtr<Uint8ClampedArray> asUnmultipliedImage(const IntRect&);
PassRefPtr<Uint8ClampedArray> asPremultipliedImage(const IntRect&);
void copyUnmultipliedImage(Uint8ClampedArray* destination, const IntRect&);
void copyPremultipliedImage(Uint8ClampedArray* destination, const IntRect&);
FilterEffectVector& inputEffects() { return m_inputEffects; }
FilterEffect* inputEffect(unsigned) const;
unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
inline bool hasResult() const
{
return m_imageBufferResult
|| m_unmultipliedImageResult
|| m_premultipliedImageResult;
}
IntRect drawingRegionOfInputImage(const IntRect&) const;
IntRect requestedRegionOfInputImageData(const IntRect&) const;
bool isAlphaImage() const { return m_alphaImage; }
void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
IntRect absolutePaintRect() const { return m_absolutePaintRect; }
FloatRect maxEffectRect() const { return m_maxEffectRect; }
void setMaxEffectRect(const FloatRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; }
void apply();
virtual void correctFilterResultIfNeeded() { }
virtual PassRefPtr<SkImageFilter> createImageFilter(SkiaImageFilterBuilder*);
virtual FloatRect mapRect(const FloatRect& rect, bool forward = true) { return rect; }
virtual FloatRect mapPaintRect(const FloatRect& rect, bool forward)
{
return mapRect(rect, forward);
}
FloatRect mapRectRecursive(const FloatRect&);
FloatRect getSourceRect(const FloatRect& destRect, const FloatRect& clipRect);
virtual FilterEffectType filterEffectType() const { return FilterEffectTypeUnknown; }
virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const;
bool hasX() const { return m_hasX; }
void setHasX(bool value) { m_hasX = value; }
bool hasY() const { return m_hasY; }
void setHasY(bool value) { m_hasY = value; }
bool hasWidth() const { return m_hasWidth; }
void setHasWidth(bool value) { m_hasWidth = value; }
bool hasHeight() const { return m_hasHeight; }
void setHasHeight(bool value) { m_hasHeight = value; }
FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; }
void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; }
FloatRect effectBoundaries() const { return m_effectBoundaries; }
void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; }
Filter* filter() { return m_filter; }
const Filter* filter() const { return m_filter; }
bool clipsToBounds() const { return m_clipsToBounds; }
void setClipsToBounds(bool value) { m_clipsToBounds = value; }
ColorSpace operatingColorSpace() const { return m_operatingColorSpace; }
virtual void setOperatingColorSpace(ColorSpace colorSpace) { m_operatingColorSpace = colorSpace; }
ColorSpace resultColorSpace() const { return m_resultColorSpace; }
virtual void setResultColorSpace(ColorSpace colorSpace) { m_resultColorSpace = colorSpace; }
virtual void transformResultColorSpace(FilterEffect* in, const int) { in->transformResultColorSpace(m_operatingColorSpace); }
void transformResultColorSpace(ColorSpace);
FloatRect determineFilterPrimitiveSubregion(DetermineSubregionFlags = DetermineSubregionNone);
void determineAllAbsolutePaintRects();
virtual FloatRect determineAbsolutePaintRect(const FloatRect& requestedAbsoluteRect);
virtual bool affectsTransparentPixels() { return false; }
protected:
FilterEffect(Filter*);
ImageBuffer* createImageBufferResult();
Uint8ClampedArray* createUnmultipliedImageResult();
Uint8ClampedArray* createPremultipliedImageResult();
Color adaptColorToOperatingColorSpace(const Color& deviceColor);
virtual bool requiresValidPreMultipliedPixels() { return true; }
void forceValidPreMultipliedPixels();
SkImageFilter::CropRect getCropRect(const FloatSize& cropOffset) const;
void addAbsolutePaintRect(const FloatRect& absolutePaintRect);
private:
void applyRecursive();
virtual void applySoftware() = 0;
inline void copyImageBytes(Uint8ClampedArray* source, Uint8ClampedArray* destination, const IntRect&);
OwnPtr<ImageBuffer> m_imageBufferResult;
RefPtr<Uint8ClampedArray> m_unmultipliedImageResult;
RefPtr<Uint8ClampedArray> m_premultipliedImageResult;
FilterEffectVector m_inputEffects;
bool m_alphaImage;
IntRect m_absolutePaintRect;
FloatRect m_maxEffectRect;
Filter* m_filter;
FloatRect m_filterPrimitiveSubregion;
FloatRect m_effectBoundaries;
bool m_hasX;
bool m_hasY;
bool m_hasWidth;
bool m_hasHeight;
bool m_clipsToBounds;
ColorSpace m_operatingColorSpace;
ColorSpace m_resultColorSpace;
};
}
#endif