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