Line data Source code
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 0 : 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 0 : SVGFETurbulenceElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
27 : {
28 0 : return SVGFETurbulenceElementBinding::Wrap(aCx, this, aGivenProto);
29 : }
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 : // nsIDOMNode methods
81 :
82 0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFETurbulenceElement)
83 :
84 : //----------------------------------------------------------------------
85 :
86 : already_AddRefed<SVGAnimatedNumber>
87 0 : SVGFETurbulenceElement::BaseFrequencyX()
88 : {
89 0 : return mNumberPairAttributes[BASE_FREQ].ToDOMAnimatedNumber(nsSVGNumberPair::eFirst, this);
90 : }
91 :
92 : already_AddRefed<SVGAnimatedNumber>
93 0 : SVGFETurbulenceElement::BaseFrequencyY()
94 : {
95 0 : return mNumberPairAttributes[BASE_FREQ].ToDOMAnimatedNumber(nsSVGNumberPair::eSecond, this);
96 : }
97 :
98 : already_AddRefed<SVGAnimatedInteger>
99 0 : SVGFETurbulenceElement::NumOctaves()
100 : {
101 0 : return mIntegerAttributes[OCTAVES].ToDOMAnimatedInteger(this);
102 : }
103 :
104 : already_AddRefed<SVGAnimatedNumber>
105 0 : SVGFETurbulenceElement::Seed()
106 : {
107 0 : return mNumberAttributes[SEED].ToDOMAnimatedNumber(this);
108 : }
109 :
110 : already_AddRefed<SVGAnimatedEnumeration>
111 0 : SVGFETurbulenceElement::StitchTiles()
112 : {
113 0 : return mEnumAttributes[STITCHTILES].ToDOMAnimatedEnum(this);
114 : }
115 :
116 : already_AddRefed<SVGAnimatedEnumeration>
117 0 : SVGFETurbulenceElement::Type()
118 : {
119 0 : return mEnumAttributes[TYPE].ToDOMAnimatedEnum(this);
120 : }
121 :
122 : FilterPrimitiveDescription
123 0 : SVGFETurbulenceElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
124 : const IntRect& aFilterSubregion,
125 : const nsTArray<bool>& aInputsAreTainted,
126 : nsTArray<RefPtr<SourceSurface>>& aInputImages)
127 : {
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 :
135 0 : if (fX == 0 || fY == 0) {
136 : // A base frequency of zero results in transparent black for
137 : // type="turbulence" and in 50% alpha 50% gray for type="fractalNoise".
138 0 : if (type == SVG_TURBULENCE_TYPE_TURBULENCE) {
139 0 : return FilterPrimitiveDescription(PrimitiveType::Empty);
140 : }
141 0 : FilterPrimitiveDescription descr(PrimitiveType::Flood);
142 0 : descr.Attributes().Set(eFloodColor, Color(0.5, 0.5, 0.5, 0.5));
143 0 : return descr;
144 : }
145 :
146 : // We interpret the base frequency as relative to user space units. In other
147 : // words, we consider one turbulence base period to be 1 / fX user space
148 : // units wide and 1 / fY user space units high. We do not scale the frequency
149 : // depending on the filter primitive region.
150 0 : gfxRect firstPeriodInUserSpace(0, 0, 1 / fX, 1 / fY);
151 0 : gfxRect firstPeriodInFilterSpace = aInstance->UserSpaceToFilterSpace(firstPeriodInUserSpace);
152 0 : Size frequencyInFilterSpace(1 / firstPeriodInFilterSpace.width,
153 0 : 1 / firstPeriodInFilterSpace.height);
154 0 : gfxPoint offset = firstPeriodInFilterSpace.TopLeft();
155 :
156 0 : FilterPrimitiveDescription descr(PrimitiveType::Turbulence);
157 0 : descr.Attributes().Set(eTurbulenceOffset, IntPoint::Truncate(offset.x, offset.y));
158 0 : descr.Attributes().Set(eTurbulenceBaseFrequency, frequencyInFilterSpace);
159 0 : descr.Attributes().Set(eTurbulenceSeed, seed);
160 0 : descr.Attributes().Set(eTurbulenceNumOctaves, octaves);
161 0 : descr.Attributes().Set(eTurbulenceStitchable, stitch == SVG_STITCHTYPE_STITCH);
162 0 : descr.Attributes().Set(eTurbulenceType, type);
163 0 : return descr;
164 : }
165 :
166 : bool
167 0 : SVGFETurbulenceElement::AttributeAffectsRendering(int32_t aNameSpaceID,
168 : nsIAtom* aAttribute) const
169 : {
170 0 : return SVGFETurbulenceElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
171 0 : (aNameSpaceID == kNameSpaceID_None &&
172 0 : (aAttribute == nsGkAtoms::seed ||
173 0 : aAttribute == nsGkAtoms::baseFrequency ||
174 0 : aAttribute == nsGkAtoms::numOctaves ||
175 0 : aAttribute == nsGkAtoms::type ||
176 0 : aAttribute == nsGkAtoms::stitchTiles));
177 : }
178 :
179 : //----------------------------------------------------------------------
180 : // nsSVGElement methods
181 :
182 : nsSVGElement::NumberAttributesInfo
183 0 : SVGFETurbulenceElement::GetNumberInfo()
184 : {
185 : return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
186 0 : ArrayLength(sNumberInfo));
187 : }
188 :
189 : nsSVGElement::NumberPairAttributesInfo
190 0 : SVGFETurbulenceElement::GetNumberPairInfo()
191 : {
192 : return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
193 0 : ArrayLength(sNumberPairInfo));
194 : }
195 :
196 : nsSVGElement::IntegerAttributesInfo
197 0 : SVGFETurbulenceElement::GetIntegerInfo()
198 : {
199 : return IntegerAttributesInfo(mIntegerAttributes, sIntegerInfo,
200 0 : ArrayLength(sIntegerInfo));
201 : }
202 :
203 : nsSVGElement::EnumAttributesInfo
204 0 : SVGFETurbulenceElement::GetEnumInfo()
205 : {
206 : return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
207 0 : ArrayLength(sEnumInfo));
208 : }
209 :
210 : nsSVGElement::StringAttributesInfo
211 0 : SVGFETurbulenceElement::GetStringInfo()
212 : {
213 : return StringAttributesInfo(mStringAttributes, sStringInfo,
214 0 : ArrayLength(sStringInfo));
215 : }
216 :
217 : } // namespace dom
218 : } // namespace mozilla
|