JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_ColourGradient.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
30{
31 #if JUCE_DEBUG
32 point1.setX (987654.0f);
33 #define JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED jassert (! exactlyEqual (point1.x, 987654.0f));
34 #else
35 #define JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED
36 #endif
37}
38
40 : point1 (other.point1), point2 (other.point2), isRadial (other.isRadial), colours (other.colours)
41{}
42
43ColourGradient::ColourGradient (ColourGradient&& other) noexcept
44 : point1 (other.point1), point2 (other.point2), isRadial (other.isRadial),
45 colours (std::move (other.colours))
46{}
47
48ColourGradient& ColourGradient::operator= (const ColourGradient& other)
49{
50 point1 = other.point1;
51 point2 = other.point2;
52 isRadial = other.isRadial;
53 colours = other.colours;
54 return *this;
55}
56
57ColourGradient& ColourGradient::operator= (ColourGradient&& other) noexcept
58{
59 point1 = other.point1;
60 point2 = other.point2;
61 isRadial = other.isRadial;
62 colours = std::move (other.colours);
63 return *this;
64}
65
67 Colour colour2, float x2, float y2, bool radial)
69 colour2, Point<float> (x2, y2), radial)
70{
71}
72
75 : point1 (p1),
76 point2 (p2),
77 isRadial (radial)
78{
79 colours.add (ColourPoint { 0.0, colour1 },
80 ColourPoint { 1.0, colour2 });
81}
82
84
86{
87 return { c1, 0, y1, c2, 0, y2, false };
88}
89
91{
92 return { c1, x1, 0, c2, x2, 0, false };
93}
94
95bool ColourGradient::operator== (const ColourGradient& other) const noexcept
96{
97 return point1 == other.point1 && point2 == other.point2
98 && isRadial == other.isRadial
99 && colours == other.colours;
100}
101
102bool ColourGradient::operator!= (const ColourGradient& other) const noexcept
103{
104 return ! operator== (other);
105}
106
107//==============================================================================
109{
110 colours.clear();
111}
112
114{
115 // must be within the two end-points
117
119 {
120 colours.set (0, { 0.0, colour });
121 return 0;
122 }
123
124 auto pos = jmin (1.0, proportionAlongGradient);
125
126 int i;
127 for (i = 0; i < colours.size(); ++i)
128 if (colours.getReference (i).position > pos)
129 break;
130
131 colours.insert (i, { pos, colour });
132 return i;
133}
134
136{
137 jassert (index > 0 && index < colours.size() - 1);
138 colours.remove (index);
139}
140
142{
143 for (auto& c : colours)
144 c.colour = c.colour.withMultipliedAlpha (multiplier);
145}
146
147//==============================================================================
149{
150 return colours.size();
151}
152
153double ColourGradient::getColourPosition (int index) const noexcept
154{
155 if (isPositiveAndBelow (index, colours.size()))
156 return colours.getReference (index).position;
157
158 return 0;
159 }
160
161Colour ColourGradient::getColour (int index) const noexcept
162{
163 if (isPositiveAndBelow (index, colours.size()))
164 return colours.getReference (index).colour;
165
166 return {};
167}
168
170{
171 if (isPositiveAndBelow (index, colours.size()))
172 colours.getReference (index).colour = newColour;
173}
174
175Colour ColourGradient::getColourAtPosition (double position) const noexcept
176{
177 jassert (approximatelyEqual (colours.getReference (0).position, 0.0)); // the first colour specified has to go at position 0
178
179 if (position <= 0 || colours.size() <= 1)
180 return colours.getReference (0).colour;
181
182 int i = colours.size() - 1;
183 while (position < colours.getReference (i).position)
184 --i;
185
186 auto& p1 = colours.getReference (i);
187
188 if (i >= colours.size() - 1)
189 return p1.colour;
190
191 auto& p2 = colours.getReference (i + 1);
192
193 return p1.colour.interpolatedWith (p2.colour, (float) ((position - p1.position) / (p2.position - p1.position)));
194}
195
196//==============================================================================
197void ColourGradient::createLookupTable (PixelARGB* const lookupTable, const int numEntries) const noexcept
198{
199 JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED // Trying to use this object without setting its coordinates?
200 jassert (colours.size() >= 2);
201 jassert (numEntries > 0);
202 jassert (approximatelyEqual (colours.getReference (0).position, 0.0)); // The first colour specified has to go at position 0
203
204 int index = 0;
205
206 for (int j = 0; j < colours.size() - 1; ++j)
207 {
208 const auto& o = colours.getReference (j + 0);
209 const auto& p = colours.getReference (j + 1);
210 const auto numToDo = roundToInt (p.position * (numEntries - 1)) - index;
211 const auto pix1 = o.colour.getNonPremultipliedPixelARGB();
212 const auto pix2 = p.colour.getNonPremultipliedPixelARGB();
213
214 for (auto i = 0; i < numToDo; ++i)
215 {
216 auto blended = pix1;
217 blended.tween (pix2, (uint32) ((i << 8) / numToDo));
218 blended.premultiply();
219
220 jassert (0 <= index && index < numEntries);
221 lookupTable[index++] = blended;
222 }
223 }
224
225 std::fill (lookupTable + index, lookupTable + numEntries, colours.getLast().colour.getPixelARGB());
226}
227
229{
230 JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED // Trying to use this object without setting its coordinates?
231 jassert (colours.size() >= 2);
232
233 auto numEntries = jlimit (1, jmax (1, (colours.size() - 1) << 8),
234 3 * (int) point1.transformedBy (transform)
235 .getDistanceFrom (point2.transformedBy (transform)));
236 lookupTable.malloc (numEntries);
237 createLookupTable (lookupTable, numEntries);
238 return numEntries;
239}
240
242{
243 for (auto& c : colours)
244 if (! c.colour.isOpaque())
245 return false;
246
247 return true;
248}
249
251{
252 for (auto& c : colours)
253 if (! c.colour.isTransparent())
254 return false;
255
256 return true;
257}
258
259bool ColourGradient::ColourPoint::operator== (ColourPoint other) const noexcept
260{
261 const auto tie = [] (const ColourPoint& p) { return std::tie (p.position, p.colour); };
262 return tie (*this) == tie (other);
263}
264
265bool ColourGradient::ColourPoint::operator!= (ColourPoint other) const noexcept
266{
267 return ! operator== (other);
268}
269
270} // namespace juce
Represents a 2D affine-transformation matrix.
int size() const noexcept
Returns the current number of elements in the array.
Definition juce_Array.h:215
void remove(int indexToRemove)
Removes an element from the array.
Definition juce_Array.h:742
void insert(int indexToInsertAt, ParameterType newElement)
Inserts a new element into the array at a given position.
Definition juce_Array.h:462
void add(const ElementType &newElement)
Appends a new element at the end of the array.
Definition juce_Array.h:418
void set(int indexToChange, ParameterType newValue)
Replaces an element with a new value.
Definition juce_Array.h:542
void clear()
Removes all elements from the array.
Definition juce_Array.h:188
ElementType & getReference(int index) noexcept
Returns a direct reference to one of the elements in the array, without checking the index passed in.
Definition juce_Array.h:267
Describes the layout and colours that should be used to paint a colour gradient.
static ColourGradient horizontal(Colour colour1, float x1, Colour colour2, float x2)
Creates a horizontal linear gradient between two X coordinates.
ColourGradient() noexcept
Creates an uninitialised gradient.
int createLookupTable(const AffineTransform &transform, HeapBlock< PixelARGB > &resultLookupTable) const
Creates a set of interpolated premultiplied ARGB values.
Colour getColour(int index) const noexcept
Returns the colour that was added with a given index.
bool isOpaque() const noexcept
Returns true if all colours are opaque.
static ColourGradient vertical(Colour colour1, float y1, Colour colour2, float y2)
Creates a vertical linear gradient between two Y coordinates.
Colour getColourAtPosition(double position) const noexcept
Returns the an interpolated colour at any position along the gradient.
void removeColour(int index)
Removes one of the colours from the gradient.
bool isRadial
If true, the gradient should be filled circularly, centred around point1, with point2 defining a poin...
int getNumColours() const noexcept
Returns the number of colour-stops that have been added.
bool isInvisible() const noexcept
Returns true if all colours are completely transparent.
void multiplyOpacity(float multiplier) noexcept
Multiplies the alpha value of all the colours by the given scale factor.
void setColour(int index, Colour newColour) noexcept
Changes the colour at a given index.
void clearColours()
Removes any colours that have been added.
int addColour(double proportionAlongGradient, Colour colour)
Adds a colour at a point along the length of the gradient.
double getColourPosition(int index) const noexcept
Returns the position along the length of the gradient of the colour with this index.
Represents a colour, also including a transparency value.
Definition juce_Colour.h:38
Very simple container class to hold a pointer to some data on the heap.
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Allocates a specified amount of memory.
Represents a 32-bit INTERNAL pixel with premultiplied alpha, and can perform compositing operations w...
A pair of (x, y) coordinates.
Definition juce_Point.h:42
ValueType getDistanceFrom(Point other) const noexcept
Returns the straight-line distance between this point and another one.
Definition juce_Point.h:165
void setX(ValueType newX) noexcept
Sets the point's x coordinate.
Definition juce_Point.h:78
Point transformedBy(const AffineTransform &transform) const noexcept
Returns the position of this point, if it is transformed by a given AffineTransform.
Definition juce_Point.h:228
T fill(T... args)
#define jassert(expression)
Platform-independent assertion macro.
typedef float
JUCE Namespace.
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Returns true if a value is at least zero, and also below a specified upper limit.
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
T tie(T... args)
y1