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