/src/mozilla-central/layout/svg/nsSVGIntegrationUtils.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef NSSVGINTEGRATIONUTILS_H_ |
8 | | #define NSSVGINTEGRATIONUTILS_H_ |
9 | | |
10 | | #include "ImgDrawResult.h" |
11 | | #include "gfxMatrix.h" |
12 | | #include "gfxRect.h" |
13 | | #include "nsRegionFwd.h" |
14 | | #include "mozilla/gfx/Rect.h" |
15 | | |
16 | | class gfxContext; |
17 | | class gfxDrawable; |
18 | | class nsDisplayList; |
19 | | class nsDisplayListBuilder; |
20 | | class nsIFrame; |
21 | | |
22 | | struct nsRect; |
23 | | |
24 | | namespace mozilla { |
25 | | namespace gfx { |
26 | | class DrawTarget; |
27 | | } // namespace gfx |
28 | | namespace layers { |
29 | | class LayerManager; |
30 | | } // namespace layers |
31 | | } // namespace mozilla |
32 | | |
33 | | struct nsPoint; |
34 | | struct nsSize; |
35 | | |
36 | | /** |
37 | | * Integration of SVG effects (clipPath clipping, masking and filters) into |
38 | | * regular display list based painting and hit-testing. |
39 | | */ |
40 | | class nsSVGIntegrationUtils final |
41 | | { |
42 | | typedef mozilla::gfx::DrawTarget DrawTarget; |
43 | | typedef mozilla::gfx::IntRect IntRect; |
44 | | typedef mozilla::image::imgDrawingParams imgDrawingParams; |
45 | | |
46 | | public: |
47 | | /** |
48 | | * Returns true if SVG effects are currently applied to this frame. |
49 | | */ |
50 | | static bool |
51 | | UsingEffectsForFrame(const nsIFrame* aFrame); |
52 | | |
53 | | /** |
54 | | * Returns true if mask or clippath are currently applied to this frame. |
55 | | */ |
56 | | static bool |
57 | | UsingMaskOrClipPathForFrame(const nsIFrame* aFrame); |
58 | | |
59 | | /** |
60 | | * Returns the size of the union of the border-box rects of all of |
61 | | * aNonSVGFrame's continuations. |
62 | | */ |
63 | | static nsSize |
64 | | GetContinuationUnionSize(nsIFrame* aNonSVGFrame); |
65 | | |
66 | | /** |
67 | | * When SVG effects need to resolve percentage, userSpaceOnUse lengths, they |
68 | | * need a coordinate context to resolve them against. This method provides |
69 | | * that coordinate context for non-SVG frames with SVG effects applied to |
70 | | * them. The gfxSize returned is the size of the union of all of the given |
71 | | * frame's continuations' border boxes, converted to SVG user units (equal to |
72 | | * CSS px units), as required by the SVG code. |
73 | | */ |
74 | | static mozilla::gfx::Size |
75 | | GetSVGCoordContextForNonSVGFrame(nsIFrame* aNonSVGFrame); |
76 | | |
77 | | /** |
78 | | * SVG effects such as SVG filters, masking and clipPath may require an SVG |
79 | | * "bbox" for the element they're being applied to in order to make decisions |
80 | | * about positioning, and to resolve various lengths against. This method |
81 | | * provides the "bbox" for non-SVG frames. The bbox returned is in CSS px |
82 | | * units, and aUnionContinuations decide whether bbox contains the area of |
83 | | * current frame only or the union of all aNonSVGFrame's continuations' |
84 | | * overflow areas, relative to the top-left of the union of all aNonSVGFrame's |
85 | | * continuations' border box rects. |
86 | | */ |
87 | | static gfxRect |
88 | | GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame, bool aUnionContinuations); |
89 | | |
90 | | /** |
91 | | * Used to adjust a frame's pre-effects visual overflow rect to take account |
92 | | * of SVG effects. |
93 | | * |
94 | | * XXX This method will not do the right thing for frames with continuations. |
95 | | * It really needs all the continuations to have been reflowed before being |
96 | | * called, but we currently call it on each continuation as its overflow |
97 | | * rects are set during the reflow of each particular continuation. Gecko's |
98 | | * current reflow architecture does not allow us to set the overflow rects |
99 | | * for a whole chain of continuations for a given element at the point when |
100 | | * the last continuation is reflowed. See: |
101 | | * http://groups.google.com/group/mozilla.dev.tech.layout/msg/6b179066f3051f65 |
102 | | */ |
103 | | static nsRect |
104 | | ComputePostEffectsVisualOverflowRect(nsIFrame* aFrame, |
105 | | const nsRect& aPreEffectsOverflowRect); |
106 | | |
107 | | /** |
108 | | * Used to adjust the area of a frame that needs to be invalidated to take |
109 | | * account of SVG effects. |
110 | | * |
111 | | * @param aFrame The effects frame. |
112 | | * @param aToReferenceFrame The offset (in app units) from aFrame to its |
113 | | * reference display item. |
114 | | * @param aInvalidRegion The pre-effects invalid region in pixels relative to |
115 | | * the reference display item. |
116 | | * @return The post-effects invalid rect in pixels relative to the reference |
117 | | * display item. |
118 | | */ |
119 | | static nsIntRegion |
120 | | AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame, const nsPoint& aToReferenceFrame, |
121 | | const nsIntRegion& aInvalidRegion); |
122 | | |
123 | | /** |
124 | | * Figure out which area of the source is needed given an area to |
125 | | * repaint |
126 | | */ |
127 | | static nsRect |
128 | | GetRequiredSourceForInvalidArea(nsIFrame* aFrame, const nsRect& aDamageRect); |
129 | | |
130 | | /** |
131 | | * Returns true if the given point is not clipped out by effects. |
132 | | * @param aPt in appunits relative to aFrame |
133 | | */ |
134 | | static bool |
135 | | HitTestFrameForEffects(nsIFrame* aFrame, const nsPoint& aPt); |
136 | | |
137 | | struct MOZ_STACK_CLASS PaintFramesParams { |
138 | | gfxContext& ctx; |
139 | | nsIFrame* frame; |
140 | | const nsRect& dirtyRect; |
141 | | const nsRect& borderArea; |
142 | | nsDisplayListBuilder* builder; |
143 | | mozilla::layers::LayerManager* layerManager; |
144 | | bool handleOpacity; // If true, PaintMaskAndClipPath/ PaintFilter should |
145 | | // apply css opacity. |
146 | | IntRect maskRect; |
147 | | imgDrawingParams& imgParams; |
148 | | |
149 | | explicit PaintFramesParams(gfxContext& aCtx, nsIFrame* aFrame, |
150 | | const nsRect& aDirtyRect, |
151 | | const nsRect& aBorderArea, |
152 | | nsDisplayListBuilder* aBuilder, |
153 | | mozilla::layers::LayerManager* aLayerManager, |
154 | | bool aHandleOpacity, |
155 | | imgDrawingParams& aImgParams) |
156 | | : ctx(aCtx), frame(aFrame), dirtyRect(aDirtyRect), |
157 | | borderArea(aBorderArea), builder(aBuilder), |
158 | | layerManager(aLayerManager), handleOpacity(aHandleOpacity), |
159 | | imgParams(aImgParams) |
160 | 0 | { } |
161 | | }; |
162 | | |
163 | | /** |
164 | | * Paint non-SVG frame with mask, clipPath and opacity effect. |
165 | | */ |
166 | | static void |
167 | | PaintMaskAndClipPath(const PaintFramesParams& aParams); |
168 | | |
169 | | // This should use FunctionRef instead of std::function because we don't need |
170 | | // to take ownership of the function. See bug 1490781. |
171 | | static void |
172 | | PaintMaskAndClipPath(const PaintFramesParams& aParams, const std::function<void()>& aPaintChild); |
173 | | |
174 | | /** |
175 | | * Paint mask of non-SVG frame onto a given context, aParams.ctx. |
176 | | * aParams.ctx must contain an A8 surface. Returns false if the mask |
177 | | * didn't get painted and should be ignored at the call site. |
178 | | */ |
179 | | static bool |
180 | | PaintMask(const PaintFramesParams& aParams); |
181 | | |
182 | | /** |
183 | | * Return true if all the mask resource of aFrame are ready. |
184 | | */ |
185 | | static bool |
186 | | IsMaskResourceReady(nsIFrame* aFrame); |
187 | | |
188 | | /** |
189 | | * Paint non-SVG frame with filter and opacity effect. |
190 | | */ |
191 | | static void |
192 | | PaintFilter(const PaintFramesParams& aParams); |
193 | | |
194 | | /** |
195 | | * @param aRenderingContext the target rendering context in which the paint |
196 | | * server will be rendered |
197 | | * @param aTarget the target frame onto which the paint server will be |
198 | | * rendered |
199 | | * @param aPaintServer a first-continuation frame to use as the source |
200 | | * @param aFilter a filter to be applied when scaling |
201 | | * @param aDest the area the paint server image should be mapped to |
202 | | * @param aFill the area to be filled with copies of the paint server image |
203 | | * @param aAnchor a point in aFill which we will ensure is pixel-aligned in |
204 | | * the output |
205 | | * @param aDirty pixels outside this area may be skipped |
206 | | * @param aPaintServerSize the size that would be filled when using |
207 | | * background-repeat:no-repeat and background-size:auto. For normal background |
208 | | * images, this would be the intrinsic size of the image; for gradients and |
209 | | * patterns this would be the whole target frame fill area. |
210 | | * @param aFlags pass FLAG_SYNC_DECODE_IMAGES and any images in the paint |
211 | | * server will be decoding synchronously if they are not decoded already. |
212 | | */ |
213 | | enum { |
214 | | FLAG_SYNC_DECODE_IMAGES = 0x01, |
215 | | }; |
216 | | |
217 | | static already_AddRefed<gfxDrawable> |
218 | | DrawableFromPaintServer(nsIFrame* aFrame, |
219 | | nsIFrame* aTarget, |
220 | | const nsSize& aPaintServerSize, |
221 | | const mozilla::gfx::IntSize& aRenderSize, |
222 | | const DrawTarget* aDrawTarget, |
223 | | const gfxMatrix& aContextMatrix, |
224 | | uint32_t aFlags); |
225 | | |
226 | | /** |
227 | | * For non-SVG frames, this gives the offset to the frame's "user space". |
228 | | * For SVG frames, this returns a zero offset. |
229 | | */ |
230 | | static nsPoint |
231 | | GetOffsetToBoundingBox(nsIFrame* aFrame); |
232 | | }; |
233 | | |
234 | | #endif /*NSSVGINTEGRATIONUTILS_H_*/ |