Bug 1867925 - Mark some storage-access-api tests as intermittent after wpt-sync....
[gecko.git] / layout / svg / SVGIntegrationUtils.h
blobb53f2b629495c843cf6863b0aa72877d85c7c911
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/. */
7 #ifndef LAYOUT_SVG_SVGINTEGRATIONUTILS_H_
8 #define LAYOUT_SVG_SVGINTEGRATIONUTILS_H_
10 #include "ImgDrawResult.h"
11 #include "gfxMatrix.h"
12 #include "gfxRect.h"
13 #include "nsRegionFwd.h"
14 #include "mozilla/gfx/Rect.h"
15 #include "mozilla/ServoStyleConsts.h"
16 #include "mozilla/webrender/WebRenderTypes.h"
18 class gfxContext;
19 class gfxDrawable;
20 class nsIFrame;
21 struct nsPoint;
22 struct nsRect;
23 struct nsSize;
25 struct WrFiltersHolder {
26 nsTArray<mozilla::wr::FilterOp> filters;
27 nsTArray<mozilla::wr::WrFilterData> filter_datas;
28 mozilla::Maybe<nsRect> post_filters_clip;
29 // This exists just to own the values long enough for them to be copied into
30 // rust.
31 nsTArray<nsTArray<float>> values;
34 namespace mozilla {
35 class nsDisplayList;
36 class nsDisplayListBuilder;
38 /**
39 * Whether we're dealing with a backdrop-filter or a filter.
41 enum class StyleFilterType : uint8_t { BackdropFilter, Filter };
43 namespace gfx {
44 class DrawTarget;
45 } // namespace gfx
47 /**
48 * Integration of SVG effects (clipPath clipping, masking and filters) into
49 * regular display list based painting and hit-testing.
51 class SVGIntegrationUtils final {
52 using DrawTarget = gfx::DrawTarget;
53 using IntRect = gfx::IntRect;
54 using imgDrawingParams = image::imgDrawingParams;
56 public:
57 /**
58 * Returns true if SVG effects that affect the overflow of the given frame
59 * are currently applied to the frame.
61 static bool UsingOverflowAffectingEffects(const nsIFrame* aFrame);
63 /**
64 * Returns true if SVG effects are currently applied to this frame.
66 static bool UsingEffectsForFrame(const nsIFrame* aFrame);
68 /**
69 * Returns the size of the union of the border-box rects of all of
70 * aNonSVGFrame's continuations.
72 static nsSize GetContinuationUnionSize(nsIFrame* aNonSVGFrame);
74 /**
75 * When SVG effects need to resolve percentage, userSpaceOnUse lengths, they
76 * need a coordinate context to resolve them against. This method provides
77 * that coordinate context for non-SVG frames with SVG effects applied to
78 * them. The gfxSize returned is the size of the union of all of the given
79 * frame's continuations' border boxes, converted to SVG user units (equal to
80 * CSS px units), as required by the SVG code.
82 static gfx::Size GetSVGCoordContextForNonSVGFrame(nsIFrame* aNonSVGFrame);
84 /**
85 * SVG effects such as SVG filters, masking and clipPath may require an SVG
86 * "bbox" for the element they're being applied to in order to make decisions
87 * about positioning, and to resolve various lengths against. This method
88 * provides the "bbox" for non-SVG frames. The bbox returned is in CSS px
89 * units, and aUnionContinuations decide whether bbox contains the area of
90 * current frame only or the union of all aNonSVGFrame's continuations'
91 * overflow areas, relative to the top-left of the union of all aNonSVGFrame's
92 * continuations' border box rects.
94 static gfxRect GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame,
95 bool aUnionContinuations);
97 /**
98 * Used to adjust a frame's pre-effects ink overflow rect to take account
99 * of SVG effects.
101 * XXX This method will not do the right thing for frames with continuations.
102 * It really needs all the continuations to have been reflowed before being
103 * called, but we currently call it on each continuation as its overflow
104 * rects are set during the reflow of each particular continuation. Gecko's
105 * current reflow architecture does not allow us to set the overflow rects
106 * for a whole chain of continuations for a given element at the point when
107 * the last continuation is reflowed. See:
108 * http://groups.google.com/group/mozilla.dev.tech.layout/msg/6b179066f3051f65
110 static nsRect ComputePostEffectsInkOverflowRect(
111 nsIFrame* aFrame, const nsRect& aPreEffectsOverflowRect);
114 * Figure out which area of the source is needed given an area to
115 * repaint
117 static nsRect GetRequiredSourceForInvalidArea(nsIFrame* aFrame,
118 const nsRect& aDirtyRect);
121 * Returns true if the given point is not clipped out by effects.
122 * @param aPt in appunits relative to aFrame
124 static bool HitTestFrameForEffects(nsIFrame* aFrame, const nsPoint& aPt);
126 struct MOZ_STACK_CLASS PaintFramesParams {
127 gfxContext& ctx;
128 nsIFrame* frame;
129 nsRect dirtyRect;
130 nsRect borderArea;
131 nsDisplayListBuilder* builder;
132 bool handleOpacity; // If true, PaintMaskAndClipPath/ PaintFilter should
133 // apply css opacity.
134 Maybe<LayoutDeviceRect> maskRect;
135 imgDrawingParams& imgParams;
137 explicit PaintFramesParams(gfxContext& aCtx, nsIFrame* aFrame,
138 const nsRect& aDirtyRect,
139 const nsRect& aBorderArea,
140 nsDisplayListBuilder* aBuilder,
141 bool aHandleOpacity,
142 imgDrawingParams& aImgParams)
143 : ctx(aCtx),
144 frame(aFrame),
145 dirtyRect(aDirtyRect),
146 borderArea(aBorderArea),
147 builder(aBuilder),
148 handleOpacity(aHandleOpacity),
149 imgParams(aImgParams) {}
152 // This should use FunctionRef instead of std::function because we don't need
153 // to take ownership of the function. See bug 1490781.
154 static void PaintMaskAndClipPath(const PaintFramesParams& aParams,
155 const std::function<void()>& aPaintChild);
158 * Paint mask of frame onto a given context, aParams.ctx.
159 * aParams.ctx must contain an A8 surface. Returns false if the mask
160 * didn't get painted and should be ignored at the call site.
161 * isMaskComplete is an outparameter returning whether the mask is complete.
162 * Incomplete masks should not be drawn and the proper fallback behaviour
163 * depends on if the masked element is html or svg.
165 static bool PaintMask(const PaintFramesParams& aParams,
166 bool& aOutIsMaskComplete);
169 * Paint the frame contents.
170 * SVG frames will have had matrix propagation set to false already.
171 * Non-SVG frames have to do their own thing.
172 * The caller will do a Save()/Restore() as necessary so feel free
173 * to mess with context state.
174 * The context will be configured to use the "user space" coordinate
175 * system if passing aTransform/aDirtyRect, or untouched otherwise.
176 * @param aImgParams the params to draw with.
177 * @param aTransform the user-to-device space matrix, if painting with
178 * filters.
179 * @param aDirtyRect the dirty rect *in user space pixels*
181 using SVGFilterPaintCallback = std::function<void(
182 gfxContext& aContext, imgDrawingParams&, const gfxMatrix* aTransform,
183 const nsIntRect* aDirtyRect)>;
186 * Paint non-SVG frame with filter and opacity effect.
188 static void PaintFilter(const PaintFramesParams& aParams,
189 Span<const StyleFilter> aFilters,
190 const SVGFilterPaintCallback& aCallback);
193 * Build WebRender filters for a frame with CSS filters applied to it.
195 static bool CreateWebRenderCSSFilters(Span<const StyleFilter> aFilters,
196 nsIFrame* aFrame,
197 WrFiltersHolder& aWrFilters);
200 * Try to build WebRender filters for a frame with SVG filters applied to it
201 * if the filters are supported.
203 static bool BuildWebRenderFilters(nsIFrame* aFilteredFrame,
204 Span<const StyleFilter> aFilters,
205 StyleFilterType aStyleFilterType,
206 WrFiltersHolder& aWrFilters,
207 bool& aInitialized);
210 * Check if the filters present on |aFrame| are supported by WebRender.
212 static bool CanCreateWebRenderFiltersForFrame(nsIFrame* aFrame);
215 * Check if |aFrame| uses any SVG effects that cannot be rendered in the
216 * compositor.
218 static bool UsesSVGEffectsNotSupportedInCompositor(nsIFrame* aFrame);
221 * @param aRenderingContext the target rendering context in which the paint
222 * server will be rendered
223 * @param aTarget the target frame onto which the paint server will be
224 * rendered
225 * @param aPaintServer a first-continuation frame to use as the source
226 * @param aFilter a filter to be applied when scaling
227 * @param aDest the area the paint server image should be mapped to
228 * @param aFill the area to be filled with copies of the paint server image
229 * @param aAnchor a point in aFill which we will ensure is pixel-aligned in
230 * the output
231 * @param aDirty pixels outside this area may be skipped
232 * @param aPaintServerSize the size that would be filled when using
233 * background-repeat:no-repeat and background-size:auto. For normal background
234 * images, this would be the intrinsic size of the image; for gradients and
235 * patterns this would be the whole target frame fill area.
236 * @param aFlags pass FLAG_SYNC_DECODE_IMAGES and any images in the paint
237 * server will be decoding synchronously if they are not decoded already.
239 enum {
240 FLAG_SYNC_DECODE_IMAGES = 0x01,
243 static already_AddRefed<gfxDrawable> DrawableFromPaintServer(
244 nsIFrame* aFrame, nsIFrame* aTarget, const nsSize& aPaintServerSize,
245 const gfx::IntSize& aRenderSize, const DrawTarget* aDrawTarget,
246 const gfxMatrix& aContextMatrix, uint32_t aFlags);
249 * For non-SVG frames, this gives the offset to the frame's "user space".
250 * For SVG frames, this returns a zero offset.
252 static nsPoint GetOffsetToBoundingBox(nsIFrame* aFrame);
255 * The offset between the reference frame and the bounding box of the
256 * target frame in device units.
258 static gfxPoint GetOffsetToUserSpaceInDevPx(nsIFrame* aFrame,
259 const PaintFramesParams& aParams);
262 } // namespace mozilla
264 #endif // LAYOUT_SVG_SVGINTEGRATIONUTILS_H_