michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef __FilterSupport_h michael@0: #define __FilterSupport_h michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "mozilla/RefPtr.h" michael@0: #include "mozilla/TypedEnum.h" michael@0: #include "mozilla/gfx/Rect.h" michael@0: #include "mozilla/gfx/Matrix.h" michael@0: #include "nsClassHashtable.h" michael@0: #include "nsTArray.h" michael@0: #include "nsRegion.h" michael@0: michael@0: namespace mozilla { michael@0: namespace gfx { michael@0: michael@0: // Morphology Operators michael@0: const unsigned short SVG_OPERATOR_UNKNOWN = 0; michael@0: const unsigned short SVG_OPERATOR_ERODE = 1; michael@0: const unsigned short SVG_OPERATOR_DILATE = 2; michael@0: michael@0: // ColorMatrix types michael@0: const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0; michael@0: const unsigned short SVG_FECOLORMATRIX_TYPE_MATRIX = 1; michael@0: const unsigned short SVG_FECOLORMATRIX_TYPE_SATURATE = 2; michael@0: const unsigned short SVG_FECOLORMATRIX_TYPE_HUE_ROTATE = 3; michael@0: const unsigned short SVG_FECOLORMATRIX_TYPE_LUMINANCE_TO_ALPHA = 4; michael@0: michael@0: // ComponentTransfer types michael@0: const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0; michael@0: const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1; michael@0: const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2; michael@0: const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3; michael@0: const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4; michael@0: const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5; michael@0: michael@0: // Blend Mode Values michael@0: const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0; michael@0: const unsigned short SVG_FEBLEND_MODE_NORMAL = 1; michael@0: const unsigned short SVG_FEBLEND_MODE_MULTIPLY = 2; michael@0: const unsigned short SVG_FEBLEND_MODE_SCREEN = 3; michael@0: const unsigned short SVG_FEBLEND_MODE_DARKEN = 4; michael@0: const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5; michael@0: michael@0: // Edge Mode Values michael@0: const unsigned short SVG_EDGEMODE_UNKNOWN = 0; michael@0: const unsigned short SVG_EDGEMODE_DUPLICATE = 1; michael@0: const unsigned short SVG_EDGEMODE_WRAP = 2; michael@0: const unsigned short SVG_EDGEMODE_NONE = 3; michael@0: michael@0: // Channel Selectors michael@0: const unsigned short SVG_CHANNEL_UNKNOWN = 0; michael@0: const unsigned short SVG_CHANNEL_R = 1; michael@0: const unsigned short SVG_CHANNEL_G = 2; michael@0: const unsigned short SVG_CHANNEL_B = 3; michael@0: const unsigned short SVG_CHANNEL_A = 4; michael@0: michael@0: // Turbulence Types michael@0: const unsigned short SVG_TURBULENCE_TYPE_UNKNOWN = 0; michael@0: const unsigned short SVG_TURBULENCE_TYPE_FRACTALNOISE = 1; michael@0: const unsigned short SVG_TURBULENCE_TYPE_TURBULENCE = 2; michael@0: michael@0: // Composite Operators michael@0: const unsigned short SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0; michael@0: const unsigned short SVG_FECOMPOSITE_OPERATOR_OVER = 1; michael@0: const unsigned short SVG_FECOMPOSITE_OPERATOR_IN = 2; michael@0: const unsigned short SVG_FECOMPOSITE_OPERATOR_OUT = 3; michael@0: const unsigned short SVG_FECOMPOSITE_OPERATOR_ATOP = 4; michael@0: const unsigned short SVG_FECOMPOSITE_OPERATOR_XOR = 5; michael@0: const unsigned short SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6; michael@0: michael@0: enum AttributeName { michael@0: eBlendBlendmode = 0, michael@0: eMorphologyRadii, michael@0: eMorphologyOperator, michael@0: eColorMatrixType, michael@0: eColorMatrixValues, michael@0: eFloodColor, michael@0: eTileSourceRect, michael@0: eComponentTransferFunctionR, michael@0: eComponentTransferFunctionG, michael@0: eComponentTransferFunctionB, michael@0: eComponentTransferFunctionA, michael@0: eComponentTransferFunctionType, michael@0: eComponentTransferFunctionTableValues, michael@0: eComponentTransferFunctionSlope, michael@0: eComponentTransferFunctionIntercept, michael@0: eComponentTransferFunctionAmplitude, michael@0: eComponentTransferFunctionExponent, michael@0: eComponentTransferFunctionOffset, michael@0: eConvolveMatrixKernelSize, michael@0: eConvolveMatrixKernelMatrix, michael@0: eConvolveMatrixDivisor, michael@0: eConvolveMatrixBias, michael@0: eConvolveMatrixTarget, michael@0: eConvolveMatrixEdgeMode, michael@0: eConvolveMatrixKernelUnitLength, michael@0: eConvolveMatrixPreserveAlpha, michael@0: eOffsetOffset, michael@0: eDropShadowStdDeviation, michael@0: eDropShadowOffset, michael@0: eDropShadowColor, michael@0: eDisplacementMapScale, michael@0: eDisplacementMapXChannel, michael@0: eDisplacementMapYChannel, michael@0: eTurbulenceOffset, michael@0: eTurbulenceBaseFrequency, michael@0: eTurbulenceNumOctaves, michael@0: eTurbulenceSeed, michael@0: eTurbulenceStitchable, michael@0: eTurbulenceType, michael@0: eCompositeOperator, michael@0: eCompositeCoefficients, michael@0: eGaussianBlurStdDeviation, michael@0: eLightingLight, michael@0: eLightingSurfaceScale, michael@0: eLightingKernelUnitLength, michael@0: eLightingColor, michael@0: eDiffuseLightingDiffuseConstant, michael@0: eSpecularLightingSpecularConstant, michael@0: eSpecularLightingSpecularExponent, michael@0: eLightType, michael@0: eLightTypeNone, michael@0: eLightTypePoint, michael@0: eLightTypeSpot, michael@0: eLightTypeDistant, michael@0: ePointLightPosition, michael@0: eSpotLightPosition, michael@0: eSpotLightPointsAt, michael@0: eSpotLightFocus, michael@0: eSpotLightLimitingConeAngle, michael@0: eDistantLightAzimuth, michael@0: eDistantLightElevation, michael@0: eImageInputIndex, michael@0: eImageFilter, michael@0: eImageNativeSize, michael@0: eImageSubregion, michael@0: eImageTransform, michael@0: eLastAttributeName michael@0: }; michael@0: michael@0: class DrawTarget; michael@0: class SourceSurface; michael@0: class FilterNode; michael@0: struct FilterAttribute; michael@0: michael@0: MOZ_BEGIN_ENUM_CLASS(AttributeType) michael@0: eBool, michael@0: eUint, michael@0: eFloat, michael@0: eSize, michael@0: eIntSize, michael@0: eIntPoint, michael@0: eMatrix, michael@0: eMatrix5x4, michael@0: ePoint3D, michael@0: eColor, michael@0: eAttributeMap, michael@0: eFloats, michael@0: Max michael@0: MOZ_END_ENUM_CLASS(AttributeType) michael@0: michael@0: // A class that stores values of different types, keyed by an attribute name. michael@0: // The Get*() methods assert that they're called for the same type that the michael@0: // attribute was Set() with. michael@0: // AttributeMaps can be nested because AttributeMap is a valid attribute type. michael@0: class AttributeMap MOZ_FINAL { michael@0: public: michael@0: AttributeMap(); michael@0: AttributeMap(const AttributeMap& aOther); michael@0: AttributeMap& operator=(const AttributeMap& aOther); michael@0: bool operator==(const AttributeMap& aOther) const; michael@0: bool operator!=(const AttributeMap& aOther) const michael@0: { michael@0: return !(*this == aOther); michael@0: } michael@0: ~AttributeMap(); michael@0: michael@0: void Set(AttributeName aName, bool aValue); michael@0: void Set(AttributeName aName, uint32_t aValue); michael@0: void Set(AttributeName aName, float aValue); michael@0: void Set(AttributeName aName, const Size& aValue); michael@0: void Set(AttributeName aName, const IntSize& aValue); michael@0: void Set(AttributeName aName, const IntPoint& aValue); michael@0: void Set(AttributeName aName, const Matrix& aValue); michael@0: void Set(AttributeName aName, const Matrix5x4& aValue); michael@0: void Set(AttributeName aName, const Point3D& aValue); michael@0: void Set(AttributeName aName, const Color& aValue); michael@0: void Set(AttributeName aName, const AttributeMap& aValue); michael@0: void Set(AttributeName aName, const float* aValues, int32_t aLength); michael@0: michael@0: bool GetBool(AttributeName aName) const; michael@0: uint32_t GetUint(AttributeName aName) const; michael@0: float GetFloat(AttributeName aName) const; michael@0: Size GetSize(AttributeName aName) const; michael@0: IntSize GetIntSize(AttributeName aName) const; michael@0: IntPoint GetIntPoint(AttributeName aName) const; michael@0: Matrix GetMatrix(AttributeName aName) const; michael@0: Matrix5x4 GetMatrix5x4(AttributeName aName) const; michael@0: Point3D GetPoint3D(AttributeName aName) const; michael@0: Color GetColor(AttributeName aName) const; michael@0: AttributeMap GetAttributeMap(AttributeName aName) const; michael@0: const nsTArray& GetFloats(AttributeName aName) const; michael@0: michael@0: typedef bool (*AttributeHandleCallback)(AttributeName aName, AttributeType aType, void* aUserData); michael@0: void EnumerateRead(AttributeHandleCallback aCallback, void* aUserData) const; michael@0: uint32_t Count() const; michael@0: michael@0: private: michael@0: mutable nsClassHashtable mMap; michael@0: }; michael@0: michael@0: MOZ_BEGIN_ENUM_CLASS(ColorSpace) michael@0: SRGB, michael@0: LinearRGB, michael@0: Max michael@0: MOZ_END_ENUM_CLASS(ColorSpace) michael@0: michael@0: MOZ_BEGIN_ENUM_CLASS(AlphaModel) michael@0: Unpremultiplied, michael@0: Premultiplied michael@0: MOZ_END_ENUM_CLASS(AlphaModel) michael@0: michael@0: class ColorModel { michael@0: public: michael@0: static ColorModel PremulSRGB() michael@0: { michael@0: return ColorModel(ColorSpace::SRGB, AlphaModel::Premultiplied); michael@0: } michael@0: michael@0: ColorModel(ColorSpace aColorSpace, AlphaModel aAlphaModel) : michael@0: mColorSpace(aColorSpace), mAlphaModel(aAlphaModel) {} michael@0: ColorModel() : michael@0: mColorSpace(ColorSpace::SRGB), mAlphaModel(AlphaModel::Premultiplied) {} michael@0: bool operator==(const ColorModel& aOther) const { michael@0: return mColorSpace == aOther.mColorSpace && michael@0: mAlphaModel == aOther.mAlphaModel; michael@0: } michael@0: michael@0: // Used to index FilterCachedColorModels::mFilterForColorModel. michael@0: uint8_t ToIndex() const michael@0: { michael@0: return (uint8_t(mColorSpace) << 1) + uint8_t(mAlphaModel); michael@0: } michael@0: michael@0: ColorSpace mColorSpace; michael@0: AlphaModel mAlphaModel; michael@0: }; michael@0: michael@0: MOZ_BEGIN_ENUM_CLASS(PrimitiveType) michael@0: Empty = 0, michael@0: Blend, michael@0: Morphology, michael@0: ColorMatrix, michael@0: Flood, michael@0: Tile, michael@0: ComponentTransfer, michael@0: ConvolveMatrix, michael@0: Offset, michael@0: DisplacementMap, michael@0: Turbulence, michael@0: Composite, michael@0: Merge, michael@0: Image, michael@0: GaussianBlur, michael@0: DropShadow, michael@0: DiffuseLighting, michael@0: SpecularLighting, michael@0: Max michael@0: MOZ_END_ENUM_CLASS(PrimitiveType) michael@0: michael@0: /** michael@0: * A data structure to carry attributes for a given primitive that's part of a michael@0: * filter. Will be serializable via IPDL, so it must not contain complex michael@0: * functionality. michael@0: * Used as part of a FilterDescription. michael@0: */ michael@0: class FilterPrimitiveDescription MOZ_FINAL { michael@0: public: michael@0: enum { michael@0: kPrimitiveIndexSourceGraphic = -1, michael@0: kPrimitiveIndexSourceAlpha = -2, michael@0: kPrimitiveIndexFillPaint = -3, michael@0: kPrimitiveIndexStrokePaint = -4 michael@0: }; michael@0: michael@0: FilterPrimitiveDescription(); michael@0: FilterPrimitiveDescription(PrimitiveType aType); michael@0: FilterPrimitiveDescription(const FilterPrimitiveDescription& aOther); michael@0: FilterPrimitiveDescription& operator=(const FilterPrimitiveDescription& aOther); michael@0: michael@0: PrimitiveType Type() const { return mType; } michael@0: void SetType(PrimitiveType aType) { mType = aType; } michael@0: const AttributeMap& Attributes() const { return mAttributes; } michael@0: AttributeMap& Attributes() { return mAttributes; } michael@0: michael@0: IntRect PrimitiveSubregion() const { return mFilterPrimitiveSubregion; } michael@0: bool IsTainted() const { return mIsTainted; } michael@0: michael@0: size_t NumberOfInputs() const { return mInputPrimitives.Length(); } michael@0: int32_t InputPrimitiveIndex(size_t aInputIndex) const michael@0: { michael@0: return aInputIndex < mInputPrimitives.Length() ? michael@0: mInputPrimitives[aInputIndex] : 0; michael@0: } michael@0: michael@0: ColorSpace InputColorSpace(size_t aInputIndex) const michael@0: { michael@0: return aInputIndex < mInputColorSpaces.Length() ? michael@0: mInputColorSpaces[aInputIndex] : ColorSpace(); michael@0: } michael@0: michael@0: ColorSpace OutputColorSpace() const { return mOutputColorSpace; } michael@0: michael@0: void SetPrimitiveSubregion(const IntRect& aRect) michael@0: { michael@0: mFilterPrimitiveSubregion = aRect; michael@0: } michael@0: michael@0: void SetIsTainted(bool aIsTainted) michael@0: { michael@0: mIsTainted = aIsTainted; michael@0: } michael@0: michael@0: void SetInputPrimitive(size_t aInputIndex, int32_t aInputPrimitiveIndex) michael@0: { michael@0: mInputPrimitives.EnsureLengthAtLeast(aInputIndex + 1); michael@0: mInputPrimitives[aInputIndex] = aInputPrimitiveIndex; michael@0: } michael@0: michael@0: void SetInputColorSpace(size_t aInputIndex, ColorSpace aColorSpace) michael@0: { michael@0: mInputColorSpaces.EnsureLengthAtLeast(aInputIndex + 1); michael@0: mInputColorSpaces[aInputIndex] = aColorSpace; michael@0: } michael@0: michael@0: void SetOutputColorSpace(const ColorSpace& aColorSpace) michael@0: { michael@0: mOutputColorSpace = aColorSpace; michael@0: } michael@0: michael@0: bool operator==(const FilterPrimitiveDescription& aOther) const; michael@0: bool operator!=(const FilterPrimitiveDescription& aOther) const michael@0: { michael@0: return !(*this == aOther); michael@0: } michael@0: michael@0: private: michael@0: PrimitiveType mType; michael@0: AttributeMap mAttributes; michael@0: nsTArray mInputPrimitives; michael@0: IntRect mFilterPrimitiveSubregion; michael@0: nsTArray mInputColorSpaces; michael@0: ColorSpace mOutputColorSpace; michael@0: bool mIsTainted; michael@0: }; michael@0: michael@0: /** michael@0: * A data structure that contains one or more FilterPrimitiveDescriptions. michael@0: * Designed to be serializable via IPDL, so it must not contain complex michael@0: * functionality. michael@0: */ michael@0: struct FilterDescription MOZ_FINAL { michael@0: FilterDescription() {} michael@0: FilterDescription(const nsTArray& aPrimitives, michael@0: const IntRect& aFilterSpaceBounds) michael@0: : mPrimitives(aPrimitives) michael@0: , mFilterSpaceBounds(aFilterSpaceBounds) michael@0: {} michael@0: michael@0: bool operator==(const FilterDescription& aOther) const; michael@0: bool operator!=(const FilterDescription& aOther) const michael@0: { michael@0: return !(*this == aOther); michael@0: } michael@0: michael@0: nsTArray mPrimitives; michael@0: IntRect mFilterSpaceBounds; michael@0: }; michael@0: michael@0: /** michael@0: * The methods of this class are not on FilterDescription because michael@0: * FilterDescription is designed as a simple value holder that can be used michael@0: * on any thread. michael@0: */ michael@0: class FilterSupport { michael@0: public: michael@0: michael@0: /** michael@0: * Draw the filter described by aFilter. All rect parameters are in filter michael@0: * space coordinates. aRenderRect specifies the part of the filter output michael@0: * that will be drawn at (0, 0) into the draw target aDT, subject to the michael@0: * current transform on aDT but with no additional scaling. michael@0: * The source surfaces must match their corresponding rect in size. michael@0: * aAdditionalImages carries the images that are referenced by the michael@0: * eImageInputIndex attribute on any image primitives in the filter. michael@0: */ michael@0: static void michael@0: RenderFilterDescription(DrawTarget* aDT, michael@0: const FilterDescription& aFilter, michael@0: const Rect& aRenderRect, michael@0: SourceSurface* aSourceGraphic, michael@0: const IntRect& aSourceGraphicRect, michael@0: SourceSurface* aFillPaint, michael@0: const IntRect& aFillPaintRect, michael@0: SourceSurface* aStrokePaint, michael@0: const IntRect& aStrokePaintRect, michael@0: nsTArray>& aAdditionalImages); michael@0: michael@0: /** michael@0: * Computes the region that changes in the filter output due to a change in michael@0: * input. michael@0: */ michael@0: static nsIntRegion michael@0: ComputeResultChangeRegion(const FilterDescription& aFilter, michael@0: const nsIntRegion& aSourceGraphicChange, michael@0: const nsIntRegion& aFillPaintChange, michael@0: const nsIntRegion& aStrokePaintChange); michael@0: michael@0: /** michael@0: * Computes the regions that need to be supplied in the filter inputs when michael@0: * painting aResultNeededRegion of the filter output. michael@0: */ michael@0: static void michael@0: ComputeSourceNeededRegions(const FilterDescription& aFilter, michael@0: const nsIntRegion& aResultNeededRegion, michael@0: nsIntRegion& aSourceGraphicNeededRegion, michael@0: nsIntRegion& aFillPaintNeededRegion, michael@0: nsIntRegion& aStrokePaintNeededRegion); michael@0: michael@0: /** michael@0: * Computes the size of the filter output. michael@0: */ michael@0: static nsIntRegion michael@0: ComputePostFilterExtents(const FilterDescription& aFilter, michael@0: const nsIntRegion& aSourceGraphicExtents); michael@0: michael@0: }; michael@0: michael@0: } michael@0: } michael@0: michael@0: #endif // __FilterSupport_h