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_DropShadowEffect.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
29static void blurDataTriplets (uint8* d, int num, const int delta) noexcept
30{
31 uint32 last = d[0];
32 d[0] = (uint8) ((d[0] + d[delta] + 1) / 3);
33 d += delta;
34
35 num -= 2;
36
37 do
38 {
39 const uint32 newLast = d[0];
40 d[0] = (uint8) ((last + d[0] + d[delta] + 1) / 3);
41 d += delta;
42 last = newLast;
43 }
44 while (--num > 0);
45
46 d[0] = (uint8) ((last + d[0] + 1) / 3);
47}
48
49static void blurSingleChannelImage (uint8* const data, const int width, const int height,
50 const int lineStride, const int repetitions) noexcept
51{
52 jassert (width > 2 && height > 2);
53
54 for (int y = 0; y < height; ++y)
55 for (int i = repetitions; --i >= 0;)
56 blurDataTriplets (data + lineStride * y, width, 1);
57
58 for (int x = 0; x < width; ++x)
59 for (int i = repetitions; --i >= 0;)
60 blurDataTriplets (data + x, height, lineStride);
61}
62
63static void blurSingleChannelImage (Image& image, int radius)
64{
65 const Image::BitmapData bm (image, Image::BitmapData::readWrite);
66 blurSingleChannelImage (bm.data, bm.width, bm.height, bm.lineStride, 2 * radius);
67}
68
69//==============================================================================
70DropShadow::DropShadow (Colour shadowColour, const int r, Point<int> o) noexcept
71 : colour (shadowColour), radius (r), offset (o)
72{
73 jassert (radius > 0);
74}
75
76void DropShadow::drawForImage (Graphics& g, const Image& srcImage) const
77{
78 jassert (radius > 0);
79
80 if (srcImage.isValid())
81 {
82 Image shadowImage (srcImage.convertedToFormat (Image::SingleChannel));
83 shadowImage.duplicateIfShared();
84
85 blurSingleChannelImage (shadowImage, radius);
86
87 g.setColour (colour);
88 g.drawImageAt (shadowImage, offset.x, offset.y, true);
89 }
90}
91
92void DropShadow::drawForPath (Graphics& g, const Path& path) const
93{
94 jassert (radius > 0);
95
96 auto area = (path.getBounds().getSmallestIntegerContainer() + offset)
97 .expanded (radius + 1)
98 .getIntersection (g.getClipBounds().expanded (radius + 1));
99
100 if (area.getWidth() > 2 && area.getHeight() > 2)
101 {
102 Image renderedPath (Image::SingleChannel, area.getWidth(), area.getHeight(), true);
103
104 {
105 Graphics g2 (renderedPath);
106 g2.setColour (Colours::white);
107 g2.fillPath (path, AffineTransform::translation ((float) (offset.x - area.getX()),
108 (float) (offset.y - area.getY())));
109 }
110
111 blurSingleChannelImage (renderedPath, radius);
112
113 g.setColour (colour);
114 g.drawImageAt (renderedPath, area.getX(), area.getY(), true);
115 }
116}
117
118static void drawShadowSection (Graphics& g, ColourGradient& cg, Rectangle<float> area,
119 bool isCorner, float centreX, float centreY, float edgeX, float edgeY)
120{
121 cg.point1 = area.getRelativePoint (centreX, centreY);
122 cg.point2 = area.getRelativePoint (edgeX, edgeY);
123 cg.isRadial = isCorner;
124
125 g.setGradientFill (cg);
126 g.fillRect (area);
127}
128
129void DropShadow::drawForRectangle (Graphics& g, const Rectangle<int>& targetArea) const
130{
131 ColourGradient cg (colour, 0, 0, colour.withAlpha (0.0f), 0, 0, false);
132
133 for (float i = 0.05f; i < 1.0f; i += 0.1f)
134 cg.addColour (1.0 - i, colour.withMultipliedAlpha (i * i));
135
136 const float radiusInset = (float) radius / 2.0f;
137 const float expandedRadius = (float) radius + radiusInset;
138
139 auto area = targetArea.toFloat().reduced (radiusInset) + offset.toFloat();
140
141 auto r = area.expanded (expandedRadius);
142 auto top = r.removeFromTop (expandedRadius);
143 auto bottom = r.removeFromBottom (expandedRadius);
144
145 drawShadowSection (g, cg, top.removeFromLeft (expandedRadius), true, 1.0f, 1.0f, 0, 1.0f);
146 drawShadowSection (g, cg, top.removeFromRight (expandedRadius), true, 0, 1.0f, 1.0f, 1.0f);
147 drawShadowSection (g, cg, top, false, 0, 1.0f, 0, 0);
148
149 drawShadowSection (g, cg, bottom.removeFromLeft (expandedRadius), true, 1.0f, 0, 0, 0);
150 drawShadowSection (g, cg, bottom.removeFromRight (expandedRadius), true, 0, 0, 1.0f, 0);
151 drawShadowSection (g, cg, bottom, false, 0, 0, 0, 1.0f);
152
153 drawShadowSection (g, cg, r.removeFromLeft (expandedRadius), false, 1.0f, 0, 0, 0);
154 drawShadowSection (g, cg, r.removeFromRight (expandedRadius), false, 0, 0, 1.0f, 0);
155
156 g.setColour (colour);
157 g.fillRect (area);
158}
159
160//==============================================================================
163
165{
166 shadow = newShadow;
167}
168
169void DropShadowEffect::applyEffect (Image& image, Graphics& g, float scaleFactor, float alpha)
170{
171 DropShadow s (shadow);
172 s.radius = roundToInt ((float) s.radius * scaleFactor);
173 s.colour = s.colour.withMultipliedAlpha (alpha);
174 s.offset.x = roundToInt ((float) s.offset.x * scaleFactor);
175 s.offset.y = roundToInt ((float) s.offset.y * scaleFactor);
176
177 s.drawForImage (g, image);
178
179 g.setOpacity (alpha);
180 g.drawImageAt (image, 0, 0);
181}
182
183} // namespace juce
static AffineTransform translation(float deltaX, float deltaY) noexcept
Returns a new transform which is a translation.
Describes the layout and colours that should be used to paint a colour gradient.
bool isRadial
If true, the gradient should be filled circularly, centred around point1, with point2 defining a poin...
int addColour(double proportionAlongGradient, Colour colour)
Adds a colour at a point along the length of the gradient.
Represents a colour, also including a transparency value.
Definition juce_Colour.h:38
Colour withAlpha(uint8 newAlpha) const noexcept
Returns a colour that's the same colour as this one, but with a new alpha value.
Colour withMultipliedAlpha(float alphaMultiplier) const noexcept
Returns a colour that's the same colour as this one, but with a modified alpha value.
DropShadowEffect()
Creates a default drop-shadow effect.
void setShadowProperties(const DropShadow &newShadow)
Sets up parameters affecting the shadow's appearance.
void applyEffect(Image &sourceImage, Graphics &destContext, float scaleFactor, float alpha) override
Overridden to render the effect.
~DropShadowEffect() override
Destructor.
A graphics context, used for drawing a component or image.
void setOpacity(float newOpacity)
Changes the opacity to use with the current colour.
void drawImageAt(const Image &imageToDraw, int topLeftX, int topLeftY, bool fillAlphaChannelWithCurrentBrush=false) const
Draws an image.
void setGradientFill(const ColourGradient &gradient)
Sets the context to use a gradient for its fill pattern.
void fillRect(Rectangle< int > rectangle) const
Fills a rectangle with the current colour or brush.
void fillPath(const Path &path) const
Fills a path using the currently selected colour or brush.
Rectangle< int > getClipBounds() const
Returns the position of the bounding box for the current clipping region.
void setColour(Colour newColour)
Changes the current drawing colour.
Holds a fixed-size bitmap.
Definition juce_Image.h:58
Image convertedToFormat(PixelFormat newFormat) const
Returns a version of this image with a different image format.
void duplicateIfShared()
Makes sure that no other Image objects share the same underlying data as this one.
bool isValid() const noexcept
Returns true if this image isn't null.
Definition juce_Image.h:147
@ SingleChannel
< each pixel is a 1-byte alpha channel value.
Definition juce_Image.h:68
A path is a sequence of lines and curves that may either form a closed shape or be open-ended.
Definition juce_Path.h:65
Rectangle< float > getBounds() const noexcept
Returns the smallest rectangle that contains all points within the path.
A pair of (x, y) coordinates.
Definition juce_Point.h:42
constexpr Point< float > toFloat() const noexcept
Casts this point to a Point<float> object.
Definition juce_Point.h:239
ValueType y
The point's Y coordinate.
Definition juce_Point.h:252
ValueType x
The point's X coordinate.
Definition juce_Point.h:251
Manages a rectangle and allows geometric operations to be performed on it.
Rectangle< float > toFloat() const noexcept
Casts this rectangle to a Rectangle<float>.
Rectangle< int > getSmallestIntegerContainer() const noexcept
Returns the smallest integer-aligned rectangle that completely contains this one.
Rectangle removeFromBottom(ValueType amountToRemove) noexcept
Removes a strip from the bottom of this rectangle, reducing this rectangle by the specified amount an...
Rectangle removeFromTop(ValueType amountToRemove) noexcept
Removes a strip from the top of this rectangle, reducing this rectangle by the specified amount and r...
Rectangle reduced(ValueType deltaX, ValueType deltaY) const noexcept
Returns a rectangle that is smaller than this one by a given amount.
Point< ValueType > getRelativePoint(FloatType relativeX, FloatType relativeY) const noexcept
Returns a point within this rectangle, specified as proportional coordinates.
Rectangle expanded(ValueType deltaX, ValueType deltaY) const noexcept
Returns a rectangle that is larger than this one by a given amount.
#define jassert(expression)
Platform-independent assertion macro.
typedef float
JUCE Namespace.
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
Defines a drop-shadow effect.
Point< int > offset
The offset of the shadow.
void drawForPath(Graphics &g, const Path &path) const
Renders a drop-shadow based on the shape of a path.
void drawForImage(Graphics &g, const Image &srcImage) const
Renders a drop-shadow based on the alpha-channel of the given image.
int radius
The approximate spread of the shadow.
void drawForRectangle(Graphics &g, const Rectangle< int > &area) const
Renders a drop-shadow for a rectangle.
DropShadow()=default
Creates a default drop-shadow effect.
Colour colour
The colour with which to render the shadow.