Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef __FilterSupport_h
7 : #define __FilterSupport_h
8 :
9 : #include "mozilla/Attributes.h"
10 : #include "mozilla/RefPtr.h"
11 : #include "mozilla/gfx/Rect.h"
12 : #include "mozilla/gfx/Matrix.h"
13 : #include "mozilla/gfx/2D.h"
14 : #include "nsClassHashtable.h"
15 : #include "nsTArray.h"
16 : #include "nsRegion.h"
17 :
18 : namespace mozilla {
19 : namespace gfx {
20 :
21 : // Morphology Operators
22 : const unsigned short SVG_OPERATOR_UNKNOWN = 0;
23 : const unsigned short SVG_OPERATOR_ERODE = 1;
24 : const unsigned short SVG_OPERATOR_DILATE = 2;
25 :
26 : // ColorMatrix types
27 : const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0;
28 : const unsigned short SVG_FECOLORMATRIX_TYPE_MATRIX = 1;
29 : const unsigned short SVG_FECOLORMATRIX_TYPE_SATURATE = 2;
30 : const unsigned short SVG_FECOLORMATRIX_TYPE_HUE_ROTATE = 3;
31 : const unsigned short SVG_FECOLORMATRIX_TYPE_LUMINANCE_TO_ALPHA = 4;
32 : // ColorMatrix types for CSS filters
33 : const unsigned short SVG_FECOLORMATRIX_TYPE_SEPIA = 5;
34 :
35 : // ComponentTransfer types
36 : const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0;
37 : const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1;
38 : const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2;
39 : const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3;
40 : const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4;
41 : const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5;
42 :
43 : // Blend Mode Values
44 : const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0;
45 : const unsigned short SVG_FEBLEND_MODE_NORMAL = 1;
46 : const unsigned short SVG_FEBLEND_MODE_MULTIPLY = 2;
47 : const unsigned short SVG_FEBLEND_MODE_SCREEN = 3;
48 : const unsigned short SVG_FEBLEND_MODE_DARKEN = 4;
49 : const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5;
50 : const unsigned short SVG_FEBLEND_MODE_OVERLAY = 6;
51 : const unsigned short SVG_FEBLEND_MODE_COLOR_DODGE = 7;
52 : const unsigned short SVG_FEBLEND_MODE_COLOR_BURN = 8;
53 : const unsigned short SVG_FEBLEND_MODE_HARD_LIGHT = 9;
54 : const unsigned short SVG_FEBLEND_MODE_SOFT_LIGHT = 10;
55 : const unsigned short SVG_FEBLEND_MODE_DIFFERENCE = 11;
56 : const unsigned short SVG_FEBLEND_MODE_EXCLUSION = 12;
57 : const unsigned short SVG_FEBLEND_MODE_HUE = 13;
58 : const unsigned short SVG_FEBLEND_MODE_SATURATION = 14;
59 : const unsigned short SVG_FEBLEND_MODE_COLOR = 15;
60 : const unsigned short SVG_FEBLEND_MODE_LUMINOSITY = 16;
61 :
62 : // Edge Mode Values
63 : const unsigned short SVG_EDGEMODE_UNKNOWN = 0;
64 : const unsigned short SVG_EDGEMODE_DUPLICATE = 1;
65 : const unsigned short SVG_EDGEMODE_WRAP = 2;
66 : const unsigned short SVG_EDGEMODE_NONE = 3;
67 :
68 : // Channel Selectors
69 : const unsigned short SVG_CHANNEL_UNKNOWN = 0;
70 : const unsigned short SVG_CHANNEL_R = 1;
71 : const unsigned short SVG_CHANNEL_G = 2;
72 : const unsigned short SVG_CHANNEL_B = 3;
73 : const unsigned short SVG_CHANNEL_A = 4;
74 :
75 : // Turbulence Types
76 : const unsigned short SVG_TURBULENCE_TYPE_UNKNOWN = 0;
77 : const unsigned short SVG_TURBULENCE_TYPE_FRACTALNOISE = 1;
78 : const unsigned short SVG_TURBULENCE_TYPE_TURBULENCE = 2;
79 :
80 : // Composite Operators
81 : const unsigned short SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0;
82 : const unsigned short SVG_FECOMPOSITE_OPERATOR_OVER = 1;
83 : const unsigned short SVG_FECOMPOSITE_OPERATOR_IN = 2;
84 : const unsigned short SVG_FECOMPOSITE_OPERATOR_OUT = 3;
85 : const unsigned short SVG_FECOMPOSITE_OPERATOR_ATOP = 4;
86 : const unsigned short SVG_FECOMPOSITE_OPERATOR_XOR = 5;
87 : const unsigned short SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6;
88 :
89 : enum AttributeName {
90 : eBlendBlendmode = 0,
91 : eMorphologyRadii,
92 : eMorphologyOperator,
93 : eColorMatrixType,
94 : eColorMatrixValues,
95 : eFloodColor,
96 : eTileSourceRect,
97 : eComponentTransferFunctionR,
98 : eComponentTransferFunctionG,
99 : eComponentTransferFunctionB,
100 : eComponentTransferFunctionA,
101 : eComponentTransferFunctionType,
102 : eComponentTransferFunctionTableValues,
103 : eComponentTransferFunctionSlope,
104 : eComponentTransferFunctionIntercept,
105 : eComponentTransferFunctionAmplitude,
106 : eComponentTransferFunctionExponent,
107 : eComponentTransferFunctionOffset,
108 : eConvolveMatrixKernelSize,
109 : eConvolveMatrixKernelMatrix,
110 : eConvolveMatrixDivisor,
111 : eConvolveMatrixBias,
112 : eConvolveMatrixTarget,
113 : eConvolveMatrixEdgeMode,
114 : eConvolveMatrixKernelUnitLength,
115 : eConvolveMatrixPreserveAlpha,
116 : eOffsetOffset,
117 : eDropShadowStdDeviation,
118 : eDropShadowOffset,
119 : eDropShadowColor,
120 : eDisplacementMapScale,
121 : eDisplacementMapXChannel,
122 : eDisplacementMapYChannel,
123 : eTurbulenceOffset,
124 : eTurbulenceBaseFrequency,
125 : eTurbulenceNumOctaves,
126 : eTurbulenceSeed,
127 : eTurbulenceStitchable,
128 : eTurbulenceType,
129 : eCompositeOperator,
130 : eCompositeCoefficients,
131 : eGaussianBlurStdDeviation,
132 : eLightingLight,
133 : eLightingSurfaceScale,
134 : eLightingKernelUnitLength,
135 : eLightingColor,
136 : eDiffuseLightingDiffuseConstant,
137 : eSpecularLightingSpecularConstant,
138 : eSpecularLightingSpecularExponent,
139 : eLightType,
140 : eLightTypeNone,
141 : eLightTypePoint,
142 : eLightTypeSpot,
143 : eLightTypeDistant,
144 : ePointLightPosition,
145 : eSpotLightPosition,
146 : eSpotLightPointsAt,
147 : eSpotLightFocus,
148 : eSpotLightLimitingConeAngle,
149 : eDistantLightAzimuth,
150 : eDistantLightElevation,
151 : eImageInputIndex,
152 : eImageFilter,
153 : eImageNativeSize,
154 : eImageSubregion,
155 : eImageTransform,
156 : eLastAttributeName
157 : };
158 :
159 : class DrawTarget;
160 : class SourceSurface;
161 : struct FilterAttribute;
162 :
163 : enum class AttributeType {
164 : eBool,
165 : eUint,
166 : eFloat,
167 : eSize,
168 : eIntSize,
169 : eIntPoint,
170 : eMatrix,
171 : eMatrix5x4,
172 : ePoint3D,
173 : eColor,
174 : eAttributeMap,
175 : eFloats,
176 : Max
177 : };
178 :
179 : // Limits
180 : const float kMaxStdDeviation = 500;
181 :
182 : // A class that stores values of different types, keyed by an attribute name.
183 : // The Get*() methods assert that they're called for the same type that the
184 : // attribute was Set() with.
185 : // AttributeMaps can be nested because AttributeMap is a valid attribute type.
186 : class AttributeMap final {
187 : public:
188 : AttributeMap();
189 : AttributeMap(const AttributeMap& aOther);
190 : AttributeMap& operator=(const AttributeMap& aOther);
191 : bool operator==(const AttributeMap& aOther) const;
192 : bool operator!=(const AttributeMap& aOther) const
193 : {
194 : return !(*this == aOther);
195 : }
196 : ~AttributeMap();
197 :
198 : void Set(AttributeName aName, bool aValue);
199 : void Set(AttributeName aName, uint32_t aValue);
200 : void Set(AttributeName aName, float aValue);
201 : void Set(AttributeName aName, const Size& aValue);
202 : void Set(AttributeName aName, const IntSize& aValue);
203 : void Set(AttributeName aName, const IntPoint& aValue);
204 : void Set(AttributeName aName, const Matrix& aValue);
205 : void Set(AttributeName aName, const Matrix5x4& aValue);
206 : void Set(AttributeName aName, const Point3D& aValue);
207 : void Set(AttributeName aName, const Color& aValue);
208 : void Set(AttributeName aName, const AttributeMap& aValue);
209 : void Set(AttributeName aName, const float* aValues, int32_t aLength);
210 :
211 : bool GetBool(AttributeName aName) const;
212 : uint32_t GetUint(AttributeName aName) const;
213 : float GetFloat(AttributeName aName) const;
214 : Size GetSize(AttributeName aName) const;
215 : IntSize GetIntSize(AttributeName aName) const;
216 : IntPoint GetIntPoint(AttributeName aName) const;
217 : Matrix GetMatrix(AttributeName aName) const;
218 : Matrix5x4 GetMatrix5x4(AttributeName aName) const;
219 : Point3D GetPoint3D(AttributeName aName) const;
220 : Color GetColor(AttributeName aName) const;
221 : AttributeMap GetAttributeMap(AttributeName aName) const;
222 : const nsTArray<float>& GetFloats(AttributeName aName) const;
223 :
224 : uint32_t Count() const;
225 :
226 : nsClassHashtable<nsUint32HashKey, FilterAttribute>::Iterator ConstIter() const;
227 :
228 : static AttributeType GetType(FilterAttribute* aAttribute);
229 :
230 : private:
231 : mutable nsClassHashtable<nsUint32HashKey, FilterAttribute> mMap;
232 : };
233 :
234 : enum class ColorSpace {
235 : SRGB,
236 : LinearRGB,
237 : Max
238 : };
239 :
240 : enum class AlphaModel {
241 : Unpremultiplied,
242 : Premultiplied
243 : };
244 :
245 : class ColorModel {
246 : public:
247 0 : static ColorModel PremulSRGB()
248 : {
249 0 : return ColorModel(ColorSpace::SRGB, AlphaModel::Premultiplied);
250 : }
251 :
252 0 : ColorModel(ColorSpace aColorSpace, AlphaModel aAlphaModel) :
253 0 : mColorSpace(aColorSpace), mAlphaModel(aAlphaModel) {}
254 : ColorModel() :
255 : mColorSpace(ColorSpace::SRGB), mAlphaModel(AlphaModel::Premultiplied) {}
256 0 : bool operator==(const ColorModel& aOther) const {
257 0 : return mColorSpace == aOther.mColorSpace &&
258 0 : mAlphaModel == aOther.mAlphaModel;
259 : }
260 :
261 : // Used to index FilterCachedColorModels::mFilterForColorModel.
262 0 : uint8_t ToIndex() const
263 : {
264 0 : return (uint8_t(mColorSpace) << 1) + uint8_t(mAlphaModel);
265 : }
266 :
267 : ColorSpace mColorSpace;
268 : AlphaModel mAlphaModel;
269 : };
270 :
271 : enum class PrimitiveType {
272 : Empty = 0,
273 : Blend,
274 : Morphology,
275 : ColorMatrix,
276 : Flood,
277 : Tile,
278 : ComponentTransfer,
279 : ConvolveMatrix,
280 : Offset,
281 : DisplacementMap,
282 : Turbulence,
283 : Composite,
284 : Merge,
285 : Image,
286 : GaussianBlur,
287 : DropShadow,
288 : DiffuseLighting,
289 : SpecularLighting,
290 : ToAlpha,
291 : Max
292 : };
293 :
294 : /**
295 : * A data structure to carry attributes for a given primitive that's part of a
296 : * filter. Will be serializable via IPDL, so it must not contain complex
297 : * functionality.
298 : * Used as part of a FilterDescription.
299 : */
300 0 : class FilterPrimitiveDescription final {
301 : public:
302 : enum {
303 : kPrimitiveIndexSourceGraphic = -1,
304 : kPrimitiveIndexSourceAlpha = -2,
305 : kPrimitiveIndexFillPaint = -3,
306 : kPrimitiveIndexStrokePaint = -4
307 : };
308 :
309 : FilterPrimitiveDescription();
310 : explicit FilterPrimitiveDescription(PrimitiveType aType);
311 : FilterPrimitiveDescription(const FilterPrimitiveDescription& aOther);
312 : FilterPrimitiveDescription& operator=(const FilterPrimitiveDescription& aOther);
313 :
314 0 : PrimitiveType Type() const { return mType; }
315 : void SetType(PrimitiveType aType) { mType = aType; }
316 0 : const AttributeMap& Attributes() const { return mAttributes; }
317 0 : AttributeMap& Attributes() { return mAttributes; }
318 :
319 0 : IntRect PrimitiveSubregion() const { return mFilterPrimitiveSubregion; }
320 0 : IntRect FilterSpaceBounds() const { return mFilterSpaceBounds; }
321 0 : bool IsTainted() const { return mIsTainted; }
322 :
323 0 : size_t NumberOfInputs() const { return mInputPrimitives.Length(); }
324 0 : int32_t InputPrimitiveIndex(size_t aInputIndex) const
325 : {
326 0 : return aInputIndex < mInputPrimitives.Length() ?
327 0 : mInputPrimitives[aInputIndex] : 0;
328 : }
329 :
330 0 : ColorSpace InputColorSpace(size_t aInputIndex) const
331 : {
332 0 : return aInputIndex < mInputColorSpaces.Length() ?
333 0 : mInputColorSpaces[aInputIndex] : ColorSpace();
334 : }
335 :
336 0 : ColorSpace OutputColorSpace() const { return mOutputColorSpace; }
337 :
338 0 : void SetPrimitiveSubregion(const IntRect& aRect)
339 : {
340 0 : mFilterPrimitiveSubregion = aRect;
341 0 : }
342 :
343 0 : void SetFilterSpaceBounds(const IntRect& aRect)
344 : {
345 0 : mFilterSpaceBounds = aRect;
346 0 : }
347 :
348 0 : void SetIsTainted(bool aIsTainted)
349 : {
350 0 : mIsTainted = aIsTainted;
351 0 : }
352 :
353 0 : void SetInputPrimitive(size_t aInputIndex, int32_t aInputPrimitiveIndex)
354 : {
355 0 : mInputPrimitives.EnsureLengthAtLeast(aInputIndex + 1);
356 0 : mInputPrimitives[aInputIndex] = aInputPrimitiveIndex;
357 0 : }
358 :
359 0 : void SetInputColorSpace(size_t aInputIndex, ColorSpace aColorSpace)
360 : {
361 0 : mInputColorSpaces.EnsureLengthAtLeast(aInputIndex + 1);
362 0 : mInputColorSpaces[aInputIndex] = aColorSpace;
363 0 : }
364 :
365 0 : void SetOutputColorSpace(const ColorSpace& aColorSpace)
366 : {
367 0 : mOutputColorSpace = aColorSpace;
368 0 : }
369 :
370 : bool operator==(const FilterPrimitiveDescription& aOther) const;
371 : bool operator!=(const FilterPrimitiveDescription& aOther) const
372 : {
373 : return !(*this == aOther);
374 : }
375 :
376 : private:
377 : PrimitiveType mType;
378 : AttributeMap mAttributes;
379 : nsTArray<int32_t> mInputPrimitives;
380 : IntRect mFilterPrimitiveSubregion;
381 : IntRect mFilterSpaceBounds;
382 : nsTArray<ColorSpace> mInputColorSpaces;
383 : ColorSpace mOutputColorSpace;
384 : bool mIsTainted;
385 : };
386 :
387 : /**
388 : * A data structure that contains one or more FilterPrimitiveDescriptions.
389 : * Designed to be serializable via IPDL, so it must not contain complex
390 : * functionality.
391 : */
392 0 : struct FilterDescription final {
393 0 : FilterDescription() {}
394 0 : explicit FilterDescription(const nsTArray<FilterPrimitiveDescription>& aPrimitives)
395 0 : : mPrimitives(aPrimitives)
396 0 : {}
397 :
398 : bool operator==(const FilterDescription& aOther) const;
399 : bool operator!=(const FilterDescription& aOther) const
400 : {
401 : return !(*this == aOther);
402 : }
403 :
404 : nsTArray<FilterPrimitiveDescription> mPrimitives;
405 : };
406 :
407 : /**
408 : * The methods of this class are not on FilterDescription because
409 : * FilterDescription is designed as a simple value holder that can be used
410 : * on any thread.
411 : */
412 : class FilterSupport {
413 : public:
414 :
415 : /**
416 : * Draw the filter described by aFilter. All rect parameters are in filter
417 : * space coordinates. aRenderRect specifies the part of the filter output
418 : * that will be drawn at (0, 0) into the draw target aDT, subject to the
419 : * current transform on aDT but with no additional scaling.
420 : * The source surfaces must match their corresponding rect in size.
421 : * aAdditionalImages carries the images that are referenced by the
422 : * eImageInputIndex attribute on any image primitives in the filter.
423 : */
424 : static void
425 : RenderFilterDescription(DrawTarget* aDT,
426 : const FilterDescription& aFilter,
427 : const Rect& aRenderRect,
428 : SourceSurface* aSourceGraphic,
429 : const IntRect& aSourceGraphicRect,
430 : SourceSurface* aFillPaint,
431 : const IntRect& aFillPaintRect,
432 : SourceSurface* aStrokePaint,
433 : const IntRect& aStrokePaintRect,
434 : nsTArray<RefPtr<SourceSurface>>& aAdditionalImages,
435 : const Point& aDestPoint,
436 : const DrawOptions& aOptions = DrawOptions());
437 :
438 : /**
439 : * Computes the region that changes in the filter output due to a change in
440 : * input. This is primarily needed when an individual piece of content inside
441 : * a filtered container element changes.
442 : */
443 : static nsIntRegion
444 : ComputeResultChangeRegion(const FilterDescription& aFilter,
445 : const nsIntRegion& aSourceGraphicChange,
446 : const nsIntRegion& aFillPaintChange,
447 : const nsIntRegion& aStrokePaintChange);
448 :
449 : /**
450 : * Computes the regions that need to be supplied in the filter inputs when
451 : * painting aResultNeededRegion of the filter output.
452 : */
453 : static void
454 : ComputeSourceNeededRegions(const FilterDescription& aFilter,
455 : const nsIntRegion& aResultNeededRegion,
456 : nsIntRegion& aSourceGraphicNeededRegion,
457 : nsIntRegion& aFillPaintNeededRegion,
458 : nsIntRegion& aStrokePaintNeededRegion);
459 :
460 : /**
461 : * Computes the size of the filter output.
462 : */
463 : static nsIntRegion
464 : ComputePostFilterExtents(const FilterDescription& aFilter,
465 : const nsIntRegion& aSourceGraphicExtents);
466 :
467 : /**
468 : * Computes the size of a single FilterPrimitiveDescription's output given a
469 : * set of input extents.
470 : */
471 : static nsIntRegion
472 : PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& aDescription,
473 : const nsTArray<nsIntRegion>& aInputExtents);
474 : };
475 :
476 : } // namespace gfx
477 : } // namespace mozilla
478 :
479 : #endif // __FilterSupport_h
|