Document recursion limitations of the graphical effects.
[qt:qtgraphicaleffects.git] / src / effects / DropShadow.qml
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Graphical Effects module.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 **     of its contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 import QtQuick 2.0
42 import "private"
43
44 /*!
45     \qmltype DropShadow
46     \inqmlmodule QtGraphicalEffects 1.0
47     \since QtGraphicalEffects 1.0
48     \inherits QtQuick2::Item
49     \ingroup qtgraphicaleffects-drop-shadow
50     \brief Generates a colorized and blurred shadow image of the
51     source and places it behind the original, giving the impression that
52     source item is raised from the background.
53
54     By default the effect produces a high quality shadow image, thus the
55     rendering speed of the shadow might not be the highest possible. The
56     rendering speed is reduced especially if the shadow edges are heavily
57     softened.
58
59     For use cases that require faster rendering speed and for which the highest
60     possible visual quality is not necessary, property
61     \l{DropShadow::fast}{fast} can be set to true.
62
63     \table
64     \header
65         \li Source
66         \li Effect applied
67     \row
68         \li \image Original_butterfly.png
69         \li \image DropShadow_butterfly.png
70     \endtable
71
72     \section1 Example
73
74     The following example shows how to apply the effect.
75     \snippet DropShadow-example.qml example
76
77 */
78 Item {
79     id: rootItem
80
81     /*!
82         This property defines the source item that is going to be used as the
83         source for the generated shadow.
84
85         \note It is not supported to let the effect include itself, for
86         instance by setting source to the effect's parent.
87     */
88     property variant source
89
90     /*!
91         Radius defines the softness of the shadow. A larger radius causes the
92         edges of the shadow to appear more blurry.
93
94         Depending on the radius value, value of the
95         \l{DropShadow::samples}{samples} should be set to sufficiently large to
96         ensure the visual quality.
97
98         The value ranges from 0.0 (no blur) to inf. By default, the property is
99         set to \c 0.0 (no blur).
100
101         \table
102         \header
103         \li Output examples with different radius values
104         \li
105         \li
106         \row
107             \li \image DropShadow_radius1.png
108             \li \image DropShadow_radius2.png
109             \li \image DropShadow_radius3.png
110         \row
111             \li \b { radius: 0 }
112             \li \b { radius: 6 }
113             \li \b { radius: 12 }
114         \row
115             \li \l samples: 24
116             \li \l samples: 24
117             \li \l samples: 24
118         \row
119             \li \l color: #000000
120             \li \l color: #000000
121             \li \l color: #000000
122         \row
123             \li \l horizontalOffset: 0
124             \li \l horizontalOffset: 0
125             \li \l horizontalOffset: 0
126         \row
127             \li \l verticalOffset: 20
128             \li \l verticalOffset: 20
129             \li \l verticalOffset: 20
130         \row
131             \li \l spread: 0
132             \li \l spread: 0
133             \li \l spread: 0
134         \endtable
135
136     */
137     property real radius: 0.0
138
139     /*!
140         This property defines how many samples are taken per pixel when edge
141         softening blur calculation is done. Larger value produces better
142         quality, but is slower to render.
143
144         Ideally, this value should be twice as large as the highest required
145         radius value, for example, if the radius is animated between 0.0 and
146         4.0, samples should be set to 8.
147
148         The value ranges from 0 to 32. By default, the property is set to \c 0.
149
150         This property is not intended to be animated. Changing this property may
151         cause the underlying OpenGL shaders to be recompiled.
152
153         When \l{DropShadow::fast}{fast} property is set to true, this property
154         has no effect.
155
156     */
157     property int samples: 0
158
159     /*!
160         This property defines the RGBA color value which is used for the shadow.
161
162         By default, the property is set to \c "black".
163
164         \table
165         \header
166         \li Output examples with different color values
167         \li
168         \li
169         \row
170             \li \image DropShadow_color1.png
171             \li \image DropShadow_color2.png
172             \li \image DropShadow_color3.png
173         \row
174             \li \b { color: #000000 }
175             \li \b { color: #0000ff }
176             \li \b { color: #aa000000 }
177         \row
178             \li \l radius: 8
179             \li \l radius: 8
180             \li \l radius: 8
181         \row
182             \li \l samples: 16
183             \li \l samples: 16
184             \li \l samples: 16
185         \row
186             \li \l horizontalOffset: 0
187             \li \l horizontalOffset: 0
188             \li \l horizontalOffset: 0
189         \row
190             \li \l verticalOffset: 20
191             \li \l verticalOffset: 20
192             \li \l verticalOffset: 20
193         \row
194             \li \l spread: 0
195             \li \l spread: 0
196             \li \l spread: 0
197         \endtable
198
199     */
200     property color color: "black"
201
202     /*!
203         \qmlproperty real QtGraphicalEffects1::DropShadow::horizontalOffset
204         \qmlproperty real QtGraphicalEffects1::DropShadow::verticalOffset
205
206         HorizontalOffset and verticalOffset properties define the offset for the
207         rendered shadow compared to the DropShadow item position. Often, the
208         DropShadow item is anchored so that it fills the source element. In this
209         case, if the HorizontalOffset and verticalOffset properties are set to
210         0, the shadow is rendered exactly under the source item. By changing the
211         offset properties, the shadow can be positioned relatively to the source
212         item.
213
214         The values range from -inf to inf. By default, the properties are set to
215         \c 0.
216
217         \table
218         \header
219         \li Output examples with different horizontalOffset values
220         \li
221         \li
222         \row
223             \li \image DropShadow_horizontalOffset1.png
224             \li \image DropShadow_horizontalOffset2.png
225             \li \image DropShadow_horizontalOffset3.png
226         \row
227             \li \b { horizontalOffset: -20 }
228             \li \b { horizontalOffset: 0 }
229             \li \b { horizontalOffset: 20 }
230         \row
231             \li \l radius: 4
232             \li \l radius: 4
233             \li \l radius: 4
234         \row
235             \li \l samples: 8
236             \li \l samples: 8
237             \li \l samples: 8
238         \row
239             \li \l color: #000000
240             \li \l color: #000000
241             \li \l color: #000000
242         \row
243             \li \l verticalOffset: 0
244             \li \l verticalOffset: 0
245             \li \l verticalOffset: 0
246         \row
247             \li \l spread: 0
248             \li \l spread: 0
249             \li \l spread: 0
250         \endtable
251
252     */
253     property real horizontalOffset: 0.0
254     property real verticalOffset: 0.0
255
256     /*!
257         This property defines how large part of the shadow color is strenghtened
258         near the source edges.
259
260         The value ranges from 0.0 to 1.0. By default, the property is set to \c
261         0.5.
262
263         \table
264         \header
265         \li Output examples with different spread values
266         \li
267         \li
268         \row
269             \li \image DropShadow_spread1.png
270             \li \image DropShadow_spread2.png
271             \li \image DropShadow_spread3.png
272         \row
273             \li \b { spread: 0.0 }
274             \li \b { spread: 0.5 }
275             \li \b { spread: 1.0 }
276         \row
277             \li \l radius: 8
278             \li \l radius: 8
279             \li \l radius: 8
280         \row
281             \li \l samples: 16
282             \li \l samples: 16
283             \li \l samples: 16
284         \row
285             \li \l color: #000000
286             \li \l color: #000000
287             \li \l color: #000000
288         \row
289             \li \l horizontalOffset: 0
290             \li \l horizontalOffset: 0
291             \li \l horizontalOffset: 0
292         \row
293             \li \l verticalOffset: 20
294             \li \l verticalOffset: 20
295             \li \l verticalOffset: 20
296         \endtable
297
298     */
299     property real spread: 0.0
300
301     /*!
302         This property selects the blurring algorithm that is used to produce the
303         softness for the effect. Setting this to true enables fast algorithm,
304         setting value to false produces higher quality result.
305
306         By default, the property is set to \c false.
307
308         \table
309         \header
310         \li Output examples with different fast values
311         \li
312         \li
313         \row
314             \li \image DropShadow_fast1.png
315             \li \image DropShadow_fast2.png
316         \row
317             \li \b { fast: false }
318             \li \b { fast: true }
319         \row
320             \li \l radius: 16
321             \li \l radius: 16
322         \row
323             \li \l samples: 24
324             \li \l samples: 24
325         \row
326             \li \l color: #000000
327             \li \l color: #000000
328         \row
329             \li \l horizontalOffset: 0
330             \li \l horizontalOffset: 0
331         \row
332             \li \l verticalOffset: 20
333             \li \l verticalOffset: 20
334         \row
335             \li \l spread: 0
336             \li \l spread: 0
337         \endtable
338
339     */
340     property bool fast: false
341
342     /*!
343         This property allows the effect output pixels to be cached in order to
344         improve the rendering performance. Every time the source or effect
345         properties are changed, the pixels in the cache must be updated. Memory
346         consumption is increased, because an extra buffer of memory is required
347         for storing the effect output.
348
349         It is recommended to disable the cache when the source or the effect
350         properties are animated.
351
352         By default, the property is set to \c false.
353
354     */
355     property bool cached: false
356
357     property bool transparentBorder: false
358
359     Loader {
360         x: rootItem.horizontalOffset
361         y: rootItem.verticalOffset
362         width: parent.width
363         height: parent.height
364         sourceComponent: rootItem.fast ? fastGlow : gaussianGlow
365     }
366
367     Component {
368         id: gaussianGlow
369         GaussianGlow {
370             anchors.fill: parent
371             source: sourceProxy.output
372             radius: rootItem.radius
373             maximumRadius: rootItem.samples * 0.5
374             color: rootItem.color
375             cached: rootItem.cached
376             spread: rootItem.spread
377             transparentBorder: rootItem.transparentBorder
378         }
379     }
380
381     Component {
382         id: fastGlow
383         FastGlow {
384             anchors.fill: parent
385             source: sourceProxy.output
386             blur: Math.pow(rootItem.radius / 64.0, 0.4)
387             color: rootItem.color
388             cached: rootItem.cached
389             spread: rootItem.spread
390             transparentBorder: rootItem.transparentBorder
391         }
392     }
393
394     SourceProxy {
395         id: sourceProxy
396         input: rootItem.source
397         sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
398     }
399     ShaderEffect {
400         anchors.fill: parent
401         property variant source: sourceProxy.output
402     }
403 }