Coverage Report

Created: 2018-09-25 14:53

/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_*/