Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef __NS_SVGFILTERINSTANCE_H__ |
michael@0 | 7 | #define __NS_SVGFILTERINSTANCE_H__ |
michael@0 | 8 | |
michael@0 | 9 | #include "gfxMatrix.h" |
michael@0 | 10 | #include "gfxRect.h" |
michael@0 | 11 | #include "nsSVGFilters.h" |
michael@0 | 12 | #include "nsSVGNumber2.h" |
michael@0 | 13 | #include "nsSVGNumberPair.h" |
michael@0 | 14 | #include "nsTArray.h" |
michael@0 | 15 | #include "nsIFrame.h" |
michael@0 | 16 | |
michael@0 | 17 | class nsIFrame; |
michael@0 | 18 | class nsSVGFilterFrame; |
michael@0 | 19 | class nsSVGFilterPaintCallback; |
michael@0 | 20 | |
michael@0 | 21 | namespace mozilla { |
michael@0 | 22 | namespace dom { |
michael@0 | 23 | class SVGFilterElement; |
michael@0 | 24 | } |
michael@0 | 25 | } |
michael@0 | 26 | |
michael@0 | 27 | /** |
michael@0 | 28 | * This class helps nsFilterInstance build its filter graph by processing a |
michael@0 | 29 | * single SVG reference filter. |
michael@0 | 30 | * |
michael@0 | 31 | * In BuildPrimitives, this class iterates through the referenced <filter> |
michael@0 | 32 | * element's primitive elements, creating a FilterPrimitiveDescription for |
michael@0 | 33 | * each one. |
michael@0 | 34 | * |
michael@0 | 35 | * This class uses several different coordinate spaces, defined as follows: |
michael@0 | 36 | * |
michael@0 | 37 | * "user space" |
michael@0 | 38 | * The filtered SVG element's user space or the filtered HTML element's |
michael@0 | 39 | * CSS pixel space. The origin for an HTML element is the top left corner of |
michael@0 | 40 | * its border box. |
michael@0 | 41 | * |
michael@0 | 42 | * "filter space" |
michael@0 | 43 | * User space scaled to device pixels. Shares the same origin as user space. |
michael@0 | 44 | * This space is the same across chained SVG and CSS filters. To compute the |
michael@0 | 45 | * overall filter space for a chain, we first need to build each filter's |
michael@0 | 46 | * FilterPrimitiveDescriptions in some common space. That space is |
michael@0 | 47 | * filter space. |
michael@0 | 48 | * |
michael@0 | 49 | * To understand the spaces better, let's take an example filter: |
michael@0 | 50 | * <filter id="f">...</filter> |
michael@0 | 51 | * |
michael@0 | 52 | * And apply the filter to a div element: |
michael@0 | 53 | * <div style="filter: url(#f); ...">...</div> |
michael@0 | 54 | * |
michael@0 | 55 | * And let's say there are 2 device pixels for every 1 CSS pixel. |
michael@0 | 56 | * |
michael@0 | 57 | * Finally, let's define an arbitrary point in user space: |
michael@0 | 58 | * "user space point" = (10, 10) |
michael@0 | 59 | * |
michael@0 | 60 | * The point will be inset 10 CSS pixels from both the top and left edges of the |
michael@0 | 61 | * div element's border box. |
michael@0 | 62 | * |
michael@0 | 63 | * Now, let's transform the point from user space to filter space: |
michael@0 | 64 | * "filter space point" = "user space point" * "device pixels per CSS pixel" |
michael@0 | 65 | * "filter space point" = (10, 10) * 2 |
michael@0 | 66 | * "filter space point" = (20, 20) |
michael@0 | 67 | */ |
michael@0 | 68 | class nsSVGFilterInstance |
michael@0 | 69 | { |
michael@0 | 70 | typedef mozilla::gfx::Point3D Point3D; |
michael@0 | 71 | typedef mozilla::gfx::IntRect IntRect; |
michael@0 | 72 | typedef mozilla::gfx::SourceSurface SourceSurface; |
michael@0 | 73 | typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription; |
michael@0 | 74 | |
michael@0 | 75 | public: |
michael@0 | 76 | /** |
michael@0 | 77 | * @param aFilter The SVG reference filter to process. |
michael@0 | 78 | * @param aTargetFrame The frame of the filtered element under consideration. |
michael@0 | 79 | * @param aTargetBBox The SVG bbox to use for the target frame, computed by |
michael@0 | 80 | * the caller. The caller may decide to override the actual SVG bbox. |
michael@0 | 81 | */ |
michael@0 | 82 | nsSVGFilterInstance(const nsStyleFilter& aFilter, |
michael@0 | 83 | nsIFrame *aTargetFrame, |
michael@0 | 84 | const gfxRect& aTargetBBox, |
michael@0 | 85 | const gfxSize& aUserSpaceToFilterSpaceScale, |
michael@0 | 86 | const gfxSize& aFilterSpaceToUserSpaceScale); |
michael@0 | 87 | |
michael@0 | 88 | /** |
michael@0 | 89 | * Returns true if the filter instance was created successfully. |
michael@0 | 90 | */ |
michael@0 | 91 | bool IsInitialized() const { return mInitialized; } |
michael@0 | 92 | |
michael@0 | 93 | /** |
michael@0 | 94 | * Iterates through the <filter> element's primitive elements, creating a |
michael@0 | 95 | * FilterPrimitiveDescription for each one. Appends the new |
michael@0 | 96 | * FilterPrimitiveDescription(s) to the aPrimitiveDescrs list. Also, appends |
michael@0 | 97 | * new images from feImage filter primitive elements to the aInputImages list. |
michael@0 | 98 | */ |
michael@0 | 99 | nsresult BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs, |
michael@0 | 100 | nsTArray<mozilla::RefPtr<SourceSurface>>& aInputImages); |
michael@0 | 101 | |
michael@0 | 102 | /** |
michael@0 | 103 | * Returns the user specified "filter region", in the filtered element's user |
michael@0 | 104 | * space, after it has been adjusted out (if necessary) so that its edges |
michael@0 | 105 | * coincide with pixel boundaries of the offscreen surface into which the |
michael@0 | 106 | * filtered output would/will be painted. |
michael@0 | 107 | */ |
michael@0 | 108 | gfxRect GetFilterRegion() const { return mUserSpaceBounds; } |
michael@0 | 109 | |
michael@0 | 110 | /** |
michael@0 | 111 | * Returns the size of the user specified "filter region", in filter space. |
michael@0 | 112 | */ |
michael@0 | 113 | nsIntRect GetFilterSpaceBounds() const { return mFilterSpaceBounds; } |
michael@0 | 114 | |
michael@0 | 115 | float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumber2 *aNumber) const |
michael@0 | 116 | { |
michael@0 | 117 | return GetPrimitiveNumber(aCtxType, aNumber->GetAnimValue()); |
michael@0 | 118 | } |
michael@0 | 119 | float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumberPair *aNumberPair, |
michael@0 | 120 | nsSVGNumberPair::PairIndex aIndex) const |
michael@0 | 121 | { |
michael@0 | 122 | return GetPrimitiveNumber(aCtxType, aNumberPair->GetAnimValue(aIndex)); |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | /** |
michael@0 | 126 | * Converts a userSpaceOnUse/objectBoundingBoxUnits unitless point |
michael@0 | 127 | * into filter space, depending on the value of mPrimitiveUnits. (For |
michael@0 | 128 | * objectBoundingBoxUnits, the bounding box offset is applied to the point.) |
michael@0 | 129 | */ |
michael@0 | 130 | Point3D ConvertLocation(const Point3D& aPoint) const; |
michael@0 | 131 | |
michael@0 | 132 | /** |
michael@0 | 133 | * Transform a rect between user space and filter space. |
michael@0 | 134 | */ |
michael@0 | 135 | gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpaceRect) const; |
michael@0 | 136 | |
michael@0 | 137 | private: |
michael@0 | 138 | /** |
michael@0 | 139 | * Finds the filter frame associated with this SVG filter. |
michael@0 | 140 | */ |
michael@0 | 141 | nsSVGFilterFrame* GetFilterFrame(); |
michael@0 | 142 | |
michael@0 | 143 | /** |
michael@0 | 144 | * Computes the filter primitive subregion for the given primitive. |
michael@0 | 145 | */ |
michael@0 | 146 | IntRect ComputeFilterPrimitiveSubregion(nsSVGFE* aFilterElement, |
michael@0 | 147 | const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs, |
michael@0 | 148 | const nsTArray<int32_t>& aInputIndices); |
michael@0 | 149 | |
michael@0 | 150 | /** |
michael@0 | 151 | * Takes the input indices of a filter primitive and returns for each input |
michael@0 | 152 | * whether the input's output is tainted. |
michael@0 | 153 | */ |
michael@0 | 154 | void GetInputsAreTainted(const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs, |
michael@0 | 155 | const nsTArray<int32_t>& aInputIndices, |
michael@0 | 156 | nsTArray<bool>& aOutInputsAreTainted); |
michael@0 | 157 | |
michael@0 | 158 | /** |
michael@0 | 159 | * Scales a numeric filter primitive length in the X, Y or "XY" directions |
michael@0 | 160 | * into a length in filter space (no offset is applied). |
michael@0 | 161 | */ |
michael@0 | 162 | float GetPrimitiveNumber(uint8_t aCtxType, float aValue) const; |
michael@0 | 163 | |
michael@0 | 164 | /** |
michael@0 | 165 | * Transform a rect between user space and filter space. |
michael@0 | 166 | */ |
michael@0 | 167 | gfxRect FilterSpaceToUserSpace(const gfxRect& aFilterSpaceRect) const; |
michael@0 | 168 | |
michael@0 | 169 | /** |
michael@0 | 170 | * Returns the transform from frame space to the coordinate space that |
michael@0 | 171 | * GetCanvasTM transforms to. "Frame space" is the origin of a frame, aka the |
michael@0 | 172 | * top-left corner of its border box, aka the top left corner of its mRect. |
michael@0 | 173 | */ |
michael@0 | 174 | gfxMatrix GetUserSpaceToFrameSpaceInCSSPxTransform() const; |
michael@0 | 175 | |
michael@0 | 176 | /** |
michael@0 | 177 | * Finds the index in aPrimitiveDescrs of each input to aPrimitiveElement. |
michael@0 | 178 | * For example, if aPrimitiveElement is: |
michael@0 | 179 | * <feGaussianBlur in="another-primitive" .../> |
michael@0 | 180 | * Then, the resulting aSourceIndices will contain the index of the |
michael@0 | 181 | * FilterPrimitiveDescription representing "another-primitive". |
michael@0 | 182 | */ |
michael@0 | 183 | nsresult GetSourceIndices(nsSVGFE* aPrimitiveElement, |
michael@0 | 184 | const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs, |
michael@0 | 185 | const nsDataHashtable<nsStringHashKey, int32_t>& aImageTable, |
michael@0 | 186 | nsTArray<int32_t>& aSourceIndices); |
michael@0 | 187 | |
michael@0 | 188 | /** |
michael@0 | 189 | * Compute the filter region in user space, filter space, and filter |
michael@0 | 190 | * space. |
michael@0 | 191 | */ |
michael@0 | 192 | nsresult ComputeBounds(); |
michael@0 | 193 | |
michael@0 | 194 | /** |
michael@0 | 195 | * The SVG reference filter originally from the style system. |
michael@0 | 196 | */ |
michael@0 | 197 | const nsStyleFilter mFilter; |
michael@0 | 198 | |
michael@0 | 199 | /** |
michael@0 | 200 | * The frame for the element that is currently being filtered. |
michael@0 | 201 | */ |
michael@0 | 202 | nsIFrame* mTargetFrame; |
michael@0 | 203 | |
michael@0 | 204 | /** |
michael@0 | 205 | * The filter element referenced by mTargetFrame's element. |
michael@0 | 206 | */ |
michael@0 | 207 | const mozilla::dom::SVGFilterElement* mFilterElement; |
michael@0 | 208 | |
michael@0 | 209 | /** |
michael@0 | 210 | * The frame for the SVG filter element. |
michael@0 | 211 | */ |
michael@0 | 212 | nsSVGFilterFrame* mFilterFrame; |
michael@0 | 213 | |
michael@0 | 214 | /** |
michael@0 | 215 | * The SVG bbox of the element that is being filtered, in user space. |
michael@0 | 216 | */ |
michael@0 | 217 | gfxRect mTargetBBox; |
michael@0 | 218 | |
michael@0 | 219 | /** |
michael@0 | 220 | * The "filter region" in various spaces. |
michael@0 | 221 | */ |
michael@0 | 222 | gfxRect mUserSpaceBounds; |
michael@0 | 223 | nsIntRect mFilterSpaceBounds; |
michael@0 | 224 | |
michael@0 | 225 | /** |
michael@0 | 226 | * The scale factors between user space and filter space. |
michael@0 | 227 | */ |
michael@0 | 228 | gfxSize mUserSpaceToFilterSpaceScale; |
michael@0 | 229 | gfxSize mFilterSpaceToUserSpaceScale; |
michael@0 | 230 | |
michael@0 | 231 | /** |
michael@0 | 232 | * The 'primitiveUnits' attribute value (objectBoundingBox or userSpaceOnUse). |
michael@0 | 233 | */ |
michael@0 | 234 | uint16_t mPrimitiveUnits; |
michael@0 | 235 | |
michael@0 | 236 | /** |
michael@0 | 237 | * The index of the FilterPrimitiveDescription that this SVG filter should use |
michael@0 | 238 | * as its SourceGraphic, or the SourceGraphic keyword index if this is the |
michael@0 | 239 | * first filter in a chain. |
michael@0 | 240 | */ |
michael@0 | 241 | int32_t mSourceGraphicIndex; |
michael@0 | 242 | |
michael@0 | 243 | bool mInitialized; |
michael@0 | 244 | }; |
michael@0 | 245 | |
michael@0 | 246 | #endif |