Mercurial > audlegacy-plugins
comparison src/aosd/aosd_style.c @ 569:d401f87f89f7 trunk
[svn] - added Audacious OSD, yet-another-written-from-scratch plugin to display OSD, based on Ghosd library; currently untied from configure, to compile it you have to run make in its directory; will be added to configure after some testing
author | giacomo |
---|---|
date | Mon, 29 Jan 2007 06:40:04 -0800 |
parents | |
children | 7ad870f10241 |
comparison
equal
deleted
inserted
replaced
568:8c64b5abdcda | 569:d401f87f89f7 |
---|---|
1 /* | |
2 * | |
3 * Author: Giacomo Lozito <james@develia.org>, (C) 2005-2007 | |
4 * | |
5 * This program is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License as published by the | |
7 * Free Software Foundation; either version 2 of the License, or (at your | |
8 * option) any later version. | |
9 * | |
10 * This program is distributed in the hope that it will be useful, but | |
11 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU General Public License along | |
16 * with this program; if not, write to the Free Software Foundation, Inc., | |
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
18 * | |
19 */ | |
20 | |
21 #include "aosd_style.h" | |
22 #include "aosd_style_private.h" | |
23 #include "aosd_cfg.h" | |
24 #include <glib.h> | |
25 #include <glib/gi18n.h> | |
26 #include <X11/Xlib.h> | |
27 #include <cairo/cairo.h> | |
28 #include <pango/pangocairo.h> | |
29 #include "ghosd.h" | |
30 #include "ghosd-text.h" | |
31 | |
32 | |
33 /* HOW TO ADD A NEW DECORATION STYLE | |
34 -------------------------------------------------------------------------- | |
35 First, add a new decoration style code; then, provide the decoration style | |
36 information by adding a new entry in the aosd_deco_styles[] array (name, | |
37 render function, etc.); add the new decoration style code in the array | |
38 of decoration style codes, and update the define containing the array size. | |
39 The render function uses three parameters; the Ghosd instance, the cairo | |
40 object you use to draw, and a aosd_deco_style_data_t object that contains | |
41 user-defined options (look into aosd_style.h and aosd_cfg.h for details). | |
42 Have fun! :) | |
43 */ | |
44 | |
45 | |
46 /* decoration style codes ( the code values do not need to be sequential ) */ | |
47 enum | |
48 { | |
49 AOSD_DECO_STYLE_RECT = 0, | |
50 AOSD_DECO_STYLE_ROUNDRECT = 1, | |
51 AOSD_DECO_STYLE_CONCAVERECT = 2 | |
52 }; | |
53 | |
54 /* decoration style codes array size */ | |
55 #define AOSD_DECO_STYLE_CODES_ARRAY_SIZE 3 | |
56 | |
57 /* decoration style codes array */ | |
58 gint aosd_deco_style_codes[] = | |
59 { | |
60 AOSD_DECO_STYLE_RECT, | |
61 AOSD_DECO_STYLE_ROUNDRECT, | |
62 AOSD_DECO_STYLE_CONCAVERECT | |
63 }; | |
64 | |
65 /* prototypes of render functions */ | |
66 static void aosd_deco_rfunc_rect ( Ghosd * , cairo_t * , aosd_deco_style_data_t * ); | |
67 static void aosd_deco_rfunc_roundrect ( Ghosd * , cairo_t * , aosd_deco_style_data_t * ); | |
68 static void aosd_deco_rfunc_concaverect ( Ghosd * , cairo_t * , aosd_deco_style_data_t * ); | |
69 | |
70 /* map decoration style codes to decoration objects */ | |
71 aosd_deco_style_t aosd_deco_styles[] = | |
72 { | |
73 [AOSD_DECO_STYLE_RECT] = { N_("Rectangle") , | |
74 aosd_deco_rfunc_rect , | |
75 2 , { 10 , 10 , 10 , 10 } }, | |
76 | |
77 [AOSD_DECO_STYLE_ROUNDRECT] = { N_("Rounded Rectangle") , | |
78 aosd_deco_rfunc_roundrect , | |
79 2 , { 10 , 10 , 10 , 10 } }, | |
80 | |
81 [AOSD_DECO_STYLE_CONCAVERECT] = { N_("Concave Rectangle") , | |
82 aosd_deco_rfunc_concaverect , | |
83 2 , { 10 , 10 , 10 , 10 } } | |
84 }; | |
85 | |
86 | |
87 | |
88 /* DECORATION STYLE API */ | |
89 | |
90 | |
91 void | |
92 aosd_deco_style_get_codes_array ( gint ** array , gint * array_size ) | |
93 { | |
94 *array = aosd_deco_style_codes; | |
95 *array_size = AOSD_DECO_STYLE_CODES_ARRAY_SIZE; | |
96 return; | |
97 } | |
98 | |
99 | |
100 void | |
101 aosd_deco_style_get_padding ( gint deco_code , | |
102 gint * ptop , gint * pbottom , | |
103 gint * pleft , gint * pright ) | |
104 { | |
105 if ( ptop != NULL ) *ptop = aosd_deco_styles[deco_code].padding.top; | |
106 if ( pbottom != NULL ) *pbottom = aosd_deco_styles[deco_code].padding.bottom; | |
107 if ( pleft != NULL ) *pleft = aosd_deco_styles[deco_code].padding.left; | |
108 if ( pright != NULL ) *pright = aosd_deco_styles[deco_code].padding.right; | |
109 return; | |
110 } | |
111 | |
112 | |
113 const gchar * | |
114 aosd_deco_style_get_desc ( gint deco_code ) | |
115 { | |
116 return aosd_deco_styles[deco_code].desc; | |
117 } | |
118 | |
119 | |
120 gint | |
121 aosd_deco_style_get_numcol ( gint deco_code ) | |
122 { | |
123 return aosd_deco_styles[deco_code].colors_num; | |
124 } | |
125 | |
126 | |
127 void | |
128 aosd_deco_style_render ( gint deco_code , gpointer ghosd , gpointer cr , gpointer user_data ) | |
129 { | |
130 aosd_deco_styles[deco_code].render_func( (Ghosd*)ghosd , (cairo_t*)cr , user_data ); | |
131 } | |
132 | |
133 | |
134 gint | |
135 aosd_deco_style_get_first_code ( void ) | |
136 { | |
137 return AOSD_DECO_STYLE_RECT; | |
138 } | |
139 | |
140 | |
141 gint | |
142 aosd_deco_style_get_max_numcol ( void ) | |
143 { | |
144 gint i = 0; | |
145 gint max_numcol = 0; | |
146 | |
147 for ( i = 0 ; i < AOSD_DECO_STYLE_CODES_ARRAY_SIZE ; i++ ) | |
148 { | |
149 gint numcol = aosd_deco_style_get_numcol( aosd_deco_style_codes[i] ); | |
150 if ( numcol > max_numcol ) | |
151 max_numcol = numcol; | |
152 } | |
153 | |
154 return max_numcol; | |
155 } | |
156 | |
157 | |
158 | |
159 /* RENDER FUNCTIONS */ | |
160 | |
161 static void | |
162 aosd_deco_rfunc_rect( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data ) | |
163 { | |
164 /* decoration information | |
165 ---------------------- | |
166 draws a simple rectangular decoration; uses 2 colors | |
167 (user color 1 and 2) and 1 font (user font 1), with optional shadow | |
168 */ | |
169 PangoLayout *osd_layout = data->layout; | |
170 aosd_color_t color0 = g_array_index( data->decoration->colors , aosd_color_t , 0 ); | |
171 aosd_color_t color1 = g_array_index( data->decoration->colors , aosd_color_t , 1 ); | |
172 aosd_color_t textcolor0 = data->text->fonts_color[0]; | |
173 aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0]; | |
174 gboolean draw_shadow = data->text->fonts_draw_shadow[0]; | |
175 gint width = 0, height = 0; | |
176 | |
177 pango_layout_get_pixel_size( osd_layout , &width , &height ); | |
178 | |
179 /* draw rectangle container */ | |
180 cairo_set_source_rgba( cr , (gdouble)color0.red / 65535 , (gdouble)color0.green / 65535 , | |
181 (gdouble)color0.blue / 65535 , (gdouble)color0.alpha / 65535 ); | |
182 cairo_rectangle( cr , 0 , 0 , | |
183 aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.left + width + | |
184 aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.right, | |
185 aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.top + height + | |
186 aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.bottom ); | |
187 cairo_fill_preserve( cr ); | |
188 cairo_set_source_rgba( cr , (gdouble)color1.red / 65535 , (gdouble)color1.green / 65535 , | |
189 (gdouble)color1.blue / 65535 , (gdouble)color1.alpha / 65535 ); | |
190 cairo_stroke( cr ); | |
191 | |
192 if ( draw_shadow == TRUE ) | |
193 { | |
194 /* draw text shadow */ | |
195 cairo_set_source_rgba( cr , (gdouble)shadowcolor0.red / 65535 , (gdouble)shadowcolor0.green / 65535 , | |
196 (gdouble)shadowcolor0.blue / 65535 , (gdouble)shadowcolor0.alpha / 65535 ); | |
197 cairo_move_to( cr, | |
198 aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.left + 2 , | |
199 aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.top + 2 ); | |
200 pango_cairo_show_layout( cr , osd_layout ); | |
201 } | |
202 | |
203 /* draw text */ | |
204 cairo_set_source_rgba( cr , (gdouble)textcolor0.red / 65535 , (gdouble)textcolor0.green / 65535 , | |
205 (gdouble)textcolor0.blue / 65535 , (gdouble)textcolor0.alpha / 65535 ); | |
206 cairo_move_to( cr, | |
207 aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.left , | |
208 aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.top ); | |
209 pango_cairo_show_layout( cr , osd_layout ); | |
210 } | |
211 | |
212 | |
213 static void | |
214 aosd_deco_rfunc_roundrect ( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data ) | |
215 { | |
216 /* decoration information | |
217 ---------------------- | |
218 draws a rectangular decoration with rounded angles; uses 2 colors | |
219 (user color 1 and 2) and 1 font (user font 1), with optional shadow | |
220 */ | |
221 PangoLayout *osd_layout = data->layout; | |
222 aosd_color_t color0 = g_array_index( data->decoration->colors , aosd_color_t , 0 ); | |
223 aosd_color_t color1 = g_array_index( data->decoration->colors , aosd_color_t , 1 ); | |
224 aosd_color_t textcolor0 = data->text->fonts_color[0]; | |
225 aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0]; | |
226 gboolean draw_shadow = data->text->fonts_draw_shadow[0]; | |
227 gint width = 0, height = 0; | |
228 | |
229 pango_layout_get_pixel_size( osd_layout , &width , &height ); | |
230 | |
231 /* draw rounded-rectangle container */ | |
232 cairo_set_source_rgba( cr , (gdouble)color0.red / 65535 , (gdouble)color0.green / 65535 , | |
233 (gdouble)color0.blue / 65535 , (gdouble)color0.alpha / 65535 ); | |
234 cairo_move_to( cr , aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left , 0 ); | |
235 cairo_arc( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left , | |
236 aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top , | |
237 10. , -G_PI_2 , 0. ); | |
238 cairo_arc( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left , | |
239 aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top + height , | |
240 10. , -4. * G_PI_2 , -3. * G_PI_2 ); | |
241 cairo_arc( cr , aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left , | |
242 aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top + height , | |
243 10. , -3. * G_PI_2 , -2. * G_PI_2 ); | |
244 cairo_arc( cr , aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left , | |
245 aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top , | |
246 10. , -2. * G_PI_2 , -G_PI_2 ); | |
247 cairo_close_path( cr ); | |
248 cairo_fill_preserve( cr ); | |
249 cairo_set_source_rgba( cr , (gdouble)color1.red / 65535 , (gdouble)color1.green / 65535 , | |
250 (gdouble)color1.blue / 65535 , (gdouble)color1.alpha / 65535 ); | |
251 cairo_stroke( cr ); | |
252 | |
253 if ( draw_shadow == TRUE ) | |
254 { | |
255 /* draw text shadow */ | |
256 cairo_set_source_rgba( cr , (gdouble)shadowcolor0.red / 65535 , (gdouble)shadowcolor0.green / 65535 , | |
257 (gdouble)shadowcolor0.blue / 65535 , (gdouble)shadowcolor0.alpha / 65535 ); | |
258 cairo_move_to( cr , | |
259 aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left + 2 , | |
260 aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top + 2 ); | |
261 pango_cairo_show_layout( cr , osd_layout ); | |
262 } | |
263 | |
264 /* draw text */ | |
265 cairo_set_source_rgba( cr , (gdouble)textcolor0.red / 65535 , (gdouble)textcolor0.green / 65535 , | |
266 (gdouble)textcolor0.blue / 65535 , (gdouble)textcolor0.alpha / 65535 ); | |
267 cairo_move_to( cr , | |
268 aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left , | |
269 aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top ); | |
270 pango_cairo_show_layout( cr , osd_layout ); | |
271 } | |
272 | |
273 | |
274 static void | |
275 aosd_deco_rfunc_concaverect ( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data ) | |
276 { | |
277 /* decoration information | |
278 ---------------------- | |
279 draws a rectangle with concave angles; uses 2 colors | |
280 (user color 1 and 2) and 1 font (user font 1), with optional shadow | |
281 */ | |
282 PangoLayout *osd_layout = data->layout; | |
283 aosd_color_t color0 = g_array_index( data->decoration->colors , aosd_color_t , 0 ); | |
284 aosd_color_t color1 = g_array_index( data->decoration->colors , aosd_color_t , 1 ); | |
285 aosd_color_t textcolor0 = data->text->fonts_color[0]; | |
286 aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0]; | |
287 gboolean draw_shadow = data->text->fonts_draw_shadow[0]; | |
288 gint width = 0, height = 0; | |
289 | |
290 pango_layout_get_pixel_size( osd_layout , &width , &height ); | |
291 | |
292 /* draw jigsaw-piece-like container */ | |
293 cairo_set_source_rgba( cr , (gdouble)color0.red / 65535 , (gdouble)color0.green / 65535 , | |
294 (gdouble)color0.blue / 65535 , (gdouble)color0.alpha / 65535 ); | |
295 cairo_move_to( cr , aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left , 0 ); | |
296 cairo_arc_negative( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + 2 , | |
297 aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top - 2 , | |
298 8. , -G_PI_2 , 0. ); | |
299 cairo_arc_negative( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + 2 , | |
300 aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top + height + 2 , | |
301 8. , -4. * G_PI_2 , -3. * G_PI_2 ); | |
302 cairo_arc_negative( cr , aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left - 2 , | |
303 aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top + height + 2 , | |
304 8. , -3. * G_PI_2 , -2. * G_PI_2 ); | |
305 cairo_arc_negative( cr , aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left - 2 , | |
306 aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top - 2 , | |
307 8. , -2. * G_PI_2 , -G_PI_2 ); | |
308 cairo_close_path( cr ); | |
309 cairo_fill_preserve( cr ); | |
310 cairo_set_source_rgba( cr , (gdouble)color1.red / 65535 , (gdouble)color1.green / 65535 , | |
311 (gdouble)color1.blue / 65535 , (gdouble)color1.alpha / 65535 ); | |
312 cairo_stroke( cr ); | |
313 | |
314 if ( draw_shadow == TRUE ) | |
315 { | |
316 /* draw text shadow */ | |
317 cairo_set_source_rgba( cr , (gdouble)shadowcolor0.red / 65535 , (gdouble)shadowcolor0.green / 65535 , | |
318 (gdouble)shadowcolor0.blue / 65535 , (gdouble)shadowcolor0.alpha / 65535 ); | |
319 cairo_move_to( cr , | |
320 aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + 2 , | |
321 aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top + 2 ); | |
322 pango_cairo_show_layout( cr , osd_layout ); | |
323 } | |
324 | |
325 /* draw text */ | |
326 cairo_set_source_rgba( cr , (gdouble)textcolor0.red / 65535 , (gdouble)textcolor0.green / 65535 , | |
327 (gdouble)textcolor0.blue / 65535 , (gdouble)textcolor0.alpha / 65535 ); | |
328 cairo_move_to( cr , | |
329 aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left , | |
330 aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top ); | |
331 pango_cairo_show_layout( cr , osd_layout ); | |
332 } |