1 ////////////////////////////////////////////////////////////////////////////////
2 //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
3 // 10 20 30 40 50 60 70 80
4 //
5 // notify-osd
6 //
7 // raico-blur.c - implements public API for blurring cairo image-surfaces
8 //
9 // Copyright 2009 Canonical Ltd.
10 //
11 // Authors:
12 // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com>
13 //
14 // This program is free software: you can redistribute it and/or modify it
15 // under the terms of the GNU General Public License version 3, as published
16 // by the Free Software Foundation.
17 //
18 // This program is distributed in the hope that it will be useful, but
19 // WITHOUT ANY WARRANTY; without even the implied warranties of
20 // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
21 // PURPOSE. See the GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with this program. If not, see <http://www.gnu.org/licenses/>.
25 //
26 ////////////////////////////////////////////////////////////////////////////////
27
28 #include "raico-blur.h"
29 #include "exponential-blur.h"
30 #include "stack-blur.h"
31 #include "gaussian-blur.h"
32
33 struct _raico_blur_private_t
34 {
35 raico_blur_quality_t quality; // low, medium, high
36 guint radius; // blur-radius
37 };
38
39 raico_blur_t*
raico_blur_create(raico_blur_quality_t quality)40 raico_blur_create (raico_blur_quality_t quality)
41 {
42 raico_blur_t* blur = NULL;
43 raico_blur_private_t* priv = NULL;
44
45 blur = g_new0 (raico_blur_t, 1);
46 if (!blur)
47 {
48 g_debug ("raico_blur_create(): could not allocate blur struct");
49 return NULL;
50 }
51
52 priv = g_new0 (raico_blur_private_t, 1);
53 if (!priv)
54 {
55 g_debug ("raico_blur_create(): could not allocate priv struct");
56 g_free ((gpointer) blur);
57 return NULL;
58 }
59
60 priv->quality = quality;
61 priv->radius = 0;
62
63 blur->priv = priv;
64
65 return blur;
66 }
67
68 raico_blur_quality_t
raico_blur_get_quality(raico_blur_t * blur)69 raico_blur_get_quality (raico_blur_t* blur)
70 {
71 g_assert (blur != NULL);
72
73 return blur->priv->quality;
74 }
75
76 void
raico_blur_set_quality(raico_blur_t * blur,raico_blur_quality_t quality)77 raico_blur_set_quality (raico_blur_t* blur,
78 raico_blur_quality_t quality)
79 {
80 if (!blur)
81 {
82 g_debug ("raico_blur_set_quality(): NULL blur-pointer passed");
83 return;
84 }
85
86 blur->priv->quality = quality;
87 }
88
89 guint
raico_blur_get_radius(raico_blur_t * blur)90 raico_blur_get_radius (raico_blur_t* blur)
91 {
92 g_assert (blur != NULL);
93
94 return blur->priv->radius;
95 }
96
97 void
raico_blur_set_radius(raico_blur_t * blur,guint radius)98 raico_blur_set_radius (raico_blur_t* blur,
99 guint radius)
100 {
101 if (!blur)
102 {
103 g_debug ("raico_blur_set_radius(): NULL blur-pointer passed");
104 return;
105 }
106
107 blur->priv->radius = radius;
108 }
109
110 void
raico_blur_apply(raico_blur_t * blur,cairo_surface_t * surface)111 raico_blur_apply (raico_blur_t* blur,
112 cairo_surface_t* surface)
113 {
114 cairo_format_t format;
115
116 // sanity checks
117 if (!blur)
118 {
119 g_debug ("raico_blur_apply(): NULL blur-pointer passed");
120 return;
121 }
122
123 if (!surface)
124 {
125 g_debug ("raico_blur_apply(): NULL surface-pointer passed");
126 return;
127 }
128
129 if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
130 {
131 g_debug ("raico_blur_apply(): invalid surface status");
132 return;
133 }
134
135 if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_IMAGE)
136 {
137 g_debug ("raico_blur_apply(): non-image surface passed");
138 return;
139 }
140
141 format = cairo_image_surface_get_format (surface);
142 if (format != CAIRO_FORMAT_A8 &&
143 format != CAIRO_FORMAT_RGB24 &&
144 format != CAIRO_FORMAT_ARGB32)
145 {
146 g_debug ("raico_blur_apply(): unsupported image-format");
147 return;
148 }
149
150 // stupid, but you never know
151 if (blur->priv->radius == 0)
152 return;
153
154 // now do the real work
155 switch (blur->priv->quality)
156 {
157 case RAICO_BLUR_QUALITY_LOW:
158 surface_exponential_blur (surface, blur->priv->radius);
159 break;
160
161 case RAICO_BLUR_QUALITY_MEDIUM:
162 //surface_stack_blur (surface, blur->priv->radius);
163 surface_gaussian_blur (surface, blur->priv->radius);
164 break;
165
166 case RAICO_BLUR_QUALITY_HIGH:
167 surface_gaussian_blur (surface, blur->priv->radius);
168 break;
169 }
170 }
171
172 void
raico_blur_destroy(raico_blur_t * blur)173 raico_blur_destroy (raico_blur_t* blur)
174 {
175 if (!blur)
176 {
177 g_debug ("raico_blur_destroy(): invalid blur-pointer passed");
178 return;
179 }
180
181 g_free ((gpointer) blur->priv);
182 g_free ((gpointer) blur);
183 }
184
185