Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/svg/nsSVGClipPathFrame.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 __NS_SVGCLIPPATHFRAME_H__
8
#define __NS_SVGCLIPPATHFRAME_H__
9
10
#include "gfxMatrix.h"
11
#include "mozilla/Attributes.h"
12
#include "nsSVGContainerFrame.h"
13
#include "nsSVGUtils.h"
14
15
class gfxContext;
16
class nsSVGDisplayableFrame;
17
18
class nsSVGClipPathFrame final : public nsSVGContainerFrame
19
{
20
  friend nsIFrame*
21
  NS_NewSVGClipPathFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle);
22
23
  typedef mozilla::gfx::Matrix Matrix;
24
  typedef mozilla::gfx::SourceSurface SourceSurface;
25
  typedef mozilla::image::imgDrawingParams imgDrawingParams;
26
27
protected:
28
  explicit nsSVGClipPathFrame(ComputedStyle* aStyle)
29
    : nsSVGContainerFrame(aStyle, kClassID)
30
    , mIsBeingProcessed(false)
31
0
  {
32
0
    AddStateBits(NS_FRAME_IS_NONDISPLAY);
33
0
  }
34
35
public:
36
  NS_DECL_FRAMEARENA_HELPERS(nsSVGClipPathFrame)
37
38
  // nsIFrame methods:
39
  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
40
0
                                const nsDisplayListSet& aLists) override {}
41
42
  // nsSVGClipPathFrame methods:
43
44
  /**
45
   * Applies the clipPath by pushing a clip path onto the DrawTarget.
46
   *
47
   * This method must only be used if IsTrivial() returns true, otherwise use
48
   * GetClipMask.
49
   *
50
   * @param aContext The context that the clip path is to be applied to.
51
   * @param aClippedFrame The/an nsIFrame of the element that references this
52
   *   clipPath that is currently being processed.
53
   * @param aMatrix The transform from aClippedFrame's user space to aContext's
54
   *   current transform.
55
   */
56
  void ApplyClipPath(gfxContext& aContext,
57
                     nsIFrame* aClippedFrame,
58
                     const gfxMatrix &aMatrix);
59
60
  /**
61
   * Returns an alpha mask surface containing the clipping geometry.
62
   *
63
   * This method must only be used if IsTrivial() returns false, otherwise use
64
   * ApplyClipPath.
65
   *
66
   * @param aReferenceContext Used to determine the backend for and size of the
67
   *   returned SourceSurface, the size being limited to the device space clip
68
   *   extents on the context.
69
   * @param aClippedFrame The/an nsIFrame of the element that references this
70
   *   clipPath that is currently being processed.
71
   * @param aMatrix The transform from aClippedFrame's user space to aContext's
72
   *   current transform.
73
   * @param [out] aMaskTransform The transform to use with the returned
74
   *   surface.
75
   * @param [in, optional] aExtraMask An extra surface that the returned
76
   *   surface should be masked with.
77
   * @param [in, optional] aExtraMasksTransform The transform to use with
78
   *   aExtraMask. Should be passed when aExtraMask is passed.
79
   */
80
  already_AddRefed<SourceSurface>
81
  GetClipMask(gfxContext& aReferenceContext, nsIFrame* aClippedFrame,
82
              const gfxMatrix& aMatrix, Matrix* aMaskTransform,
83
              SourceSurface* aExtraMask = nullptr,
84
              const Matrix& aExtraMasksTransform = Matrix());
85
86
  /**
87
   * Paint mask directly onto a given context(aMaskContext).
88
   *
89
   * @param aMaskContext The target of mask been painting on.
90
   * @param aClippedFrame The/an nsIFrame of the element that references this
91
   *   clipPath that is currently being processed.
92
   * @param aMatrix The transform from aClippedFrame's user space to
93
   *   current transform.
94
   * @param [out] aMaskTransform The transform to use with the returned
95
   *   surface.
96
   * @param [in, optional] aExtraMask An extra surface that the returned
97
   *   surface should be masked with.
98
   * @param [in, optional] aExtraMasksTransform The transform to use with
99
   *   aExtraMask. Should be passed when aExtraMask is passed.
100
   */
101
  void
102
  PaintClipMask(gfxContext& aMaskContext, nsIFrame* aClippedFrame,
103
                const gfxMatrix& aMatrix, Matrix* aMaskTransform,
104
                SourceSurface* aExtraMask, const Matrix& aExtraMasksTransform);
105
106
  /**
107
   * aPoint is expected to be in aClippedFrame's SVG user space.
108
   */
109
  bool PointIsInsideClipPath(nsIFrame* aClippedFrame, const gfxPoint &aPoint);
110
111
  // Check if this clipPath is made up of more than one geometry object.
112
  // If so, the clipping API in cairo isn't enough and we need to use
113
  // mask based clipping.
114
  bool IsTrivial(nsSVGDisplayableFrame **aSingleChild = nullptr);
115
116
  bool IsValid();
117
118
  // nsIFrame interface:
119
  virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
120
                                    nsAtom*        aAttribute,
121
                                    int32_t         aModType) override;
122
123
  virtual void Init(nsIContent*       aContent,
124
                    nsContainerFrame* aParent,
125
                    nsIFrame*         aPrevInFlow) override;
126
127
#ifdef DEBUG_FRAME_DUMP
128
  virtual nsresult GetFrameName(nsAString& aResult) const override
129
  {
130
    return MakeFrameName(NS_LITERAL_STRING("SVGClipPath"), aResult);
131
  }
132
#endif
133
134
  SVGBBox GetBBoxForClipPathFrame(const SVGBBox& aBBox,
135
                                  const gfxMatrix& aMatrix,
136
                                  uint32_t aFlags);
137
138
  /**
139
   * If the clipPath element transforms its children due to
140
   * clipPathUnits="objectBoundingBox" being set on it and/or due to the
141
   * 'transform' attribute being set on it, this function returns the resulting
142
   * transform.
143
   */
144
  gfxMatrix GetClipPathTransform(nsIFrame* aClippedFrame);
145
146
private:
147
148
  // nsSVGContainerFrame methods:
149
  virtual gfxMatrix GetCanvasTM() override;
150
151
  already_AddRefed<DrawTarget> CreateClipMask(gfxContext& aReferenceContext,
152
                                              mozilla::gfx::IntPoint& aOffset);
153
154
  void PaintFrameIntoMask(nsIFrame *aFrame, nsIFrame* aClippedFrame,
155
                          gfxContext& aTarget, const gfxMatrix& aMatrix);
156
157
  // Set, during a GetClipMask() call, to the transform that still needs to be
158
  // concatenated to the transform of the DrawTarget that was passed to
159
  // GetClipMask in order to establish the coordinate space that the clipPath
160
  // establishes for its contents (i.e. including applying 'clipPathUnits' and
161
  // any 'transform' attribute set on the clipPath) specifically for clipping
162
  // the frame that was passed to GetClipMask at that moment in time.  This is
163
  // set so that if our GetCanvasTM method is called while GetClipMask is
164
  // painting its children, the returned matrix will include the transforms
165
  // that should be used when creating the mask for the frame passed to
166
  // GetClipMask.
167
  //
168
  // Note: The removal of GetCanvasTM is nearly complete, so our GetCanvasTM
169
  // may not even be called soon/any more.
170
  gfxMatrix mMatrixForChildren;
171
172
  // Flag used to indicate whether a methods that may reenter due to
173
  // following a reference to another instance is currently executing.
174
  bool mIsBeingProcessed;
175
};
176
177
#endif