1 /* Clearlooks - a cairo based GTK+ engine
2  * Copyright (C) 2006 Benjamin Berg <benjamin@sipsolutions.net>
3  * Copyright (C) 2007-2008 Andrea Cimitan <andrea.cimitan@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * Project contact: <gnome-themes-list@gnome.org>
20  *
21  *
22  * This file defines the Clearlooks Glossy style
23  * Written by Andrea Cimitan <andrea.cimitan@gmail.com>
24  *        and Benjamin Berg <benjamin@sipsolutions.net>
25  * Based on code by Richard Stellingwerff <remenic@gmail.com>
26  *              and Daniel Borgmann <daniel.borgmann@gmail.com>
27  * from the ubuntulooks engine.
28  *
29  */
30 
31 
32 #include "clearlooks_draw.h"
33 #include "clearlooks_style.h"
34 #include "clearlooks_types.h"
35 
36 #include "support.h"
37 #include <ge-support.h>
38 
39 #include <cairo.h>
40 
41 
42 static void
clearlooks_draw_glossy_gradient(cairo_t * cr,double x,double y,int width,int height,const CairoColor * color,gboolean disabled,gboolean radius,CairoCorners corners)43 clearlooks_draw_glossy_gradient (cairo_t         *cr,
44                                  double x, double y, int width, int height,
45                                  const CairoColor *color,
46                                  gboolean disabled, gboolean radius, CairoCorners corners)
47 {
48 	CairoColor a, b, c, d;
49 	cairo_pattern_t *pt;
50 
51 	ge_shade_color (color, disabled? 1.06 : 1.16, &a);
52 	ge_shade_color (color, disabled? 1.02 : 1.08, &b);
53 	ge_shade_color (color, disabled? 0.98 : 1.00, &c);
54 	ge_shade_color (color, disabled? 1.02 : 1.08, &d);
55 
56 	pt = cairo_pattern_create_linear (x, y, x, y+height);
57 	cairo_pattern_add_color_stop_rgb (pt, 0.0, a.r, a.g, a.b);
58 	cairo_pattern_add_color_stop_rgb (pt, 0.5, b.r, b.g, b.b);
59 	cairo_pattern_add_color_stop_rgb (pt, 0.5, c.r, c.g, c.b);
60 	cairo_pattern_add_color_stop_rgb (pt, 1.0, d.r, d.g, d.b);
61 
62 	cairo_set_source (cr, pt);
63 	ge_cairo_rounded_rectangle (cr, x, y, width, height, radius, corners);
64 	cairo_fill (cr);
65 
66 	cairo_pattern_destroy (pt);
67 }
68 
69 /* This draw_inset implementation only differes in the shades values from the
70  * default one. */
71 static void
clearlooks_glossy_draw_inset(cairo_t * cr,const CairoColor * bg_color,double x,double y,double width,double height,double radius,uint8 corners)72 clearlooks_glossy_draw_inset (cairo_t          *cr,
73                               const CairoColor *bg_color,
74                               double x, double y, double width, double height,
75                               double radius, uint8 corners)
76 {
77 	CairoColor shadow;
78 	CairoColor highlight;
79 	double line_width;
80 	double min = MIN (width, height);
81 
82 	line_width = cairo_get_line_width (cr);
83 
84 	/* not really sure of shading ratios... we will think */
85 	ge_shade_color (bg_color, 0.93, &shadow);
86 	ge_shade_color (bg_color, 1.07, &highlight);
87 
88 	/* highlight */
89 	cairo_save (cr);
90 
91 	cairo_move_to (cr, x, y + height);
92 	cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0);
93 	cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0);
94 	cairo_line_to (cr, x + width, y);
95 	cairo_line_to (cr, x, y);
96 	cairo_close_path (cr);
97 
98 	cairo_clip (cr);
99 
100 	ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0,
101 	                            width - line_width, height - line_width,
102 	                            radius, corners);
103 
104 	ge_cairo_set_color (cr, &shadow);
105 	cairo_stroke (cr);
106 
107 	cairo_restore (cr);
108 
109 	/* shadow */
110 	cairo_save (cr);
111 
112 	cairo_move_to (cr, x, y + height);
113 	cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0);
114 	cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0);
115 	cairo_line_to (cr, x + width, y);
116 	cairo_line_to (cr, x + width, y + height);
117 	cairo_close_path (cr);
118 
119 	cairo_clip (cr);
120 
121 	ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0,
122 	                            width - line_width, height - line_width,
123 	                            radius, corners);
124 
125 	ge_cairo_set_color (cr, &highlight);
126 	cairo_stroke (cr);
127 
128 	cairo_restore (cr);
129 }
130 
131 static void
clearlooks_glossy_draw_light_inset(cairo_t * cr,const CairoColor * bg_color,double x,double y,double w,double h,double radius,uint8 corners)132 clearlooks_glossy_draw_light_inset (cairo_t          *cr,
133                                     const CairoColor *bg_color,
134                                     double x, double y, double w, double h,
135                                     double radius, uint8 corners)
136 {
137 	CairoColor shadow;
138 	CairoColor highlight;
139 
140 	/* not really sure of shading ratios... we will think */
141 	ge_shade_color (bg_color, 0.95, &shadow);
142 	ge_shade_color (bg_color, 1.05, &highlight);
143 
144 	/* highlight */
145 	cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */
146 
147 	if (corners & CR_CORNER_TOPRIGHT)
148 		cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.75, G_PI * 2);
149 	else
150 		cairo_line_to (cr, x + w, y);
151 
152 	if (corners & CR_CORNER_BOTTOMRIGHT)
153 		cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, G_PI * 0.5);
154 	else
155 		cairo_line_to (cr, x + w, y + h);
156 
157 	if (corners & CR_CORNER_BOTTOMLEFT)
158 		cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.5, G_PI * 0.75);
159 	else
160 		cairo_line_to (cr, x, y + h);
161 
162 	ge_cairo_set_color (cr, &highlight);
163 	cairo_stroke (cr);
164 
165 	/* shadow */
166 	cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188));
167 
168 	if (corners & CR_CORNER_BOTTOMLEFT)
169 		cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.75, G_PI);
170 	else
171 		cairo_line_to (cr, x, y + h);
172 
173 	if (corners & CR_CORNER_TOPLEFT)
174 		cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 1.5);
175 	else
176 		cairo_line_to (cr, x, y);
177 
178 	if (corners & CR_CORNER_TOPRIGHT)
179 	    cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.5, G_PI * 1.75);
180 	else
181 		cairo_line_to (cr, x + w, y);
182 
183 	ge_cairo_set_color (cr, &shadow);
184 	cairo_stroke (cr);
185 }
186 
187 /* This function currently assumes that the input is translated by 0.5px! */
188 static void
clearlooks_glossy_draw_highlight_and_shade(cairo_t * cr,const CairoColor * bg_color,const ShadowParameters * params,int width,int height,gdouble radius)189 clearlooks_glossy_draw_highlight_and_shade (cairo_t          *cr,
190                                             const CairoColor *bg_color,
191                                             const ShadowParameters *params,
192                                             int width, int height, gdouble radius)
193 {
194 	CairoColor shadow;
195 	CairoColor highlight;
196 	uint8 corners = params->corners;
197 	double x = 1.0;
198 	double y = 1.0;
199 
200 	/* not really sure of shading ratios... we will think */
201 	ge_shade_color (bg_color, 0.8, &shadow);
202 	ge_shade_color (bg_color, 1.2, &highlight);
203 
204 	cairo_save (cr);
205 
206 	/* Top/Left highlight */
207 	if (corners & CR_CORNER_BOTTOMLEFT)
208 		cairo_move_to (cr, x, y+height-radius);
209 	else
210 		cairo_move_to (cr, x, y+height);
211 
212 	ge_cairo_rounded_corner (cr, x, y, radius, corners & CR_CORNER_TOPLEFT);
213 
214 	if (corners & CR_CORNER_TOPRIGHT)
215 		cairo_line_to (cr, x+width-radius, y);
216 	else
217 		cairo_line_to (cr, x+width, y);
218 
219 	if (params->shadow & CL_SHADOW_OUT)
220 		cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
221 	else
222 		cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5);
223 
224 	cairo_stroke (cr);
225 
226 	/* Bottom/Right highlight -- this includes the corners */
227 	cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */
228 	ge_cairo_rounded_corner (cr, x+width, y, radius, corners & CR_CORNER_TOPRIGHT);
229 	ge_cairo_rounded_corner (cr, x+width, y+height, radius, corners & CR_CORNER_BOTTOMRIGHT);
230 	ge_cairo_rounded_corner (cr, x, y+height, radius, corners & CR_CORNER_BOTTOMLEFT);
231 
232 	if (params->shadow & CL_SHADOW_OUT)
233 		cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5);
234 	else
235 		cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
236 
237 	cairo_stroke (cr);
238 
239 	cairo_restore (cr);
240 }
241 
242 static void
clearlooks_glossy_draw_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)243 clearlooks_glossy_draw_button (cairo_t *cr,
244                                const ClearlooksColors *colors,
245                                const WidgetParameters *params,
246                                int x, int y, int width, int height)
247 {
248 	double xoffset = 0, yoffset = 0;
249 	CairoColor fill            = colors->bg[params->state_type];
250 	CairoColor border_normal   = colors->shade[6];
251 	CairoColor border_disabled = colors->shade[4];
252 	double radius;
253 
254 	cairo_pattern_t *pattern;
255 
256 	cairo_save (cr);
257 	cairo_translate (cr, x, y);
258 	cairo_set_line_width (cr, 1.0);
259 
260 	/* Shadows and shadow */
261 	if (params->xthickness == 3 || params->ythickness == 3)
262 	{
263 		if (params->xthickness == 3)
264 			xoffset = 1;
265 		if (params->ythickness == 3)
266 			yoffset = 1;
267 	}
268 
269 	radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0, (height - 2.0 - 2*yoffset) / 2.0));
270 
271 	if (params->xthickness == 3 || params->ythickness == 3)
272 	{
273 		/* if (params->enable_shadow && !params->active && !params->disabled) */
274 		if (!params->active && (params->prelight || params->enable_shadow))
275 		{
276 			/* shadow becomes a shadow to have 3d prelight buttons :) */
277 			CairoColor shadow;
278 
279 			radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0));
280 
281 			ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius+1, params->corners);
282 			ge_shade_color (&params->parentbg, 0.96, &shadow);
283 			ge_cairo_set_color (cr, &shadow);
284 			cairo_stroke (cr);
285 
286 			ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-2, height-2, radius+1, params->corners);
287 			ge_shade_color (&params->parentbg, 0.92, &shadow);
288 			ge_cairo_set_color (cr, &shadow);
289 			cairo_stroke (cr);
290 		}
291 		else
292 		{
293 			if (!(params->disabled))
294 				params->style_functions->draw_inset (cr, &params->parentbg, 0, 0, width, height, params->radius+1, params->corners);
295 			else
296 				/*Draw a lighter inset */
297 				clearlooks_glossy_draw_light_inset (cr, &params->parentbg, 0, 0, width, height, params->radius+1, params->corners);
298 		}
299 	}
300 
301 	clearlooks_draw_glossy_gradient (cr, xoffset+1, yoffset+1,
302 	                              width-(xoffset*2)-2, height-(yoffset*2)-2,
303 	                              &fill, params->disabled, radius, params->corners);
304 
305 	/* Pressed button shadow */
306 	if (params->active)
307 	{
308 		CairoColor shadow;
309 		ge_shade_color (&fill, 0.92, &shadow);
310 
311 		cairo_save (cr);
312 
313 		ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height, radius, params->corners & (CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMLEFT));
314 		cairo_clip (cr);
315 		cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3);
316 
317 		pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4);
318 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
319 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
320 		cairo_set_source (cr, pattern);
321 		cairo_fill (cr);
322 		cairo_pattern_destroy (pattern);
323 
324 		cairo_rectangle (cr, xoffset+1, yoffset+1, 3, height-(yoffset*2)-2);
325 
326 		pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+4, yoffset+1);
327 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
328 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
329 		cairo_set_source (cr, pattern);
330 		cairo_fill (cr);
331 		cairo_pattern_destroy (pattern);
332 
333 		cairo_restore (cr);
334 	}
335 
336 	/* Default button highlight */
337 	if (params->is_default && !params->active && !params->disabled)
338 	{
339 		const CairoColor *shadow = &colors->spot[0];
340 		double hh = (height-5)/2.0 + 1;
341 
342 		cairo_rectangle (cr, 3.5, 3.5, width-7, height-7);
343 		ge_cairo_set_color (cr, shadow);
344 		cairo_stroke (cr);
345 
346 		shadow = &colors->spot[0];
347 		cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, -hh);
348 		cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, hh);
349 		ge_cairo_set_color (cr, shadow);
350 		cairo_stroke (cr);
351 
352 		hh--;
353 
354 		shadow = &colors->spot[1];
355 		cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, hh);
356 		cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, -hh);
357 		ge_cairo_set_color (cr, shadow);
358 		cairo_stroke (cr);
359 	}
360 
361 	/* Border */
362 	if (params->is_default || (params->prelight && params->enable_shadow))
363 		border_normal = colors->spot[2];
364 		/* ge_mix_color (&border_normal, &colors->spot[2], 0.5, &border_normal); */
365 	if (params->disabled)
366 		ge_cairo_set_color (cr, &border_disabled);
367 	else
368 		clearlooks_set_mixed_color (cr, &border_normal, &fill, 0.2);
369 	ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5,
370                                   width-(xoffset*2)-1, height-(yoffset*2)-1,
371                                   radius, params->corners);
372 	cairo_stroke (cr);
373 	cairo_restore (cr);
374 }
375 
376 static void
clearlooks_glossy_draw_progressbar_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)377 clearlooks_glossy_draw_progressbar_trough (cairo_t *cr,
378                                     const ClearlooksColors *colors,
379                                     const WidgetParameters *params,
380                                     int x, int y, int width, int height)
381 {
382 	const CairoColor *border = &colors->shade[6];
383 	CairoColor        shadow;
384 	cairo_pattern_t  *pattern;
385 	double           radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0));
386 
387 	cairo_save (cr);
388 
389 	cairo_set_line_width (cr, 1.0);
390 
391 	/* Create trough box */
392 	ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
393 	ge_cairo_set_color (cr, &colors->shade[2]);
394 	cairo_fill (cr);
395 
396 	/* Draw border */
397 	ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1, radius, params->corners);
398 	clearlooks_set_mixed_color (cr, border, &colors->shade[2], 0.3);
399 	cairo_stroke (cr);
400 
401 	/* clip the corners of the shadows */
402 	ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
403 	cairo_clip (cr);
404 
405 	ge_shade_color (border, 0.92, &shadow);
406 
407 	/* Top shadow */
408 	cairo_rectangle (cr, x+1, y+1, width-2, 4);
409 	pattern = cairo_pattern_create_linear (x, y, x, y+4);
410 	cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3);
411 	cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.);
412 	cairo_set_source (cr, pattern);
413 	cairo_fill (cr);
414 	cairo_pattern_destroy (pattern);
415 
416 	/* Left shadow */
417 	cairo_rectangle (cr, x+1, y+1, 4, height-2);
418 	pattern = cairo_pattern_create_linear (x, y, x+4, y);
419 	cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3);
420 	cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.);
421 	cairo_set_source (cr, pattern);
422 	cairo_fill (cr);
423 	cairo_pattern_destroy (pattern);
424 
425 	cairo_restore (cr);
426 }
427 
428 static void
clearlooks_glossy_draw_progressbar_fill(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const ProgressBarParameters * progressbar,int x,int y,int width,int height,gint offset)429 clearlooks_glossy_draw_progressbar_fill (cairo_t *cr,
430                                   const ClearlooksColors *colors,
431                                   const WidgetParameters *params,
432                                   const ProgressBarParameters *progressbar,
433                                   int x, int y, int width, int height,
434                                   gint offset)
435 {
436 	boolean      is_horizontal = progressbar->orientation < 2;
437 	double       tile_pos = 0;
438 	double       stroke_width;
439 	double       radius;
440 	int          x_step;
441 
442 	cairo_pattern_t *pattern;
443 	CairoColor       a;
444 	CairoColor       b;
445 	CairoColor       e;
446 	CairoColor       border;
447 	CairoColor       shadow;
448 
449 	radius = MAX (0, params->radius - params->xthickness);
450 
451 	cairo_save (cr);
452 
453 	if (!is_horizontal)
454 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
455 
456 	if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP))
457 		ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height);
458 
459 	/* Clamp the radius so that the _height_ fits ...  */
460 	radius = MIN (radius, height / 2.0);
461 
462 	stroke_width = height*2;
463 	x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */
464 
465 	cairo_translate (cr, x, y);
466 
467 	cairo_save (cr);
468 	/* This is kind of nasty ... Clip twice from each side in case the length
469 	 * of the fill is smaller than twice the radius. */
470 	ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
471 	cairo_clip (cr);
472 	ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
473 	cairo_clip (cr);
474 
475 	/* Draw the background gradient */
476 	ge_shade_color (&colors->spot[1], 1.16, &a);
477 	ge_shade_color (&colors->spot[1], 1.08, &b);
478 	ge_shade_color (&colors->spot[1], 1.08, &e);
479 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
480 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, a.r, a.g, a.b);
481 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, b.r, b.g, b.b);
482 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b);
483 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, e.r, e.g, e.b);
484 	cairo_set_source (cr, pattern);
485 	cairo_paint (cr);
486 	cairo_pattern_destroy (pattern);
487 
488 	/* Draw the Strokes */
489 	while (stroke_width > 0 && tile_pos <= width+x_step)
490 	{
491 		cairo_move_to (cr, stroke_width/2-x_step, 0);
492 		cairo_line_to (cr, stroke_width-x_step,   0);
493 		cairo_line_to (cr, stroke_width/2-x_step, height);
494 		cairo_line_to (cr, -x_step, height);
495 
496 		cairo_translate (cr, stroke_width, 0);
497 		tile_pos += stroke_width;
498 	}
499 
500 	cairo_set_source_rgba (cr, colors->spot[2].r,
501 	                           colors->spot[2].g,
502 	                           colors->spot[2].b,
503 	                           0.15);
504 
505 	cairo_fill (cr);
506 	cairo_restore (cr); /* rounded clip region */
507 
508 	/* inner highlight border
509 	 * This is again kinda ugly. Draw once from each side, clipping away the other. */
510 	cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.3);
511 
512 	/* left side */
513 	cairo_save (cr);
514 	cairo_rectangle (cr, 0, 0, width / 2, height);
515 	cairo_clip (cr);
516 
517 	if (progressbar->pulsing)
518 		ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
519 	else
520 		ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
521 
522 	cairo_stroke (cr);
523 	cairo_restore (cr); /* clip */
524 
525 	/* right side */
526 	cairo_save (cr);
527 	cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height);
528 	cairo_clip (cr);
529 
530 	if (progressbar->value < 1.0 || progressbar->pulsing)
531 		ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
532 	else
533 		ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
534 
535 	cairo_stroke (cr);
536 	cairo_restore (cr); /* clip */
537 
538 
539 	/* Draw the dark lines and the shadow */
540 	cairo_save (cr);
541 	/* Again, this weird clip area. */
542 	ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
543 	cairo_clip (cr);
544 	ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
545 	cairo_clip (cr);
546 
547 	border = colors->spot[2];
548 	border.a = 0.5;
549 	ge_shade_color (&colors->shade[6], 0.92, &shadow);
550 	shadow.a = 0.2;
551 
552 	if (progressbar->pulsing)
553 	{
554 		/* At the beginning of the bar. */
555 		cairo_move_to (cr, 0.5 + radius, height + 0.5);
556 		ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
557 		ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
558 		ge_cairo_set_color (cr, &border);
559 		cairo_stroke (cr);
560 
561 		cairo_move_to (cr, -0.5 + radius, height + 0.5);
562 		ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
563 		ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
564 		ge_cairo_set_color (cr, &shadow);
565 		cairo_stroke (cr);
566 	}
567 	if (progressbar->value < 1.0 || progressbar->pulsing)
568 	{
569 		/* At the end of the bar. */
570 		cairo_move_to (cr, width - 0.5 - radius, -0.5);
571 		ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
572 		ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
573 		ge_cairo_set_color (cr, &border);
574 		cairo_stroke (cr);
575 
576 		cairo_move_to (cr, width + 0.5 - radius, -0.5);
577 		ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
578 		ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
579 		ge_cairo_set_color (cr, &shadow);
580 		cairo_stroke (cr);
581 	}
582 
583 	cairo_restore (cr);
584 
585 	cairo_restore (cr); /* rotation, mirroring */
586 }
587 
588 static void
clearlooks_glossy_scale_draw_gradient(cairo_t * cr,const CairoColor * c1,const CairoColor * c2,const CairoColor * c3,int x,int y,int width,int height,boolean horizontal)589 clearlooks_glossy_scale_draw_gradient (cairo_t *cr,
590                                 const CairoColor *c1,
591                                 const CairoColor *c2,
592                                 const CairoColor *c3,
593                                 int x, int y, int width, int height,
594                                 boolean horizontal)
595 {
596 	cairo_pattern_t *pattern;
597 
598 	pattern = cairo_pattern_create_linear (0.5, 0.5, horizontal ? 0.5 :  width + 1, horizontal ? height + 1 : 0.5);
599 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, c1->r, c1->g, c1->b);
600 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, c2->r, c2->g, c2->b);
601 
602 	cairo_rectangle (cr, x, y, width, height);
603 	cairo_set_source (cr, pattern);
604 	cairo_fill (cr);
605 	cairo_pattern_destroy (pattern);
606 
607 	clearlooks_set_mixed_color (cr, c3, c1, 0.3);
608 	ge_cairo_inner_rectangle (cr, x, y, width, height);
609 	cairo_stroke (cr);
610 }
611 
612 #define TROUGH_SIZE 7
613 static void
clearlooks_glossy_draw_scale_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)614 clearlooks_glossy_draw_scale_trough (cairo_t *cr,
615                               const ClearlooksColors *colors,
616                               const WidgetParameters *params,
617                               const SliderParameters *slider,
618                               int x, int y, int width, int height)
619 {
620 	int     trough_width, trough_height;
621 	double  translate_x, translate_y;
622 
623 	cairo_save (cr);
624 
625 	if (slider->horizontal)
626 	{
627 		trough_width  = width;
628 		trough_height = TROUGH_SIZE;
629 
630 		translate_x   = x;
631 		translate_y   = y + (height/2) - (TROUGH_SIZE/2);
632 	}
633 	else
634 	{
635 		trough_width  = TROUGH_SIZE;
636 		trough_height = height;
637 
638 		translate_x   = x + (width/2) - (TROUGH_SIZE/2);
639 		translate_y  = y;
640 	}
641 
642 	cairo_set_line_width (cr, 1.0);
643 	cairo_translate (cr, translate_x, translate_y);
644 
645 	if (!slider->fill_level)
646 		params->style_functions->draw_inset (cr, &params->parentbg, 0, 0, trough_width, trough_height, 0, 0);
647 
648 	if (!slider->lower && !slider->fill_level)
649 		clearlooks_glossy_scale_draw_gradient (cr, &colors->shade[3], /* top */
650 		                                    &colors->shade[2], /* bottom */
651 		                                    &colors->shade[6], /* border */
652 		                                    1.0, 1.0, trough_width - 2, trough_height - 2,
653 		                                    slider->horizontal);
654 	else
655 		clearlooks_glossy_scale_draw_gradient (cr, &colors->spot[1], /* top */
656 		                                    &colors->spot[0], /* bottom */
657 		                                    &colors->spot[2], /* border */
658 		                                    1.0, 1.0, trough_width - 2, trough_height - 2,
659 		                                    slider->horizontal);
660 	cairo_restore (cr);
661 }
662 
663 static void
clearlooks_glossy_draw_tab(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const TabParameters * tab,int x,int y,int width,int height)664 clearlooks_glossy_draw_tab (cairo_t *cr,
665                             const ClearlooksColors *colors,
666                             const WidgetParameters *params,
667                             const TabParameters    *tab,
668                             int x, int y, int width, int height)
669 {
670 
671 	const CairoColor    *border       = &colors->shade[5];
672 	const CairoColor    *stripe_fill   = &colors->spot[1];
673 	const CairoColor    *stripe_border = &colors->spot[2];
674 	const CairoColor    *fill;
675 	CairoColor           hilight;
676 
677 	cairo_pattern_t     *pattern;
678 
679 	double               radius;
680 	double               strip_size;
681 	double               length;
682 
683 	radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
684 
685 	/* Set clip */
686 	cairo_rectangle      (cr, x, y, width, height);
687 	cairo_clip           (cr);
688 	cairo_new_path       (cr);
689 
690 	/* Translate and set line width */
691 	cairo_set_line_width (cr, 1.0);
692 	cairo_translate      (cr, x+0.5, y+0.5);
693 
694 
695 	/* Make the tabs slightly bigger than they should be, to create a gap */
696 	/* And calculate the strip size too, while you're at it */
697 	if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM)
698 	{
699 		height += 3.0;
700 		length = height;
701 	 	strip_size = 2.0/height; /* 2 pixel high strip */
702 
703 		if (tab->gap_side == CL_GAP_TOP)
704 			cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
705 	}
706 	else
707 	{
708 		width += 3.0;
709 		length = width;
710 	 	strip_size = 2.0/width;
711 
712 		if (tab->gap_side == CL_GAP_LEFT)
713 			cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
714 	}
715 
716 	/* Set the fill color */
717 	fill = &colors->bg[params->state_type];
718 
719 	/* Set tab shape */
720 	ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1,
721 	                            radius, params->corners);
722 
723 	/* Draw fill */
724 	ge_cairo_set_color (cr, fill);
725 	cairo_fill   (cr);
726 
727 	ge_shade_color (fill, 1.3, &hilight);
728 
729 	/* Draw highlight */
730 	if (!params->active)
731 	{
732 		ShadowParameters shadow;
733 
734 		shadow.shadow  = CL_SHADOW_OUT;
735 		shadow.corners = params->corners;
736 
737 		/* This is the only usage of clearlooks_glossy_draw_highlight_and_shade,
738 		 * the function assumes currently that the input is translated by 0.5 px. */
739 		clearlooks_glossy_draw_highlight_and_shade (cr, &colors->bg[0], &shadow,
740 		                                     width,
741 		                                     height, radius);
742 	}
743 
744 	if (params->active)
745 	{
746 		CairoColor shadow, hilight, f1, f2;
747 
748 		switch (tab->gap_side)
749 		{
750 			case CL_GAP_TOP:
751 				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
752 				break;
753 			case CL_GAP_BOTTOM:
754 				pattern = cairo_pattern_create_linear (0, 1, 0, height);
755 				break;
756 			case CL_GAP_LEFT:
757 				pattern = cairo_pattern_create_linear (width-2, 0, 1, 0);
758 				break;
759 			case CL_GAP_RIGHT:
760 				pattern = cairo_pattern_create_linear (1, 0, width-2, 0);
761 				break;
762 			default:
763 				pattern = NULL;
764 		}
765 
766 		ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
767 
768 		ge_shade_color (fill, 1.06, &shadow);
769 		ge_shade_color (fill, 1.18, &hilight);
770 		ge_shade_color (fill, 1.12, &f1);
771 		ge_shade_color (fill, 1.06, &f2);
772 
773 		cairo_pattern_add_color_stop_rgb (pattern, 0.0,        hilight.r, hilight.g, hilight.b);
774 		cairo_pattern_add_color_stop_rgb (pattern, 1.0/length, hilight.r, hilight.g, hilight.b);
775 		cairo_pattern_add_color_stop_rgb (pattern, 1.0/length, f1.r, f1.g, f1.b);
776 		cairo_pattern_add_color_stop_rgb (pattern, 0.45,       f2.r, f2.g, f2.b);
777 		cairo_pattern_add_color_stop_rgb (pattern, 0.45,       fill->r, fill->g, fill->b);
778 		cairo_pattern_add_color_stop_rgb (pattern, 1.0,        shadow.r, shadow.g, shadow.b);
779 		cairo_set_source (cr, pattern);
780 		cairo_fill (cr);
781 		cairo_pattern_destroy (pattern);
782 	}
783 	else
784 	{
785 		/* Draw shade */
786 		switch (tab->gap_side)
787 		{
788 			case CL_GAP_TOP:
789 				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
790 				break;
791 			case CL_GAP_BOTTOM:
792 				pattern = cairo_pattern_create_linear (0, 0, 0, height);
793 				break;
794 			case CL_GAP_LEFT:
795 				pattern = cairo_pattern_create_linear (width-2, 0, 0, 0);
796 				break;
797 			case CL_GAP_RIGHT:
798 				pattern = cairo_pattern_create_linear (0, 0, width, 0);
799 				break;
800 			default:
801 				pattern = NULL;
802 		}
803 
804 		ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
805 
806 
807 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.5);
808 		cairo_pattern_add_color_stop_rgba (pattern, 0.8, fill->r, fill->g, fill->b, 0.0);
809 		cairo_set_source (cr, pattern);
810 		cairo_fill (cr);
811 		cairo_pattern_destroy (pattern);
812 	}
813 
814 	ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
815 
816 	if (params->active)
817 	{
818 		ge_cairo_set_color (cr, border);
819 		cairo_stroke (cr);
820 	}
821 	else
822 	{
823 		switch (tab->gap_side)
824 		{
825 			case CL_GAP_TOP:
826 				pattern = cairo_pattern_create_linear (2, height-2, 2, 2);
827 				break;
828 			case CL_GAP_BOTTOM:
829 				pattern = cairo_pattern_create_linear (2, 2, 2, height);
830 				break;
831 			case CL_GAP_LEFT:
832 				pattern = cairo_pattern_create_linear (width-2, 2, 2, 2);
833 				break;
834 			case CL_GAP_RIGHT:
835 				pattern = cairo_pattern_create_linear (2, 2, width, 2);
836 				break;
837 			default:
838 				pattern = NULL;
839 		}
840 
841 		cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b);
842 		cairo_pattern_add_color_stop_rgb (pattern, 0.8, border->r,        border->g,        border->b);
843 		cairo_set_source (cr, pattern);
844 		cairo_stroke (cr);
845 		cairo_pattern_destroy (pattern);
846 	}
847 }
848 
849 static void
clearlooks_glossy_draw_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)850 clearlooks_glossy_draw_slider (cairo_t *cr,
851                         const ClearlooksColors *colors,
852                         const WidgetParameters *params,
853                         int x, int y, int width, int height)
854 {
855 	const CairoColor *border  = &colors->shade[7];
856 	CairoColor  fill;
857 	CairoColor  hilight;
858 	CairoColor  a, b, c, d;
859 	cairo_pattern_t *pattern;
860 
861 	cairo_set_line_width (cr, 1.0);
862 	cairo_translate      (cr, x, y);
863 
864 	ge_shade_color (&colors->bg[params->state_type], 1.0, &fill);
865 	if (params->prelight)
866 		ge_shade_color (&fill, 1.1, &fill);
867 
868 	ge_shade_color (&fill, 1.25, &hilight);
869 	ge_shade_color (&fill, 1.16, &a);
870 	ge_shade_color (&fill, 1.08, &b);
871 	ge_shade_color (&fill, 1.0,  &c);
872 	ge_shade_color (&fill, 1.08, &d);
873 
874 	pattern = cairo_pattern_create_linear (1, 1, 1, height-2);
875 	cairo_pattern_add_color_stop_rgb (pattern, 0,   a.r, a.g, a.b);
876 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, b.r, b.g, b.b);
877 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, c.r, c.g, c.b);
878 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, d.r, d.g, d.b);
879 	cairo_rectangle (cr, 1, 1, width-2, height-2);
880 	cairo_set_source (cr, pattern);
881 	cairo_fill (cr);
882 	cairo_pattern_destroy (pattern);
883 
884 	clearlooks_set_mixed_color (cr, border, &fill, 0.2);
885 	if (params->prelight)
886 		ge_cairo_set_color (cr, &colors->spot[2]);
887 	ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, 2.5, params->corners);
888 	cairo_stroke (cr);
889 
890 	cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
891 	ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-3, height-3, 2.0, params->corners);
892 	cairo_stroke (cr);
893 }
894 
895 static void
clearlooks_glossy_draw_slider_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)896 clearlooks_glossy_draw_slider_button (cairo_t *cr,
897                                       const ClearlooksColors *colors,
898                                       const WidgetParameters *params,
899                                       const SliderParameters *slider,
900                                       int x, int y, int width, int height)
901 {
902 	double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0));
903 
904 	cairo_set_line_width (cr, 1.0);
905 
906 	if (!slider->horizontal)
907 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
908 
909 	cairo_translate (cr, x, y);
910 	params->style_functions->draw_shadow (cr, colors, radius, width, height);
911 	params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2);
912 }
913 
914 static void
clearlooks_glossy_draw_scrollbar_stepper(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,const ScrollBarStepperParameters * stepper,int x,int y,int width,int height)915 clearlooks_glossy_draw_scrollbar_stepper (cairo_t *cr,
916                                    const ClearlooksColors           *colors,
917                                    const WidgetParameters           *widget,
918                                    const ScrollBarParameters        *scrollbar,
919                                    const ScrollBarStepperParameters *stepper,
920                                    int x, int y, int width, int height)
921 {
922 	CairoCorners corners = CR_CORNER_NONE;
923 	const CairoColor *border = &colors->shade[7];
924 	CairoColor  fill, s1, s2, s4;
925 	cairo_pattern_t *pattern;
926 	ShadowParameters shadow;
927 	double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
928 
929 	if (scrollbar->horizontal)
930 	{
931 		if (stepper->stepper == CL_STEPPER_A)
932 			corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
933 		else if (stepper->stepper == CL_STEPPER_D)
934 			corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
935 
936 		if (stepper->stepper == CL_STEPPER_B)
937 		{
938 			x -= 1;
939 			width += 1;
940 		}
941 		else if (stepper->stepper == CL_STEPPER_C)
942 		{
943 			width += 1;
944 		}
945 	}
946 	else
947 	{
948 		if (stepper->stepper == CL_STEPPER_A)
949 			corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT;
950 		else if (stepper->stepper == CL_STEPPER_D)
951 			corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT;
952 
953 		if (stepper->stepper == CL_STEPPER_B)
954 		{
955 			y -= 1;
956 			height += 1;
957 		}
958 		else if (stepper->stepper == CL_STEPPER_C)
959 		{
960 			height += 1;
961 		}
962 	}
963 
964 	cairo_translate (cr, x, y);
965 	cairo_set_line_width (cr, 1);
966 
967 	ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners);
968 
969 	if (scrollbar->horizontal)
970 		pattern = cairo_pattern_create_linear (0, 0, 0, height);
971 	else
972 		pattern = cairo_pattern_create_linear (0, 0, width, 0);
973 
974 	fill = colors->bg[widget->state_type];
975 	ge_shade_color(&fill, 1.16, &s1);
976 	ge_shade_color(&fill, 1.08, &s2);
977 	ge_shade_color(&fill, 1.08, &s4);
978 
979 	cairo_pattern_add_color_stop_rgb(pattern, 0,    s1.r, s1.g, s1.b);
980 	cairo_pattern_add_color_stop_rgb(pattern, 0.5,	s2.r, s2.g, s2.b);
981 	cairo_pattern_add_color_stop_rgb(pattern, 0.5,	fill.r, fill.g, fill.b);
982 	cairo_pattern_add_color_stop_rgb(pattern, 1.0,  s4.r, s4.g, s4.b);
983 	cairo_set_source (cr, pattern);
984 	cairo_fill (cr);
985 	cairo_pattern_destroy (pattern);
986 
987 	ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, corners);
988 	clearlooks_set_mixed_color (cr, border, &fill, 0.2);
989 	if (widget->prelight)
990 		ge_cairo_set_color (cr, &colors->spot[2]);
991 	cairo_stroke (cr);
992 
993 	shadow.shadow  = CL_SHADOW_OUT;
994 	shadow.corners = corners;
995 }
996 
997 static void
clearlooks_glossy_draw_scrollbar_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)998 clearlooks_glossy_draw_scrollbar_slider (cairo_t *cr,
999                                    const ClearlooksColors          *colors,
1000                                    const WidgetParameters          *widget,
1001                                    const ScrollBarParameters       *scrollbar,
1002                                    int x, int y, int width, int height)
1003 {
1004 	const CairoColor *border  = &colors->shade[7];
1005 	CairoColor  fill  = scrollbar->color;
1006 	CairoColor  hilight;
1007 	CairoColor  shade1, shade2, shade3;
1008 	cairo_pattern_t *pattern;
1009 
1010 	if (scrollbar->junction & CL_JUNCTION_BEGIN)
1011 	{
1012 		if (scrollbar->horizontal)
1013 		{
1014 			x -= 1;
1015 			width += 1;
1016 		}
1017 		else
1018 		{
1019 			y -= 1;
1020 			height += 1;
1021 		}
1022 	}
1023 	if (scrollbar->junction & CL_JUNCTION_END)
1024 	{
1025 		if (scrollbar->horizontal)
1026 			width += 1;
1027 		else
1028 			height += 1;
1029 	}
1030 
1031 	if (!scrollbar->horizontal)
1032 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
1033 
1034 	cairo_translate (cr, x, y);
1035 
1036 	if (widget->prelight)
1037 		ge_shade_color (&fill, 1.1, &fill);
1038 
1039 	cairo_set_line_width (cr, 1);
1040 
1041 	ge_shade_color (&fill, 1.25, &hilight);
1042 	ge_shade_color (&fill, 1.16, &shade1);
1043 	ge_shade_color (&fill, 1.08, &shade2);
1044 	ge_shade_color (&fill, 1.08, &shade3);
1045 
1046 	pattern = cairo_pattern_create_linear (1, 1, 1, height-2);
1047 	cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
1048 	cairo_pattern_add_color_stop_rgb (pattern, 0.5,	shade2.r, shade2.g, shade2.b);
1049 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, 	fill.r,  fill.g,  fill.b);
1050 	cairo_pattern_add_color_stop_rgb (pattern, 1,	shade3.r, shade3.g, shade3.b);
1051 	cairo_rectangle (cr, 1, 1, width-2, height-2);
1052 	cairo_set_source (cr, pattern);
1053 	cairo_fill (cr);
1054 	cairo_pattern_destroy (pattern);
1055 
1056 	if (scrollbar->has_color)
1057 	{
1058 		cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
1059 		ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3);
1060 	}
1061 
1062 	clearlooks_set_mixed_color (cr, border, &fill, scrollbar->has_color? 0.4 : 0.2);
1063 	ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1064 }
1065 
1066 static void
clearlooks_glossy_draw_list_view_header(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const ListViewHeaderParameters * header,int x,int y,int width,int height)1067 clearlooks_glossy_draw_list_view_header (cairo_t *cr,
1068                                   const ClearlooksColors          *colors,
1069                                   const WidgetParameters          *params,
1070                                   const ListViewHeaderParameters  *header,
1071                                   int x, int y, int width, int height)
1072 {
1073 /*
1074 	CairoColor *border = !params->prelight? (CairoColor*)&colors->shade[4] : (CairoColor*)&colors->spot[1];
1075 */
1076 	const CairoColor *border = &colors->shade[4];
1077 	const CairoColor *fill   = &colors->bg[params->state_type];
1078 	CairoColor hilight;
1079 	CairoColor shade1, shade2, shade3;
1080 
1081 	cairo_pattern_t *pattern;
1082 
1083  	ge_shade_color (fill, 1.2, &hilight);
1084 	ge_shade_color (fill, 1.08, &shade1);
1085 	ge_shade_color (fill, 1.04, &shade2);
1086 	ge_shade_color (fill, 1.04, &shade3);
1087 
1088 	cairo_translate (cr, x, y);
1089 	cairo_set_line_width (cr, 1.0);
1090 
1091 	/* Draw the fill */
1092 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
1093 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
1094 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1095 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b);
1096 	cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, shade3.r, shade3.g, shade3.b);
1097 	cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, border->r, border->g, border->b);
1098 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, border->r, border->g, border->b);
1099 
1100 	cairo_set_source (cr, pattern);
1101 	cairo_rectangle (cr, 0, 0, width, height);
1102 	cairo_fill (cr);
1103 
1104 	cairo_pattern_destroy (pattern);
1105 
1106 	/* Draw highlight */
1107 	if (header->order & CL_ORDER_FIRST)
1108 	{
1109 		cairo_move_to (cr, 0.5, height-1);
1110 		cairo_line_to (cr, 0.5, 0.5);
1111 	}
1112 	else
1113 		cairo_move_to (cr, 0.0, 0.5);
1114 
1115 	cairo_line_to (cr, width, 0.5);
1116 
1117 	cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
1118 	cairo_stroke (cr);
1119 
1120 	/* Draw resize grip */
1121 	if ((params->ltr && !(header->order & CL_ORDER_LAST)) ||
1122 	    (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable)
1123 	{
1124 		SeparatorParameters separator;
1125 		separator.horizontal = FALSE;
1126 
1127 		if (params->ltr)
1128 			params->style_functions->draw_separator (cr, colors, params, &separator,
1129 			                                         width-1.5, 4.0, 2, height-8.0);
1130 		else
1131 			params->style_functions->draw_separator (cr, colors, params, &separator,
1132 			                                         1.5, 4.0, 2, height-8.0);
1133 	}
1134 }
1135 
1136 static void
clearlooks_glossy_draw_toolbar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ToolbarParameters * toolbar,int x,int y,int width,int height)1137 clearlooks_glossy_draw_toolbar (cairo_t *cr,
1138                          const ClearlooksColors          *colors,
1139                          const WidgetParameters          *widget,
1140                          const ToolbarParameters         *toolbar,
1141                          int x, int y, int width, int height)
1142 {
1143 	const CairoColor *fill  = &colors->bg[GTK_STATE_NORMAL];
1144 	const CairoColor *dark  = &colors->shade[3];
1145 	CairoColor light;
1146 	ge_shade_color (fill, 1.1, &light);
1147 
1148 	cairo_set_line_width (cr, 1.0);
1149 	cairo_translate (cr, x, y);
1150 
1151 	if (toolbar->style == 1) /* Enable Extra features */
1152 	{
1153 		cairo_pattern_t *pattern;
1154 		CairoColor shade1, shade2, shade3;
1155 
1156 		ge_shade_color (fill, 1.08, &shade1);
1157 		ge_shade_color (fill, 1.04, &shade2);
1158 		ge_shade_color (fill, 1.04, &shade3);
1159 
1160 		/* Draw the fill */
1161 		pattern = cairo_pattern_create_linear (0, 0, 0, height);
1162 		cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
1163 		cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1164 		cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b);
1165 		cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b);
1166 
1167 		cairo_set_source (cr, pattern);
1168 		cairo_rectangle (cr, 0, 0, width, height);
1169 		cairo_fill (cr);
1170 
1171 		cairo_pattern_destroy (pattern);
1172 	}
1173 	else /* Flat */
1174 	{
1175 		ge_cairo_set_color (cr, fill);
1176 		cairo_paint (cr);
1177 
1178 		if (!toolbar->topmost)
1179 		{
1180 			/* Draw highlight */
1181 			cairo_move_to       (cr, 0, 0.5);
1182 			cairo_line_to       (cr, width-1, 0.5);
1183 			ge_cairo_set_color  (cr, &light);
1184 			cairo_stroke        (cr);
1185 		}
1186 	}
1187 
1188 	/* Draw shadow */
1189 	cairo_move_to       (cr, 0, height-0.5);
1190 	cairo_line_to       (cr, width-1, height-0.5);
1191 	ge_cairo_set_color  (cr, dark);
1192 	cairo_stroke        (cr);
1193 }
1194 
1195 static void
clearlooks_glossy_draw_menuitem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1196 clearlooks_glossy_draw_menuitem (cairo_t                   *cr,
1197                                  const ClearlooksColors    *colors,
1198                                  const WidgetParameters    *params,
1199                                  int x, int y, int width, int height)
1200 {
1201 	const CairoColor *fill = &colors->spot[1];
1202 	const CairoColor *border = &colors->spot[2];
1203 	CairoColor shade1, shade2, shade3;
1204 	cairo_pattern_t *pattern;
1205 
1206 	ge_shade_color (fill, 1.16, &shade1);
1207 	ge_shade_color (fill, 1.08, &shade2);
1208 	ge_shade_color (fill, 1.08, &shade3);
1209 	cairo_set_line_width (cr, 1.0);
1210 
1211 	ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners);
1212 
1213 	pattern = cairo_pattern_create_linear (x, y, x, y + height);
1214 	cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
1215 	cairo_pattern_add_color_stop_rgb (pattern, 0.5,	shade2.r, shade2.g, shade2.b);
1216 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r,  fill->g,  fill->b);
1217 	cairo_pattern_add_color_stop_rgb (pattern, 1,	shade3.r, shade3.g, shade3.b);
1218 
1219 	cairo_set_source (cr, pattern);
1220 	cairo_fill_preserve  (cr);
1221 	cairo_pattern_destroy (pattern);
1222 
1223 	ge_cairo_set_color (cr, border);
1224 	cairo_stroke (cr);
1225 }
1226 
1227 static void
clearlooks_glossy_draw_menubaritem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1228 clearlooks_glossy_draw_menubaritem (cairo_t                   *cr,
1229                                     const ClearlooksColors    *colors,
1230                                     const WidgetParameters    *params,
1231                                     int x, int y, int width, int height)
1232 {
1233 	const CairoColor *fill = &colors->spot[1];
1234 	const CairoColor *border = &colors->spot[2];
1235 	CairoColor shade1, shade2, shade3;
1236 	cairo_pattern_t *pattern;
1237 
1238 	ge_shade_color (fill, 1.16, &shade1);
1239 	ge_shade_color (fill, 1.08, &shade2);
1240 	ge_shade_color (fill, 1.08, &shade3);
1241 	cairo_set_line_width (cr, 1.0);
1242 
1243 	ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners);
1244 
1245 	pattern = cairo_pattern_create_linear (x, y, x, y + height);
1246 	cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
1247 	cairo_pattern_add_color_stop_rgb (pattern, 0.5,	shade2.r, shade2.g, shade2.b);
1248 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r,  fill->g,  fill->b);
1249 	cairo_pattern_add_color_stop_rgb (pattern, 1,	shade3.r, shade3.g, shade3.b);
1250 
1251 	cairo_set_source (cr, pattern);
1252 	cairo_fill_preserve  (cr);
1253 	cairo_pattern_destroy (pattern);
1254 
1255 	ge_cairo_set_color (cr, border);
1256 	cairo_stroke (cr);
1257 }
1258 
1259 static void
clearlooks_glossy_draw_selected_cell(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1260 clearlooks_glossy_draw_selected_cell (cairo_t                  *cr,
1261 	                              const ClearlooksColors   *colors,
1262 	                              const WidgetParameters   *params,
1263 	                              int x, int y, int width, int height)
1264 {
1265 	CairoColor color;
1266 
1267 	if (params->focus)
1268 		color = colors->base[params->state_type];
1269 	else
1270 		color = colors->base[GTK_STATE_ACTIVE];
1271 
1272 	clearlooks_draw_glossy_gradient (cr, x, y, width, height, &color, params->disabled, 0.0, CR_CORNER_NONE);
1273 }
1274 
1275 
1276 static void
clearlooks_glossy_draw_radiobutton(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)1277 clearlooks_glossy_draw_radiobutton (cairo_t *cr,
1278                              const ClearlooksColors  *colors,
1279                              const WidgetParameters  *widget,
1280                              const CheckboxParameters *checkbox,
1281                              int x, int y, int width, int height)
1282 {
1283 	const CairoColor *border;
1284 	const CairoColor *dot;
1285 	CairoColor shadow;
1286 	CairoColor highlight;
1287 	cairo_pattern_t *pt;
1288 	gboolean inconsistent;
1289 	gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
1290 	gdouble w, h, cx, cy, radius;
1291 
1292 	w = (gdouble) width;
1293 	h = (gdouble) height;
1294 	cx = width / 2.0;
1295 	cy = height / 2.0;
1296 	radius = MIN (width, height) / 2.0;
1297 
1298 	inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
1299 	draw_bullet |= inconsistent;
1300 
1301 	if (widget->disabled)
1302 	{
1303 		border = &colors->shade[5];
1304 		dot    = &colors->shade[6];
1305 	}
1306 	else
1307 	{
1308 		if (widget->prelight)
1309 			border = &colors->spot[2];
1310 		else
1311 			border = &colors->shade[6];
1312 		dot    = &colors->text[0];
1313 	}
1314 
1315 	ge_shade_color (&widget->parentbg, 0.9, &shadow);
1316 	ge_shade_color (&widget->parentbg, 1.1, &highlight);
1317 
1318 	pt = cairo_pattern_create_linear (0, 0, radius * 2.0, radius * 2.0);
1319 	cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g);
1320 	cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5);
1321 	cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5);
1322 	cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b);
1323 
1324 	cairo_translate (cr, x, y);
1325 
1326 	cairo_set_line_width (cr, MAX (1.0, floor (radius/3)));
1327 	cairo_arc (cr, ceil (cx), ceil (cy), floor (radius - 0.1), 0, G_PI*2);
1328 	cairo_set_source (cr, pt);
1329 	cairo_stroke (cr);
1330 	cairo_pattern_destroy (pt);
1331 
1332 	cairo_set_line_width (cr, MAX (1.0, floor (radius/6)));
1333 
1334 	cairo_arc (cr, ceil (cx), ceil (cy), MAX (1.0, ceil (radius) - 1.5), 0, G_PI*2);
1335 
1336 	if (!widget->disabled)
1337 	{
1338 		if (widget->prelight)
1339 			clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5);
1340 		else
1341 			ge_cairo_set_color (cr, &colors->base[0]);
1342 		cairo_fill_preserve (cr);
1343 	}
1344 
1345 	ge_cairo_set_color (cr, border);
1346 	cairo_stroke (cr);
1347 
1348 	if (draw_bullet)
1349 	{
1350 		if (inconsistent)
1351 		{
1352 			cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
1353 			cairo_set_line_width (cr, ceil (radius * 2 / 3));
1354 
1355 			cairo_move_to (cr, ceil (cx - radius/3.0), ceil (cy));
1356 			cairo_line_to (cr, ceil (cx + radius/3.0), ceil (cy));
1357 
1358 			ge_cairo_set_color (cr, dot);
1359 			cairo_stroke (cr);
1360 		}
1361 		else
1362 		{
1363 			cairo_arc (cr, ceil (cx), ceil (cy), floor (radius/2.0), 0, G_PI*2);
1364 			ge_cairo_set_color (cr, dot);
1365 			cairo_fill (cr);
1366 
1367 			cairo_arc (cr, floor (cx - radius/10.0), floor (cy - radius/10.0), floor (radius/6.0), 0, G_PI*2);
1368 			cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
1369 			cairo_fill (cr);
1370 		}
1371 	}
1372 }
1373 
1374 static void
clearlooks_glossy_draw_checkbox(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)1375 clearlooks_glossy_draw_checkbox (cairo_t *cr,
1376                           const ClearlooksColors  *colors,
1377                           const WidgetParameters  *widget,
1378                           const CheckboxParameters *checkbox,
1379                           int x, int y, int width, int height)
1380 {
1381 	const CairoColor *border;
1382 	const CairoColor *dot;
1383 	gboolean inconsistent = FALSE;
1384 	gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
1385 
1386 	inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
1387 	draw_bullet |= inconsistent;
1388 
1389 	if (widget->disabled)
1390 	{
1391 		border = &colors->shade[5];
1392 		dot    = &colors->shade[6];
1393 	}
1394 	else
1395 	{
1396 		if (widget->prelight)
1397 			border = &colors->spot[2];
1398 		else
1399 			border = &colors->shade[6];
1400 		dot    = &colors->text[GTK_STATE_NORMAL];
1401 	}
1402 
1403 	cairo_translate (cr, x, y);
1404 	cairo_set_line_width (cr, 1);
1405 
1406 	if (widget->xthickness > 2 && widget->ythickness > 2)
1407 	{
1408 		widget->style_functions->draw_inset (cr, &widget->parentbg, 0, 0,
1409                                            width, height, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
1410 
1411 		/* Draw the rectangle for the checkbox itself */
1412 		ge_cairo_rounded_rectangle (cr, 1.5, 1.5,
1413                                   width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
1414 	}
1415 	else
1416 	{
1417 		/* Draw the rectangle for the checkbox itself */
1418 		ge_cairo_rounded_rectangle (cr, 0.5, 0.5,
1419                                   width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
1420 	}
1421 
1422 	if (!widget->disabled)
1423 	{
1424 		if (widget->prelight)
1425 			clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5);
1426 		else
1427 			ge_cairo_set_color (cr, &colors->base[0]);
1428 		cairo_fill_preserve (cr);
1429 	}
1430 
1431 	ge_cairo_set_color (cr, border);
1432 	cairo_stroke (cr);
1433 
1434 	if (draw_bullet)
1435 	{
1436 		if (inconsistent) /* Inconsistent */
1437 		{
1438 			cairo_set_line_width (cr, 2.0);
1439 			cairo_move_to (cr, 3, height*0.5);
1440 			cairo_line_to (cr, width-3, height*0.5);
1441 		}
1442 		else
1443 		{
1444 			cairo_set_line_width (cr, 1.7);
1445 			cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5));
1446 			cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7));
1447 
1448 			cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7),
1449 			                    0.5 + (width*0.5), (height*0.4),
1450 			                    0.5 + (width*0.70), (height*0.25));
1451 
1452 		}
1453 
1454 		ge_cairo_set_color (cr, dot);
1455 		cairo_stroke (cr);
1456 	}
1457 }
1458 
1459 static void
clearlooks_glossy_draw_icon_view_item(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1460 clearlooks_glossy_draw_icon_view_item (cairo_t                *cr,
1461 	                                   const ClearlooksColors *colors,
1462 	                                   const WidgetParameters *params,
1463 	                                   int x, int y, int width, int height)
1464 {
1465 	CairoColor color;
1466 	gfloat radius;
1467 
1468 	if (params->focus)
1469 		color = colors->base[params->state_type];
1470 	else
1471 		color = colors->base[GTK_STATE_ACTIVE];
1472 
1473 	radius = MIN (width / 2, params->radius);
1474 	radius = MIN (height / 2, radius);
1475 
1476 	clearlooks_draw_glossy_gradient (cr, x, y, width, height, &color, params->disabled, params->radius, CR_CORNER_ALL);
1477 }
1478 
1479 void
clearlooks_register_style_glossy(ClearlooksStyleFunctions * functions,ClearlooksStyleConstants * constants)1480 clearlooks_register_style_glossy (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants)
1481 {
1482 	functions->draw_inset              = clearlooks_glossy_draw_inset;
1483 	functions->draw_button             = clearlooks_glossy_draw_button;
1484 	functions->draw_progressbar_trough = clearlooks_glossy_draw_progressbar_trough;
1485 	functions->draw_progressbar_fill   = clearlooks_glossy_draw_progressbar_fill;
1486 	functions->draw_scale_trough       = clearlooks_glossy_draw_scale_trough;
1487 	functions->draw_tab                = clearlooks_glossy_draw_tab;
1488 	functions->draw_slider             = clearlooks_glossy_draw_slider;
1489 	functions->draw_slider_button      = clearlooks_glossy_draw_slider_button;
1490 	functions->draw_scrollbar_stepper  = clearlooks_glossy_draw_scrollbar_stepper;
1491 	functions->draw_scrollbar_slider   = clearlooks_glossy_draw_scrollbar_slider;
1492 	functions->draw_list_view_header   = clearlooks_glossy_draw_list_view_header;
1493 	functions->draw_toolbar            = clearlooks_glossy_draw_toolbar;
1494 	functions->draw_menuitem           = clearlooks_glossy_draw_menuitem;
1495 	functions->draw_menubaritem        = clearlooks_glossy_draw_menubaritem;
1496 	functions->draw_selected_cell      = clearlooks_glossy_draw_selected_cell;
1497 	functions->draw_checkbox           = clearlooks_glossy_draw_checkbox;
1498 	functions->draw_radiobutton        = clearlooks_glossy_draw_radiobutton;
1499 	functions->draw_icon_view_item     = clearlooks_glossy_draw_icon_view_item;
1500 }
1501