Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/svg/nsSVGGradientFrame.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_SVGGRADIENTFRAME_H__
8
#define __NS_SVGGRADIENTFRAME_H__
9
10
#include "mozilla/Attributes.h"
11
#include "gfxMatrix.h"
12
#include "gfxRect.h"
13
#include "nsCOMPtr.h"
14
#include "nsFrame.h"
15
#include "nsLiteralString.h"
16
#include "nsSVGPaintServerFrame.h"
17
18
class gfxPattern;
19
class nsAtom;
20
class nsIContent;
21
class nsIPresShell;
22
23
namespace mozilla {
24
class nsSVGAnimatedTransformList;
25
26
namespace dom {
27
class SVGLinearGradientElement;
28
class SVGRadialGradientElement;
29
} // namespace dom
30
} // namespace mozilla
31
32
/**
33
 * Gradients can refer to other gradients. We create an nsSVGPaintingProperty
34
 * with property type nsGkAtoms::href to track the referenced gradient.
35
 */
36
class nsSVGGradientFrame : public nsSVGPaintServerFrame
37
{
38
  typedef mozilla::gfx::ExtendMode ExtendMode;
39
40
protected:
41
  nsSVGGradientFrame(ComputedStyle* aStyle, ClassID aID);
42
43
public:
44
  NS_DECL_ABSTRACT_FRAME(nsSVGGradientFrame)
45
46
  // nsSVGPaintServerFrame methods:
47
  virtual already_AddRefed<gfxPattern>
48
    GetPaintServerPattern(nsIFrame *aSource,
49
                          const DrawTarget* aDrawTarget,
50
                          const gfxMatrix& aContextMatrix,
51
                          nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
52
                          float aOpacity,
53
                          imgDrawingParams& aImgParams,
54
                          const gfxRect* aOverrideBounds) override;
55
56
  // nsIFrame interface:
57
  virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
58
                                    nsAtom*        aAttribute,
59
                                    int32_t         aModType) override;
60
61
#ifdef DEBUG_FRAME_DUMP
62
  virtual nsresult GetFrameName(nsAString& aResult) const override
63
  {
64
    return MakeFrameName(NS_LITERAL_STRING("SVGGradient"), aResult);
65
  }
66
#endif // DEBUG
67
68
private:
69
70
  // Parse our xlink:href and set up our nsSVGPaintingProperty if we
71
  // reference another gradient and we don't have a property. Return
72
  // the referenced gradient's frame if available, null otherwise.
73
  nsSVGGradientFrame* GetReferencedGradient();
74
75
  // Optionally get a stop frame (returns stop index/count)
76
  void GetStopFrames(nsTArray<nsIFrame*>* aStopFrames);
77
78
  const mozilla::nsSVGAnimatedTransformList* GetGradientTransformList(
79
    nsIContent* aDefault);
80
  // Will be singular for gradientUnits="objectBoundingBox" with an empty bbox.
81
  gfxMatrix GetGradientTransform(nsIFrame *aSource,
82
                                 const gfxRect *aOverrideBounds);
83
84
protected:
85
  virtual bool GradientVectorLengthIsZero() = 0;
86
  virtual already_AddRefed<gfxPattern> CreateGradient() = 0;
87
88
  // Accessors to lookup gradient attributes
89
  uint16_t GetEnumValue(uint32_t aIndex, nsIContent *aDefault);
90
  uint16_t GetEnumValue(uint32_t aIndex)
91
0
  {
92
0
    return GetEnumValue(aIndex, mContent);
93
0
  }
94
  uint16_t GetGradientUnits();
95
  uint16_t GetSpreadMethod();
96
97
  // Gradient-type-specific lookups since the length values differ between
98
  // linear and radial gradients
99
  virtual mozilla::dom::SVGLinearGradientElement * GetLinearGradientWithLength(
100
    uint32_t aIndex, mozilla::dom::SVGLinearGradientElement* aDefault);
101
  virtual mozilla::dom::SVGRadialGradientElement * GetRadialGradientWithLength(
102
    uint32_t aIndex, mozilla::dom::SVGRadialGradientElement* aDefault);
103
104
  // The frame our gradient is (currently) being applied to
105
  nsIFrame*                              mSource;
106
107
private:
108
  // Flag to mark this frame as "in use" during recursive calls along our
109
  // gradient's reference chain so we can detect reference loops. See:
110
  // http://www.w3.org/TR/SVG11/pservers.html#LinearGradientElementHrefAttribute
111
  bool                                   mLoopFlag;
112
  // Gradients often don't reference other gradients, so here we cache
113
  // the fact that that isn't happening.
114
  bool                                   mNoHRefURI;
115
};
116
117
118
// -------------------------------------------------------------------------
119
// Linear Gradients
120
// -------------------------------------------------------------------------
121
122
class nsSVGLinearGradientFrame final : public nsSVGGradientFrame
123
{
124
  friend nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
125
                                                ComputedStyle* aStyle);
126
protected:
127
  explicit nsSVGLinearGradientFrame(ComputedStyle* aStyle)
128
    : nsSVGGradientFrame(aStyle, kClassID)
129
0
  {}
130
131
public:
132
  NS_DECL_FRAMEARENA_HELPERS(nsSVGLinearGradientFrame)
133
134
  // nsIFrame interface:
135
#ifdef DEBUG
136
  virtual void Init(nsIContent*       aContent,
137
                    nsContainerFrame* aParent,
138
                    nsIFrame*         aPrevInFlow) override;
139
#endif
140
141
  virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
142
                                    nsAtom*        aAttribute,
143
                                    int32_t         aModType) override;
144
145
#ifdef DEBUG_FRAME_DUMP
146
  virtual nsresult GetFrameName(nsAString& aResult) const override
147
  {
148
    return MakeFrameName(NS_LITERAL_STRING("SVGLinearGradient"), aResult);
149
  }
150
#endif // DEBUG
151
152
protected:
153
  float GetLengthValue(uint32_t aIndex);
154
  virtual mozilla::dom::SVGLinearGradientElement* GetLinearGradientWithLength(
155
    uint32_t aIndex, mozilla::dom::SVGLinearGradientElement* aDefault) override;
156
  virtual bool GradientVectorLengthIsZero() override;
157
  virtual already_AddRefed<gfxPattern> CreateGradient() override;
158
};
159
160
// -------------------------------------------------------------------------
161
// Radial Gradients
162
// -------------------------------------------------------------------------
163
164
class nsSVGRadialGradientFrame final : public nsSVGGradientFrame
165
{
166
  friend nsIFrame* NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
167
                                                ComputedStyle* aStyle);
168
protected:
169
  explicit nsSVGRadialGradientFrame(ComputedStyle* aStyle)
170
    : nsSVGGradientFrame(aStyle, kClassID)
171
0
  {}
172
173
public:
174
  NS_DECL_FRAMEARENA_HELPERS(nsSVGRadialGradientFrame)
175
176
  // nsIFrame interface:
177
#ifdef DEBUG
178
  virtual void Init(nsIContent*       aContent,
179
                    nsContainerFrame* aParent,
180
                    nsIFrame*         aPrevInFlow) override;
181
#endif
182
183
  virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
184
                                    nsAtom*        aAttribute,
185
                                    int32_t         aModType) override;
186
187
#ifdef DEBUG_FRAME_DUMP
188
  virtual nsresult GetFrameName(nsAString& aResult) const override
189
  {
190
    return MakeFrameName(NS_LITERAL_STRING("SVGRadialGradient"), aResult);
191
  }
192
#endif // DEBUG
193
194
protected:
195
  float GetLengthValue(uint32_t aIndex);
196
  float GetLengthValue(uint32_t aIndex, float aDefaultValue);
197
  float GetLengthValueFromElement(uint32_t aIndex,
198
                                  mozilla::dom::SVGRadialGradientElement& aElement);
199
  virtual mozilla::dom::SVGRadialGradientElement* GetRadialGradientWithLength(
200
    uint32_t aIndex, mozilla::dom::SVGRadialGradientElement* aDefault) override;
201
  virtual bool GradientVectorLengthIsZero() override;
202
  virtual already_AddRefed<gfxPattern> CreateGradient() override;
203
};
204
205
#endif // __NS_SVGGRADIENTFRAME_H__
206