1 /* Clearlooks - a cairo based GTK+ engine
2  * Copyright (C) 2006 Richard Stellingwerff <remenic@gmail.com>
3  * Copyright (C) 2006 Daniel Borgman <daniel.borgmann@gmail.com>
4  * Copyright (C) 2007 Benjamin Berg <benjamin@sipsolutions.net>
5  * Copyright (C) 2007-2008 Andrea Cimitan <andrea.cimitan@gmail.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  * Project contact: <gnome-themes-list@gnome.org>
22  *
23  */
24 
25 
26 #include "clearlooks_draw.h"
27 #include "clearlooks_style.h"
28 #include "clearlooks_types.h"
29 
30 #include "support.h"
31 #include <ge-support.h>
32 #include <math.h>
33 
34 #include <cairo.h>
35 
36 /* Normal shadings */
37 #define SHADE_TOP 1.055
38 #define SHADE_CENTER_TOP 1.01
39 #define SHADE_CENTER_BOTTOM 0.98
40 #define SHADE_BOTTOM 0.90
41 
42 typedef void (*menubar_draw_proto) (cairo_t *cr,
43                                     const ClearlooksColors *colors,
44                                     const WidgetParameters *params,
45                                     const MenuBarParameters *menubar,
46                                     int x, int y, int width, int height);
47 
48 static void
clearlooks_draw_inset(cairo_t * cr,const CairoColor * bg_color,double x,double y,double width,double height,double radius,uint8 corners)49 clearlooks_draw_inset (cairo_t          *cr,
50                        const CairoColor *bg_color,
51                        double x, double y, double width, double height,
52                        double radius, uint8 corners)
53 {
54 	CairoColor shadow;
55 	CairoColor highlight;
56 	double line_width;
57 	double min = MIN (width, height);
58 
59 	line_width = cairo_get_line_width (cr);
60 
61 	/* not really sure of shading ratios... we will think */
62 	ge_shade_color (bg_color, 0.94, &shadow);
63 	ge_shade_color (bg_color, 1.06, &highlight);
64 
65 	/* highlight */
66 	cairo_save (cr);
67 
68 	cairo_move_to (cr, x, y + height);
69 	cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0);
70 	cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0);
71 	cairo_line_to (cr, x + width, y);
72 	cairo_line_to (cr, x, y);
73 	cairo_close_path (cr);
74 
75 	cairo_clip (cr);
76 
77 	ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0,
78 	                            width - line_width, height - line_width,
79 	                            radius, corners);
80 
81 	ge_cairo_set_color (cr, &shadow);
82 	cairo_stroke (cr);
83 
84 	cairo_restore (cr);
85 
86 	/* shadow */
87 	cairo_save (cr);
88 
89 	cairo_move_to (cr, x, y + height);
90 	cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0);
91 	cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0);
92 	cairo_line_to (cr, x + width, y);
93 	cairo_line_to (cr, x + width, y + height);
94 	cairo_close_path (cr);
95 
96 	cairo_clip (cr);
97 
98 	ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0,
99 	                            width - line_width, height - line_width,
100 	                            radius, corners);
101 
102 	ge_cairo_set_color (cr, &highlight);
103 	cairo_stroke (cr);
104 
105 	cairo_restore (cr);
106 }
107 
108 static void
clearlooks_draw_shadow(cairo_t * cr,const ClearlooksColors * colors,gfloat radius,int width,int height)109 clearlooks_draw_shadow (cairo_t *cr, const ClearlooksColors *colors, gfloat radius, int width, int height)
110 {
111 	CairoColor shadow;
112 	cairo_save (cr);
113 
114 	ge_shade_color (&colors->shade[6], 0.92, &shadow);
115 
116 	cairo_set_line_width (cr, 1.0);
117 	cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
118 
119 	cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.1);
120 
121 	cairo_move_to (cr, width - 0.5, radius);
122 	ge_cairo_rounded_corner (cr, width - 0.5, height - 0.5, radius, CR_CORNER_BOTTOMRIGHT);
123 	cairo_line_to (cr, radius, height - 0.5);
124 
125 	cairo_stroke (cr);
126 	cairo_restore (cr);
127 }
128 
129 /* This is copied at least in clearlooks_draw_gummy.c.
130  * KEEP IN SYNC IF POSSIBLE! */
131 static void
clearlooks_draw_top_left_highlight(cairo_t * cr,const CairoColor * color,const WidgetParameters * params,int x,int y,int width,int height,gdouble radius,CairoCorners corners)132 clearlooks_draw_top_left_highlight (cairo_t *cr, const CairoColor *color,
133                                     const WidgetParameters *params,
134                                     int x, int y, int width, int height,
135                                     gdouble radius, CairoCorners corners)
136 {
137 	CairoColor hilight;
138 
139 	double line_width = cairo_get_line_width (cr);
140 	double offset = line_width / 2.0;
141 	double light_top, light_bottom, light_left, light_right;
142 
143 	cairo_save (cr);
144 
145 	cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
146 
147 	light_top = y + offset;
148 	light_bottom = y + height;
149 	light_left = x + offset;
150 	light_right = x + width;
151 
152 	if (corners & CR_CORNER_BOTTOMLEFT)
153 		light_bottom -= radius;
154 	if (corners & CR_CORNER_TOPRIGHT)
155 		light_right -= radius;
156 
157 	ge_shade_color (color, params->style_constants->topleft_highlight_shade, &hilight);
158 	cairo_move_to         (cr, light_left, light_bottom);
159 
160 	ge_cairo_rounded_corner (cr, light_left, light_top, radius, corners & CR_CORNER_TOPLEFT);
161 
162 	cairo_line_to         (cr, light_right, light_top);
163 	cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, params->style_constants->topleft_highlight_alpha);
164 	cairo_stroke          (cr);
165 
166 	cairo_restore (cr);
167 }
168 
169 #ifdef DEVELOPMENT
170 #warning seems to be very slow in scrollbar_stepper
171 #endif
172 
173 static void
clearlooks_draw_highlight_and_shade(cairo_t * cr,const ClearlooksColors * colors,const ShadowParameters * params,int width,int height,gdouble radius)174 clearlooks_draw_highlight_and_shade (cairo_t *cr, const ClearlooksColors *colors,
175                                      const ShadowParameters *params,
176                                      int width, int height, gdouble radius)
177 {
178 	CairoColor hilight;
179 	CairoColor shadow;
180 	uint8 corners = params->corners;
181 	double x = 1.0;
182 	double y = 1.0;
183 
184 	ge_shade_color (&colors->bg[0], 1.06, &hilight);
185 	ge_shade_color (&colors->bg[0], 0.94, &shadow);
186 
187 	width  -= 2;
188 	height -= 2;
189 
190 	cairo_save (cr);
191 
192 	/* Top/Left highlight */
193 	if (corners & CR_CORNER_BOTTOMLEFT)
194 		cairo_move_to (cr, x + 0.5, y+height-radius);
195 	else
196 		cairo_move_to (cr, x + 0.5, y+height);
197 
198 	ge_cairo_rounded_corner (cr, x + 0.5, y + 0.5, radius, corners & CR_CORNER_TOPLEFT);
199 
200 	if (corners & CR_CORNER_TOPRIGHT)
201 		cairo_line_to (cr, x+width-radius, y + 0.5);
202 	else
203 		cairo_line_to (cr, x+width, y + 0.5);
204 
205 	if (params->shadow & CL_SHADOW_OUT)
206 		ge_cairo_set_color (cr, &hilight);
207 	else
208 		ge_cairo_set_color (cr, &shadow);
209 
210 	cairo_stroke (cr);
211 
212 	/* Bottom/Right highlight -- this includes the corners */
213 	cairo_arc (cr, x + width - 0.5 - radius, y + radius, radius, G_PI * (3/2.0+1/4.0), G_PI * 2);
214 	ge_cairo_rounded_corner (cr, x+width - 0.5, y+height - 0.5, radius, corners & CR_CORNER_BOTTOMRIGHT);
215 	cairo_arc (cr, x + radius, y + height - 0.5 - radius, radius, G_PI * 1/2, G_PI * 3/4);
216 
217 	if (params->shadow & CL_SHADOW_OUT)
218 		ge_cairo_set_color (cr, &shadow);
219 	else
220 		ge_cairo_set_color (cr, &hilight);
221 
222 	cairo_stroke (cr);
223 
224 	cairo_restore (cr);
225 }
226 
227 static void
clearlooks_set_border_gradient(cairo_t * cr,const CairoColor * color,double hilight,int width,int height)228 clearlooks_set_border_gradient (cairo_t *cr, const CairoColor *color, double hilight, int width, int height)
229 {
230 	cairo_pattern_t *pattern;
231 
232 	CairoColor bottom_shade;
233 	ge_shade_color (color, hilight, &bottom_shade);
234 
235 	pattern	= cairo_pattern_create_linear (0, 0, width, height);
236 	cairo_pattern_add_color_stop_rgb (pattern, 0, color->r, color->g, color->b);
237 	cairo_pattern_add_color_stop_rgb (pattern, 1, bottom_shade.r, bottom_shade.g, bottom_shade.b);
238 
239 	cairo_set_source (cr, pattern);
240 	cairo_pattern_destroy (pattern);
241 }
242 
243 static void
clearlooks_draw_gripdots(cairo_t * cr,const ClearlooksColors * colors,int x,int y,int width,int height,int xr,int yr,float contrast)244 clearlooks_draw_gripdots (cairo_t *cr, const ClearlooksColors *colors, int x, int y,
245                           int width, int height, int xr, int yr,
246                           float contrast)
247 {
248 	const CairoColor *dark = &colors->shade[4];
249 	CairoColor hilight;
250 	int i, j;
251 	int xoff, yoff;
252 	int x_start, y_start;
253 
254 	ge_shade_color (dark, 1.5, &hilight);
255 
256 	/* The "- 1" is because there is no space in front of the first dot. */
257 	x_start = x + width / 2 - ((xr * 3 - 1) / 2);
258 	y_start = y + height / 2 - ((yr * 3 - 1) / 2);
259 
260 	for ( i = 0; i < xr; i++ )
261 	{
262 		for ( j = 0; j < yr; j++ )
263 		{
264 			xoff = 3 * i;
265 			yoff = 3 * j;
266 
267 			cairo_rectangle (cr, x_start + xoff, y_start + yoff, 2, 2);
268 			cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.8+contrast);
269 			cairo_fill (cr);
270 			cairo_rectangle (cr, x_start + xoff, y_start + yoff, 1, 1);
271 			cairo_set_source_rgba (cr, dark->r, dark->g, dark->b, 0.8+contrast);
272 			cairo_fill (cr);
273 		}
274 	}
275 }
276 
277 static void
clearlooks_draw_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)278 clearlooks_draw_button (cairo_t *cr,
279                         const ClearlooksColors *colors,
280                         const WidgetParameters *params,
281                         int x, int y, int width, int height)
282 {
283 	double xoffset = 0, yoffset = 0;
284 	double radius = params->radius;
285 	const CairoColor *fill = &colors->bg[params->state_type];
286 	CairoColor border_normal = colors->shade[6];
287 	CairoColor border_disabled = colors->shade[4];
288 
289 	CairoColor shadow;
290 	ge_shade_color (&border_normal, 1.04, &border_normal);
291 	ge_shade_color (&border_normal, 0.94, &shadow);
292 	ge_shade_color (&border_disabled, 1.08, &border_disabled);
293 
294 	cairo_save (cr);
295 
296 	cairo_translate (cr, x, y);
297 	cairo_set_line_width (cr, 1.0);
298 
299 	if (params->xthickness >= 3 && params->ythickness >= 3)
300 	{
301 		xoffset = 1;
302 		yoffset = 1;
303 	}
304 
305 	radius = MIN (radius, MIN ((width - 2.0 - xoffset * 2.0) / 2.0, (height - 2.0 - yoffset * 2) / 2.0));
306 
307 	if (params->xthickness >= 3 && params->ythickness >= 3)
308 	{
309 		params->style_functions->draw_inset (cr, &params->parentbg, 0, 0, width, height, radius+1, params->corners);
310 	}
311 
312 	ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1,
313 	                                     width-(xoffset*2)-2,
314 	                                     height-(yoffset*2)-2,
315 	                                     radius, params->corners);
316 
317 	if (!params->active)
318 	{
319 		cairo_pattern_t *pattern;
320 		CairoColor top_shade, topmiddle_shade, bottom_shade, middle_shade;
321 
322 		ge_shade_color (fill, SHADE_TOP, &top_shade);
323 		ge_shade_color (fill, SHADE_CENTER_TOP, &topmiddle_shade);
324 		ge_shade_color (fill, SHADE_CENTER_BOTTOM, &middle_shade);
325 		ge_shade_color (fill, SHADE_BOTTOM, &bottom_shade);
326 
327 		cairo_save (cr);
328 		cairo_clip_preserve (cr);
329 
330 		pattern	= cairo_pattern_create_linear (0, 0, 0, height);
331 		cairo_pattern_add_color_stop_rgb (pattern, 0.0, top_shade.r, top_shade.g, top_shade.b);
332 		cairo_pattern_add_color_stop_rgb (pattern, 0.3, topmiddle_shade.r, topmiddle_shade.g, topmiddle_shade.b);
333 		cairo_pattern_add_color_stop_rgb (pattern, 0.7, middle_shade.r, middle_shade.g, middle_shade.b);
334 		cairo_pattern_add_color_stop_rgb (pattern, 1.0, bottom_shade.r, bottom_shade.g, bottom_shade.b);
335 		cairo_set_source (cr, pattern);
336 		cairo_fill (cr);
337 		cairo_pattern_destroy (pattern);
338 
339 		cairo_move_to (cr, width-(xoffset*2)-0.5, 0);
340 		cairo_line_to (cr, width-(xoffset*2)-0.5, height);
341 		ge_cairo_set_color (cr, &bottom_shade);
342 		cairo_stroke (cr);
343 
344 		/* Draw topleft shadow */
345 		params->style_functions->draw_top_left_highlight (cr, fill, params, xoffset + 1, yoffset + 1,
346 		                                                  width - 2*(xoffset + 1), height - 2*(yoffset + 1),
347 		                                                  MAX(radius-1, 0), params->corners);
348 
349 		cairo_restore (cr);
350 	}
351 	else
352 	{
353 		cairo_pattern_t *pattern;
354 
355 		ge_cairo_set_color (cr, fill);
356 		cairo_fill_preserve (cr);
357 
358 		pattern	= cairo_pattern_create_linear (0, 0, 0, height);
359 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.0);
360 		cairo_pattern_add_color_stop_rgba (pattern, 0.4, shadow.r, shadow.g, shadow.b, 0.0);
361 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.2);
362 		cairo_set_source (cr, pattern);
363 		cairo_fill_preserve (cr);
364 		cairo_pattern_destroy (pattern);
365 
366 		pattern	= cairo_pattern_create_linear (0, yoffset+1, 0, 3+yoffset);
367 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.32);
368 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
369 		cairo_set_source (cr, pattern);
370 		cairo_fill_preserve (cr);
371 		cairo_pattern_destroy (pattern);
372 
373 		pattern	= cairo_pattern_create_linear (xoffset+1, 0, 3+xoffset, 0);
374 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.32);
375 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
376 		cairo_set_source (cr, pattern);
377 		cairo_fill (cr);
378 		cairo_pattern_destroy (pattern);
379 	}
380 
381 	/* Drawing the border */
382 	if (!params->active && params->is_default)
383 	{
384 		ge_shade_color (&border_normal, 0.74, &border_normal);
385 	}
386 
387 	ge_cairo_inner_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), radius, params->corners);
388 
389 	if (params->disabled)
390 	{
391 		ge_cairo_set_color (cr, &border_disabled);
392 	}
393 	else
394 	{
395 		if (!params->active)
396 			clearlooks_set_border_gradient (cr, &border_normal,
397 			                                params->is_default ? 1.1 : 1.3, 0, height);
398 		else
399 		{
400 			ge_shade_color (&border_normal, 1.08, &border_normal);
401 			ge_cairo_set_color (cr, &border_normal);
402 		}
403 	}
404 
405 	cairo_stroke (cr);
406 
407 	cairo_restore (cr);
408 }
409 
410 static void
clearlooks_draw_entry(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const FocusParameters * focus,int x,int y,int width,int height)411 clearlooks_draw_entry (cairo_t *cr,
412                        const ClearlooksColors *colors,
413                        const WidgetParameters *params,
414                        const FocusParameters  *focus,
415                        int x, int y, int width, int height)
416 {
417 	const CairoColor *base = &colors->base[params->state_type];
418 	CairoColor border = colors->shade[params->disabled ? 3 : 6];
419 	double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0));
420 	int xoffset, yoffset;
421 
422 	if (params->focus)
423 		border = focus->color;
424 
425 	cairo_save (cr);
426 
427 	cairo_translate (cr, x, y);
428 	cairo_set_line_width (cr, 1.0);
429 
430 	if (params->xthickness >= 3 && params->ythickness >= 3)
431 	{
432 		params->style_functions->draw_inset (cr, &params->parentbg, 0, 0, width, height, radius+1, params->corners);
433 		xoffset = 1;
434 		yoffset = 1;
435 	}
436 	else
437 	{
438 		xoffset = 0;
439 		yoffset = 0;
440 	}
441 
442 	/* Now fill the area we want to be base[NORMAL]. */
443 	ge_cairo_rounded_rectangle (cr, xoffset + 1, yoffset + 1, width - (xoffset + 1)*2,
444 	                            height - (yoffset + 1) * 2, MAX(0, radius-1),
445 	                            params->corners);
446 	ge_cairo_set_color (cr, base);
447 	cairo_fill (cr);
448 
449 	/* Draw the inner shadow */
450 	if (params->focus)
451 	{
452 		CairoColor focus_shadow;
453 		ge_shade_color (&border, 1.61, &focus_shadow);
454 
455 		clearlooks_set_mixed_color (cr, base, &focus_shadow, 0.5);
456 		ge_cairo_inner_rounded_rectangle (cr, xoffset + 1, yoffset + 1,
457 		                                  width - (xoffset + 1)*2, height - (yoffset + 1)*2,
458 		                                  MAX(0, radius-1), params->corners);
459 		cairo_stroke (cr);
460 	}
461 	else
462 	{
463 		CairoColor shadow;
464 		ge_shade_color (&border, 0.925, &shadow);
465 
466 		cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, params->disabled ? 0.05 : 0.1);
467 
468 		cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
469 		cairo_move_to (cr, 2.5, height-radius);
470 		cairo_arc (cr, xoffset + 1.5 + MAX(0, radius-1), yoffset + 1.5 + MAX(0, radius-1),
471 		           MAX(0, radius-1), G_PI, 270*(G_PI/180));
472 		cairo_line_to (cr, width-radius, 2.5);
473 		cairo_stroke (cr);
474 	}
475 
476 	ge_cairo_inner_rounded_rectangle (cr, xoffset, yoffset,
477 	                                  width-2*xoffset, height-2*yoffset,
478 	                                  radius, params->corners);
479 	if (params->focus || params->disabled)
480 		ge_cairo_set_color (cr, &border);
481 	else
482 		clearlooks_set_border_gradient (cr, &border, 1.32, 0, height);
483 	cairo_stroke (cr);
484 
485 	cairo_restore (cr);
486 }
487 
488 static void
clearlooks_draw_entry_progress(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const EntryProgressParameters * progress,int x,int y,int width,int height)489 clearlooks_draw_entry_progress (cairo_t *cr,
490                                 const ClearlooksColors *colors,
491                                 const WidgetParameters *params,
492                                 const EntryProgressParameters *progress,
493                                 int x, int y, int width, int height)
494 {
495 	CairoColor border;
496 	CairoColor fill;
497 	gint entry_width, entry_height;
498 	double entry_radius;
499 	double radius;
500 
501 	cairo_save (cr);
502 
503 	fill = colors->bg[params->state_type];
504 	ge_shade_color (&fill, 0.9, &border);
505 
506 	if (progress->max_size_known)
507 	{
508 		entry_width = progress->max_size.width + progress->border.left + progress->border.right;
509 		entry_height = progress->max_size.height + progress->border.top + progress->border.bottom;
510 		entry_radius = MIN (params->radius, MIN ((entry_width - 4.0) / 2.0, (entry_height - 4.0) / 2.0));
511 	}
512 	else
513 	{
514 		entry_radius = params->radius;
515 	}
516 
517 	radius = MAX (0, entry_radius + 1.0 - MAX (MAX (progress->border.left, progress->border.right),
518 	                                           MAX (progress->border.top, progress->border.bottom)));
519 
520 	if (progress->max_size_known)
521 	{
522 		/* Clip to the max size, and then draw a (larger) rectangle ... */
523 		ge_cairo_rounded_rectangle (cr, progress->max_size.x,
524 		                                progress->max_size.y,
525 		                                progress->max_size.width,
526 		                                progress->max_size.height,
527 		                                radius,
528 		                                CR_CORNER_ALL);
529 		cairo_clip (cr);
530 
531 		/* We just draw wider by one pixel ... */
532 		ge_cairo_set_color (cr, &fill);
533 		cairo_rectangle (cr, x, y + 1, width, height - 2);
534 		cairo_fill (cr);
535 
536 		cairo_set_line_width (cr, 1.0);
537 		ge_cairo_set_color (cr, &border);
538 		ge_cairo_inner_rectangle (cr, x - 1, y, width + 2, height);
539 		cairo_stroke (cr);
540 	}
541 	else
542 	{
543 		ge_cairo_rounded_rectangle (cr, x, y, width + 10, height + 10, radius, CR_CORNER_ALL);
544 		cairo_clip (cr);
545 		ge_cairo_rounded_rectangle (cr, x - 10, y - 10, width + 10, height + 10, radius, CR_CORNER_ALL);
546 		cairo_clip (cr);
547 
548 		ge_cairo_set_color (cr, &fill);
549 		ge_cairo_rounded_rectangle (cr, x + 1, y + 1, width - 2, height - 2, radius, CR_CORNER_ALL);
550 		cairo_fill (cr);
551 
552 		cairo_set_line_width (cr, 1.0);
553 		ge_cairo_set_color (cr, &border);
554 		ge_cairo_rounded_rectangle (cr, x + 0.5, y + 0.5, width - 1.0, height - 1.0, radius, CR_CORNER_ALL);
555 		cairo_stroke (cr);
556 	}
557 
558 	cairo_restore (cr);
559 }
560 
561 static void
clearlooks_draw_spinbutton(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)562 clearlooks_draw_spinbutton (cairo_t *cr,
563                             const ClearlooksColors *colors,
564                             const WidgetParameters *params,
565                             int x, int y, int width, int height)
566 {
567 	const CairoColor *border = &colors->shade[!params->disabled ? 5 : 3];
568 	CairoColor hilight;
569 
570 	params->style_functions->draw_button (cr, colors, params, x, y, width, height);
571 
572 	ge_shade_color (&colors->bg[0], params->style_constants->topleft_highlight_shade, &hilight);
573 	hilight.a = params->style_constants->topleft_highlight_alpha;
574 
575 	cairo_translate (cr, x, y);
576 
577 	cairo_move_to (cr, params->xthickness + 0.5,       (height/2) + 0.5);
578 	cairo_line_to (cr, width-params->xthickness - 0.5, (height/2) + 0.5);
579 	ge_cairo_set_color (cr, border);
580 	cairo_stroke (cr);
581 
582 	cairo_move_to (cr, params->xthickness + 0.5,       (height/2)+1.5);
583 	cairo_line_to (cr, width-params->xthickness - 0.5, (height/2)+1.5);
584 	ge_cairo_set_color (cr, &hilight);
585 	cairo_stroke (cr);
586 }
587 
588 static void
clearlooks_draw_spinbutton_down(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)589 clearlooks_draw_spinbutton_down (cairo_t *cr,
590                                  const ClearlooksColors *colors,
591                                  const WidgetParameters *params,
592                                  int x, int y, int width, int height)
593 {
594 	cairo_pattern_t *pattern;
595 	double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0));
596 	CairoColor shadow;
597 	ge_shade_color (&colors->bg[0], 0.8, &shadow);
598 
599 	cairo_translate (cr, x+1, y+1);
600 
601 	ge_cairo_rounded_rectangle (cr, 1, 1, width-4, height-4, radius, params->corners);
602 
603 	ge_cairo_set_color (cr, &colors->bg[params->state_type]);
604 
605 	cairo_fill_preserve (cr);
606 
607 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
608 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, shadow.r, shadow.g, shadow.b);
609 	cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
610 
611 	cairo_set_source (cr, pattern);
612 	cairo_fill (cr);
613 
614 	cairo_pattern_destroy (pattern);
615 }
616 
617 static void
clearlooks_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)618 clearlooks_scale_draw_gradient (cairo_t *cr,
619                                 const CairoColor *c1,
620                                 const CairoColor *c2,
621                                 const CairoColor *c3,
622                                 int x, int y, int width, int height,
623                                 boolean horizontal)
624 {
625 	cairo_pattern_t *pattern;
626 
627 	pattern = cairo_pattern_create_linear (0.5, 0.5, horizontal ? 0.5 :  width + 1, horizontal ? height + 1: 0.5);
628 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, c1->r, c1->g, c1->b);
629 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, c2->r, c2->g, c2->b);
630 
631 	cairo_rectangle (cr, x, y, width, height);
632 	cairo_set_source (cr, pattern);
633 	cairo_fill (cr);
634 	cairo_pattern_destroy (pattern);
635 
636 	ge_cairo_set_color (cr, c3);
637 	ge_cairo_inner_rectangle (cr, x, y, width, height);
638 	cairo_stroke (cr);
639 }
640 
641 #define TROUGH_SIZE 7
642 static void
clearlooks_draw_scale_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)643 clearlooks_draw_scale_trough (cairo_t *cr,
644                               const ClearlooksColors *colors,
645                               const WidgetParameters *params,
646                               const SliderParameters *slider,
647                               int x, int y, int width, int height)
648 {
649 	int     trough_width, trough_height;
650 	double  translate_x, translate_y;
651 
652 	cairo_save (cr);
653 
654 	if (slider->horizontal)
655 	{
656 		trough_width  = width;
657 		trough_height = TROUGH_SIZE;
658 
659 		translate_x   = x;
660 		translate_y   = y + (height/2) - (TROUGH_SIZE/2);
661 	}
662 	else
663 	{
664 		trough_width  = TROUGH_SIZE;
665 		trough_height = height;
666 
667 		translate_x   = x + (width/2) - (TROUGH_SIZE/2);
668 		translate_y  = y;
669 	}
670 
671 	cairo_set_line_width (cr, 1.0);
672 	cairo_translate (cr, translate_x, translate_y);
673 
674 	if (!slider->fill_level)
675 		params->style_functions->draw_inset (cr, &params->parentbg, 0, 0, trough_width, trough_height, 0, 0);
676 
677 	if (!slider->lower && !slider->fill_level)
678 	{
679 		CairoColor shadow;
680 		ge_shade_color (&colors->shade[2], 0.96, &shadow);
681 
682 		clearlooks_scale_draw_gradient (cr, &shadow, /* top */
683 		                                &colors->shade[2], /* bottom */
684 		                                &colors->shade[4], /* border */
685 		                                1.0, 1.0, trough_width - 2, trough_height - 2,
686 		                                slider->horizontal);
687 	}
688 	else
689 	{
690 		CairoColor border = colors->spot[2];
691 		border.a = 0.64;
692 
693 		clearlooks_scale_draw_gradient (cr, &colors->spot[1], /* top */
694 		                                &colors->spot[0], /* bottom */
695 		                                &border, /* border */
696 		                                1.0, 1.0, trough_width - 2, trough_height - 2,
697 		                                slider->horizontal);
698 	}
699 	cairo_restore (cr);
700 }
701 
702 static void
clearlooks_draw_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)703 clearlooks_draw_slider (cairo_t *cr,
704                         const ClearlooksColors *colors,
705                         const WidgetParameters *params,
706                         int x, int y, int width, int height)
707 {
708 	const CairoColor *spot   = &colors->spot[1];
709 	const CairoColor *fill   = &colors->shade[2];
710 	CairoColor border = colors->shade[params->disabled ? 4 : 6];
711 	double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0));
712 
713 	cairo_pattern_t *pattern;
714 
715 	cairo_set_line_width (cr, 1.0);
716 	cairo_translate      (cr, x, y);
717 
718 	if (params->prelight)
719 		border = colors->spot[2];
720 
721 	/* fill the widget */
722 	ge_cairo_rounded_rectangle (cr, 1.0, 1.0, width-2, height-2, radius, params->corners);
723 
724 	/* Fake light */
725 	if (!params->disabled)
726 	{
727 		const CairoColor *top = &colors->shade[0];
728 		const CairoColor *bot = &colors->shade[2];
729 
730 		pattern	= cairo_pattern_create_linear (0, 0, 0, height);
731 		cairo_pattern_add_color_stop_rgb (pattern, 0.0,  top->r, top->g, top->b);
732 		cairo_pattern_add_color_stop_rgb (pattern, 1.0,  bot->r, bot->g, bot->b);
733 		cairo_set_source (cr, pattern);
734 		cairo_fill (cr);
735 		cairo_pattern_destroy (pattern);
736 	}
737 	else
738 	{
739 		ge_cairo_set_color (cr, fill);
740 		cairo_fill         (cr);
741 	}
742 
743 	/* Set the clip */
744 	cairo_save (cr);
745 	cairo_rectangle (cr, 1.0, 1.0, 6, height-2);
746 	cairo_rectangle (cr, width-7.0, 1.0, 6, height-2);
747 	cairo_clip_preserve (cr);
748 
749 	cairo_new_path (cr);
750 
751 	/* Draw the handles */
752 	ge_cairo_rounded_rectangle (cr, 1.0, 1.0, width-1, height-1, radius, params->corners);
753 	pattern = cairo_pattern_create_linear (1.0, 1.0, 1.0, 1.0+height);
754 
755 	if (params->prelight)
756 	{
757 		CairoColor highlight;
758 		ge_shade_color (spot, 1.3, &highlight);
759 		cairo_pattern_add_color_stop_rgb (pattern, 0.0, highlight.r, highlight.g, highlight.b);
760 		cairo_pattern_add_color_stop_rgb (pattern, 1.0, spot->r, spot->g, spot->b);
761 		cairo_set_source (cr, pattern);
762 	}
763 	else
764 	{
765 		CairoColor hilight;
766 		ge_shade_color (fill, 1.3, &hilight);
767 		cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
768 	}
769 
770 	cairo_fill (cr);
771 	cairo_pattern_destroy (pattern);
772 
773 	cairo_restore (cr);
774 
775 	/* Draw the border */
776 	ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners);
777 
778 	if (params->prelight || params->disabled)
779 		ge_cairo_set_color (cr, &border);
780 	else
781 		clearlooks_set_border_gradient (cr, &border, 1.2, 0, height);
782 	cairo_stroke (cr);
783 
784 	/* Draw handle lines */
785 	if (width > 14)
786 	{
787 		cairo_move_to (cr, 6.5, 1.0);
788 		cairo_line_to (cr, 6.5, height-1);
789 
790 		cairo_move_to (cr, width-6.5, 1.0);
791 		cairo_line_to (cr, width-6.5, height-1);
792 
793 		cairo_set_line_width (cr, 1.0);
794 		border.a = params->disabled ? 0.6 : 0.3;
795 		ge_cairo_set_color (cr, &border);
796 		cairo_stroke (cr);
797 	}
798 }
799 
800 static void
clearlooks_draw_slider_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)801 clearlooks_draw_slider_button (cairo_t *cr,
802                                const ClearlooksColors *colors,
803                                const WidgetParameters *params,
804                                const SliderParameters *slider,
805                                int x, int y, int width, int height)
806 {
807 	double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0));
808 
809 	cairo_save (cr);
810 	cairo_set_line_width (cr, 1.0);
811 
812 	if (!slider->horizontal)
813 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
814 	cairo_translate (cr, x, y);
815 
816 	params->style_functions->draw_shadow (cr, colors, radius, width, height);
817 	params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2);
818 
819 	if (width > 24)
820 		params->style_functions->draw_gripdots (cr, colors, 1, 1, width-2, height-2, 3, 3, 0);
821 
822 	cairo_restore (cr);
823 }
824 
825 static void
clearlooks_draw_progressbar_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)826 clearlooks_draw_progressbar_trough (cairo_t *cr,
827                                     const ClearlooksColors *colors,
828                                     const WidgetParameters *params,
829                                     int x, int y, int width, int height)
830 {
831 	const CairoColor *border = &colors->shade[4];
832 	CairoColor        shadow;
833 	cairo_pattern_t  *pattern;
834 	double            radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0));
835 
836 	cairo_save (cr);
837 
838 	cairo_set_line_width (cr, 1.0);
839 
840 	/* Create trough box */
841 	ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
842 	ge_cairo_set_color (cr, &colors->shade[2]);
843 	cairo_fill (cr);
844 
845 	/* Draw border */
846 	ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1, radius, params->corners);
847 	ge_cairo_set_color (cr, border);
848 	cairo_stroke (cr);
849 
850 	/* clip the corners of the shadows */
851 	ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
852 	cairo_clip (cr);
853 
854 	ge_shade_color (border, 0.925, &shadow);
855 
856 	/* Top shadow */
857 	cairo_rectangle (cr, x+1, y+1, width-2, 4);
858 	pattern = cairo_pattern_create_linear (x, y, x, y+4);
859 	cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.2);
860 	cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0);
861 	cairo_set_source (cr, pattern);
862 	cairo_fill (cr);
863 	cairo_pattern_destroy (pattern);
864 
865 	/* Left shadow */
866 	cairo_rectangle (cr, x+1, y+1, 4, height-2);
867 	pattern = cairo_pattern_create_linear (x, y, x+4, y);
868 	cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.2);
869 	cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0);
870 	cairo_set_source (cr, pattern);
871 	cairo_fill (cr);
872 	cairo_pattern_destroy (pattern);
873 
874 	cairo_restore (cr);
875 }
876 
877 static void
clearlooks_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)878 clearlooks_draw_progressbar_fill (cairo_t *cr,
879                                   const ClearlooksColors *colors,
880                                   const WidgetParameters *params,
881                                   const ProgressBarParameters *progressbar,
882                                   int x, int y, int width, int height,
883                                   gint offset)
884 {
885 	boolean      is_horizontal = progressbar->orientation < 2;
886 	double       tile_pos = 0;
887 	double       stroke_width;
888 	double       radius;
889 	int          x_step;
890 
891 	cairo_pattern_t *pattern;
892 	CairoColor       bg_shade;
893 	CairoColor       border;
894 	CairoColor       shadow;
895 
896 	radius = MAX (0, params->radius - params->xthickness);
897 
898 	cairo_save (cr);
899 
900 	if (!is_horizontal)
901 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
902 
903 	if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP))
904 		ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height);
905 
906 	/* Clamp the radius so that the _height_ fits ...  */
907 	radius = MIN (radius, height / 2.0);
908 
909 	stroke_width = height;
910 	x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */
911 
912 	cairo_translate (cr, x, y);
913 
914 	cairo_save (cr);
915 	/* This is kind of nasty ... Clip twice from each side in case the length
916 	 * of the fill is smaller than twice the radius. */
917 	ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
918 	cairo_clip (cr);
919 	ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
920 	cairo_clip (cr);
921 
922 	/* Draw the background gradient */
923 	ge_shade_color (&colors->spot[1], 1.1, &bg_shade);
924 
925 	/* Just leave this disabled, maybe we could use the same gradient
926 	 * as the buttons in the future, not flat fill */
927 /*	pattern = cairo_pattern_create_linear (0, 0, 0, height);*/
928 /*	cairo_pattern_add_color_stop_rgb (pattern, 0.0, bg_shade.r, bg_shade.g, bg_shade.b);*/
929 /*	cairo_pattern_add_color_stop_rgb (pattern, 0.6, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b);*/
930 /*	cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg_shade.r, bg_shade.g, bg_shade.b);*/
931 /*	cairo_set_source (cr, pattern);*/
932 /*	cairo_paint (cr);*/
933 /*	cairo_pattern_destroy (pattern);*/
934 
935 	ge_cairo_set_color (cr, &bg_shade);
936 	cairo_paint (cr);
937 
938 	/* Draw the Strokes */
939 	while (stroke_width > 0 && tile_pos <= width+x_step)
940 	{
941 		cairo_move_to (cr, stroke_width/2-x_step, 0);
942 		cairo_line_to (cr, stroke_width-x_step,   0);
943 		cairo_line_to (cr, stroke_width/2-x_step, height);
944 		cairo_line_to (cr, -x_step, height);
945 
946 		cairo_translate (cr, stroke_width, 0);
947 		tile_pos += stroke_width;
948 	}
949 
950 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
951 	cairo_pattern_add_color_stop_rgba (pattern, 0.0, colors->spot[2].r, colors->spot[2].g, colors->spot[2].b, 0);
952 	cairo_pattern_add_color_stop_rgba (pattern, 1.0, colors->spot[2].r, colors->spot[2].g, colors->spot[2].b, 0.24);
953 	cairo_set_source (cr, pattern);
954 	cairo_fill (cr);
955 	cairo_pattern_destroy (pattern);
956 
957 	cairo_restore (cr); /* rounded clip region */
958 
959 	/* Draw the dark lines and the shadow */
960 	cairo_save (cr);
961 	/* Again, this weird clip area. */
962 	ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
963 	cairo_clip (cr);
964 	ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
965 	cairo_clip (cr);
966 
967 	shadow.r = 0.0;
968 	shadow.g = 0.0;
969 	shadow.b = 0.0;
970 	shadow.a = 0.1;
971 
972 	if (progressbar->pulsing)
973 	{
974 		/* At the beginning of the bar. */
975 		cairo_move_to (cr, -0.5 + radius, height + 0.5);
976 		ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
977 		ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
978 		ge_cairo_set_color (cr, &shadow);
979 		cairo_stroke (cr);
980 	}
981 	if (progressbar->value < 1.0 || progressbar->pulsing)
982 	{
983 		/* At the end of the bar. */
984 		cairo_move_to (cr, width + 0.5 - radius, -0.5);
985 		ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
986 		ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
987 		ge_cairo_set_color (cr, &shadow);
988 		cairo_stroke (cr);
989 	}
990 
991 /*	ge_cairo_rounded_rectangle (cr, 1.5,1.5, width-2, height-2, radius, CR_CORNER_ALL);*/
992 /*	cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 1);*/
993 /*	cairo_stroke (cr);*/
994 
995 	params->style_functions->draw_top_left_highlight (cr, &colors->spot[1], params, 1.5, 1.5,
996 	                                                  width - 1, height - 1,
997 	                                                  radius, params->corners);
998 
999 	border = colors->spot[2];
1000 	border.a = 0.6;
1001 	ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, CR_CORNER_ALL);
1002 	ge_cairo_set_color (cr, &border);
1003 	cairo_stroke (cr);
1004 
1005 	cairo_restore (cr);
1006 
1007 	cairo_restore (cr); /* rotation, mirroring */
1008 }
1009 
1010 static void
clearlooks_draw_optionmenu(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const OptionMenuParameters * optionmenu,int x,int y,int width,int height)1011 clearlooks_draw_optionmenu (cairo_t *cr,
1012                             const ClearlooksColors *colors,
1013                             const WidgetParameters *params,
1014                             const OptionMenuParameters *optionmenu,
1015                             int x, int y, int width, int height)
1016 {
1017 	SeparatorParameters separator;
1018 	int offset = params->ythickness + 2;
1019 
1020 	params->style_functions->draw_button (cr, colors, params, x, y, width, height);
1021 
1022 	separator.horizontal = FALSE;
1023 	params->style_functions->draw_separator (cr, colors, params, &separator, x+optionmenu->linepos, y + offset, 2, height - offset*2);
1024 }
1025 
1026 static void
clearlooks_draw_menu_item_separator(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const SeparatorParameters * separator,int x,int y,int width,int height)1027 clearlooks_draw_menu_item_separator (cairo_t                   *cr,
1028                                      const ClearlooksColors    *colors,
1029                                      const WidgetParameters    *widget,
1030                                      const SeparatorParameters *separator,
1031                                      int x, int y, int width, int height)
1032 {
1033 	cairo_save (cr);
1034 	cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
1035 	ge_cairo_set_color (cr, &colors->shade[5]);
1036 
1037 	if (separator->horizontal)
1038 		cairo_rectangle (cr, x, y, width, 1);
1039 	else
1040 		cairo_rectangle (cr, x, y, 1, height);
1041 
1042 	cairo_fill      (cr);
1043 
1044 	cairo_restore (cr);
1045 }
1046 
1047 static void
clearlooks_draw_menubar0(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const MenuBarParameters * menubar,int x,int y,int width,int height)1048 clearlooks_draw_menubar0 (cairo_t *cr,
1049                           const ClearlooksColors *colors,
1050                           const WidgetParameters *params,
1051                           const MenuBarParameters *menubar,
1052                           int x, int y, int width, int height)
1053 {
1054 	const CairoColor *dark = &colors->shade[3];
1055 
1056 	cairo_save (cr);
1057 
1058 	cairo_set_line_width (cr, 1);
1059 	cairo_translate (cr, x, y);
1060 
1061 	cairo_move_to (cr, 0, height-0.5);
1062 	cairo_line_to (cr, width, height-0.5);
1063 	ge_cairo_set_color (cr, dark);
1064 	cairo_stroke (cr);
1065 
1066 	cairo_restore (cr);
1067 }
1068 
1069 static void
clearlooks_draw_menubar2(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const MenuBarParameters * menubar,int x,int y,int width,int height)1070 clearlooks_draw_menubar2 (cairo_t *cr,
1071                           const ClearlooksColors *colors,
1072                           const WidgetParameters *params,
1073                           const MenuBarParameters *menubar,
1074                           int x, int y, int width, int height)
1075 {
1076 	CairoColor lower;
1077 	cairo_pattern_t *pattern;
1078 
1079 	cairo_save (cr);
1080 
1081 	ge_shade_color (&colors->bg[0], 0.96, &lower);
1082 
1083 	cairo_translate (cr, x, y);
1084 	cairo_rectangle (cr, 0, 0, width, height);
1085 
1086 	/* Draw the gradient */
1087 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
1088 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, colors->bg[0].r,
1089 	                                                colors->bg[0].g,
1090 	                                                colors->bg[0].b);
1091 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower.r,
1092 	                                                lower.g,
1093 	                                                lower.b);
1094 	cairo_set_source      (cr, pattern);
1095 	cairo_fill            (cr);
1096 	cairo_pattern_destroy (pattern);
1097 
1098 	/* Draw bottom line */
1099 	cairo_set_line_width (cr, 1.0);
1100 	cairo_move_to        (cr, 0, height-0.5);
1101 	cairo_line_to        (cr, width, height-0.5);
1102 	ge_cairo_set_color   (cr, &colors->shade[3]);
1103 	cairo_stroke         (cr);
1104 
1105 	cairo_restore (cr);
1106 }
1107 
1108 static void
clearlooks_draw_menubar1(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const MenuBarParameters * menubar,int x,int y,int width,int height)1109 clearlooks_draw_menubar1 (cairo_t *cr,
1110                           const ClearlooksColors *colors,
1111                           const WidgetParameters *params,
1112                           const MenuBarParameters *menubar,
1113                           int x, int y, int width, int height)
1114 {
1115 	const CairoColor *border = &colors->shade[3];
1116 
1117 	clearlooks_draw_menubar2 (cr, colors, params, menubar,
1118 	                          x, y, width, height);
1119 
1120 	ge_cairo_set_color (cr, border);
1121 	ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1122 }
1123 
1124 
1125 static menubar_draw_proto clearlooks_menubar_draw[3] =
1126 {
1127 	clearlooks_draw_menubar0,
1128 	clearlooks_draw_menubar1,
1129 	clearlooks_draw_menubar2
1130 };
1131 
1132 static void
clearlooks_draw_menubar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const MenuBarParameters * menubar,int x,int y,int width,int height)1133 clearlooks_draw_menubar (cairo_t *cr,
1134                          const ClearlooksColors *colors,
1135                          const WidgetParameters *params,
1136                          const MenuBarParameters *menubar,
1137                          int x, int y, int width, int height)
1138 {
1139 	if (menubar->style < 0 || menubar->style >= G_N_ELEMENTS (clearlooks_menubar_draw))
1140 		return;
1141 
1142 	clearlooks_menubar_draw[menubar->style](cr, colors, params, menubar,
1143 	                             x, y, width, height);
1144 }
1145 
1146 static void
clearlooks_get_frame_gap_clip(int x,int y,int width,int height,const FrameParameters * frame,ClearlooksRectangle * bevel,ClearlooksRectangle * border)1147 clearlooks_get_frame_gap_clip (int x, int y, int width, int height,
1148                                const FrameParameters     *frame,
1149                                ClearlooksRectangle *bevel,
1150                                ClearlooksRectangle *border)
1151 {
1152 	if (frame->gap_side == CL_GAP_TOP)
1153 	{
1154 		CLEARLOOKS_RECTANGLE_SET (*bevel,  2.0 + frame->gap_x,  0.0,
1155 		                          frame->gap_width - 3, 2.0);
1156 		CLEARLOOKS_RECTANGLE_SET (*border, 1.0 + frame->gap_x,  0.0,
1157 		                         frame->gap_width - 2, 2.0);
1158 	}
1159 	else if (frame->gap_side == CL_GAP_BOTTOM)
1160 	{
1161 		CLEARLOOKS_RECTANGLE_SET (*bevel,  2.0 + frame->gap_x,  height - 2.0,
1162 		                          frame->gap_width - 3, 2.0);
1163 		CLEARLOOKS_RECTANGLE_SET (*border, 1.0 + frame->gap_x,  height - 1.0,
1164 		                          frame->gap_width - 2, 2.0);
1165 	}
1166 	else if (frame->gap_side == CL_GAP_LEFT)
1167 	{
1168 		CLEARLOOKS_RECTANGLE_SET (*bevel,  0.0, 2.0 + frame->gap_x,
1169 		                          2.0, frame->gap_width - 3);
1170 		CLEARLOOKS_RECTANGLE_SET (*border, 0.0, 1.0 + frame->gap_x,
1171 		                          1.0, frame->gap_width - 2);
1172 	}
1173 	else if (frame->gap_side == CL_GAP_RIGHT)
1174 	{
1175 		CLEARLOOKS_RECTANGLE_SET (*bevel,  width - 2.0, 2.0 + frame->gap_x,
1176 		                          2.0, frame->gap_width - 3);
1177 		CLEARLOOKS_RECTANGLE_SET (*border, width - 1.0, 1.0 + frame->gap_x,
1178 		                          1.0, frame->gap_width - 2);
1179 	}
1180 }
1181 
1182 static void
clearlooks_draw_frame(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const FrameParameters * frame,int x,int y,int width,int height)1183 clearlooks_draw_frame            (cairo_t *cr,
1184                                   const ClearlooksColors     *colors,
1185                                   const WidgetParameters     *params,
1186                                   const FrameParameters      *frame,
1187                                   int x, int y, int width, int height)
1188 {
1189 	const CairoColor *border = frame->border;
1190 	const CairoColor *dark   = (CairoColor*)&colors->shade[4];
1191 	ClearlooksRectangle bevel_clip = {0, 0, 0, 0};
1192 	ClearlooksRectangle frame_clip = {0, 0, 0, 0};
1193 	double radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
1194 	CairoColor hilight;
1195 
1196 	ge_shade_color (&colors->bg[0], 1.05, &hilight);
1197 
1198 	if (frame->shadow == CL_SHADOW_NONE)
1199 		return;
1200 
1201 	if (frame->gap_x != -1)
1202 		clearlooks_get_frame_gap_clip (x, y, width, height,
1203 		                               frame, &bevel_clip, &frame_clip);
1204 
1205 	cairo_set_line_width (cr, 1.0);
1206 	cairo_translate      (cr, x, y);
1207 
1208 	/* save everything */
1209 	cairo_save (cr);
1210 	/* Set clip for the bevel */
1211 	if (frame->gap_x != -1)
1212 	{
1213 		/* Set clip for gap */
1214 		cairo_set_fill_rule  (cr, CAIRO_FILL_RULE_EVEN_ODD);
1215 		cairo_rectangle      (cr, 0, 0, width, height);
1216 		cairo_rectangle      (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
1217 		cairo_clip           (cr);
1218 	}
1219 
1220 	/* Draw the bevel */
1221 	if (frame->shadow == CL_SHADOW_ETCHED_IN || frame->shadow == CL_SHADOW_ETCHED_OUT)
1222 	{
1223 		ge_cairo_set_color (cr, &hilight);
1224 		if (frame->shadow == CL_SHADOW_ETCHED_IN)
1225 			ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-1, height-1, radius, params->corners);
1226 		else
1227 			ge_cairo_inner_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
1228 		cairo_stroke (cr);
1229 	}
1230 	else if (frame->shadow != CL_SHADOW_NONE)
1231 	{
1232 		ShadowParameters shadow;
1233 		shadow.corners = params->corners;
1234 		shadow.shadow  = frame->shadow;
1235 		clearlooks_draw_highlight_and_shade (cr, colors, &shadow, width, height, radius);
1236 	}
1237 
1238 	/* restore the previous clip region */
1239 	cairo_restore    (cr);
1240 	cairo_save       (cr);
1241 	if (frame->gap_x != -1)
1242 	{
1243 		/* Set clip for gap */
1244 		cairo_set_fill_rule  (cr, CAIRO_FILL_RULE_EVEN_ODD);
1245 		cairo_rectangle      (cr, 0, 0, width, height);
1246 		cairo_rectangle      (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
1247 		cairo_clip           (cr);
1248 	}
1249 
1250 	/* Draw frame */
1251 	if (frame->shadow == CL_SHADOW_ETCHED_IN || frame->shadow == CL_SHADOW_ETCHED_OUT)
1252 	{
1253 		ge_cairo_set_color (cr, dark);
1254 		if (frame->shadow == CL_SHADOW_ETCHED_IN)
1255 			ge_cairo_inner_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
1256 		else
1257 			ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-1, height-1, radius, params->corners);
1258 	}
1259 	else
1260 	{
1261 		ge_cairo_set_color (cr, border);
1262 		ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners);
1263 	}
1264 	cairo_stroke (cr);
1265 
1266 	cairo_restore (cr);
1267 }
1268 
1269 static void
clearlooks_draw_tab(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const TabParameters * tab,int x,int y,int width,int height)1270 clearlooks_draw_tab (cairo_t *cr,
1271                      const ClearlooksColors *colors,
1272                      const WidgetParameters *params,
1273                      const TabParameters    *tab,
1274                      int x, int y, int width, int height)
1275 {
1276 	const CairoColor *border1       = &colors->shade[6];
1277 	const CairoColor *border2       = &colors->shade[5];
1278 	const CairoColor *stripe_fill   = &colors->spot[1];
1279 	const CairoColor *stripe_border = &colors->spot[2];
1280 	const CairoColor *fill;
1281 	CairoColor        hilight;
1282 
1283 	cairo_pattern_t  *pattern;
1284 
1285 	double            radius;
1286 	double            stripe_size = 2.0;
1287 	double            stripe_fill_size;
1288 	double            length;
1289 
1290 	radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
1291 
1292 	cairo_save (cr);
1293 
1294 	/* Set clip */
1295 	cairo_rectangle      (cr, x, y, width, height);
1296 	cairo_clip           (cr);
1297 	cairo_new_path       (cr);
1298 
1299 	/* Translate and set line width */
1300 	cairo_set_line_width (cr, 1.0);
1301 	cairo_translate      (cr, x, y);
1302 
1303 
1304 	/* Make the tabs slightly bigger than they should be, to create a gap */
1305 	/* And calculate the strip size too, while you're at it */
1306 	if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM)
1307 	{
1308 		height += 3.0;
1309 		length = height;
1310 		stripe_fill_size = (tab->gap_side == CL_GAP_TOP ? stripe_size/height : stripe_size/(height-2));
1311 
1312 		if (tab->gap_side == CL_GAP_TOP)
1313 			cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
1314 	}
1315 	else
1316 	{
1317 		width += 3.0;
1318 		length = width;
1319 		stripe_fill_size = (tab->gap_side == CL_GAP_LEFT ? stripe_size/width : stripe_size/(width-2));
1320 
1321 		if (tab->gap_side == CL_GAP_LEFT)
1322 			cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
1323 	}
1324 
1325 	/* Set the fill color */
1326 	fill = &colors->bg[params->state_type];
1327 
1328 	/* Set tab shape */
1329 	ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1,
1330 	                            radius, params->corners);
1331 
1332 	/* Draw fill */
1333 	ge_cairo_set_color (cr, fill);
1334 	cairo_fill   (cr);
1335 
1336 
1337 	ge_shade_color (fill, 1.3, &hilight);
1338 
1339 	/* Draw highlight */
1340 	if (!params->active)
1341 	{
1342 		ShadowParameters shadow;
1343 
1344 		shadow.shadow  = CL_SHADOW_OUT;
1345 		shadow.corners = params->corners;
1346 
1347 		clearlooks_draw_highlight_and_shade (cr, colors, &shadow,
1348 		                                     width,
1349 		                                     height, radius);
1350 	}
1351 
1352 	if (params->active)
1353 	{
1354 		CairoColor shadow;
1355 		switch (tab->gap_side)
1356 		{
1357 			case CL_GAP_TOP:
1358 				pattern = cairo_pattern_create_linear (0.5, height-1.5, 0.5, 0.5);
1359 				break;
1360 			case CL_GAP_BOTTOM:
1361 				pattern = cairo_pattern_create_linear (0.5, 1.5, 0.5, height+0.5);
1362 				break;
1363 			case CL_GAP_LEFT:
1364 				pattern = cairo_pattern_create_linear (width-1.5, 0.5, 1.5, 0.5);
1365 				break;
1366 			case CL_GAP_RIGHT:
1367 				pattern = cairo_pattern_create_linear (1.5, 0.5, width-1.5, 0.5);
1368 				break;
1369 			default:
1370 				pattern = NULL;
1371 		}
1372 
1373 		ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners);
1374 
1375 		ge_shade_color (fill, 0.92, &shadow);
1376 
1377 		cairo_pattern_add_color_stop_rgba  (pattern, 0.0,        hilight.r, hilight.g, hilight.b, 0.4);
1378 		cairo_pattern_add_color_stop_rgba  (pattern, 1.0/length, hilight.r, hilight.g, hilight.b, 0.4);
1379 		cairo_pattern_add_color_stop_rgb   (pattern, 1.0/length, fill->r,fill->g,fill->b);
1380 		cairo_pattern_add_color_stop_rgb   (pattern, 1.0,        shadow.r,shadow.g,shadow.b);
1381 		cairo_set_source (cr, pattern);
1382 		cairo_fill (cr);
1383 		cairo_pattern_destroy (pattern);
1384 	}
1385 	else
1386 	{
1387 		/* Draw shade */
1388 		switch (tab->gap_side)
1389 		{
1390 			case CL_GAP_TOP:
1391 				pattern = cairo_pattern_create_linear (0.5, height-1.5, 0.5, 0.5);
1392 				break;
1393 			case CL_GAP_BOTTOM:
1394 				pattern = cairo_pattern_create_linear (0.5, 0.5, 0.5, height+0.5);
1395 				break;
1396 			case CL_GAP_LEFT:
1397 				pattern = cairo_pattern_create_linear (width-1.5, 0.5, 0.5, 0.5);
1398 				break;
1399 			case CL_GAP_RIGHT:
1400 				pattern = cairo_pattern_create_linear (0.5, 0.5, width+0.5, 0.5);
1401 				break;
1402 			default:
1403 				pattern = NULL;
1404 		}
1405 
1406 		ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners);
1407 
1408 		cairo_pattern_add_color_stop_rgb  (pattern, 0.0,        stripe_fill->r, stripe_fill->g, stripe_fill->b);
1409 		cairo_pattern_add_color_stop_rgb  (pattern, stripe_fill_size, stripe_fill->r, stripe_fill->g, stripe_fill->b);
1410 		cairo_pattern_add_color_stop_rgba (pattern, stripe_fill_size, hilight.r, hilight.g, hilight.b, 0.5);
1411 		cairo_pattern_add_color_stop_rgba (pattern, 0.8,        hilight.r, hilight.g, hilight.b, 0.0);
1412 		cairo_set_source (cr, pattern);
1413 		cairo_fill (cr);
1414 		cairo_pattern_destroy (pattern);
1415 	}
1416 
1417 	ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners);
1418 
1419 	if (params->active)
1420 	{
1421 		ge_cairo_set_color (cr, border2);
1422 		cairo_stroke (cr);
1423 	}
1424 	else
1425 	{
1426 		switch (tab->gap_side)
1427 		{
1428 			case CL_GAP_TOP:
1429 				pattern = cairo_pattern_create_linear (2.5, height-1.5, 2.5, 2.5);
1430 				break;
1431 			case CL_GAP_BOTTOM:
1432 				pattern = cairo_pattern_create_linear (2.5, 2.5, 2.5, height+0.5);
1433 				break;
1434 			case CL_GAP_LEFT:
1435 				pattern = cairo_pattern_create_linear (width-1.5, 2.5, 2.5, 2.5);
1436 				break;
1437 			case CL_GAP_RIGHT:
1438 				pattern = cairo_pattern_create_linear (2.5, 2.5, width+0.5, 2.5);
1439 				break;
1440 			default:
1441 				pattern = NULL;
1442 		}
1443 
1444 		cairo_pattern_add_color_stop_rgb (pattern, 0.0,        stripe_border->r, stripe_border->g, stripe_border->b);
1445 		cairo_pattern_add_color_stop_rgb (pattern, stripe_fill_size, stripe_border->r, stripe_border->g, stripe_border->b);
1446 		cairo_pattern_add_color_stop_rgb (pattern, stripe_fill_size, border1->r,       border1->g,       border1->b);
1447 		cairo_pattern_add_color_stop_rgb (pattern, 1.0,        border2->r,       border2->g,       border2->b);
1448 		cairo_set_source (cr, pattern);
1449 		cairo_stroke (cr);
1450 		cairo_pattern_destroy (pattern);
1451 	}
1452 
1453 	cairo_restore (cr);
1454 }
1455 
1456 static void
clearlooks_draw_separator(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const SeparatorParameters * separator,int x,int y,int width,int height)1457 clearlooks_draw_separator (cairo_t *cr,
1458                            const ClearlooksColors     *colors,
1459                            const WidgetParameters     *widget,
1460                            const SeparatorParameters  *separator,
1461                            int x, int y, int width, int height)
1462 {
1463 	CairoColor color = colors->shade[2];
1464 	CairoColor hilight;
1465 	ge_shade_color (&colors->bg[0], 1.065, &hilight);
1466 
1467 	cairo_save (cr);
1468 	cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
1469 
1470 	if (separator->horizontal)
1471 	{
1472 		cairo_set_line_width  (cr, 1.0);
1473 		cairo_translate       (cr, x, y+0.5);
1474 
1475 		cairo_move_to         (cr, 0.0,   0.0);
1476 		cairo_line_to         (cr, width, 0.0);
1477 		ge_cairo_set_color    (cr, &color);
1478 		cairo_stroke          (cr);
1479 
1480 		cairo_move_to         (cr, 0.0,   1.0);
1481 		cairo_line_to         (cr, width, 1.0);
1482 		ge_cairo_set_color    (cr, &hilight);
1483 		cairo_stroke          (cr);
1484 	}
1485 	else
1486 	{
1487 		cairo_set_line_width  (cr, 1.0);
1488 		cairo_translate       (cr, x+0.5, y);
1489 
1490 		cairo_move_to         (cr, 0.0, 0.0);
1491 		cairo_line_to         (cr, 0.0, height);
1492 		ge_cairo_set_color    (cr, &color);
1493 		cairo_stroke          (cr);
1494 
1495 		cairo_move_to         (cr, 1.0, 0.0);
1496 		cairo_line_to         (cr, 1.0, height);
1497 		ge_cairo_set_color    (cr, &hilight);
1498 		cairo_stroke          (cr);
1499 	}
1500 
1501 	cairo_restore (cr);
1502 }
1503 
1504 static void
clearlooks_draw_list_view_header(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const ListViewHeaderParameters * header,int x,int y,int width,int height)1505 clearlooks_draw_list_view_header (cairo_t *cr,
1506                                   const ClearlooksColors          *colors,
1507                                   const WidgetParameters          *params,
1508                                   const ListViewHeaderParameters  *header,
1509                                   int x, int y, int width, int height)
1510 {
1511 	const CairoColor *border = &colors->shade[4];
1512 	CairoColor hilight;
1513 
1514 	ge_shade_color (&colors->bg[params->state_type],
1515 	                params->style_constants->topleft_highlight_shade, &hilight);
1516 	hilight.a = params->style_constants->topleft_highlight_alpha;
1517 
1518 	cairo_translate (cr, x, y);
1519 	cairo_set_line_width (cr, 1.0);
1520 
1521 	/* Draw highlight */
1522 	if (header->order & CL_ORDER_FIRST)
1523 	{
1524 		cairo_move_to (cr, 0.5, height-1);
1525 		cairo_line_to (cr, 0.5, 0.5);
1526 	}
1527 	else
1528 		cairo_move_to (cr, 0.0, 0.5);
1529 
1530 	cairo_line_to (cr, width, 0.5);
1531 
1532 	ge_cairo_set_color (cr, &hilight);
1533 	cairo_stroke (cr);
1534 
1535 	/* Draw bottom border */
1536 	cairo_move_to (cr, 0.0, height-0.5);
1537 	cairo_line_to (cr, width, height-0.5);
1538 	ge_cairo_set_color (cr, border);
1539 	cairo_stroke (cr);
1540 
1541 	/* Draw resize grip */
1542 	if ((params->ltr && !(header->order & CL_ORDER_LAST)) ||
1543 	    (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable)
1544 	{
1545 		SeparatorParameters separator;
1546 		separator.horizontal = FALSE;
1547 
1548 		if (params->ltr)
1549 			params->style_functions->draw_separator (cr, colors, params, &separator,
1550 			                                         width-1.5, 4.0, 2, height-8.0);
1551 		else
1552 			params->style_functions->draw_separator (cr, colors, params, &separator,
1553 			                                         1.5, 4.0, 2, height-8.0);
1554 	}
1555 }
1556 
1557 /* We can't draw transparent things here, since it will be called on the same
1558  * surface multiple times, when placed on a handlebox_bin or dockitem_bin */
1559 static void
clearlooks_draw_toolbar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ToolbarParameters * toolbar,int x,int y,int width,int height)1560 clearlooks_draw_toolbar (cairo_t *cr,
1561                          const ClearlooksColors          *colors,
1562                          const WidgetParameters          *widget,
1563                          const ToolbarParameters         *toolbar,
1564                          int x, int y, int width, int height)
1565 {
1566 	const CairoColor *fill  = &colors->bg[0];
1567 	const CairoColor *dark  = &colors->shade[3];
1568 	CairoColor light;
1569 	ge_shade_color (fill, 1.065, &light);
1570 
1571 	cairo_set_line_width (cr, 1.0);
1572 	cairo_translate (cr, x, y);
1573 
1574 	ge_cairo_set_color (cr, fill);
1575 	cairo_paint (cr);
1576 
1577 	if (!toolbar->topmost)
1578 	{
1579 		/* Draw highlight */
1580 		cairo_move_to       (cr, 0, 0.5);
1581 		cairo_line_to       (cr, width-1, 0.5);
1582 		ge_cairo_set_color  (cr, &light);
1583 		cairo_stroke        (cr);
1584 	}
1585 
1586 	/* Draw shadow */
1587 	cairo_move_to       (cr, 0, height-0.5);
1588 	cairo_line_to       (cr, width-1, height-0.5);
1589 	ge_cairo_set_color  (cr, dark);
1590 	cairo_stroke        (cr);
1591 }
1592 
1593 static void
clearlooks_draw_menuitem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1594 clearlooks_draw_menuitem (cairo_t *cr,
1595                           const ClearlooksColors          *colors,
1596                           const WidgetParameters          *widget,
1597                           int x, int y, int width, int height)
1598 {
1599 	const CairoColor *fill = &colors->spot[1];
1600 	CairoColor fill_shade;
1601 	CairoColor border = colors->spot[2];
1602 	cairo_pattern_t *pattern;
1603 
1604 	ge_shade_color (&border, 1.05, &border);
1605 	ge_shade_color (fill, 0.85, &fill_shade);
1606 	cairo_set_line_width (cr, 1.0);
1607 
1608 	ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, widget->radius, widget->corners);
1609 
1610 	pattern = cairo_pattern_create_linear (x, y, x, y + height);
1611 	cairo_pattern_add_color_stop_rgb (pattern, 0,   fill->r, fill->g, fill->b);
1612 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, fill_shade.r, fill_shade.g, fill_shade.b);
1613 
1614 	cairo_set_source (cr, pattern);
1615 	cairo_fill_preserve  (cr);
1616 	cairo_pattern_destroy (pattern);
1617 
1618 	ge_cairo_set_color (cr, &border);
1619 	cairo_stroke (cr);
1620 }
1621 
1622 static void
clearlooks_draw_menubaritem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1623 clearlooks_draw_menubaritem (cairo_t *cr,
1624                           const ClearlooksColors          *colors,
1625                           const WidgetParameters          *widget,
1626                           int x, int y, int width, int height)
1627 {
1628 	const CairoColor *fill = &colors->spot[1];
1629 	CairoColor fill_shade;
1630 	CairoColor border = colors->spot[2];
1631 	cairo_pattern_t *pattern;
1632 
1633 	ge_shade_color (&border, 1.05, &border);
1634 	ge_shade_color (fill, 0.85, &fill_shade);
1635 
1636 	cairo_set_line_width (cr, 1.0);
1637 	ge_cairo_rounded_rectangle (cr, x + 0.5, y + 0.5, width - 1, height, widget->radius, widget->corners);
1638 
1639 	pattern = cairo_pattern_create_linear (x, y, x, y + height);
1640 	cairo_pattern_add_color_stop_rgb (pattern, 0,   fill->r, fill->g, fill->b);
1641 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, fill_shade.r, fill_shade.g, fill_shade.b);
1642 
1643 	cairo_set_source (cr, pattern);
1644 	cairo_fill_preserve  (cr);
1645 	cairo_pattern_destroy (pattern);
1646 
1647 	ge_cairo_set_color (cr, &border);
1648 	cairo_stroke_preserve (cr);
1649 }
1650 
1651 static void
clearlooks_draw_selected_cell(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1652 clearlooks_draw_selected_cell (cairo_t                  *cr,
1653 	                       const ClearlooksColors   *colors,
1654 	                       const WidgetParameters   *params,
1655 	                       int x, int y, int width, int height)
1656 {
1657 	CairoColor upper_color;
1658 	CairoColor lower_color;
1659 	cairo_pattern_t *pattern;
1660 	cairo_save (cr);
1661 
1662 	cairo_translate (cr, x, y);
1663 
1664 	if (params->focus)
1665 		upper_color = colors->base[params->state_type];
1666 	else
1667 		upper_color = colors->base[GTK_STATE_ACTIVE];
1668 
1669 	ge_shade_color(&upper_color, 0.92, &lower_color);
1670 
1671 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
1672 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, upper_color.r,
1673 	                                                upper_color.g,
1674 	                                                upper_color.b);
1675 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower_color.r,
1676 	                                                lower_color.g,
1677 	                                                lower_color.b);
1678 
1679 	cairo_set_source (cr, pattern);
1680 	cairo_rectangle  (cr, 0, 0, width, height);
1681 	cairo_fill       (cr);
1682 
1683 	cairo_pattern_destroy (pattern);
1684 
1685 	cairo_restore (cr);
1686 }
1687 
1688 
1689 static void
clearlooks_draw_scrollbar_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)1690 clearlooks_draw_scrollbar_trough (cairo_t *cr,
1691                                   const ClearlooksColors           *colors,
1692                                   const WidgetParameters           *widget,
1693                                   const ScrollBarParameters        *scrollbar,
1694                                   int x, int y, int width, int height)
1695 {
1696 	const CairoColor *bg     = &colors->shade[2];
1697 	const CairoColor *border = &colors->shade[5];
1698 	CairoColor        bg_shade;
1699 	cairo_pattern_t *pattern;
1700 	double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
1701 
1702 	ge_shade_color (bg, 0.95, &bg_shade);
1703 
1704 	cairo_set_line_width (cr, 1);
1705 	/* cairo_translate (cr, x, y); */
1706 
1707 	if (scrollbar->horizontal)
1708 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
1709 
1710 	cairo_translate (cr, x, y);
1711 
1712 	/* Draw fill */
1713 	if (radius > 3.0)
1714 		ge_cairo_rounded_rectangle (cr, 1, 0, width-2, height,
1715 		                            radius, widget->corners);
1716 	else
1717 		cairo_rectangle (cr, 1, 0, width-2, height);
1718 	ge_cairo_set_color (cr, bg);
1719 	cairo_fill (cr);
1720 
1721 	/* Draw shadow */
1722 	pattern = cairo_pattern_create_linear (1, 0, 3, 0);
1723 	cairo_pattern_add_color_stop_rgb (pattern, 0,   bg_shade.r, bg_shade.g, bg_shade.b);
1724 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg->r,      bg->g,      bg->b);
1725 	cairo_rectangle (cr, 1, 0, 4, height);
1726 	cairo_set_source (cr, pattern);
1727 	cairo_fill (cr);
1728 	cairo_pattern_destroy (pattern);
1729 
1730 	/* Draw border */
1731 	if (radius > 3.0)
1732 		ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1,
1733 		                            radius, widget->corners);
1734 	else
1735 		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
1736 	ge_cairo_set_color (cr, border);
1737 	cairo_stroke (cr);
1738 }
1739 
1740 static void
clearlooks_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)1741 clearlooks_draw_scrollbar_stepper (cairo_t *cr,
1742                                    const ClearlooksColors           *colors,
1743                                    const WidgetParameters           *widget,
1744                                    const ScrollBarParameters        *scrollbar,
1745                                    const ScrollBarStepperParameters *stepper,
1746                                    int x, int y, int width, int height)
1747 {
1748 	CairoCorners corners = CR_CORNER_NONE;
1749 	CairoColor   border;
1750 	CairoColor   s1, s2, s3, s4;
1751 	cairo_pattern_t *pattern;
1752 	double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
1753 
1754 	ge_shade_color(&colors->shade[6], 1.08, &border);
1755 
1756 	if (scrollbar->horizontal)
1757 	{
1758 		if (stepper->stepper == CL_STEPPER_A)
1759 			corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
1760 		else if (stepper->stepper == CL_STEPPER_D)
1761 			corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
1762 
1763 		if (stepper->stepper == CL_STEPPER_B)
1764 		{
1765 			x -= 1;
1766 			width += 1;
1767 		}
1768 		else if (stepper->stepper == CL_STEPPER_C)
1769 		{
1770 			width += 1;
1771 		}
1772 	}
1773 	else
1774 	{
1775 		if (stepper->stepper == CL_STEPPER_A)
1776 			corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT;
1777 		else if (stepper->stepper == CL_STEPPER_D)
1778 			corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT;
1779 
1780 		if (stepper->stepper == CL_STEPPER_B)
1781 		{
1782 			y -= 1;
1783 			height += 1;
1784 		}
1785 		else if (stepper->stepper == CL_STEPPER_C)
1786 		{
1787 			height += 1;
1788 		}
1789 	}
1790 
1791 	cairo_translate (cr, x, y);
1792 	cairo_set_line_width (cr, 1);
1793 
1794 	ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners);
1795 
1796 	if (scrollbar->horizontal)
1797 		pattern = cairo_pattern_create_linear (0, 0, 0, height);
1798 	else
1799 		pattern = cairo_pattern_create_linear (0, 0, width, 0);
1800 
1801 	ge_shade_color (&colors->bg[widget->state_type], SHADE_TOP, &s1);
1802 	ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_TOP, &s2);
1803 	ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_BOTTOM, &s3);
1804 	ge_shade_color (&colors->bg[widget->state_type], SHADE_BOTTOM, &s4);
1805 
1806 	cairo_pattern_add_color_stop_rgb(pattern, 0,   s1.r, s1.g, s1.b);
1807 	cairo_pattern_add_color_stop_rgb(pattern, 0.3, s2.r, s2.g, s2.b);
1808 	cairo_pattern_add_color_stop_rgb(pattern, 0.7, s3.r, s3.g, s3.b);
1809 	cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b);
1810 	cairo_set_source (cr, pattern);
1811 	cairo_fill (cr);
1812 	cairo_pattern_destroy (pattern);
1813 
1814 	widget->style_functions->draw_top_left_highlight (cr, &s2, widget, 1, 1, width - 2, height - 2, MAX(radius - 1, 0), corners);
1815 
1816 	ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, corners);
1817 	clearlooks_set_border_gradient (cr, &border, 1.1, (scrollbar->horizontal ? 0 : width), (scrollbar->horizontal ? height: 0));
1818 	cairo_stroke (cr);
1819 }
1820 
1821 static void
clearlooks_draw_scrollbar_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)1822 clearlooks_draw_scrollbar_slider (cairo_t *cr,
1823                                    const ClearlooksColors          *colors,
1824                                    const WidgetParameters          *widget,
1825                                    const ScrollBarParameters       *scrollbar,
1826                                    int x, int y, int width, int height)
1827 {
1828 	cairo_save (cr);
1829 
1830 	if (scrollbar->junction & CL_JUNCTION_BEGIN)
1831 	{
1832 		if (scrollbar->horizontal)
1833 		{
1834 			x -= 1;
1835 			width += 1;
1836 		}
1837 		else
1838 		{
1839 			y -= 1;
1840 			height += 1;
1841 		}
1842 	}
1843 	if (scrollbar->junction & CL_JUNCTION_END)
1844 	{
1845 		if (scrollbar->horizontal)
1846 			width += 1;
1847 		else
1848 			height += 1;
1849 	}
1850 
1851 	if (!scrollbar->horizontal)
1852 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
1853 
1854 	cairo_translate (cr, x, y);
1855 
1856 	if (scrollbar->has_color)
1857 	{
1858 		const CairoColor *border  = &colors->shade[7];
1859 		CairoColor  fill    = scrollbar->color;
1860 		CairoColor  hilight;
1861 		CairoColor  shade1, shade2, shade3;
1862 		cairo_pattern_t *pattern;
1863 
1864 		if (widget->prelight)
1865 			ge_shade_color (&fill, 1.1, &fill);
1866 
1867 		cairo_set_line_width (cr, 1);
1868 
1869 		ge_shade_color (&fill, 1.3, &hilight);
1870 		ge_shade_color (&fill, 1.1, &shade1);
1871 		ge_shade_color (&fill, 1.05, &shade2);
1872 		ge_shade_color (&fill, 0.98, &shade3);
1873 
1874 		pattern = cairo_pattern_create_linear (1, 1, 1, height-2);
1875 		cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
1876 		cairo_pattern_add_color_stop_rgb (pattern, 0.5,	shade2.r, shade2.g, shade2.b);
1877 		cairo_pattern_add_color_stop_rgb (pattern, 0.5,	shade3.r, shade3.g, shade3.b);
1878 		cairo_pattern_add_color_stop_rgb (pattern, 1, 	fill.r,  fill.g,  fill.b);
1879 		cairo_rectangle (cr, 1, 1, width-2, height-2);
1880 		cairo_set_source (cr, pattern);
1881 		cairo_fill (cr);
1882 		cairo_pattern_destroy (pattern);
1883 
1884 		cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
1885 		ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3);
1886 
1887 		ge_cairo_set_color (cr, border);
1888 		ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1889 	}
1890 	else
1891 	{
1892 		const CairoColor *dark  = &colors->shade[4];
1893 		const CairoColor *light = &colors->shade[0];
1894 		CairoColor border;
1895 		CairoColor s1, s2, s3, s4, s5;
1896 		cairo_pattern_t *pattern;
1897 		int bar_x, i;
1898 
1899 		ge_shade_color (&colors->shade[6], 1.08, &border);
1900 		ge_shade_color (&colors->bg[widget->state_type], SHADE_TOP, &s1);
1901 		ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_TOP, &s2);
1902 		ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_BOTTOM, &s3);
1903 		ge_shade_color (&colors->bg[widget->state_type], SHADE_BOTTOM, &s4);
1904 
1905 		pattern = cairo_pattern_create_linear(1, 1, 1, height-1);
1906 		cairo_pattern_add_color_stop_rgb(pattern, 0,   s1.r, s1.g, s1.b);
1907 		cairo_pattern_add_color_stop_rgb(pattern, 0.3, s2.r, s2.g, s2.b);
1908 		cairo_pattern_add_color_stop_rgb(pattern, 0.7, s3.r, s3.g, s3.b);
1909 		cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b);
1910 
1911 		cairo_rectangle (cr, 1, 1, width-2, height-2);
1912 		cairo_set_source(cr, pattern);
1913 		cairo_fill(cr);
1914 		cairo_pattern_destroy(pattern);
1915 
1916 		clearlooks_set_border_gradient (cr, &border, 1.1, 0, height);
1917 		ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1918 
1919 		cairo_move_to (cr, 1.5, height-1.5);
1920 		cairo_line_to (cr, 1.5, 1.5);
1921 		cairo_line_to (cr, width-1.5, 1.5);
1922 		ge_shade_color (&s2, widget->style_constants->topleft_highlight_shade, &s5);
1923 		s5.a = widget->style_constants->topleft_highlight_alpha;
1924 		ge_cairo_set_color (cr, &s5);
1925 		cairo_stroke(cr);
1926 
1927 		/* draw handles */
1928 		cairo_set_line_width (cr, 1);
1929 		cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
1930 
1931 		bar_x = width/2 - 4;
1932 
1933 		for (i=0; i<3; i++)
1934 		{
1935 			cairo_move_to (cr, bar_x + 0.5, 4);
1936 			cairo_line_to (cr, bar_x + 0.5, height-4);
1937 			ge_cairo_set_color (cr, dark);
1938 			cairo_stroke (cr);
1939 
1940 			cairo_move_to (cr, bar_x+1.5, 4);
1941 			cairo_line_to (cr, bar_x+1.5, height-4);
1942 			ge_cairo_set_color (cr, light);
1943 			cairo_stroke (cr);
1944 
1945 			bar_x += 3;
1946 		}
1947 	}
1948 
1949 	cairo_restore (cr);
1950 }
1951 
1952 static void
clearlooks_draw_statusbar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1953 clearlooks_draw_statusbar (cairo_t *cr,
1954                            const ClearlooksColors          *colors,
1955                            const WidgetParameters          *widget,
1956                            int x, int y, int width, int height)
1957 {
1958 	const CairoColor *dark = &colors->shade[3];
1959 	CairoColor hilight;
1960 
1961 	ge_shade_color (dark, 1.4, &hilight);
1962 
1963 	cairo_set_line_width  (cr, 1);
1964 	cairo_translate       (cr, x, y+0.5);
1965 	cairo_move_to         (cr, 0, 0);
1966 	cairo_line_to         (cr, width, 0);
1967 	ge_cairo_set_color    (cr, dark);
1968 	cairo_stroke          (cr);
1969 
1970 	cairo_translate       (cr, 0, 1);
1971 	cairo_move_to         (cr, 0, 0);
1972 	cairo_line_to         (cr, width, 0);
1973 	ge_cairo_set_color    (cr, &hilight);
1974 	cairo_stroke          (cr);
1975 }
1976 
1977 static void
clearlooks_draw_menu_frame(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1978 clearlooks_draw_menu_frame (cairo_t *cr,
1979                             const ClearlooksColors          *colors,
1980                             const WidgetParameters          *widget,
1981                             int x, int y, int width, int height)
1982 {
1983 	const CairoColor *border = &colors->shade[5];
1984 	cairo_translate      (cr, x, y);
1985 	cairo_set_line_width (cr, 1);
1986 
1987 	ge_cairo_set_color (cr, border);
1988 	ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1989 }
1990 
1991 static void
clearlooks_draw_tooltip(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1992 clearlooks_draw_tooltip (cairo_t *cr,
1993                          const ClearlooksColors          *colors,
1994                          const WidgetParameters          *widget,
1995                          int x, int y, int width, int height)
1996 {
1997 	CairoColor border;
1998 
1999 	ge_shade_color (&colors->bg[widget->state_type], 0.6, &border);
2000 
2001 	cairo_save (cr);
2002 
2003 	cairo_translate      (cr, x, y);
2004 	cairo_set_line_width (cr, 1);
2005 
2006 	ge_cairo_set_color (cr, &colors->bg[widget->state_type]);
2007 	cairo_rectangle (cr, 0, 0, width, height);
2008 	cairo_fill (cr);
2009 
2010 	ge_cairo_set_color (cr, &border);
2011 	ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
2012 
2013 	cairo_restore (cr);
2014 }
2015 
2016 static void
clearlooks_draw_icon_view_item(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)2017 clearlooks_draw_icon_view_item (cairo_t                  *cr,
2018 	                        const ClearlooksColors   *colors,
2019 	                        const WidgetParameters   *params,
2020 	                        int x, int y, int width, int height)
2021 {
2022 	CairoColor upper_color;
2023 	CairoColor lower_color;
2024 	cairo_pattern_t *pattern;
2025 	cairo_save (cr);
2026 
2027 	cairo_translate (cr, x, y);
2028 
2029 	if (params->focus)
2030 		upper_color = colors->base[params->state_type];
2031 	else
2032 		upper_color = colors->base[GTK_STATE_ACTIVE];
2033 
2034 	ge_shade_color(&upper_color, 0.92, &lower_color);
2035 
2036 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
2037 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, upper_color.r,
2038 	                                                upper_color.g,
2039 	                                                upper_color.b);
2040 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower_color.r,
2041 	                                                lower_color.g,
2042 	                                                lower_color.b);
2043 
2044 	cairo_set_source (cr, pattern);
2045 	ge_cairo_rounded_rectangle  (cr, 0, 0, width, height, params->radius, CR_CORNER_ALL);
2046 	cairo_fill       (cr);
2047 
2048 	cairo_pattern_destroy (pattern);
2049 
2050 	cairo_restore (cr);
2051 }
2052 
2053 static void
clearlooks_draw_handle(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const HandleParameters * handle,int x,int y,int width,int height)2054 clearlooks_draw_handle (cairo_t *cr,
2055                         const ClearlooksColors          *colors,
2056                         const WidgetParameters          *params,
2057                         const HandleParameters          *handle,
2058                         int x, int y, int width, int height)
2059 {
2060 	const CairoColor *fill  = &colors->bg[params->state_type];
2061 	int num_bars = 6; /* shut up gcc warnings */
2062 
2063 	cairo_save (cr);
2064 
2065 	switch (handle->type)
2066 	{
2067 		case CL_HANDLE_TOOLBAR:
2068 			num_bars    = 6;
2069 		break;
2070 		case CL_HANDLE_SPLITTER:
2071 			num_bars    = 16;
2072 		break;
2073 	}
2074 
2075 	if (params->prelight)
2076 	{
2077 		cairo_rectangle (cr, x, y, width, height);
2078 		ge_cairo_set_color (cr, fill);
2079 		cairo_fill (cr);
2080 	}
2081 
2082 	cairo_translate (cr, x, y);
2083 
2084 	cairo_set_line_width (cr, 1);
2085 
2086 	if (handle->horizontal)
2087 	{
2088 		params->style_functions->draw_gripdots (cr, colors, 0, 0, width, height, num_bars, 2, 0.1);
2089 	}
2090 	else
2091 	{
2092 		params->style_functions->draw_gripdots (cr, colors, 0, 0, width, height, 2, num_bars, 0.1);
2093 	}
2094 
2095 	cairo_restore (cr);
2096 }
2097 
2098 static void
clearlooks_draw_resize_grip(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ResizeGripParameters * grip,int x,int y,int width,int height)2099 clearlooks_draw_resize_grip (cairo_t *cr,
2100                              const ClearlooksColors          *colors,
2101                              const WidgetParameters          *widget,
2102                              const ResizeGripParameters      *grip,
2103                              int x, int y, int width, int height)
2104 {
2105 	const CairoColor *dark   = &colors->shade[4];
2106 	CairoColor hilight;
2107 	int lx, ly;
2108 	int x_down;
2109 	int y_down;
2110 	int dots;
2111 
2112 	ge_shade_color (dark, 1.5, &hilight);
2113 
2114 	/* The number of dots fitting into the area. Just hardcoded to 4 right now. */
2115 	/* dots = MIN (width - 2, height - 2) / 3; */
2116 	dots = 4;
2117 
2118 	cairo_save (cr);
2119 
2120 	switch (grip->edge)
2121 	{
2122 		case CL_WINDOW_EDGE_NORTH_EAST:
2123 			x_down = 0;
2124 			y_down = 0;
2125 			cairo_translate (cr, x + width - 3*dots + 2, y + 1);
2126 		break;
2127 		case CL_WINDOW_EDGE_SOUTH_EAST:
2128 			x_down = 0;
2129 			y_down = 1;
2130 			cairo_translate (cr, x + width - 3*dots + 2, y + height - 3*dots + 2);
2131 		break;
2132 		case CL_WINDOW_EDGE_SOUTH_WEST:
2133 			x_down = 1;
2134 			y_down = 1;
2135 			cairo_translate (cr, x + 1, y + height - 3*dots + 2);
2136 		break;
2137 		case CL_WINDOW_EDGE_NORTH_WEST:
2138 			x_down = 1;
2139 			y_down = 0;
2140 			cairo_translate (cr, x + 1, y + 1);
2141 		break;
2142 		default:
2143 			/* Not implemented. */
2144 			return;
2145 	}
2146 
2147 	for (lx = 0; lx < dots; lx++) /* horizontally */
2148 	{
2149 		for (ly = 0; ly <= lx; ly++) /* vertically */
2150 		{
2151 			int mx, my;
2152 			mx = x_down * dots + (1 - x_down * 2) * lx - x_down;
2153 			my = y_down * dots + (1 - y_down * 2) * ly - y_down;
2154 
2155 			ge_cairo_set_color (cr, &hilight);
2156 			cairo_rectangle (cr, mx*3-1, my*3-1, 2, 2);
2157 			cairo_fill (cr);
2158 
2159 			ge_cairo_set_color (cr, dark);
2160 			cairo_rectangle (cr, mx*3-1, my*3-1, 1, 1);
2161 			cairo_fill (cr);
2162 		}
2163 	}
2164 
2165 	cairo_restore (cr);
2166 }
2167 
2168 static void
clearlooks_draw_radiobutton(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)2169 clearlooks_draw_radiobutton (cairo_t *cr,
2170                              const ClearlooksColors  *colors,
2171                              const WidgetParameters  *widget,
2172                              const CheckboxParameters *checkbox,
2173                              int x, int y, int width, int height)
2174 {
2175 	const CairoColor *border;
2176 	const CairoColor *dot;
2177 	CairoColor shadow;
2178 	CairoColor highlight;
2179 	cairo_pattern_t *pt;
2180 	gboolean inconsistent;
2181 	gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
2182 	gdouble w, h, cx, cy, radius;
2183 
2184 	w = (gdouble) width;
2185 	h = (gdouble) height;
2186 	cx = width / 2.0;
2187 	cy = height / 2.0;
2188 	radius = MIN (width, height) / 2.0;
2189 
2190 	inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
2191 	draw_bullet |= inconsistent;
2192 
2193 	if (widget->disabled)
2194 	{
2195 		border = &colors->shade[5];
2196 		dot    = &colors->shade[6];
2197 	}
2198 	else
2199 	{
2200 		border = &colors->shade[6];
2201 		dot    = &colors->text[0];
2202 	}
2203 
2204 	ge_shade_color (&widget->parentbg, 0.9, &shadow);
2205 	ge_shade_color (&widget->parentbg, 1.1, &highlight);
2206 
2207 	pt = cairo_pattern_create_linear (0, 0, radius * 2.0, radius * 2.0);
2208 	cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g);
2209 	cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5);
2210 	cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5);
2211 	cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b);
2212 
2213 	cairo_translate (cr, x, y);
2214 
2215 	cairo_set_line_width (cr, MAX (1.0, floor (radius/3)));
2216 	cairo_arc (cr, ceil (cx), ceil (cy), floor (radius - 0.1), 0, G_PI*2);
2217 	cairo_set_source (cr, pt);
2218 	cairo_stroke (cr);
2219 	cairo_pattern_destroy (pt);
2220 
2221 	cairo_set_line_width (cr, MAX (1.0, floor (radius/6)));
2222 
2223 	cairo_arc (cr, ceil (cx), ceil (cy), MAX (1.0, ceil (radius) - 1.5), 0, G_PI*2);
2224 
2225 	if (!widget->disabled)
2226 	{
2227 		ge_cairo_set_color (cr, &colors->base[0]);
2228 		cairo_fill_preserve (cr);
2229 	}
2230 
2231 	ge_cairo_set_color (cr, border);
2232 	cairo_stroke (cr);
2233 
2234 	if (draw_bullet)
2235 	{
2236 		if (inconsistent)
2237 		{
2238 			gdouble line_width = floor (radius * 2 / 3);
2239 
2240 			cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
2241 			cairo_set_line_width (cr, line_width);
2242 
2243 			cairo_move_to (cr, ceil (cx - radius/3.0 - line_width) + line_width, ceil (cy - line_width) + line_width);
2244 			cairo_line_to (cr, floor (cx + radius/3.0 + line_width) - line_width, ceil (cy - line_width) + line_width);
2245 
2246 			ge_cairo_set_color (cr, dot);
2247 			cairo_stroke (cr);
2248 		}
2249 		else
2250 		{
2251 			cairo_arc (cr, ceil (cx), ceil (cy), floor (radius/2.0), 0, G_PI*2);
2252 			ge_cairo_set_color (cr, dot);
2253 			cairo_fill (cr);
2254 
2255 			cairo_arc (cr, floor (cx - radius/10.0), floor (cy - radius/10.0), floor (radius/6.0), 0, G_PI*2);
2256 			cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
2257 			cairo_fill (cr);
2258 		}
2259 	}
2260 }
2261 
2262 static void
clearlooks_draw_checkbox(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)2263 clearlooks_draw_checkbox (cairo_t *cr,
2264                           const ClearlooksColors  *colors,
2265                           const WidgetParameters  *widget,
2266                           const CheckboxParameters *checkbox,
2267                           int x, int y, int width, int height)
2268 {
2269 	const CairoColor *border;
2270 	const CairoColor *dot;
2271 	gboolean inconsistent = FALSE;
2272 	gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
2273 
2274 	inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
2275 	draw_bullet |= inconsistent;
2276 
2277 	if (widget->disabled)
2278 	{
2279 		border = &colors->shade[5];
2280 		dot    = &colors->shade[6];
2281 	}
2282 	else
2283 	{
2284 		border = &colors->shade[6];
2285 		dot    = &colors->text[GTK_STATE_NORMAL];
2286 	}
2287 
2288 	cairo_translate (cr, x, y);
2289 	cairo_set_line_width (cr, 1);
2290 
2291 	if (widget->xthickness >= 3 && widget->ythickness >= 3)
2292 	{
2293 		widget->style_functions->draw_inset (cr, &widget->parentbg, 0, 0, width, height, 1, CR_CORNER_ALL);
2294 
2295 		/* Draw the rectangle for the checkbox itself */
2296 		ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
2297 	}
2298 	else
2299 	{
2300 		/* Draw the rectangle for the checkbox itself */
2301 		ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
2302 	}
2303 
2304 	if (!widget->disabled)
2305 	{
2306 		ge_cairo_set_color (cr, &colors->base[0]);
2307 		cairo_fill_preserve (cr);
2308 	}
2309 
2310 	ge_cairo_set_color (cr, border);
2311 	cairo_stroke (cr);
2312 
2313 	if (draw_bullet)
2314 	{
2315 		if (inconsistent) /* Inconsistent */
2316 		{
2317 			cairo_set_line_width (cr, 2.0);
2318 			cairo_move_to (cr, 3, height*0.5);
2319 			cairo_line_to (cr, width-3, height*0.5);
2320 		}
2321 		else
2322 		{
2323 			cairo_set_line_width (cr, 1.7);
2324 			cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5));
2325 			cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7));
2326 
2327 			cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7),
2328 			                    0.5 + (width*0.5), (height*0.4),
2329 			                    0.5 + (width*0.70), (height*0.25));
2330 
2331 		}
2332 
2333 		ge_cairo_set_color (cr, dot);
2334 		cairo_stroke (cr);
2335 	}
2336 }
2337 
2338 static void
clearlooks_draw_normal_arrow(cairo_t * cr,const CairoColor * color,double x,double y,double width,double height)2339 clearlooks_draw_normal_arrow (cairo_t *cr, const CairoColor *color,
2340                               double x, double y, double width, double height)
2341 {
2342 	double arrow_width;
2343 	double arrow_height;
2344 	double line_width_2;
2345 
2346 	cairo_save (cr);
2347 
2348 	arrow_width = MIN (height * 2.0 + MAX (1.0, ceil (height * 2.0 / 6.0 * 2.0) / 2.0) / 2.0, width);
2349 	line_width_2 = MAX (1.0, ceil (arrow_width / 6.0 * 2.0) / 2.0) / 2.0;
2350 	arrow_height = arrow_width / 2.0 + line_width_2;
2351 
2352 	cairo_translate (cr, x, y - arrow_height / 2.0);
2353 
2354 	cairo_move_to (cr, -arrow_width / 2.0, line_width_2);
2355 	cairo_line_to (cr, -arrow_width / 2.0 + line_width_2, 0);
2356 	/* cairo_line_to (cr, 0, arrow_height - line_width_2); */
2357 	cairo_arc_negative (cr, 0, arrow_height - 2*line_width_2 - 2*line_width_2 * sqrt(2), 2*line_width_2, G_PI_2 + G_PI_4, G_PI_4);
2358 	cairo_line_to (cr, arrow_width / 2.0 - line_width_2, 0);
2359 	cairo_line_to (cr, arrow_width / 2.0, line_width_2);
2360 	cairo_line_to (cr, 0, arrow_height);
2361 	cairo_close_path (cr);
2362 
2363 	ge_cairo_set_color (cr, color);
2364 	cairo_fill (cr);
2365 
2366 	cairo_restore (cr);
2367 }
2368 
2369 static void
clearlooks_draw_combo_arrow(cairo_t * cr,const CairoColor * color,double x,double y,double width,double height)2370 clearlooks_draw_combo_arrow (cairo_t *cr, const CairoColor *color,
2371                              double x, double y, double width, double height)
2372 {
2373 	double arrow_width = MIN (height * 2 / 3.0, width);
2374 	double arrow_height = arrow_width / 2.0;
2375 	double gap_size = 1.0 * arrow_height;
2376 
2377 	cairo_save (cr);
2378 	cairo_translate (cr, x, y - (arrow_height + gap_size) / 2.0);
2379 	cairo_rotate (cr, G_PI);
2380 	clearlooks_draw_normal_arrow (cr, color, 0, 0, arrow_width, arrow_height);
2381 	cairo_restore (cr);
2382 
2383 	clearlooks_draw_normal_arrow (cr, color, x, y + (arrow_height + gap_size) / 2.0, arrow_width, arrow_height);
2384 }
2385 
2386 static void
_clearlooks_draw_arrow(cairo_t * cr,const CairoColor * color,ClearlooksDirection dir,ClearlooksArrowType type,double x,double y,double width,double height)2387 _clearlooks_draw_arrow (cairo_t *cr, const CairoColor *color,
2388                         ClearlooksDirection dir, ClearlooksArrowType type,
2389                         double x, double y, double width, double height)
2390 {
2391 	double rotate;
2392 
2393 	if (dir == CL_DIRECTION_LEFT)
2394 		rotate = G_PI*1.5;
2395 	else if (dir == CL_DIRECTION_RIGHT)
2396 		rotate = G_PI*0.5;
2397 	else if (dir == CL_DIRECTION_UP)
2398 		rotate = G_PI;
2399 	else if (dir == CL_DIRECTION_DOWN)
2400 		rotate = 0;
2401 	else
2402 		return;
2403 
2404 	if (type == CL_ARROW_NORMAL)
2405 	{
2406 		cairo_translate (cr, x, y);
2407 		cairo_rotate (cr, -rotate);
2408 		clearlooks_draw_normal_arrow (cr, color, 0, 0, width, height);
2409 	}
2410 	else if (type == CL_ARROW_COMBO)
2411 	{
2412 		cairo_translate (cr, x, y);
2413 		clearlooks_draw_combo_arrow (cr, color, 0, 0, width, height);
2414 	}
2415 }
2416 
2417 static void
clearlooks_draw_arrow(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ArrowParameters * arrow,int x,int y,int width,int height)2418 clearlooks_draw_arrow (cairo_t *cr,
2419                        const ClearlooksColors *colors,
2420                        const WidgetParameters *widget,
2421                        const ArrowParameters  *arrow,
2422                        int x, int y, int width, int height)
2423 {
2424 	const CairoColor *color = &colors->fg[widget->state_type];
2425 	gdouble tx, ty;
2426 
2427 	tx = x + width/2.0;
2428 	ty = y + height/2.0;
2429 
2430 	if (widget->disabled)
2431 	{
2432 		_clearlooks_draw_arrow (cr, &colors->shade[0],
2433 		                        arrow->direction, arrow->type,
2434 		                        tx+0.5, ty+0.5, width, height);
2435 	}
2436 
2437 	cairo_identity_matrix (cr);
2438 
2439 	_clearlooks_draw_arrow (cr, color, arrow->direction, arrow->type,
2440 	                        tx, ty, width, height);
2441 }
2442 
2443 void
clearlooks_draw_focus(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)2444 clearlooks_draw_focus (cairo_t *cr,
2445                        const ClearlooksColors *colors,
2446                        const WidgetParameters *widget,
2447                        const FocusParameters  *focus,
2448                        int x, int y, int width, int height)
2449 {
2450 	if (focus->has_color)
2451 		ge_cairo_set_color (cr, &focus->color);
2452 	else if (focus->type == CL_FOCUS_COLOR_WHEEL_LIGHT)
2453 		cairo_set_source_rgb (cr, 0., 0., 0.);
2454 	else if (focus->type == CL_FOCUS_COLOR_WHEEL_DARK)
2455 		cairo_set_source_rgb (cr, 1., 1., 1.);
2456 	else
2457 		cairo_set_source_rgba (cr,
2458 		                       colors->fg[widget->state_type].r,
2459 		                       colors->fg[widget->state_type].g,
2460 		                       colors->fg[widget->state_type].b,
2461 		                       0.7);
2462 
2463 	cairo_set_line_width (cr, focus->line_width);
2464 
2465 	if (focus->dash_list[0])
2466 	{
2467 		gint n_dashes = strlen ((gchar *)focus->dash_list);
2468 		gdouble *dashes = g_new (gdouble, n_dashes);
2469 		gdouble total_length = 0;
2470 		gdouble dash_offset;
2471 		gint i;
2472 
2473 		for (i = 0; i < n_dashes; i++)
2474 		{
2475 			dashes[i] = focus->dash_list[i];
2476 			total_length += focus->dash_list[i];
2477 		}
2478 
2479 		dash_offset = -focus->line_width / 2.0;
2480 		while (dash_offset < 0)
2481 			dash_offset += total_length;
2482 
2483 		cairo_set_dash (cr, dashes, n_dashes, dash_offset);
2484 		g_free (dashes);
2485 	}
2486 
2487 	cairo_rectangle (cr,
2488 	                 x + focus->line_width / 2.0,
2489 	                 y + focus->line_width / 2.0,
2490 	                 width - focus->line_width, height - focus->line_width);
2491 	cairo_stroke (cr);
2492 }
2493 
2494 void
clearlooks_set_mixed_color(cairo_t * cr,const CairoColor * color1,const CairoColor * color2,gdouble mix_factor)2495 clearlooks_set_mixed_color (cairo_t          *cr,
2496                             const CairoColor *color1,
2497                             const CairoColor *color2,
2498                             gdouble mix_factor)
2499 {
2500 	CairoColor composite;
2501 
2502 	ge_mix_color (color1, color2, mix_factor, &composite);
2503 	ge_cairo_set_color (cr, &composite);
2504 }
2505 
2506 void
clearlooks_register_style_classic(ClearlooksStyleFunctions * functions,ClearlooksStyleConstants * constants)2507 clearlooks_register_style_classic (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants)
2508 {
2509 	g_assert (functions);
2510 
2511 	functions->draw_top_left_highlight  = clearlooks_draw_top_left_highlight;
2512 	functions->draw_button              = clearlooks_draw_button;
2513 	functions->draw_scale_trough        = clearlooks_draw_scale_trough;
2514 	functions->draw_progressbar_trough  = clearlooks_draw_progressbar_trough;
2515 	functions->draw_progressbar_fill    = clearlooks_draw_progressbar_fill;
2516 	functions->draw_slider_button       = clearlooks_draw_slider_button;
2517 	functions->draw_entry               = clearlooks_draw_entry;
2518 	functions->draw_entry_progress      = clearlooks_draw_entry_progress;
2519 	functions->draw_spinbutton          = clearlooks_draw_spinbutton;
2520 	functions->draw_spinbutton_down     = clearlooks_draw_spinbutton_down;
2521 	functions->draw_optionmenu          = clearlooks_draw_optionmenu;
2522 	functions->draw_inset               = clearlooks_draw_inset;
2523 	functions->draw_menubar	            = clearlooks_draw_menubar;
2524 	functions->draw_tab                 = clearlooks_draw_tab;
2525 	functions->draw_frame               = clearlooks_draw_frame;
2526 	functions->draw_separator           = clearlooks_draw_separator;
2527 	functions->draw_menu_item_separator = clearlooks_draw_menu_item_separator;
2528 	functions->draw_list_view_header    = clearlooks_draw_list_view_header;
2529 	functions->draw_toolbar             = clearlooks_draw_toolbar;
2530 	functions->draw_menuitem            = clearlooks_draw_menuitem;
2531 	functions->draw_menubaritem         = clearlooks_draw_menubaritem;
2532 	functions->draw_selected_cell       = clearlooks_draw_selected_cell;
2533 	functions->draw_scrollbar_stepper   = clearlooks_draw_scrollbar_stepper;
2534 	functions->draw_scrollbar_slider    = clearlooks_draw_scrollbar_slider;
2535 	functions->draw_scrollbar_trough    = clearlooks_draw_scrollbar_trough;
2536 	functions->draw_statusbar           = clearlooks_draw_statusbar;
2537 	functions->draw_menu_frame          = clearlooks_draw_menu_frame;
2538 	functions->draw_tooltip             = clearlooks_draw_tooltip;
2539 	functions->draw_icon_view_item      = clearlooks_draw_icon_view_item;
2540 	functions->draw_handle              = clearlooks_draw_handle;
2541 	functions->draw_resize_grip         = clearlooks_draw_resize_grip;
2542 	functions->draw_arrow               = clearlooks_draw_arrow;
2543 	functions->draw_focus               = clearlooks_draw_focus;
2544 	functions->draw_checkbox            = clearlooks_draw_checkbox;
2545 	functions->draw_radiobutton         = clearlooks_draw_radiobutton;
2546 	functions->draw_shadow              = clearlooks_draw_shadow;
2547 	functions->draw_slider              = clearlooks_draw_slider;
2548 	functions->draw_gripdots            = clearlooks_draw_gripdots;
2549 
2550 	constants->topleft_highlight_shade  = 1.3;
2551 	constants->topleft_highlight_alpha  = 0.6;
2552 }
2553