Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/svg/SVGFETurbulenceElement.cpp
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
#include "mozilla/dom/SVGFETurbulenceElement.h"
8
#include "mozilla/dom/SVGFETurbulenceElementBinding.h"
9
#include "nsSVGFilterInstance.h"
10
#include "nsSVGUtils.h"
11
12
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FETurbulence)
13
14
using namespace mozilla::gfx;
15
16
namespace mozilla {
17
namespace dom {
18
19
// Stitch Options
20
static const unsigned short SVG_STITCHTYPE_STITCH = 1;
21
static const unsigned short SVG_STITCHTYPE_NOSTITCH = 2;
22
23
static const int32_t MAX_OCTAVES = 10;
24
25
JSObject*
26
SVGFETurbulenceElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
27
0
{
28
0
  return SVGFETurbulenceElement_Binding::Wrap(aCx, this, aGivenProto);
29
0
}
30
31
nsSVGElement::NumberInfo SVGFETurbulenceElement::sNumberInfo[1] =
32
{
33
  { &nsGkAtoms::seed, 0, false }
34
};
35
36
nsSVGElement::NumberPairInfo SVGFETurbulenceElement::sNumberPairInfo[1] =
37
{
38
  { &nsGkAtoms::baseFrequency, 0, 0 }
39
};
40
41
nsSVGElement::IntegerInfo SVGFETurbulenceElement::sIntegerInfo[1] =
42
{
43
  { &nsGkAtoms::numOctaves, 1 }
44
};
45
46
nsSVGEnumMapping SVGFETurbulenceElement::sTypeMap[] = {
47
  {&nsGkAtoms::fractalNoise,
48
   SVG_TURBULENCE_TYPE_FRACTALNOISE},
49
  {&nsGkAtoms::turbulence,
50
   SVG_TURBULENCE_TYPE_TURBULENCE},
51
  {nullptr, 0}
52
};
53
54
nsSVGEnumMapping SVGFETurbulenceElement::sStitchTilesMap[] = {
55
  {&nsGkAtoms::stitch,
56
   SVG_STITCHTYPE_STITCH},
57
  {&nsGkAtoms::noStitch,
58
   SVG_STITCHTYPE_NOSTITCH},
59
  {nullptr, 0}
60
};
61
62
nsSVGElement::EnumInfo SVGFETurbulenceElement::sEnumInfo[2] =
63
{
64
  { &nsGkAtoms::type,
65
    sTypeMap,
66
    SVG_TURBULENCE_TYPE_TURBULENCE
67
  },
68
  { &nsGkAtoms::stitchTiles,
69
    sStitchTilesMap,
70
    SVG_STITCHTYPE_NOSTITCH
71
  }
72
};
73
74
nsSVGElement::StringInfo SVGFETurbulenceElement::sStringInfo[1] =
75
{
76
  { &nsGkAtoms::result, kNameSpaceID_None, true }
77
};
78
79
//----------------------------------------------------------------------
80
// nsINode methods
81
82
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFETurbulenceElement)
83
84
//----------------------------------------------------------------------
85
86
already_AddRefed<SVGAnimatedNumber>
87
SVGFETurbulenceElement::BaseFrequencyX()
88
0
{
89
0
  return mNumberPairAttributes[BASE_FREQ].ToDOMAnimatedNumber(nsSVGNumberPair::eFirst, this);
90
0
}
91
92
already_AddRefed<SVGAnimatedNumber>
93
SVGFETurbulenceElement::BaseFrequencyY()
94
0
{
95
0
  return mNumberPairAttributes[BASE_FREQ].ToDOMAnimatedNumber(nsSVGNumberPair::eSecond, this);
96
0
}
97
98
already_AddRefed<SVGAnimatedInteger>
99
SVGFETurbulenceElement::NumOctaves()
100
0
{
101
0
  return mIntegerAttributes[OCTAVES].ToDOMAnimatedInteger(this);
102
0
}
103
104
already_AddRefed<SVGAnimatedNumber>
105
SVGFETurbulenceElement::Seed()
106
0
{
107
0
  return mNumberAttributes[SEED].ToDOMAnimatedNumber(this);
108
0
}
109
110
already_AddRefed<SVGAnimatedEnumeration>
111
SVGFETurbulenceElement::StitchTiles()
112
0
{
113
0
  return mEnumAttributes[STITCHTILES].ToDOMAnimatedEnum(this);
114
0
}
115
116
already_AddRefed<SVGAnimatedEnumeration>
117
SVGFETurbulenceElement::Type()
118
0
{
119
0
  return mEnumAttributes[TYPE].ToDOMAnimatedEnum(this);
120
0
}
121
122
FilterPrimitiveDescription
123
SVGFETurbulenceElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
124
                                                const IntRect& aFilterSubregion,
125
                                                const nsTArray<bool>& aInputsAreTainted,
126
                                                nsTArray<RefPtr<SourceSurface>>& aInputImages)
127
0
{
128
0
  float fX = mNumberPairAttributes[BASE_FREQ].GetAnimValue(nsSVGNumberPair::eFirst);
129
0
  float fY = mNumberPairAttributes[BASE_FREQ].GetAnimValue(nsSVGNumberPair::eSecond);
130
0
  float seed = mNumberAttributes[OCTAVES].GetAnimValue();
131
0
  uint32_t octaves = clamped(mIntegerAttributes[OCTAVES].GetAnimValue(), 0, MAX_OCTAVES);
132
0
  uint32_t type = mEnumAttributes[TYPE].GetAnimValue();
133
0
  uint16_t stitch = mEnumAttributes[STITCHTILES].GetAnimValue();
134
0
135
0
  if (fX == 0 && fY == 0) {
136
0
    // A base frequency of zero results in transparent black for
137
0
    // type="turbulence" and in 50% alpha 50% gray for type="fractalNoise".
138
0
    if (type == SVG_TURBULENCE_TYPE_TURBULENCE) {
139
0
      return FilterPrimitiveDescription();
140
0
    }
141
0
    FloodAttributes atts;
142
0
    atts.mColor = Color(0.5, 0.5, 0.5, 0.5);
143
0
    return FilterPrimitiveDescription(AsVariant(std::move(atts)));
144
0
  }
145
0
146
0
  // We interpret the base frequency as relative to user space units. In other
147
0
  // words, we consider one turbulence base period to be 1 / fX user space
148
0
  // units wide and 1 / fY user space units high. We do not scale the frequency
149
0
  // depending on the filter primitive region.
150
0
  // We now convert the frequency from user space to filter space.
151
0
  // If a frequency in user space units is zero, then it will also be zero in
152
0
  // filter space. During the conversion we use a dummy period length of 1
153
0
  // for those frequencies but then ignore the converted length and use 0
154
0
  // for the converted frequency. This avoids division by zero.
155
0
  gfxRect firstPeriodInUserSpace(0, 0,
156
0
                                 fX == 0 ? 1 : (1 / fX),
157
0
                                 fY == 0 ? 1 : (1 / fY));
158
0
  gfxRect firstPeriodInFilterSpace = aInstance->UserSpaceToFilterSpace(firstPeriodInUserSpace);
159
0
  Size frequencyInFilterSpace(fX == 0 ? 0 : (1 / firstPeriodInFilterSpace.width),
160
0
                              fY == 0 ? 0 : (1 / firstPeriodInFilterSpace.height));
161
0
  gfxPoint offset = firstPeriodInFilterSpace.TopLeft();
162
0
163
0
  TurbulenceAttributes atts;
164
0
  atts.mOffset = IntPoint::Truncate(offset.x, offset.y);
165
0
  atts.mBaseFrequency = frequencyInFilterSpace;
166
0
  atts.mSeed = seed;
167
0
  atts.mOctaves = octaves;
168
0
  atts.mStitchable = stitch == SVG_STITCHTYPE_STITCH;
169
0
  atts.mType = type;
170
0
  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
171
0
}
172
173
bool
174
SVGFETurbulenceElement::AttributeAffectsRendering(int32_t aNameSpaceID,
175
                                                    nsAtom* aAttribute) const
176
0
{
177
0
  return SVGFETurbulenceElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
178
0
         (aNameSpaceID == kNameSpaceID_None &&
179
0
          (aAttribute == nsGkAtoms::seed ||
180
0
           aAttribute == nsGkAtoms::baseFrequency ||
181
0
           aAttribute == nsGkAtoms::numOctaves ||
182
0
           aAttribute == nsGkAtoms::type ||
183
0
           aAttribute == nsGkAtoms::stitchTiles));
184
0
}
185
186
//----------------------------------------------------------------------
187
// nsSVGElement methods
188
189
nsSVGElement::NumberAttributesInfo
190
SVGFETurbulenceElement::GetNumberInfo()
191
0
{
192
0
  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
193
0
                              ArrayLength(sNumberInfo));
194
0
}
195
196
nsSVGElement::NumberPairAttributesInfo
197
SVGFETurbulenceElement::GetNumberPairInfo()
198
0
{
199
0
  return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
200
0
                                 ArrayLength(sNumberPairInfo));
201
0
}
202
203
nsSVGElement::IntegerAttributesInfo
204
SVGFETurbulenceElement::GetIntegerInfo()
205
0
{
206
0
  return IntegerAttributesInfo(mIntegerAttributes, sIntegerInfo,
207
0
                               ArrayLength(sIntegerInfo));
208
0
}
209
210
nsSVGElement::EnumAttributesInfo
211
SVGFETurbulenceElement::GetEnumInfo()
212
0
{
213
0
  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
214
0
                            ArrayLength(sEnumInfo));
215
0
}
216
217
nsSVGElement::StringAttributesInfo
218
SVGFETurbulenceElement::GetStringInfo()
219
0
{
220
0
  return StringAttributesInfo(mStringAttributes, sStringInfo,
221
0
                              ArrayLength(sStringInfo));
222
0
}
223
224
} // namespace dom
225
} // namespace mozilla