1 /* Murrine theme engine
2  * Copyright (C) 2006-2007-2008-2009 Andrea Cimitan
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  */
20 
21 #include <cairo.h>
22 
23 #include "murrine_draw.h"
24 #include "murrine_style.h"
25 #include "murrine_types.h"
26 #include "support.h"
27 #include "cairo-support.h"
28 #include "raico-blur.h"
29 
30 static void
murrine_draw_inset(cairo_t * cr,const MurrineRGB * bg_color,double x,double y,double w,double h,double radius,uint8 corners)31 murrine_draw_inset (cairo_t *cr,
32                     const MurrineRGB *bg_color,
33                     double x, double y, double w, double h,
34                     double radius, uint8 corners)
35 {
36 	MurrineRGB shadow, highlight;
37 	radius = MIN (radius, MIN (w/2.0, h/2.0));
38 
39 	murrine_shade (bg_color, 0.74, &shadow);
40 	murrine_shade (bg_color, 1.3, &highlight);
41 
42 	/* highlight */
43 	cairo_move_to (cr, x+w+(radius*-0.2928932188), y-(radius*-0.2928932188));
44 
45 	if (corners & MRN_CORNER_TOPRIGHT)
46 		cairo_arc (cr, x+w-radius, y+radius, radius, M_PI*1.75, M_PI*2);
47 	else
48 		cairo_line_to (cr, x+w, y);
49 
50 	if (corners & MRN_CORNER_BOTTOMRIGHT)
51 		cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI*0.5);
52 	else
53 		cairo_line_to (cr, x+w, y+h);
54 
55 	if (corners & MRN_CORNER_BOTTOMLEFT)
56 		cairo_arc (cr, x+radius, y+h-radius, radius, M_PI*0.5, M_PI*0.75);
57 	else
58 		cairo_line_to (cr, x, y+h);
59 
60 	murrine_set_color_rgba (cr, &highlight, 0.42);
61 	cairo_stroke (cr);
62 
63 	/* shadow */
64 	cairo_move_to (cr, x+(radius*0.2928932188), y+h+(radius*-0.2928932188));
65 
66 	if (corners & MRN_CORNER_BOTTOMLEFT)
67 		cairo_arc (cr, x+radius, y+h-radius, radius, M_PI*0.75, M_PI);
68 	else
69 		cairo_line_to (cr, x, y+h);
70 
71 	if (corners & MRN_CORNER_TOPLEFT)
72 		cairo_arc (cr, x+radius, y+radius, radius, M_PI, M_PI*1.5);
73 	else
74 		cairo_line_to (cr, x, y);
75 
76 	if (corners & MRN_CORNER_TOPRIGHT)
77 		cairo_arc (cr, x+w-radius, y+radius, radius, M_PI*1.5, M_PI*1.75);
78 	else
79 		cairo_line_to (cr, x+w, y);
80 
81 	murrine_set_color_rgba (cr, &shadow, 0.16);
82 	cairo_stroke (cr);
83 }
84 
85 static void
murrine_draw_highlight_and_shade(cairo_t * cr,const MurrineColors * colors,const ShadowParameters * widget,int width,int height,int radius)86 murrine_draw_highlight_and_shade (cairo_t *cr,
87                                   const MurrineColors    *colors,
88                                   const ShadowParameters *widget,
89                                   int width, int height, int radius)
90 {
91 	MurrineRGB highlight;
92 	MurrineRGB shadow;
93 	uint8 corners = widget->corners;
94 	double x = 1.0;
95 	double y = 1.0;
96 	width  -= 3;
97 	height -= 3;
98 	radius = MIN (radius, MIN ((double)width/2.0, (double)height/2.0));
99 
100 	if (radius < 0)
101 		radius = 0;
102 
103 	murrine_shade (&colors->bg[0], 1.04, &highlight);
104 	murrine_shade (&colors->bg[0], 0.96, &shadow);
105 
106 	cairo_save (cr);
107 
108 	/* Top/Left highlight */
109 	if (corners & MRN_CORNER_BOTTOMLEFT)
110 		cairo_move_to (cr, x, y+height-radius);
111 	else
112 		cairo_move_to (cr, x, y+height);
113 
114 	murrine_rounded_corner (cr, x, y, radius, corners & MRN_CORNER_TOPLEFT);
115 
116 	if (corners & MRN_CORNER_TOPRIGHT)
117 		cairo_line_to (cr, x+width-radius, y);
118 	else
119 		cairo_line_to (cr, x+width, y);
120 
121 	if (widget->shadow & MRN_SHADOW_OUT)
122 		murrine_set_color_rgb (cr, &highlight);
123 	else
124 		murrine_set_color_rgb (cr, &shadow);
125 
126 	cairo_stroke (cr);
127 
128 	/* Bottom/Right highlight -- this includes the corners */
129 	cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */
130 	murrine_rounded_corner (cr, x+width, y, radius, corners & MRN_CORNER_TOPRIGHT);
131 	murrine_rounded_corner (cr, x+width, y+height, radius, corners & MRN_CORNER_BOTTOMRIGHT);
132 	murrine_rounded_corner (cr, x, y+height, radius, corners & MRN_CORNER_BOTTOMLEFT);
133 
134 	if (widget->shadow & MRN_SHADOW_OUT)
135 		murrine_set_color_rgb (cr, &shadow);
136 	else
137 		murrine_set_color_rgb (cr, &highlight);
138 
139 	cairo_stroke (cr);
140 
141 	cairo_restore (cr);
142 }
143 
144 static void
murrine_draw_button(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ButtonParameters * button,int x,int y,int width,int height,boolean horizontal)145 murrine_draw_button (cairo_t *cr,
146                      const MurrineColors    *colors,
147                      const WidgetParameters *widget,
148                      const ButtonParameters *button,
149                      int x, int y, int width, int height,
150                      boolean horizontal)
151 {
152 	int os = (widget->xthickness > 2 && widget->ythickness > 2) ? 1 : 0;
153 	double glow_shade_new = widget->glow_shade;
154 	double highlight_shade_new = widget->highlight_shade;
155 	double lightborder_shade_new = widget->lightborder_shade;
156 	MurrineGradients mrn_gradient_new = widget->mrn_gradient;
157 	MurrineRGB border;
158 	MurrineRGB fill = colors->bg[widget->state_type];
159 /*
160 	if (widget->active)
161 	{
162 		mrn_gradient_new.has_border_colors = FALSE;
163 		mrn_gradient_new.has_gradient_colors = FALSE;
164 	}
165 */
166 	murrine_get_fill_color (&fill, &mrn_gradient_new);
167 
168 	if (widget->disabled)
169 	{
170 		mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
171 		mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 2.0);
172 		mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 2.0);
173 		glow_shade_new = murrine_get_decreased_shade (widget->glow_shade, 2.0);
174 		highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
175 		lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
176 		murrine_shade (&fill, murrine_get_contrast(0.75, widget->contrast), &border);
177 	}
178 	else
179 		murrine_shade (&fill, murrine_get_contrast(0.475, widget->contrast), &border);
180 
181 	/* Default button */
182 	if (widget->is_default && !widget->disabled)
183 	{
184 		murrine_shade (&border, murrine_get_contrast(0.8, widget->contrast), &border);
185 
186 		if (button->has_default_button_color)
187 		{
188 			mrn_gradient_new.has_border_colors = FALSE;
189 			mrn_gradient_new.has_gradient_colors = FALSE;
190 			murrine_mix_color (&fill, &button->default_button_color, 0.8, &fill);
191 		}
192 		else
193 			murrine_mix_color (&fill, &colors->spot[1], 0.2, &fill);
194 
195 		if (mrn_gradient_new.has_border_colors)
196 		{
197 			murrine_shade (&mrn_gradient_new.border_colors[0], 0.8, &mrn_gradient_new.border_colors[0]);
198 			murrine_shade (&mrn_gradient_new.border_colors[1], 0.8, &mrn_gradient_new.border_colors[1]);
199 		}
200 	}
201 
202 	if (!horizontal)
203 		murrine_exchange_axis (cr, &x, &y, &width, &height);
204 
205 	cairo_translate (cr, x, y);
206 
207 	if (!widget->active && !widget->disabled && widget->reliefstyle > 1 && os > 0)
208 	{
209 		if (widget->reliefstyle == 5)
210 			murrine_draw_shadow (cr, &widget->parentbg,
211 			                     0.5, 0.5, width-1, height-1,
212 			                     widget->roundness+1, widget->corners,
213 			                     widget->reliefstyle,
214 			                     mrn_gradient_new, 0.5);
215 		else
216 		{
217 			murrine_draw_shadow (cr, &border,
218 			                     os-0.5, os-0.5, width-(os*2)+1, height-(os*2)+1,
219 			                     widget->roundness+1, widget->corners,
220 			                     widget->reliefstyle,
221 			                     mrn_gradient_new, 0.08);
222 		}
223 	}
224 	else if (widget->reliefstyle != 0 && os > 0)
225 	{
226 		mrn_gradient_new = murrine_get_inverted_border_shades (mrn_gradient_new);
227 		murrine_draw_inset (cr, &widget->parentbg, os-0.5, os-0.5,
228 		                    width-(os*2)+1, height-(os*2)+1,
229 		                    widget->roundness+1, widget->corners);
230 	}
231 
232 	murrine_mix_color (&border, &fill, 0.4, &border);
233 
234 	cairo_save (cr);
235 
236 	murrine_rounded_rectangle_closed (cr, os+1, os+1, width-(os*2)-2, height-(os*2)-2, widget->roundness-1, widget->corners);
237 	cairo_clip_preserve (cr);
238 
239 	murrine_draw_glaze (cr, &fill,
240 	                    glow_shade_new, highlight_shade_new, !widget->active ? lightborder_shade_new : 1.0,
241 	                    mrn_gradient_new, widget,
242 	                    os+1, os+1, width-(os*2)-2, height-(os*2)-2,
243 	                    widget->roundness-1, widget->corners, horizontal);
244 
245 	cairo_restore (cr);
246 
247 	/* Draw pressed button shadow */
248 	if (widget->active)
249 	{
250 		cairo_pattern_t *pat;
251 		MurrineRGB shadow;
252 
253 		murrine_shade (&fill, 0.94, &shadow);
254 
255 		cairo_save (cr);
256 
257 		murrine_rounded_rectangle_closed (cr, os+1, os+1, width-(os*2)-2, height-(os*2)-2, widget->roundness-1,
258 		                                  widget->corners & (MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMLEFT));
259 		cairo_clip (cr);
260 
261 		cairo_rectangle (cr, os+1, os+1, width-(os*2)-2, 3);
262 		pat = cairo_pattern_create_linear (os+1, os+1, os+1, os+4);
263 		murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow, 0.58);
264 		murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.0);
265 		cairo_set_source (cr, pat);
266 		cairo_fill (cr);
267 		cairo_pattern_destroy (pat);
268 
269 		cairo_rectangle (cr, os+1, os+1, 3, height-(os*2)-2);
270 		pat = cairo_pattern_create_linear (os+1, os+1, os+4, os+1);
271 		murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow, 0.58);
272 		murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.0);
273 		cairo_set_source (cr, pat);
274 		cairo_fill (cr);
275 		cairo_pattern_destroy (pat);
276 
277 		cairo_restore (cr);
278 	}
279 
280 	murrine_draw_border (cr, &border,
281 	                     os+0.5, os+0.5, width-(os*2)-1, height-(os*2)-1,
282 	                     widget->roundness, widget->corners,
283 	                     mrn_gradient_new, 1.0);
284 }
285 
286 static void
murrine_draw_entry(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)287 murrine_draw_entry (cairo_t *cr,
288                     const MurrineColors    *colors,
289                     const WidgetParameters *widget,
290                     const FocusParameters  *focus,
291                     int x, int y, int width, int height)
292 {
293 	MurrineGradients mrn_gradient_new = widget->mrn_gradient;
294 	const MurrineRGB *base = &colors->base[widget->state_type];
295 	MurrineRGB border = colors->shade[widget->disabled ? 4 : 6];
296 	int radius = CLAMP (widget->roundness, 0, 3);
297 
298 	if (widget->focus)
299 		border = focus->color;
300 
301 	cairo_translate (cr, x+0.5, y+0.5);
302 
303 	/* Fill the entry's base color */
304 	cairo_rectangle (cr, 1.5, 1.5, width-4, height-4);
305 	murrine_set_color_rgb (cr, base);
306 	cairo_fill (cr);
307 
308 	if (widget->reliefstyle != 0)
309 		murrine_draw_inset (cr, &widget->parentbg, 0, 0, width-1, height-1, radius+1, widget->corners);
310 
311 	/* Draw the focused border */
312 	if (widget->focus)
313 	{
314 		MurrineRGB focus_shadow;
315 		murrine_shade (&border, 1.54, &focus_shadow);
316 
317 		cairo_rectangle (cr, 2, 2, width-5, height-5);
318 		murrine_set_color_rgba (cr, &focus_shadow, 0.5);
319 		cairo_stroke(cr);
320 	}
321 	else if (widget->mrn_gradient.gradients)
322 	{
323 		MurrineRGB shadow;
324 		murrine_shade (&border, 0.925, &shadow);
325 
326 		cairo_move_to (cr, 2, height-3);
327 		cairo_line_to (cr, 2, 2);
328 		cairo_line_to (cr, width-3, 2);
329 
330 		murrine_set_color_rgba (cr, &shadow, widget->disabled ? 0.05 : 0.15);
331 		cairo_stroke (cr);
332 	}
333 
334 	mrn_gradient_new = murrine_get_inverted_border_shades (mrn_gradient_new);
335 
336 	/* Draw border */
337 	murrine_draw_border (cr, &border,
338 	                     1, 1, width-3, height-3,
339 	                     radius, widget->corners,
340 	                     mrn_gradient_new, 1.0);
341 }
342 
343 static void
murrine_draw_entry_progress(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const EntryProgressParameters * progress,int x,int y,int width,int height)344 murrine_draw_entry_progress (cairo_t *cr,
345                              const MurrineColors    *colors,
346                              const WidgetParameters *widget,
347                              const EntryProgressParameters *progress,
348                              int x, int y, int width, int height)
349 {
350 	MurrineRGB border;
351 	MurrineRGB fill;
352 	gint entry_width, entry_height;
353 	double entry_radius;
354 	double radius;
355 
356 	cairo_save (cr);
357 
358 	fill = colors->bg[widget->state_type];
359 	murrine_shade (&fill, 0.9, &border);
360 
361 	if (progress->max_size_known)
362 	{
363 		entry_width = progress->max_size.width+progress->border.left+progress->border.right;
364 		entry_height = progress->max_size.height+progress->border.top+progress->border.bottom;
365 		entry_radius = MIN (widget->roundness, MIN ((entry_width-4.0)/2.0, (entry_height-4.0)/2.0));
366 	}
367 	else
368 	{
369 		entry_radius = widget->roundness;
370 	}
371 
372 	radius = MAX (0, entry_radius+1.0-MAX (MAX (progress->border.left, progress->border.right),
373 	                                            MAX (progress->border.top, progress->border.bottom)));
374 
375 	if (progress->max_size_known)
376 	{
377 		/* Clip to the max size, and then draw a (larger) rectangle ... */
378 		clearlooks_rounded_rectangle (cr, progress->max_size.x,
379 		                              progress->max_size.y,
380 		                              progress->max_size.width,
381 		                              progress->max_size.height,
382 		                              radius,
383 		                              MRN_CORNER_ALL);
384 		cairo_clip (cr);
385 
386 		/* We just draw wider by one pixel ... */
387 		murrine_set_color_rgb (cr, &fill);
388 		cairo_rectangle (cr, x, y+1, width, height-2);
389 		cairo_fill (cr);
390 
391 		cairo_set_line_width (cr, 1.0);
392 		murrine_set_color_rgb (cr, &border);
393 		cairo_rectangle (cr, x-0.5, y+0.5, width+1, height-1);
394 		cairo_stroke (cr);
395 	}
396 	else
397 	{
398 		clearlooks_rounded_rectangle (cr, x, y, width+10, height+10, radius, MRN_CORNER_ALL);
399 		cairo_clip (cr);
400 		clearlooks_rounded_rectangle (cr, x-10, y-10, width+10, height+10, radius, MRN_CORNER_ALL);
401 		cairo_clip (cr);
402 
403 		murrine_set_color_rgb (cr, &fill);
404 		clearlooks_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, MRN_CORNER_ALL);
405 		cairo_fill (cr);
406 
407 		cairo_set_line_width (cr, 1.0);
408 		murrine_set_color_rgb (cr, &border);
409 		clearlooks_rounded_rectangle (cr, x+0.5, y+0.5, width-1.0, height-1.0, radius, MRN_CORNER_ALL);
410 		cairo_stroke (cr);
411 	}
412 
413 	cairo_restore (cr);
414 }
415 
416 static void
murrine_draw_spinbutton(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const SpinbuttonParameters * spinbutton,int x,int y,int width,int height,boolean horizontal)417 murrine_draw_spinbutton (cairo_t *cr,
418 	                     const MurrineColors    *colors,
419 	                     const WidgetParameters *widget,
420 	                     const SpinbuttonParameters *spinbutton,
421 	                     int x, int y, int width, int height,
422 	                     boolean horizontal)
423 {
424 	ButtonParameters button;
425 	button.has_default_button_color = FALSE;
426 
427 	cairo_save (cr);
428 
429 	widget->style_functions->draw_button (cr, colors, widget, &button, x, y, width, height, horizontal);
430 
431 	cairo_restore (cr);
432 
433 	switch (spinbutton->style)
434 	{
435 		default:
436 		case 0:
437 			break;
438 		case 1:
439 		{
440 			MurrineRGB line = colors->shade[!widget->disabled ? 6 : 5];
441 			MurrineRGB highlight = colors->bg[widget->state_type];
442 			double lightborder_shade_new = widget->lightborder_shade;
443 			MurrineGradients mrn_gradient_new = widget->mrn_gradient;
444 
445 			if (widget->disabled)
446 			{
447 				mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
448 				lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
449 				mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 2.0);
450 				mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 2.0);
451 			}
452 			else
453 				murrine_shade (&colors->shade[6], 0.95, &line);
454 
455 			/* adjust line accordingly to buttons */
456 			if (widget->mrn_gradient.has_border_colors)
457 				murrine_mix_color (&mrn_gradient_new.border_colors[0], &mrn_gradient_new.border_colors[1], 0.5, &line);
458 			else if (widget->mrn_gradient.has_gradient_colors)
459 				murrine_mix_color (&line, &mrn_gradient_new.gradient_colors[2], 0.4, &line);
460 			else
461 				murrine_mix_color (&line, &colors->bg[widget->state_type], 0.4, &line);
462 			murrine_shade (&line, (mrn_gradient_new.border_shades[0]+mrn_gradient_new.border_shades[1])/2.0, &line);
463 
464 			/* adjust highlight accordingly to buttons */
465 			if (widget->mrn_gradient.has_gradient_colors)
466 				murrine_shade (&mrn_gradient_new.gradient_colors[2], mrn_gradient_new.gradient_shades[2], &highlight);
467 			murrine_shade (&highlight, lightborder_shade_new*mrn_gradient_new.gradient_shades[2], &highlight);
468 
469 			/* this will align the path to the cairo grid */
470 			if (height % 2 != 0)
471 				height++;
472 
473 			cairo_move_to (cr, x+2, y+height/2.0-0.5);
474 			cairo_line_to (cr, width-3,  y+height/2.0-0.5);
475 			murrine_set_color_rgb (cr, &line);
476 			cairo_stroke (cr);
477 
478 			cairo_move_to (cr, x+3, y+height/2.0+0.5);
479 			cairo_line_to (cr, width-4,  y+height/2.0+0.5);
480 			murrine_set_color_rgba (cr, &highlight, 0.5);
481 			cairo_stroke (cr);
482 			break;
483 		}
484 	}
485 }
486 
487 static void
murrine_draw_spinbutton_down(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)488 murrine_draw_spinbutton_down (cairo_t *cr,
489                               const MurrineColors    *colors,
490                               const WidgetParameters *widget,
491                               int x, int y, int width, int height)
492 {
493 	cairo_pattern_t *pat;
494 	MurrineRGB shadow;
495 	murrine_shade (&colors->bg[0], 0.8, &shadow);
496 
497 	cairo_translate (cr, x+1, y+1);
498 
499 	cairo_rectangle (cr, 1, 1, width-4, height-4);
500 	pat = cairo_pattern_create_linear (0, 0, 0, height);
501 	murrine_pattern_add_color_stop_rgb (pat, 0.0, &shadow);
502 	murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.0);
503 	cairo_set_source (cr, pat);
504 	cairo_fill (cr);
505 	cairo_pattern_destroy (pat);
506 }
507 
508 static void
murrine_scale_draw_gradient(cairo_t * cr,const MurrineRGB * c1,const MurrineRGB * c2,double lightborder_shade,int lightborderstyle,int roundness,uint8 corners,int x,int y,int width,int height,boolean horizontal)509 murrine_scale_draw_gradient (cairo_t *cr,
510                              const MurrineRGB *c1,
511                              const MurrineRGB *c2,
512                              double lightborder_shade,
513                              int lightborderstyle,
514                              int roundness, uint8 corners,
515                              int x, int y, int width, int height,
516                              boolean horizontal)
517 {
518 	murrine_set_color_rgb (cr, c1);
519 	murrine_rounded_rectangle_closed (cr, x, y, width, height, roundness, corners);
520 	cairo_fill (cr);
521 
522 	if (lightborder_shade != 1.0)
523 	{
524 		cairo_pattern_t *pat;
525 		double fill_pos = horizontal ? 1.0-1.0/(double)(height-2) :
526 		                               1.0-1.0/(double)(width-2);
527 		MurrineRGB lightborder;
528 		murrine_shade (c1, lightborder_shade, &lightborder);
529 
530 		roundness < 2 ? cairo_rectangle (cr, x, y, width, height) :
531 		                clearlooks_rounded_rectangle (cr, x+1, y+1, width-2, height-2, roundness-1, corners);
532 		pat = cairo_pattern_create_linear (x+1, y+1, horizontal ? x+1 : width+x+1, horizontal ? height+y+1 : y+1);
533 
534 		murrine_pattern_add_color_stop_rgba (pat, 0.00,     &lightborder, 0.75);
535 		murrine_pattern_add_color_stop_rgba (pat, fill_pos, &lightborder, 0.75);
536 		murrine_pattern_add_color_stop_rgba (pat, fill_pos, &lightborder, 0.0);
537 		murrine_pattern_add_color_stop_rgba (pat, 1.00,     &lightborder, 0.0);
538 
539 		cairo_set_source (cr, pat);
540 		cairo_pattern_destroy (pat);
541 
542 		cairo_stroke (cr);
543 	}
544 
545 	murrine_set_color_rgb (cr, c2);
546 	murrine_rounded_rectangle (cr, x, y, width, height, roundness, corners);
547 	cairo_stroke (cr);
548 }
549 
550 static void
murrine_scale_draw_trough(cairo_t * cr,const MurrineRGB * c1,const MurrineRGB * c2,MurrineGradients mrn_gradient,int roundness,uint8 corners,int x,int y,int width,int height,boolean horizontal)551 murrine_scale_draw_trough (cairo_t *cr,
552                            const MurrineRGB *c1,
553                            const MurrineRGB *c2,
554                            MurrineGradients mrn_gradient,
555                            int roundness, uint8 corners,
556                            int x, int y, int width, int height,
557                            boolean horizontal)
558 {
559 	murrine_draw_trough (cr, c1, x, y, width, height, roundness, corners, mrn_gradient, 1.0, horizontal);
560 	murrine_draw_trough_border (cr, c2, x, y, width, height, roundness, corners, mrn_gradient, 1.0, horizontal);
561 }
562 
563 #define TROUGH_SIZE 6
564 static void
murrine_draw_scale_trough(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const SliderParameters * slider,int x,int y,int width,int height)565 murrine_draw_scale_trough (cairo_t *cr,
566                            const MurrineColors    *colors,
567                            const WidgetParameters *widget,
568                            const SliderParameters *slider,
569                            int x, int y, int width, int height)
570 {
571 	int     trough_width, trough_height;
572 	double  translate_x, translate_y;
573 
574 	cairo_save (cr);
575 
576 	if (slider->horizontal)
577 	{
578 		trough_width  = width;
579 		trough_height = TROUGH_SIZE;
580 
581 		translate_x   = x;
582 		translate_y   = y+(height/2)-(TROUGH_SIZE/2);
583 	}
584 	else
585 	{
586 		trough_width  = TROUGH_SIZE;
587 		trough_height = height;
588 
589 		translate_x   = x+(width/2)-(TROUGH_SIZE/2);
590 		translate_y   = y;
591 	}
592 
593 	cairo_translate (cr, translate_x+0.5, translate_y+0.5);
594 
595 	if (!slider->fill_level && widget->reliefstyle != 0)
596 		murrine_draw_inset (cr, &widget->parentbg, 0, 0, trough_width, trough_height, widget->roundness, widget->corners);
597 
598 	if (!slider->lower && !slider->fill_level)
599 	{
600 		MurrineRGB fill, border;
601 		murrine_shade (&colors->bg[GTK_STATE_ACTIVE], 1.0, &fill);
602 		murrine_shade (&colors->bg[GTK_STATE_ACTIVE], murrine_get_contrast(0.82, widget->contrast), &border);
603 
604 		murrine_scale_draw_trough (cr, &fill, &border, widget->mrn_gradient,
605 		                           widget->roundness, widget->corners,
606 		                           1.0, 1.0, trough_width-2, trough_height-2,
607 		                           slider->horizontal);
608 	}
609 	else
610 	{
611 		MurrineRGB fill, border;
612 		murrine_mix_color (&colors->bg[GTK_STATE_SELECTED], &widget->parentbg, widget->disabled ? 0.25 : 0.0, &fill);
613 		murrine_shade (&fill, murrine_get_contrast(0.65, widget->contrast), &border);
614 
615 		murrine_scale_draw_gradient (cr, &fill, &border,
616 		                             widget->disabled ? 1.0 : widget->lightborder_shade,
617 		                             widget->lightborderstyle,
618 		                             widget->roundness, widget->corners,
619 		                             1.0, 1.0, trough_width-2, trough_height-2,
620 		                             slider->horizontal);
621 	}
622 
623 	cairo_restore (cr);
624 }
625 
626 static void
murrine_draw_slider_path(cairo_t * cr,int x,int y,int width,int height,int roundness)627 murrine_draw_slider_path (cairo_t *cr,
628                           int x, int y, int width, int height,
629                           int roundness)
630 {
631 	int radius = MIN (roundness, MIN (width/2.0, height/2.0));
632 
633 	cairo_move_to (cr, x+radius, y);
634 	cairo_arc (cr, x+width-radius, y+radius, radius, M_PI*1.5, M_PI*2);
635 	cairo_line_to (cr, x+width, y+height-width/2.0);
636 	cairo_line_to (cr, x+width/2.0, y+height);
637 	cairo_line_to (cr, x, y+height-width/2.0);
638 	cairo_arc (cr, x+radius, y+radius, radius, M_PI, M_PI*1.5);
639 }
640 
641 static void
murrine_draw_slider(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const SliderParameters * slider,int x,int y,int width,int height)642 murrine_draw_slider (cairo_t *cr,
643                      const MurrineColors    *colors,
644                      const WidgetParameters *widget,
645                      const SliderParameters *slider,
646                      int x, int y, int width, int height)
647 {
648 	int os = (widget->xthickness > 2 && widget->ythickness > 2) ? 1 : 0;
649 	double glow_shade_new = widget->glow_shade;
650 	double highlight_shade_new = widget->highlight_shade;
651 	double lightborder_shade_new = widget->lightborder_shade;
652 	MurrineGradients mrn_gradient_new = widget->mrn_gradient;
653 	MurrineRGB border;
654 	MurrineRGB fill = colors->bg[widget->state_type];
655 
656 	murrine_get_fill_color (&fill, &mrn_gradient_new);
657 
658 	if (widget->disabled)
659 	{
660 		mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
661 		mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 2.0);
662 		mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 2.0);
663 		glow_shade_new = murrine_get_decreased_shade (widget->glow_shade, 2.0);
664 		highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
665 		lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
666 		murrine_shade (&fill, murrine_get_contrast(0.75, widget->contrast), &border);
667 	}
668 	else
669 		murrine_shade (&fill, murrine_get_contrast(0.475, widget->contrast), &border);
670 
671 	if (!slider->horizontal)
672 		murrine_exchange_axis (cr, &x, &y, &width, &height);
673 
674 	cairo_save (cr);
675 
676 	cairo_translate (cr, x+0.5, y+0.5);
677 
678 	if (!widget->active && !widget->disabled && widget->reliefstyle > 1 && os > 0)
679 	{
680 		murrine_draw_slider_path (cr, os-1, os, width-(os*2)+2, height-(os*2)+1, widget->roundness+1);
681 		if (widget->reliefstyle == 5)
682 			murrine_draw_shadow_from_path (cr, &widget->parentbg,
683 			                               os-1, os, width-(os*2)+2, height-(os*2)+1,
684 			                               widget->reliefstyle,
685 			                               mrn_gradient_new, 0.5);
686 		else
687 			murrine_draw_shadow_from_path (cr, &border,
688 			                              os-1, os, width-(os*2)+2, height-(os*2)+1,
689 			                              widget->reliefstyle,
690 			                              mrn_gradient_new, 0.08);
691 	}
692 
693 	murrine_mix_color (&border, &fill, 0.2, &border);
694 
695 	cairo_save (cr);
696 
697 	murrine_draw_slider_path (cr, os, os+1, width-(os*2), height-(os*2)-1, widget->roundness);
698 	cairo_clip_preserve (cr);
699 
700 	murrine_draw_glaze (cr, &fill,
701 	                    glow_shade_new, highlight_shade_new, !widget->active ? lightborder_shade_new : 1.0,
702 	                    mrn_gradient_new, widget,
703 	                    os, os+1, width-(os*2), height-(os*2)-1,
704 	                    widget->roundness, widget->corners, TRUE);
705 
706 	cairo_restore (cr);
707 
708 	murrine_draw_slider_path (cr, os, os+1, width-(os*2), height-(os*2)-1, widget->roundness);
709 
710 	murrine_draw_border_from_path (cr, &border,
711 	                     os, os+1, width-(os*2), height-(os*2)-1,
712 	                     mrn_gradient_new, 1.0);
713 
714 	cairo_restore (cr);
715 
716 	if (!slider->horizontal)
717 		murrine_exchange_axis (cr, &x, &y, &width, &height);
718 }
719 
720 
721 static void
murrine_draw_slider_handle(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const HandleParameters * handle,int x,int y,int width,int height,boolean horizontal)722 murrine_draw_slider_handle (cairo_t *cr,
723                             const MurrineColors    *colors,
724                             const WidgetParameters *widget,
725                             const HandleParameters *handle,
726                             int x, int y, int width, int height,
727                             boolean horizontal)
728 {
729 	int num_handles = 2, bar_x, i;
730 	MurrineRGB color, inset;
731 	murrine_shade (&colors->shade[6], 0.95, &color);
732 
733 	murrine_mix_color (&color, &colors->bg[widget->state_type], 0.4, &color);
734 
735 	if (!horizontal)
736 	{
737 		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
738 		int tmp = height; height = width; width = tmp;
739 	}
740 
741 	if (width % 2 != 0)
742 		num_handles = 3;
743 	bar_x = width/2 - num_handles;
744 
745 	cairo_translate (cr, 0.5, 0.5);
746 
747 	switch (handle->style)
748 	{
749 		default:
750 		case 0:
751 		{
752 			for (i=0; i<num_handles; i++)
753 			{
754 				cairo_move_to (cr, bar_x, 4.5);
755 				cairo_line_to (cr, bar_x, height-5.5);
756 				murrine_set_color_rgb (cr, &color);
757 				cairo_stroke (cr);
758 
759 				bar_x += 3;
760 			}
761 			break;
762 		}
763 		case 1:
764 		{
765 			murrine_shade (&colors->bg[widget->state_type], 1.08, &inset);
766 
767 			for (i=0; i<num_handles; i++)
768 			{
769 				cairo_move_to (cr, bar_x, 4.5);
770 				cairo_line_to (cr, bar_x, height-5.5);
771 				murrine_set_color_rgb (cr, &color);
772 				cairo_stroke (cr);
773 
774 				cairo_move_to (cr, bar_x+1, 4.5);
775 				cairo_line_to (cr, bar_x+1, height-5.5);
776 				murrine_set_color_rgb (cr, &inset);
777 				cairo_stroke (cr);
778 
779 				bar_x += 3;
780 			}
781 			break;
782 		}
783 		case 2:
784 		{
785 			murrine_shade (&colors->bg[widget->state_type], 1.04, &inset);
786 
787 			bar_x++;
788 
789 			for (i=0; i<num_handles; i++)
790 			{
791 				cairo_move_to (cr, bar_x, 4.5);
792 				cairo_line_to (cr, bar_x, height-5.5);
793 				murrine_set_color_rgb (cr, &color);
794 				cairo_stroke (cr);
795 
796 				cairo_move_to (cr, bar_x+1, 4.5);
797 				cairo_line_to (cr, bar_x+1, height-5.5);
798 				murrine_set_color_rgb (cr, &inset);
799 				cairo_stroke (cr);
800 
801 				bar_x += 2;
802 			}
803 			break;
804 		}
805 	}
806 }
807 
808 static void
murrine_draw_progressbar_trough(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ProgressBarParameters * progressbar,int x,int y,int width,int height)809 murrine_draw_progressbar_trough (cairo_t *cr,
810                                  const MurrineColors    *colors,
811                                  const WidgetParameters *widget,
812                                  const ProgressBarParameters *progressbar,
813                                  int x, int y, int width, int height)
814 {
815 	MurrineRGB border, fill;
816 	int roundness = MIN (widget->roundness, MIN ((height-2.0)/2.0, (width-2.0)/2.0));
817 	boolean horizontal = progressbar->orientation < 2;
818 
819 	murrine_shade (&colors->bg[GTK_STATE_ACTIVE], 1.0, &fill);
820 	murrine_shade (&colors->bg[GTK_STATE_ACTIVE], murrine_get_contrast(0.82, widget->contrast), &border);
821 
822 	/* Create trough box */
823 	murrine_draw_trough (cr, &fill, x+1, y+1, width-2, height-2, roundness-1, widget->corners, widget->mrn_gradient, 1.0, horizontal);
824 
825 	/* Draw border */
826 	murrine_draw_trough_border (cr, &border, x+0.5, y+0.5, width-1, height-1, roundness, widget->corners, widget->mrn_gradient, 1.0, horizontal);
827 
828 	if (widget->mrn_gradient.gradients &&
829 	    widget->mrn_gradient.trough_shades[0] == 1.0 &&
830 	    widget->mrn_gradient.trough_shades[1] == 1.0)
831 	{
832 		cairo_pattern_t  *pat;
833 		MurrineRGB        shadow;
834 
835 		murrine_shade (&border, 0.94, &shadow);
836 
837 		/* clip the corners of the shadows */
838 		murrine_rounded_rectangle_closed (cr, x+1, y+1, width-2, height-2, roundness, widget->corners);
839 		cairo_clip (cr);
840 
841 		/* Top shadow */
842 		cairo_rectangle (cr, x+1, y+1, width-2, 4);
843 		pat = cairo_pattern_create_linear (x, y, x, y+4);
844 		murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow, 0.24);
845 		murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.);
846 		cairo_set_source (cr, pat);
847 		cairo_fill (cr);
848 		cairo_pattern_destroy (pat);
849 
850 		/* Left shadow */
851 		cairo_rectangle (cr, x+1, y+1, 4, height-2);
852 		pat = cairo_pattern_create_linear (x, y, x+4, y);
853 		murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow, 0.24);
854 		murrine_pattern_add_color_stop_rgba (pat, 1.0, &shadow, 0.);
855 		cairo_set_source (cr, pat);
856 		cairo_fill (cr);
857 		cairo_pattern_destroy (pat);
858 	}
859 }
860 
861 static void
murrine_draw_progressbar_fill(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ProgressBarParameters * progressbar,int x,int y,int width,int height,gint offset)862 murrine_draw_progressbar_fill (cairo_t *cr,
863                                const MurrineColors         *colors,
864                                const WidgetParameters      *widget,
865                                const ProgressBarParameters *progressbar,
866                                int x, int y, int width, int height,
867                                gint offset)
868 {
869 	double     tile_pos = 0;
870 	double     stroke_width;
871 	int        x_step;
872 	int        roundness;
873 	MurrineRGB border = colors->spot[2];
874 	MurrineRGB effect;
875 	MurrineRGB fill = colors->spot[1];
876 
877 	murrine_get_fill_color (&fill, &widget->mrn_gradient);
878 	murrine_shade (&fill, murrine_get_contrast(0.65, widget->contrast), &effect);
879 
880 	/* progressbar->orientation < 2 == boolean is_horizontal */
881 	if (progressbar->orientation < 2)
882 	{
883 		if (progressbar->orientation == MRN_ORIENTATION_LEFT_TO_RIGHT)
884 			rotate_mirror_translate (cr, 0, x, y, FALSE, FALSE);
885 		else
886 			rotate_mirror_translate (cr, 0, x+width, y, TRUE, FALSE);
887 	}
888 	else
889 	{
890 		int tmp = height; height = width; width = tmp;
891 
892 		x = x+1; y = y-1; width = width+2; height = height-2;
893 
894 		if (progressbar->orientation == MRN_ORIENTATION_TOP_TO_BOTTOM)
895 			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
896 		else
897 			rotate_mirror_translate (cr, M_PI/2, x, y+width, TRUE, FALSE);
898 	}
899 
900 	roundness = MIN (widget->roundness-widget->xthickness, height/2.0);
901 	int yos = 0;
902 	if ((2*roundness > width) && roundness > 0)
903 	{
904 		int h = height*sin((M_PI*(width))/(4*roundness));
905 		roundness = round(width/2.0);
906 		yos = 0.5+(height-h)/2.0;
907 		height = h;
908 	}
909 	stroke_width = height*2;
910 	x_step = (((float)stroke_width/10)*offset);
911 
912 	cairo_save (cr);
913 
914 	murrine_rounded_rectangle_closed (cr, 2, 1+yos, width-4, height-2, roundness-1, widget->corners);
915 	cairo_clip (cr);
916 
917 	cairo_rectangle (cr, 2, 1+yos, width-4, height-2);
918 
919 	murrine_draw_glaze (cr, &fill,
920 	                    widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
921 	                    widget->mrn_gradient, widget, 2, 1+yos, width-4, height-2,
922 	                    roundness, widget->corners, TRUE);
923 
924 	switch (progressbar->style)
925 	{
926 		case 0:
927 			break;
928 		default:
929 		case 1:
930 		{
931 			/* Draw strokes */
932 			while (stroke_width > 0 && tile_pos <= width+x_step)
933 			{
934 				cairo_move_to (cr, stroke_width/2-x_step, 0);
935 				cairo_line_to (cr, stroke_width-x_step, 0);
936 				cairo_line_to (cr, stroke_width/2-x_step, height);
937 				cairo_line_to (cr, -x_step, height);
938 
939 				cairo_translate (cr, stroke_width, 0);
940 				tile_pos += stroke_width;
941 			}
942 
943 			murrine_set_color_rgba (cr, &effect, 0.15);
944 			cairo_fill (cr);
945 			break;
946 		}
947 		case 2:
948 		{
949 			MurrineRGB highlight;
950 			int step = 18;
951 			int i;
952 
953 			murrine_shade (&fill, widget->lightborder_shade*widget->highlight_shade, &highlight);
954 
955 			for (i=step; i<width-3; i+=step)
956 			{
957 				cairo_move_to (cr, i-0.5, 1);
958 				cairo_line_to (cr, i-0.5, height-1);
959 				murrine_set_color_rgba (cr, &highlight, 0.5);
960 				cairo_stroke (cr);
961 
962 				cairo_move_to (cr, i+0.5, 1);
963 				cairo_line_to (cr, i+0.5, height-1);
964 				murrine_set_color_rgba (cr, &effect, 0.25);
965 				cairo_stroke (cr);
966 			}
967 			break;
968 		}
969 	}
970 
971 	cairo_restore (cr);
972 
973 	cairo_save (cr);
974 
975 	murrine_rounded_rectangle_closed (cr, 0.5, -0.5+yos, width-1, height+1, roundness-1, widget->corners);
976 	cairo_clip (cr);
977 
978 	/* Draw border */
979 	murrine_mix_color (&border, &fill, 0.28, &border);
980 	murrine_draw_border (cr, &border,
981 	                     1.5, 0.5+yos, width-3, height-1,
982 	                     roundness, widget->corners,
983 	                     widget->mrn_gradient, 1.0);
984 
985 	cairo_restore (cr);
986 }
987 
988 static void
murrine_draw_combobox(cairo_t * cr,MurrineColors colors,WidgetParameters widget,const ComboBoxParameters * combobox,int x,int y,int w,int h,boolean horizontal)989 murrine_draw_combobox (cairo_t *cr,
990                        MurrineColors  colors,
991                        WidgetParameters  widget,
992                        const ComboBoxParameters *combobox,
993                        int x, int y, int w, int h, boolean horizontal)
994 {
995 	switch (combobox->style)
996 	{
997 		default:
998 		case 0:
999 		{
1000 			ButtonParameters button;
1001 			button.has_default_button_color = FALSE;
1002 
1003 			widget.style_functions->draw_button (cr, &colors, &widget, &button, x, y, w, h, horizontal);
1004 			break;
1005 		}
1006 		case 1:
1007 		{
1008 			WidgetParameters params = widget;
1009 			MurrineColors colors_new = colors;
1010 			ButtonParameters button;
1011 			button.has_default_button_color = FALSE;
1012 			int box_w = (widget.xthickness > 2 && widget.ythickness > 2) ? combobox->box_w : combobox->box_w-3;
1013 			int os = (widget.xthickness > 2 && widget.ythickness > 2) ? 1 : 0;
1014 			colors_new.bg[GTK_STATE_NORMAL] = colors.spot[1];
1015 			murrine_shade (&colors_new.bg[GTK_STATE_NORMAL], combobox->prelight_shade,
1016 			               &colors_new.bg[GTK_STATE_PRELIGHT]);
1017 
1018 			if (combobox->as_list)
1019 			{
1020 				params.style_functions->draw_button (cr, &colors_new, &params, &button, x, y, w, h, horizontal);
1021 				break;
1022 			}
1023 
1024 			cairo_save (cr);
1025 			if (params.ltr)
1026 			{
1027 				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
1028 				cairo_rectangle (cr, x, y, w-box_w, h);
1029 				cairo_clip (cr);
1030 				params.style_functions->draw_button (cr, &colors, &params, &button, x, y, w-box_w+1+os, h, horizontal);
1031 			}
1032 			else
1033 			{
1034 				params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
1035 				cairo_rectangle (cr, x+box_w, y, w-box_w, h);
1036 				cairo_clip (cr);
1037 				params.style_functions->draw_button (cr, &colors, &params, &button, x+box_w-1-os, y, w-box_w+1+os, h, horizontal);
1038 			}
1039 			cairo_restore (cr);
1040 
1041 			params.mrn_gradient.has_border_colors = FALSE;
1042 			params.mrn_gradient.has_gradient_colors = FALSE;
1043 
1044 			cairo_save (cr);
1045 			if (params.ltr)
1046 			{
1047 				params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
1048 				cairo_rectangle (cr, x+w-box_w, y, box_w, h);
1049 				cairo_clip (cr);
1050 				params.style_functions->draw_button (cr, &colors_new, &params, &button, x+w-(box_w+os), y, box_w+os, h, horizontal);
1051 			}
1052 			else
1053 			{
1054 				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
1055 				cairo_rectangle (cr, x, y, box_w, h);
1056 				cairo_clip (cr);
1057 				params.style_functions->draw_button (cr, &colors_new, &params, &button, x, y, box_w+os, h, horizontal);
1058 			}
1059 			cairo_restore (cr);
1060 			break;
1061 		}
1062 	}
1063 }
1064 
1065 static void
murrine_draw_optionmenu(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const OptionMenuParameters * optionmenu,int x,int y,int width,int height)1066 murrine_draw_optionmenu (cairo_t *cr,
1067                          const MurrineColors        *colors,
1068                          const WidgetParameters     *widget,
1069                          const OptionMenuParameters *optionmenu,
1070                          int x, int y, int width, int height)
1071 {
1072 	ButtonParameters button;
1073 	button.has_default_button_color = FALSE;
1074 	int offset = widget->ythickness + 1;
1075 
1076 	boolean horizontal = TRUE;
1077 	if (((float)width/height<0.5) || (widget->glazestyle > 0 && width<height))
1078 		horizontal = FALSE;
1079 
1080 	widget->style_functions->draw_button (cr, colors, widget, &button, x, y, width, height, horizontal);
1081 
1082 	/* Draw the separator */
1083 	MurrineRGB *dark = (MurrineRGB*)&colors->shade[6];
1084 
1085 	cairo_translate        (cr, optionmenu->linepos+0.5, 1);
1086 
1087 	murrine_set_color_rgba (cr, dark, 0.4);
1088 	cairo_move_to          (cr, 0.0, offset);
1089 	cairo_line_to          (cr, 0.0, height - offset - widget->ythickness + 1);
1090 	cairo_stroke           (cr);
1091 }
1092 
1093 static void
murrine_draw_menubar(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height,int menubarstyle)1094 murrine_draw_menubar (cairo_t *cr,
1095                       const MurrineColors *colors,
1096                       const WidgetParameters *widget,
1097                       int x, int y, int width, int height,
1098                       int menubarstyle)
1099 {
1100 	const MurrineRGB *fill = &colors->bg[0];
1101 	MurrineRGB dark = colors->shade[3];
1102 
1103 	if(widget->mrn_gradient.has_border_colors)
1104 		dark = widget->mrn_gradient.border_colors[1];
1105 
1106 	cairo_translate (cr, x, y);
1107 	cairo_rectangle (cr, 0, 0, width, height);
1108 
1109 	switch (menubarstyle)
1110 	{
1111 		default:
1112 		case 0:
1113 			murrine_set_color_rgb (cr, fill);
1114 			cairo_fill (cr);
1115 			break;
1116 		case 1:
1117 		{
1118 			int os = (widget->glazestyle == 2) ? 1 : 0;
1119 			murrine_draw_glaze (cr, fill,
1120 			                    widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
1121 			                    widget->mrn_gradient, widget, os, os, width-os*2, height-os*2,
1122 			                    widget->roundness, widget->corners, TRUE);
1123 			break;
1124 		}
1125 		case 2:
1126 		{
1127 			cairo_pattern_t *pat;
1128 			double alpha = !widget->mrn_gradient.use_rgba ? 1.0 : 0.7;
1129 			MurrineRGB lower;
1130 			murrine_shade (fill, 0.95, &lower);
1131 
1132 			pat = cairo_pattern_create_linear (0, 0, 0, height);
1133 			murrine_pattern_add_color_stop_rgba (pat, 0.0, fill, alpha);
1134 			murrine_pattern_add_color_stop_rgba (pat, 1.0, &lower, alpha);
1135 			cairo_set_source (cr, pat);
1136 			cairo_fill (cr);
1137 			cairo_pattern_destroy (pat);
1138 			break;
1139 		}
1140 		case 3:
1141 		{
1142 			cairo_pattern_t *pat;
1143 			int counter = -height;
1144 			MurrineRGB low, top;
1145 			murrine_shade (fill, 0.9, &top);
1146 			murrine_shade (fill, 1.1, &low);
1147 
1148 			pat = cairo_pattern_create_linear (0, 0, 0, height);
1149 			murrine_pattern_add_color_stop_rgb (pat, 0.0, &top);
1150 			murrine_pattern_add_color_stop_rgb (pat, 1.0, &low);
1151 			cairo_set_source (cr, pat);
1152 			cairo_fill (cr);
1153 			cairo_pattern_destroy (pat);
1154 
1155 			murrine_shade (&low, 0.9, &low);
1156 			murrine_set_color_rgb (cr, &low);
1157 			while (counter < width)
1158 			{
1159 				cairo_move_to (cr, counter, height);
1160 				cairo_line_to (cr, counter+height, 0);
1161 				cairo_stroke  (cr);
1162 				counter += 5;
1163 			}
1164 			break;
1165 		}
1166 	}
1167 
1168 	/* Draw bottom line */
1169 	if (menubarstyle == 1 && widget->glazestyle == 2)
1170 		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
1171 	else
1172 	{
1173 		cairo_move_to        (cr, 0, height-0.5);
1174 		cairo_line_to        (cr, width, height-0.5);
1175 	}
1176 	murrine_set_color_rgb (cr, &dark);
1177 	cairo_stroke          (cr);
1178 }
1179 
1180 /* We can't draw transparent things here, since it will be called on the same
1181  * surface multiple times, when placed on a handlebox_bin or dockitem_bin */
1182 static void
murrine_draw_toolbar(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ToolbarParameters * toolbar,int x,int y,int width,int height)1183 murrine_draw_toolbar (cairo_t *cr,
1184                       const MurrineColors    *colors,
1185                       const WidgetParameters *widget,
1186                       const ToolbarParameters *toolbar,
1187                       int x, int y, int width, int height)
1188 {
1189 	const MurrineRGB *fill = &colors->bg[0];
1190 	const MurrineRGB *top  = &colors->shade[0];
1191 	MurrineRGB dark = colors->shade[3];
1192 
1193 	if(widget->mrn_gradient.has_border_colors)
1194 		dark = widget->mrn_gradient.border_colors[1];
1195 
1196 	cairo_translate      (cr, x, y);
1197 	cairo_rectangle (cr, 0, 0, width, height);
1198 
1199 	/* Glass toolbar */
1200 	switch (toolbar->style)
1201 	{
1202 		default:
1203 		case 0:
1204 			murrine_set_color_rgb (cr, fill);
1205 			cairo_fill (cr);
1206 
1207 			/* Draw highlight */
1208 			if (!toolbar->topmost)
1209 			{
1210 				cairo_move_to         (cr, 0, 0.5);
1211 				cairo_line_to         (cr, width, 0.5);
1212 				murrine_set_color_rgb (cr, top);
1213 				cairo_stroke          (cr);
1214 			}
1215 			break;
1216 		case 1:
1217 		{
1218 			int os = (widget->glazestyle == 2) ? 1 : 0;
1219 			murrine_draw_glaze (cr, fill,
1220 			                    widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
1221 			                    widget->mrn_gradient, widget, os, os, width-os*2, height-os*2,
1222 			                    widget->roundness, widget->corners, TRUE);
1223 			break;
1224 		}
1225 		case 2:
1226 		{
1227 			cairo_pattern_t *pat;
1228 			MurrineRGB lower;
1229 			murrine_shade (fill, 0.95, &lower);
1230 			pat = cairo_pattern_create_linear (0, 0, 0, height);
1231 			murrine_pattern_add_color_stop_rgb (pat, 0.0, fill);
1232 			murrine_pattern_add_color_stop_rgb (pat, 1.0, &lower);
1233 			cairo_set_source (cr, pat);
1234 			cairo_pattern_destroy (pat);
1235 			cairo_fill (cr);
1236 
1237 			/* Draw highlight */
1238 			if (!toolbar->topmost)
1239 			{
1240 				cairo_move_to         (cr, 0, 0.5);
1241 				cairo_line_to         (cr, width, 0.5);
1242 				murrine_set_color_rgb (cr, top);
1243 				cairo_stroke          (cr);
1244 			}
1245 			break;
1246 		}
1247 	}
1248 
1249 	/* Draw shadow */
1250 	murrine_set_color_rgb (cr, &dark);
1251 	if (toolbar->style == 1 && widget->glazestyle == 2)
1252 		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
1253 	else
1254 	{
1255 		cairo_move_to         (cr, 0, height-0.5);
1256 		cairo_line_to         (cr, width, height-0.5);
1257 	}
1258 	cairo_stroke (cr);
1259 }
1260 
1261 static void
murrine_get_frame_gap_clip(int x,int y,int width,int height,const FrameParameters * frame,MurrineRectangle * bevel,MurrineRectangle * border)1262 murrine_get_frame_gap_clip (int x, int y, int width, int height,
1263                             const FrameParameters *frame,
1264                             MurrineRectangle      *bevel,
1265                             MurrineRectangle      *border)
1266 {
1267 	switch (frame->gap_side)
1268 	{
1269 		case MRN_GAP_TOP:
1270 			MURRINE_RECTANGLE_SET ((*bevel),  1.5+frame->gap_x, -0.5,
1271 			                       frame->gap_width-3, 2.0);
1272 			MURRINE_RECTANGLE_SET ((*border), 0.5+frame->gap_x, -0.5,
1273 			                       frame->gap_width-2, 2.0);
1274 			break;
1275 		case MRN_GAP_BOTTOM:
1276 			MURRINE_RECTANGLE_SET ((*bevel),  1.5+frame->gap_x, height-2.5,
1277 			                       frame->gap_width-3, 2.0);
1278 			MURRINE_RECTANGLE_SET ((*border), 0.5+frame->gap_x, height-1.5,
1279 			                       frame->gap_width-2, 2.0);
1280 			break;
1281 		case MRN_GAP_LEFT:
1282 			MURRINE_RECTANGLE_SET ((*bevel),  -0.5, 1.5+frame->gap_x,
1283 			                       2.0, frame->gap_width-3);
1284 			MURRINE_RECTANGLE_SET ((*border), -0.5, 0.5+frame->gap_x,
1285 			                       1.0, frame->gap_width-2);
1286 			break;
1287 		case MRN_GAP_RIGHT:
1288 			MURRINE_RECTANGLE_SET ((*bevel),  width-2.5, 1.5+frame->gap_x,
1289 			                       2.0, frame->gap_width-3);
1290 			MURRINE_RECTANGLE_SET ((*border), width-1.5, 0.5+frame->gap_x,
1291 			                       1.0, frame->gap_width-2);
1292 			break;
1293 	}
1294 }
1295 
1296 static void
murrine_draw_frame(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FrameParameters * frame,int x,int y,int width,int height)1297 murrine_draw_frame (cairo_t *cr,
1298                     const MurrineColors    *colors,
1299                     const WidgetParameters *widget,
1300                     const FrameParameters  *frame,
1301                     int x, int y, int width, int height)
1302 {
1303 	MurrineRGB *border = frame->border;
1304 	MurrineRectangle bevel_clip;
1305 	MurrineRectangle frame_clip;
1306 	const MurrineRGB *dark = &colors->shade[3];
1307 	MurrineRGB highlight, shadow_color;
1308 
1309 	murrine_shade (&colors->bg[0], 1.04, &highlight);
1310 	murrine_shade (&colors->bg[0], 0.96, &shadow_color);
1311 
1312 	if (frame->shadow == MRN_SHADOW_NONE)
1313 		return;
1314 
1315 	if (frame->gap_x != -1)
1316 		murrine_get_frame_gap_clip (x, y, width, height,
1317 		                            frame, &bevel_clip, &frame_clip);
1318 
1319 	cairo_translate      (cr, x+0.5, y+0.5);
1320 
1321 	/* save everything */
1322 	cairo_save (cr);
1323 
1324 	/* Set clip for the bevel */
1325 	if (frame->gap_x != -1)
1326 	{
1327 		/* Set clip for gap */
1328 		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
1329 		cairo_rectangle     (cr, -0.5, -0.5, width, height);
1330 		cairo_rectangle     (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
1331 		cairo_clip          (cr);
1332 	}
1333 
1334 	/* Draw the bevel */
1335 	if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
1336 	{
1337 		murrine_set_color_rgb (cr, &highlight);
1338 		if (frame->shadow == MRN_SHADOW_ETCHED_IN)
1339 			murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
1340 		else
1341 			murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
1342 		cairo_stroke (cr);
1343 	}
1344 	else if (frame->shadow != MRN_SHADOW_FLAT)
1345 	{
1346 		ShadowParameters shadow;
1347 		shadow.corners = widget->corners;
1348 		shadow.shadow  = frame->shadow;
1349 		murrine_draw_highlight_and_shade (cr, colors, &shadow, width, height, widget->roundness-1);
1350 	}
1351 
1352 	/* restore the previous clip region */
1353 	cairo_restore (cr);
1354 	cairo_save    (cr);
1355 	if (frame->gap_x != -1)
1356 	{
1357 		/* Set clip for gap */
1358 		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
1359 		cairo_rectangle     (cr, -0.5, -0.5, width, height);
1360 		cairo_rectangle     (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
1361 		cairo_clip          (cr);
1362 	}
1363 
1364 	/* Draw frame */
1365 	if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
1366 	{
1367 		murrine_set_color_rgb (cr, dark);
1368 		if (frame->shadow == MRN_SHADOW_ETCHED_IN)
1369 			murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
1370 		else
1371 			murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
1372 	}
1373 	else
1374 	{
1375 		murrine_set_color_rgb (cr, border);
1376 		murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1377 	}
1378 	cairo_stroke  (cr);
1379 	cairo_restore (cr);
1380 }
1381 
1382 static void
murrine_draw_tab(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const TabParameters * tab,int x,int y,int width,int height)1383 murrine_draw_tab (cairo_t *cr,
1384                   const MurrineColors    *colors,
1385                   const WidgetParameters *widget,
1386                   const TabParameters    *tab,
1387                   int x, int y, int width, int height)
1388 {
1389 	const MurrineRGB *stripe_fill = &colors->spot[1];
1390 	const MurrineRGB *stripe_border = &colors->spot[2];
1391 	const MurrineRGB *fill = &colors->bg[widget->state_type];
1392 	const MurrineRGB *border = &colors->shade[!widget->active ? 5 : 4];
1393 	cairo_pattern_t  *pat;
1394 
1395 	/* Set clip */
1396 	cairo_rectangle (cr, x, y, width, height);
1397 	cairo_clip      (cr);
1398 	cairo_new_path  (cr);
1399 
1400 	cairo_translate      (cr, x+0.5, y+0.5);
1401 
1402 	/* Make the tabs slightly bigger than they should be, to create a gap */
1403 	/* And calculate the strip size too, while you're at it */
1404 	if (tab->gap_side == MRN_GAP_TOP || tab->gap_side == MRN_GAP_BOTTOM)
1405 	{
1406 		height += 3.0;
1407 
1408 		if (tab->gap_side == MRN_GAP_TOP)
1409 			cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
1410 	}
1411 	else
1412 	{
1413 		width += 3.0;
1414 
1415 		if (tab->gap_side == MRN_GAP_LEFT)
1416 			cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
1417 	}
1418 
1419 	/* Set tab shape */
1420 	murrine_rounded_rectangle_closed (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1421 
1422 	/* Draw fill */
1423 	murrine_set_color_rgb (cr, fill);
1424 	cairo_fill (cr);
1425 
1426 	if (widget->active)
1427 	{
1428 		MurrineRGB shade1, shade2, shade3, shade4, highlight;
1429 		MurrineGradients mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
1430 		double highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
1431 		double lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
1432 
1433 		murrine_shade (fill, mrn_gradient_new.gradient_shades[0]*highlight_shade_new, &shade1);
1434 		murrine_shade (fill, mrn_gradient_new.gradient_shades[1]*highlight_shade_new, &shade2);
1435 		murrine_shade (fill, mrn_gradient_new.gradient_shades[2], &shade3);
1436 		murrine_shade (fill, mrn_gradient_new.gradient_shades[3], &shade4);
1437 
1438 		switch (tab->gap_side)
1439 		{
1440 			case MRN_GAP_TOP:
1441 				pat = cairo_pattern_create_linear (0, height-2, 0, 0);
1442 				break;
1443 			case MRN_GAP_BOTTOM:
1444 				pat = cairo_pattern_create_linear (0, 1, 0, height);
1445 				break;
1446 			case MRN_GAP_LEFT:
1447 				pat = cairo_pattern_create_linear (width-2, 0, 1, 0);
1448 				break;
1449 			case MRN_GAP_RIGHT:
1450 				pat = cairo_pattern_create_linear (1, 0, width-2, 0);
1451 				break;
1452 		}
1453 
1454 		murrine_rounded_rectangle_closed (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1455 
1456 		murrine_pattern_add_color_stop_rgb (pat, 0.00, &shade1);
1457 		murrine_pattern_add_color_stop_rgb (pat, 0.45, &shade2);
1458 		murrine_pattern_add_color_stop_rgb (pat, 0.45, &shade3);
1459 		murrine_pattern_add_color_stop_rgb (pat, 1.00, &shade4);
1460 		cairo_set_source (cr, pat);
1461 		cairo_fill (cr);
1462 		cairo_pattern_destroy (pat);
1463 
1464 		/* Draw lightborder */
1465 		murrine_shade (fill, lightborder_shade_new*highlight_shade_new, &highlight);
1466 		murrine_shade (&highlight, mrn_gradient_new.gradient_shades[0]*highlight_shade_new, &shade1);
1467 		murrine_shade (&highlight, mrn_gradient_new.gradient_shades[1]*highlight_shade_new, &shade2);
1468 		murrine_shade (&highlight, mrn_gradient_new.gradient_shades[2], &shade3);
1469 		murrine_shade (&highlight, mrn_gradient_new.gradient_shades[3], &shade4);
1470 
1471 		switch (tab->gap_side)
1472 		{
1473 			case MRN_GAP_TOP:
1474 				pat = cairo_pattern_create_linear (0, height-2, 0, 0);
1475 				break;
1476 			case MRN_GAP_BOTTOM:
1477 				pat = cairo_pattern_create_linear (0, 1, 0, height);
1478 				break;
1479 			case MRN_GAP_LEFT:
1480 				pat = cairo_pattern_create_linear (width-2, 0, 1, 0);
1481 				break;
1482 			case MRN_GAP_RIGHT:
1483 				pat = cairo_pattern_create_linear (1, 0, width-2, 0);
1484 				break;
1485 		}
1486 
1487 		murrine_rounded_rectangle_closed (cr, 1, 1, width-3, height-3, widget->roundness, widget->corners);
1488 
1489 		murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, 0.5);
1490 		murrine_pattern_add_color_stop_rgba (pat, 0.45, &shade2, 0.5);
1491 		murrine_pattern_add_color_stop_rgba (pat, 0.45, &shade3, 0.5);
1492 		murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade4, 0.5);
1493 		cairo_set_source (cr, pat);
1494 		cairo_stroke (cr);
1495 		cairo_pattern_destroy (pat);
1496 	}
1497 	else
1498 	{
1499 		MurrineRGB shade1, shade2, shade3, shade4, highlight;
1500 		MurrineGradients mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
1501 		double highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
1502 
1503 		murrine_shade (fill, mrn_gradient_new.gradient_shades[0]*highlight_shade_new, &shade1);
1504 		murrine_shade (fill, mrn_gradient_new.gradient_shades[1]*highlight_shade_new, &shade2);
1505 		murrine_shade (fill, mrn_gradient_new.gradient_shades[2], &shade3);
1506 		murrine_shade (fill, 1.0, &shade4);
1507 
1508 		/* Draw shade */
1509 		switch (tab->gap_side)
1510 		{
1511 			case MRN_GAP_TOP:
1512 				pat = cairo_pattern_create_linear (0, height-2, 0, 0);
1513 				break;
1514 			case MRN_GAP_BOTTOM:
1515 				pat = cairo_pattern_create_linear (0, 0, 0, height);
1516 				break;
1517 			case MRN_GAP_LEFT:
1518 				pat = cairo_pattern_create_linear (width-2, 0, 0, 0);
1519 				break;
1520 			case MRN_GAP_RIGHT:
1521 				pat = cairo_pattern_create_linear (0, 0, width, 0);
1522 				break;
1523 		}
1524 
1525 		murrine_rounded_rectangle_closed (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1526 
1527 		murrine_pattern_add_color_stop_rgb (pat, 0.00, &shade1);
1528 		murrine_pattern_add_color_stop_rgb (pat, 0.45, &shade2);
1529 		murrine_pattern_add_color_stop_rgb (pat, 0.45, &shade3);
1530 		murrine_pattern_add_color_stop_rgb (pat, 1.00, &shade4);
1531 		cairo_set_source (cr, pat);
1532 		cairo_fill (cr);
1533 		cairo_pattern_destroy (pat);
1534 
1535 		/* Draw lightborder */
1536 		murrine_shade (fill, widget->lightborder_shade*highlight_shade_new, &highlight);
1537 		murrine_shade (&highlight, mrn_gradient_new.gradient_shades[0]*highlight_shade_new, &shade1);
1538 		murrine_shade (&highlight, mrn_gradient_new.gradient_shades[1]*highlight_shade_new, &shade2);
1539 		murrine_shade (&highlight, mrn_gradient_new.gradient_shades[2], &shade3);
1540 		murrine_shade (fill, 1.04, &shade4); /* this value should change as draw_frame */
1541 
1542 		switch (tab->gap_side)
1543 		{
1544 			case MRN_GAP_TOP:
1545 				pat = cairo_pattern_create_linear (0, height-2, 0, 0);
1546 				break;
1547 			case MRN_GAP_BOTTOM:
1548 				pat = cairo_pattern_create_linear (0, 0, 0, height);
1549 				break;
1550 			case MRN_GAP_LEFT:
1551 				pat = cairo_pattern_create_linear (width-2, 0, 0, 0);
1552 				break;
1553 			case MRN_GAP_RIGHT:
1554 				pat = cairo_pattern_create_linear (0, 0, width, 0);
1555 				break;
1556 		}
1557 
1558 		murrine_rounded_rectangle_closed (cr, 1, 1, width-3, height-3, widget->roundness, widget->corners);
1559 
1560 		murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, 0.5);
1561 		murrine_pattern_add_color_stop_rgba (pat, 0.45, &shade2, 0.5);
1562 		murrine_pattern_add_color_stop_rgba (pat, 0.45, &shade3, 0.5);
1563 		murrine_pattern_add_color_stop_rgb  (pat, 1.00, &shade4);
1564 		cairo_set_source (cr, pat);
1565 		cairo_stroke (cr);
1566 		cairo_pattern_destroy (pat);
1567 	}
1568 
1569 	murrine_set_color_rgb (cr, border);
1570 	murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
1571 	cairo_stroke (cr);
1572 }
1573 
1574 static void
murrine_draw_separator(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const SeparatorParameters * separator,int x,int y,int width,int height)1575 murrine_draw_separator (cairo_t *cr,
1576                         const MurrineColors       *colors,
1577                         const WidgetParameters    *widget,
1578                         const SeparatorParameters *separator,
1579                         int x, int y, int width, int height)
1580 {
1581 	MurrineRGB dark, highlight;
1582 	murrine_shade (&colors->bg[0], murrine_get_contrast(0.7, widget->contrast), &dark);
1583 	murrine_shade (&colors->bg[0], murrine_get_contrast(1.3, widget->contrast), &highlight);
1584 
1585 	if (separator->horizontal)
1586 	{
1587 		cairo_translate (cr, x, y+0.5);
1588 
1589 		switch (separator->style)
1590 		{
1591 			default:
1592 			case 0:
1593 				murrine_set_color_rgba (cr, &dark, 0.5);
1594 				break;
1595 			case 1:
1596 			{
1597 				cairo_pattern_t *pat;
1598 				pat = cairo_pattern_create_linear (0, 0, width, 0);
1599 				murrine_pattern_add_color_stop_rgba (pat, 0.00, &dark, 0.0);
1600 				murrine_pattern_add_color_stop_rgba (pat, 0.25, &dark, 0.5);
1601 				murrine_pattern_add_color_stop_rgba (pat, 0.75, &dark, 0.5);
1602 				murrine_pattern_add_color_stop_rgba (pat, 1.00, &dark, 0.0);
1603 				cairo_set_source (cr, pat);
1604 				cairo_pattern_destroy (pat);
1605 				break;
1606 			}
1607 		}
1608 
1609 		cairo_move_to (cr, 0.0,     0.0);
1610 		cairo_line_to (cr, width+1, 0.0);
1611 		cairo_stroke  (cr);
1612 
1613 		switch (separator->style)
1614 		{
1615 			default:
1616 			case 0:
1617 				murrine_set_color_rgba (cr, &highlight, 0.5);
1618 				break;
1619 			case 1:
1620 			{
1621 				cairo_pattern_t *pat;
1622 				pat = cairo_pattern_create_linear (0, 0, width, 0);
1623 				murrine_pattern_add_color_stop_rgba (pat, 0.00, &highlight, 0.0);
1624 				murrine_pattern_add_color_stop_rgba (pat, 0.25, &highlight, 0.5);
1625 				murrine_pattern_add_color_stop_rgba (pat, 0.75, &highlight, 0.5);
1626 				murrine_pattern_add_color_stop_rgba (pat, 1.00, &highlight, 0.0);
1627 				cairo_set_source (cr, pat);
1628 				cairo_pattern_destroy (pat);
1629 				break;
1630 			}
1631 			case 3:
1632 				return;
1633 				break;
1634 		}
1635 
1636 		cairo_move_to (cr, 0.0,   1.0);
1637 		cairo_line_to (cr, width, 1.0);
1638 		cairo_stroke  (cr);
1639 	}
1640 	else
1641 	{
1642 		cairo_translate (cr, x+0.5, y);
1643 
1644 		switch (separator->style)
1645 		{
1646 			default:
1647 			case 0:
1648 				murrine_set_color_rgba (cr, &dark, 0.5);
1649 				break;
1650 			case 1:
1651 			{
1652 				cairo_pattern_t *pat;
1653 				pat = cairo_pattern_create_linear (0, 0, 0, height);
1654 				murrine_pattern_add_color_stop_rgba (pat, 0.00, &dark, 0.0);
1655 				murrine_pattern_add_color_stop_rgba (pat, 0.25, &dark, 0.5);
1656 				murrine_pattern_add_color_stop_rgba (pat, 0.75, &dark, 0.5);
1657 				murrine_pattern_add_color_stop_rgba (pat, 1.00, &dark, 0.0);
1658 				cairo_set_source (cr, pat);
1659 				cairo_pattern_destroy (pat);
1660 				break;
1661 			}
1662 		}
1663 		cairo_move_to (cr, 0.0, 0.0);
1664 		cairo_line_to (cr, 0.0, height);
1665 		cairo_stroke  (cr);
1666 
1667 		switch (separator->style)
1668 		{
1669 			default:
1670 			case 0:
1671 				murrine_set_color_rgba (cr, &highlight, 0.5);
1672 				break;
1673 			case 1:
1674 			{
1675 				cairo_pattern_t *pat;
1676 				pat = cairo_pattern_create_linear (0, 0, 0, height);
1677 				murrine_pattern_add_color_stop_rgba (pat, 0.00, &highlight, 0.0);
1678 				murrine_pattern_add_color_stop_rgba (pat, 0.25, &highlight, 0.5);
1679 				murrine_pattern_add_color_stop_rgba (pat, 0.75, &highlight, 0.5);
1680 				murrine_pattern_add_color_stop_rgba (pat, 1.00, &highlight, 0.0);
1681 				cairo_set_source (cr, pat);
1682 				cairo_pattern_destroy (pat);
1683 				break;
1684 			}
1685 			case 3:
1686 				return;
1687 				break;
1688 		}
1689 
1690 		cairo_move_to (cr, 1.0, 0.0);
1691 		cairo_line_to (cr, 1.0, height);
1692 		cairo_stroke  (cr);
1693 	}
1694 }
1695 
1696 static void
murrine_draw_combo_separator(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1697 murrine_draw_combo_separator (cairo_t *cr,
1698                               const MurrineColors    *colors,
1699                               const WidgetParameters *widget,
1700                               int x, int y, int width, int height)
1701 {
1702 	const MurrineRGB *dark = &colors->shade[6];
1703 
1704 	cairo_translate        (cr, x+0.5, y);
1705 
1706 	murrine_set_color_rgba (cr, dark, 0.4);
1707 	cairo_move_to          (cr, 0.0, 0.0);
1708 	cairo_line_to          (cr, 0.0, height+1);
1709 	cairo_stroke           (cr);
1710 }
1711 
1712 static void
murrine_draw_list_view_header(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ListViewHeaderParameters * header,int x,int y,int width,int height)1713 murrine_draw_list_view_header (cairo_t *cr,
1714                                const MurrineColors            *colors,
1715                                const WidgetParameters         *widget,
1716                                const ListViewHeaderParameters *header,
1717                                int x, int y, int width, int height)
1718 {
1719 	const MurrineRGB *fill   = &colors->bg[widget->state_type];
1720 	MurrineRGB border = colors->shade[3];
1721 	MurrineRGB grip = colors->shade[3];
1722 	MurrineRGB highlight;
1723 
1724 	murrine_shade (&border, 1.3, &highlight);
1725 
1726 	cairo_translate (cr, x, y);
1727 
1728 	if (header->order & MRN_ORDER_FIRST)
1729 	{
1730 		cairo_move_to (cr, 0.5, height-1);
1731 		cairo_line_to (cr, 0.5, 0.5);
1732 	}
1733 	else
1734 		cairo_move_to (cr, 0.0, 0.5);
1735 
1736 	/* Effects */
1737 	switch (header->style)
1738 	{
1739 		case 0:
1740 			murrine_set_color_rgb (cr, &highlight);
1741 			cairo_line_to (cr, width, 0.5);
1742 			cairo_stroke (cr);
1743 			break;
1744 		case 1:
1745 			cairo_rectangle (cr, 0, 0, width, height);
1746 
1747 			murrine_draw_glaze (cr, fill,
1748 			                    widget->glow_shade, widget->highlight_shade, widget->glazestyle != 0 ? widget->lightborder_shade : 1.0,
1749 			                    widget->mrn_gradient, widget, 0, 0, width, height-1,
1750 			                    widget->roundness, widget->corners, TRUE);
1751 
1752 			if (widget->mrn_gradient.has_border_colors)
1753 			{
1754 				border = grip = widget->mrn_gradient.border_colors[1];
1755 				grip =  widget->mrn_gradient.border_colors[0];
1756 			}
1757 			break;
1758 		case 2:
1759 			border = colors->shade[4];
1760 			MurrineRGB shadow_header;
1761 			murrine_shade (fill, 0.925, &shadow_header);
1762 
1763 			if (!widget->mrn_gradient.gradients)
1764 			{
1765 				murrine_set_color_rgb (cr, &shadow_header);
1766 				cairo_rectangle       (cr, 0.0, height-3.0, width, 2.0);
1767 			}
1768 			else
1769 			{
1770 				cairo_pattern_t *pat;
1771 				pat = cairo_pattern_create_linear (0.0, height-4.0, 0.0, height-1.0);
1772 				murrine_pattern_add_color_stop_rgba (pat, 0.0, &shadow_header, 0.0);
1773 				murrine_pattern_add_color_stop_rgb (pat, 1.0, &shadow_header);
1774 				cairo_set_source      (cr, pat);
1775 				cairo_pattern_destroy (pat);
1776 				cairo_rectangle       (cr, 0.0, height-4.0, width, 3.0);
1777 			}
1778 			cairo_fill (cr);
1779 			break;
1780 	}
1781 	murrine_shade (&border, widget->mrn_gradient.border_shades[1], &border);
1782 
1783 	/* Draw bottom border */
1784 	murrine_set_color_rgb (cr, &border);
1785 	cairo_move_to (cr, 0.0, height-0.5);
1786 	cairo_line_to (cr, width, height-0.5);
1787 	cairo_stroke (cr);
1788 
1789 	/* Draw resize grip */
1790 	if ((widget->ltr && !(header->order & MRN_ORDER_LAST)) ||
1791 	    (!widget->ltr && !(header->order & MRN_ORDER_FIRST)) || header->resizable)
1792 	{
1793 		murrine_shade (&grip, widget->mrn_gradient.border_shades[0], &grip);
1794 
1795 		if (header->style == 1 && widget->glazestyle > 0)
1796 		{
1797 			cairo_translate       (cr, width-0.5, 0);
1798 
1799 			murrine_set_color_rgb (cr, &grip);
1800 			cairo_move_to         (cr, 0, 0);
1801 			cairo_line_to         (cr, 0, height-1);
1802 			cairo_stroke          (cr);
1803 		}
1804 		else
1805 		{
1806 			SeparatorParameters separator;
1807 			separator.horizontal = FALSE;
1808 
1809 			murrine_draw_separator (cr, colors, widget, &separator, width-1.5, 4.0, 2, height-8.0);
1810 		}
1811 	}
1812 }
1813 
1814 static void
murrine_draw_menuitem(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height,int menuitemstyle)1815 murrine_draw_menuitem (cairo_t *cr,
1816                        const MurrineColors    *colors,
1817                        const WidgetParameters *widget,
1818                        int x, int y, int width, int height,
1819                        int menuitemstyle)
1820 {
1821 	MurrineGradients mrn_gradient_new = widget->mrn_gradient;
1822 	MurrineRGB border = colors->spot[2];
1823 	MurrineRGB fill = colors->spot[1];
1824 
1825 	murrine_get_fill_color (&fill, &mrn_gradient_new);
1826 
1827 	cairo_translate (cr, x, y);
1828 	murrine_rounded_rectangle_closed (cr, 0, 0, width, height, widget->roundness, widget->corners);
1829 
1830 	switch (menuitemstyle)
1831 	{
1832 		case 0:
1833 			mrn_gradient_new.has_border_colors = FALSE;
1834 			mrn_gradient_new.has_gradient_colors = FALSE;
1835 
1836 			murrine_set_gradient (cr, &fill, mrn_gradient_new, 0, 0, 0, height, mrn_gradient_new.gradients, FALSE);
1837 			cairo_fill (cr);
1838 
1839 			murrine_set_color_rgba (cr, &border, 0.15);
1840 			murrine_rounded_rectangle_closed (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
1841 			cairo_fill_preserve (cr);
1842 			break;
1843 		default:
1844 		case 1:
1845 			cairo_clip_preserve (cr);
1846 
1847 			murrine_draw_glaze (cr, &fill,
1848 			                    widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
1849 			                    mrn_gradient_new, widget, 1, 1, width-2, height-2,
1850 			                    widget->roundness, widget->corners, TRUE);
1851 			break;
1852 		case 2:
1853 		{
1854 			murrine_set_gradient (cr, &fill, mrn_gradient_new, 0, 0, 0, height, mrn_gradient_new.gradients, FALSE);
1855 			cairo_fill (cr);
1856 
1857 			MurrineRGB effect;
1858 			double tile_pos = 0;
1859 			double stroke_width;
1860 			int    x_step;
1861 			stroke_width = height*2;
1862 			x_step = (((float)stroke_width/10));
1863 
1864 			murrine_shade (&fill, murrine_get_contrast(0.65, widget->contrast), &effect);
1865 
1866 			cairo_save (cr);
1867 			/* Draw strokes */
1868 			while (stroke_width > 0 && tile_pos <= width+x_step)
1869 			{
1870 				cairo_move_to (cr, stroke_width/2-x_step, 0);
1871 				cairo_line_to (cr, stroke_width-x_step, 0);
1872 				cairo_line_to (cr, stroke_width/2-x_step, height);
1873 				cairo_line_to (cr, -x_step, height);
1874 
1875 				cairo_translate (cr, stroke_width, 0);
1876 				tile_pos += stroke_width;
1877 			}
1878 			murrine_set_color_rgba (cr, &effect, 0.15);
1879 			cairo_fill (cr);
1880 			cairo_restore (cr);
1881 			break;
1882 		}
1883 	}
1884 
1885 	murrine_draw_border (cr, &border,
1886 	                     0.5, 0.5, width-1, height-1,
1887 	                     widget->roundness, widget->corners,
1888 	                     mrn_gradient_new, 0.8);
1889 }
1890 
1891 static void
murrine_draw_scrollbar_trough(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)1892 murrine_draw_scrollbar_trough (cairo_t *cr,
1893                                const MurrineColors       *colors,
1894                                const WidgetParameters    *widget,
1895                                const ScrollBarParameters *scrollbar,
1896                                int x, int y, int width, int height)
1897 {
1898 	MurrineRGB border;
1899 	MurrineRGB fill;
1900 
1901 	murrine_shade (&widget->parentbg,
1902 	               murrine_get_contrast (scrollbar->stepperstyle != 1 ? 0.86 : 0.8, widget->contrast),
1903 	               &border);
1904 	murrine_shade (&widget->parentbg, scrollbar->stepperstyle != 1 ? 0.97 : 1.026, &fill);
1905 /*
1906 	murrine_shade (&colors->bg[widget->state_type],
1907 	               murrine_get_contrast (scrollbar->stepperstyle < 1 ? 0.86 : 0.8, widget->contrast),
1908 	               &border_bg);
1909 	murrine_shade (&colors->bg[widget->state_type], scrollbar->stepperstyle < 1 ? 0.97 : 1.026, &fill_bg);
1910 	murrine_mix_color (&border_bg, &border, 0.5, &border);
1911 	murrine_mix_color (&fill_bg, &fill, 0.5, &fill);
1912 */
1913 	if (!scrollbar->horizontal)
1914 	{
1915 		cairo_translate (cr, x, y);
1916 	}
1917 	else
1918 	{
1919 		int tmp = height;
1920 		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
1921 		height = width;
1922 		width = tmp;
1923 	}
1924 
1925 	/* Draw fill */
1926 	murrine_draw_trough (cr, &fill, 0, 0, width, height, widget->roundness, widget->corners, widget->mrn_gradient, 1.0, FALSE);
1927 
1928 	if (scrollbar->stepperstyle == 3)
1929 	{
1930 		uint8 corners;
1931 		MurrineRGB fill_stepper;
1932 		MurrineRGB border_stepper;
1933 
1934 		murrine_shade (&widget->parentbg, 1.02, &fill_stepper);
1935 		murrine_shade (&border, (widget->mrn_gradient.trough_shades[0]+widget->mrn_gradient.trough_shades[1])/2.0, &border_stepper);
1936 
1937 		cairo_save (cr);
1938 
1939 		murrine_rounded_rectangle_closed (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
1940 		cairo_clip (cr);
1941 
1942 		corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
1943 		murrine_rounded_rectangle_inverted (cr, 0.5, 0.5, width-1, scrollbar->steppersize, widget->roundness, corners);
1944 		murrine_set_color_rgb (cr, &fill_stepper);
1945 		cairo_fill_preserve (cr);
1946 		murrine_draw_trough_border_from_path (cr, &border,0.5, 0.5, width-1, scrollbar->steppersize, widget->mrn_gradient, 1.0, FALSE);
1947 
1948 		corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
1949 		murrine_rounded_rectangle_inverted (cr, 0.5, height-scrollbar->steppersize-0.5, width-1, scrollbar->steppersize, widget->roundness, corners);
1950 		murrine_set_color_rgb (cr, &fill_stepper);
1951 		cairo_fill_preserve (cr);
1952 		murrine_draw_trough_border_from_path (cr, &border, 0.5, height-scrollbar->steppersize-0.5, width-1, scrollbar->steppersize, widget->mrn_gradient, 1.0, FALSE);
1953 
1954 		cairo_restore (cr);
1955 	}
1956 
1957 	/* Draw border */
1958 	if (!scrollbar->within_bevel)
1959 		murrine_draw_trough_border (cr, &border, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners, widget->mrn_gradient, 1.0, FALSE);
1960 	else
1961 	{
1962 		murrine_shade (&border, widget->mrn_gradient.trough_shades[0], &border);
1963 		murrine_set_color_rgb (cr, &border);
1964 		cairo_move_to (cr, 0.5, 0);
1965 		cairo_line_to (cr, 0.5, height);
1966 		cairo_stroke (cr);
1967 	}
1968 }
1969 
1970 static void
murrine_draw_scrollbar_stepper(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)1971 murrine_draw_scrollbar_stepper (cairo_t *cr,
1972                                 const MurrineColors       *colors,
1973                                 const WidgetParameters    *widget,
1974                                 const ScrollBarParameters *scrollbar,
1975                                 int x, int y, int width, int height)
1976 {
1977 	MurrineGradients mrn_gradient_new = widget->mrn_gradient;
1978 	double border_stop_mid = ((mrn_gradient_new.border_shades[0])+
1979 	                          (mrn_gradient_new.border_shades[1]))/2.0;
1980 	MurrineRGB border;
1981 	MurrineRGB fill  = colors->bg[widget->state_type];
1982 
1983 	murrine_get_fill_color (&fill, &mrn_gradient_new);
1984 	murrine_shade (&colors->shade[6], 0.95, &border);
1985 
1986 	mrn_gradient_new.border_shades[0] = border_stop_mid;
1987 	mrn_gradient_new.border_shades[1] = border_stop_mid;
1988 
1989 	if (!scrollbar->horizontal)
1990 		murrine_exchange_axis (cr, &x, &y, &width, &height);
1991 
1992 	/* Border color */
1993 	murrine_mix_color (&border, &fill, 0.4, &border);
1994 
1995 	cairo_translate (cr, x, y);
1996 
1997 	cairo_save (cr);
1998 
1999 	murrine_rounded_rectangle_closed (cr, 1, 1, width-2, height-2, widget->roundness-1, widget->corners);
2000 	cairo_clip_preserve(cr);
2001 
2002 	murrine_draw_glaze (cr, &fill,
2003 	                    widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
2004 	                    mrn_gradient_new, widget, 1, 1, width-2, height-2,
2005 	                    widget->roundness, widget->corners, TRUE);
2006 
2007 	cairo_restore (cr);
2008 
2009 	murrine_draw_border (cr, &border,
2010 	                     0.5, 0.5, width-1, height-1,
2011 	                     widget->roundness, widget->corners,
2012 	                     mrn_gradient_new, 1.0);
2013 }
2014 
2015 static void
murrine_draw_scrollbar_slider(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)2016 murrine_draw_scrollbar_slider (cairo_t *cr,
2017                                const MurrineColors       *colors,
2018                                const WidgetParameters    *widget,
2019                                const ScrollBarParameters *scrollbar,
2020                                int x, int y, int width, int height)
2021 {
2022 	MurrineGradients mrn_gradient_new = widget->mrn_gradient;
2023 	double border_stop_mid = ((mrn_gradient_new.border_shades[0])+
2024 	                          (mrn_gradient_new.border_shades[1]))/2.0;
2025 	MurrineRGB fill = scrollbar->has_color ? scrollbar->color : colors->bg[widget->state_type];
2026 	MurrineRGB border;
2027 	uint8 corners = widget->corners;
2028 
2029 	murrine_get_fill_color (&fill, &mrn_gradient_new);
2030 
2031 	if (scrollbar->stepperstyle != 1 && scrollbar->stepperstyle != 3)
2032 	{
2033 		if (scrollbar->junction & MRN_JUNCTION_BEGIN)
2034 		{
2035 			if (scrollbar->horizontal)
2036 			{
2037 				x -= 1;
2038 				width += 1;
2039 			}
2040 			else
2041 			{
2042 				y -= 1;
2043 				height += 1;
2044 			}
2045 		}
2046 		if (scrollbar->junction & MRN_JUNCTION_END)
2047 		{
2048 			if (scrollbar->horizontal)
2049 				width += 1;
2050 			else
2051 				height += 1;
2052 		}
2053 	}
2054 
2055 	if (scrollbar->stepperstyle == 2)
2056 	{
2057 		if (scrollbar->junction & MRN_JUNCTION_BEGIN)
2058 		{
2059 			if (scrollbar->horizontal)
2060 				corners ^= MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
2061 			else
2062 				corners ^= MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
2063 		}
2064 		if (scrollbar->junction & MRN_JUNCTION_END)
2065 		{
2066 			if (scrollbar->horizontal)
2067 				corners ^= MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
2068 			else
2069 				corners ^= MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
2070 		}
2071 	}
2072 
2073 	murrine_shade (&colors->shade[6], 0.95, &border);
2074 
2075 	mrn_gradient_new.border_shades[0] = border_stop_mid;
2076 	mrn_gradient_new.border_shades[1] = border_stop_mid;
2077 
2078 	if (widget->prelight && scrollbar->has_color)
2079 		murrine_shade (&fill, scrollbar->prelight_shade, &fill);
2080 
2081 	murrine_mix_color (&border, &fill, 0.4, &border);
2082 
2083 	if (scrollbar->horizontal)
2084 		cairo_translate (cr, x, y);
2085 	else
2086 	{
2087 		int tmp = height;
2088 		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
2089 		height = width;
2090 		width = tmp;
2091 	}
2092 
2093 	cairo_save (cr);
2094 
2095 	murrine_rounded_rectangle_closed (cr, 1, 1, width-2, height-2, widget->roundness-1, corners);
2096 	cairo_clip_preserve (cr);
2097 
2098 	murrine_draw_glaze (cr, &fill,
2099 	                    widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
2100 	                    mrn_gradient_new, widget, 1, 1, width-2, height-2,
2101 	                    widget->roundness, corners, TRUE);
2102 
2103 	/* Draw the options */
2104 	MurrineRGB style;
2105 	if (scrollbar->style > 0)
2106 		murrine_shade (&fill, 0.55, &style);
2107 
2108 	switch (scrollbar->style)
2109 	{
2110 		case 1:
2111 		{
2112 			int circ_radius = 2;
2113 			int circ_space = 5;
2114 			int i;
2115 			int x1 = circ_space+circ_radius;
2116 			int y1 = height/2;
2117 			for (i = circ_space; i < width-circ_space; i += 2*circ_radius+circ_space)
2118 			{
2119 				cairo_move_to (cr, i, 1);
2120 				cairo_arc (cr, x1, y1, circ_radius, 0, M_PI*2);
2121 
2122 				x1 += 2*circ_radius+circ_space;
2123 
2124 				cairo_close_path (cr);
2125 				murrine_set_color_rgba (cr, &style, 0.15);
2126 				cairo_fill (cr);
2127 			}
2128 			break;
2129 		}
2130 		case 3:
2131 		case 4:
2132 		{
2133 			int counter = -width;
2134 			cairo_save (cr);
2135 			cairo_rectangle (cr, 1, 1, width-2, height-2);
2136 			cairo_clip (cr);
2137 			cairo_new_path (cr);
2138 			cairo_set_line_width (cr, 5.0); /* stroke width */
2139 			murrine_set_color_rgba (cr, &style, 0.08);
2140 			while (counter < height)
2141 			{
2142 				cairo_move_to (cr, width, counter);
2143 				cairo_line_to (cr, 0, counter+width);
2144 				cairo_stroke  (cr);
2145 				counter += 12;
2146 			}
2147 			cairo_restore (cr);
2148 			break;
2149 		}
2150 		case 5:
2151 		case 6:
2152 		{
2153 			int stroke_width = 7;
2154 			int stroke_space = 5;
2155 			int i;
2156 			murrine_set_color_rgba (cr, &style, 0.08);
2157 			for (i = stroke_space; i < width-stroke_space; i += stroke_width+stroke_space)
2158 			{
2159 				cairo_move_to (cr, i, 1);
2160 				cairo_rel_line_to (cr, 0, height-2);
2161 				cairo_rel_line_to (cr, stroke_width, 0);
2162 				cairo_rel_line_to (cr, 0, -(height-2));
2163 				cairo_fill (cr);
2164 			}
2165 			break;
2166 		}
2167 	}
2168 	/* Draw the handle */
2169 	if (scrollbar->style > 0 && scrollbar->style % 2 == 0)
2170 	{
2171 		double bar_x = width/2-3.5;
2172 		int i;
2173 
2174 		switch (scrollbar->handlestyle)
2175 		{
2176 			default:
2177 			case 0:
2178 			{
2179 				for (i=0; i<3; i++)
2180 				{
2181 					cairo_move_to (cr, bar_x, 5);
2182 					cairo_line_to (cr, bar_x, height-5);
2183 					murrine_set_color_rgb (cr, &border);
2184 					cairo_stroke (cr);
2185 
2186 					bar_x += 3;
2187 				}
2188 				break;
2189 			}
2190 			case 1:
2191 			{
2192 				MurrineRGB inset;
2193 				murrine_shade (&fill, 1.08, &inset);
2194 
2195 				for (i=0; i<3; i++)
2196 				{
2197 					cairo_move_to (cr, bar_x, 5);
2198 					cairo_line_to (cr, bar_x, height-5);
2199 					murrine_set_color_rgb (cr, &border);
2200 					cairo_stroke (cr);
2201 
2202 					cairo_move_to (cr, bar_x+1, 5);
2203 					cairo_line_to (cr, bar_x+1, height-5);
2204 					murrine_set_color_rgb (cr, &inset);
2205 					cairo_stroke (cr);
2206 
2207 					bar_x += 3;
2208 				}
2209 				break;
2210 			}
2211 			case 2:
2212 			{
2213 				MurrineRGB inset;
2214 				murrine_shade (&fill, 1.08, &inset);
2215 
2216 				bar_x++;
2217 
2218 				for (i=0; i<3; i++)
2219 				{
2220 					cairo_move_to (cr, bar_x, 5);
2221 					cairo_line_to (cr, bar_x, height-5);
2222 					murrine_set_color_rgb (cr, &border);
2223 					cairo_stroke (cr);
2224 
2225 					cairo_move_to (cr, bar_x+1, 4);
2226 					cairo_line_to (cr, bar_x+1, height-5);
2227 					murrine_set_color_rgb (cr, &inset);
2228 					cairo_stroke (cr);
2229 
2230 					bar_x += 2;
2231 				}
2232 				break;
2233 			}
2234 		}
2235 	}
2236 
2237 	cairo_restore (cr);
2238 
2239 	murrine_draw_border (cr, &border,
2240 	                     0.5, 0.5, width-1, height-1,
2241 	                     widget->roundness, corners,
2242 	                     mrn_gradient_new, 1.0);
2243 }
2244 
2245 static void
murrine_draw_selected_cell(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const CellParameters * cell,int x,int y,int width,int height)2246 murrine_draw_selected_cell (cairo_t *cr,
2247                             const MurrineColors    *colors,
2248                             const WidgetParameters *widget,
2249                             const CellParameters   *cell,
2250                             int x, int y, int width, int height)
2251 {
2252 	cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
2253 	cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
2254 	MurrineRGB fill = widget->focus ? colors->base[widget->state_type] :
2255 	                                  colors->base[GTK_STATE_ACTIVE];
2256 	MurrineRGB border;
2257 	murrine_shade (&fill, (cell->style != 0 ? !widget->mrn_gradient.gradients ? 0.9 : 0.95 : 1.0), &border);
2258 
2259 	cairo_save (cr);
2260 	cairo_translate (cr, x, y);
2261 
2262 	murrine_set_gradient (cr, &fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
2263 	cairo_rectangle (cr, 0, 0, width, height);
2264 	cairo_fill (cr);
2265 
2266 	murrine_set_color_rgb (cr, &border);
2267 	cairo_move_to  (cr, 0, 0.5);
2268 	cairo_rel_line_to (cr, width, 0);
2269 	cairo_move_to (cr, 0, height-0.5);
2270 	cairo_rel_line_to (cr, width, 0);
2271 	cairo_stroke (cr);
2272 
2273 	cairo_restore (cr);
2274 }
2275 
2276 static void
murrine_draw_statusbar(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)2277 murrine_draw_statusbar (cairo_t *cr,
2278                         const MurrineColors    *colors,
2279                         const WidgetParameters *widget,
2280                         int x, int y, int width, int height)
2281 {
2282 	const MurrineRGB *dark = &colors->shade[3];
2283 	const MurrineRGB *highlight = &colors->shade[0];
2284 
2285 	cairo_translate       (cr, x, y+0.5);
2286 
2287 	murrine_set_color_rgb (cr, dark);
2288 	cairo_move_to         (cr, 0, 0);
2289 	cairo_line_to         (cr, width, 0);
2290 	cairo_stroke          (cr);
2291 
2292 	murrine_set_color_rgb (cr, highlight);
2293 	cairo_move_to         (cr, 0, 1);
2294 	cairo_line_to         (cr, width, 1);
2295 	cairo_stroke          (cr);
2296 }
2297 
2298 static void
murrine_draw_menu_frame(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height,int menustyle)2299 murrine_draw_menu_frame (cairo_t *cr,
2300                          const MurrineColors    *colors,
2301                          const WidgetParameters *widget,
2302                          int x, int y, int width, int height,
2303                          int menustyle)
2304 {
2305 	cairo_translate       (cr, x, y);
2306 
2307 	switch (menustyle)
2308 	{
2309 		case 1:
2310 		{
2311 			MurrineRGB *fill = (MurrineRGB*)&colors->spot[1];
2312 			MurrineRGB border2;
2313 			murrine_shade (fill, 0.5, &border2);
2314 
2315 			murrine_set_color_rgb (cr, &border2);
2316 			cairo_rectangle (cr, 0.5, 0.5, 3, height-1);
2317 			cairo_stroke_preserve (cr);
2318 
2319 			murrine_set_color_rgb (cr, fill);
2320 			cairo_fill (cr);
2321 		}
2322 		default:
2323 		case 0:
2324 		{
2325 			const MurrineRGB *border = &colors->shade[5];
2326 
2327 			murrine_set_color_rgb (cr, border);
2328 			cairo_rectangle       (cr, 0.5, 0.5, width-1, height-1);
2329 			cairo_stroke          (cr);
2330 			break;
2331 		}
2332 		case 2:
2333 		{
2334 			const MurrineRGB *border = &colors->shade[2];
2335 			MurrineRGB fill;
2336 			raico_blur_t* blur = NULL;
2337 			cairo_t *cr_surface;
2338 			cairo_surface_t *surface;
2339 			cairo_pattern_t *pat;
2340 			int bradius = 30;
2341 			int bheight = MIN (height, 300);
2342 
2343 			murrine_shade (&colors->bg[0], 1.14, &fill);
2344 
2345 			murrine_set_color_rgb (cr, border);
2346 			cairo_rectangle       (cr, 0.5, 0.5, width-1, height-1);
2347 			cairo_stroke          (cr);
2348 
2349 			/* draw glow */
2350 			surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, bheight);
2351 			cr_surface = cairo_create (surface);
2352 			blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW);
2353 			raico_blur_set_radius (blur, bradius);
2354 			cairo_set_line_width (cr_surface, 1.0);
2355 			cairo_rectangle (cr_surface, bradius, bradius-15, width-bradius*2, bheight-bradius*2+15);
2356 			murrine_set_color_rgb (cr_surface, &fill);
2357 			cairo_fill (cr_surface);
2358 			raico_blur_apply (blur, surface);
2359 			cairo_rectangle (cr_surface, 0, -15, width, bheight+15);
2360 			pat = cairo_pattern_create_linear (0, -15, 0.0, bheight+15);
2361 			murrine_pattern_add_color_stop_rgba (pat, 0.25, &colors->bg[0], 0.0);
2362 			murrine_pattern_add_color_stop_rgba (pat, 1.0, &colors->bg[0], 1.0);
2363 			cairo_set_source (cr_surface, pat);
2364 			cairo_pattern_destroy (pat);
2365 			cairo_fill (cr_surface);
2366 			cairo_set_source_surface (cr, surface, 0, 0);
2367 			cairo_paint (cr);
2368 			cairo_surface_destroy (surface);
2369 			cairo_destroy (cr_surface);
2370 			break;
2371 		}
2372 		case 3:
2373 		{
2374 			MurrineRGB border;
2375 			MurrineRGB fill;
2376 			raico_blur_t* blur = NULL;
2377 			cairo_t *cr_surface;
2378 			cairo_surface_t *surface;
2379 			cairo_pattern_t *pat;
2380 			int bradius = 30;
2381 			int bheight = MIN (height, 300);
2382 
2383 			murrine_shade (&colors->bg[0], murrine_get_contrast(1.1, widget->contrast), &border);
2384 			murrine_shade (&colors->bg[0], 0.96, &fill);
2385 
2386 			murrine_set_color_rgb (cr, &border);
2387 			cairo_rectangle       (cr, 0.5, 0.5, width-1, height-1);
2388 			cairo_stroke          (cr);
2389 
2390 			/* draw glow */
2391 			surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, bheight);
2392 			cr_surface = cairo_create (surface);
2393 			blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW);
2394 			raico_blur_set_radius (blur, bradius);
2395 			cairo_set_line_width (cr_surface, 1.0);
2396 			cairo_rectangle (cr_surface, bradius, bradius-15, width-bradius*2, bheight-bradius*2+15);
2397 			murrine_set_color_rgb (cr_surface, &fill);
2398 			cairo_fill (cr_surface);
2399 			raico_blur_apply (blur, surface);
2400 			cairo_rectangle (cr_surface, 0, -15, width, bheight+15);
2401 			pat = cairo_pattern_create_linear (0, -15, 0.0, bheight+15);
2402 			murrine_pattern_add_color_stop_rgba (pat, 0.25, &colors->bg[0], 0.0);
2403 			murrine_pattern_add_color_stop_rgba (pat, 1.0, &colors->bg[0], 1.0);
2404 			cairo_set_source (cr_surface, pat);
2405 			cairo_pattern_destroy (pat);
2406 			cairo_fill (cr_surface);
2407 			cairo_set_source_surface (cr, surface, 0, 0);
2408 			cairo_paint (cr);
2409 			cairo_surface_destroy (surface);
2410 			cairo_destroy (cr_surface);
2411 			break;
2412 		}
2413 	}
2414 }
2415 
2416 static void
murrine_draw_tooltip(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)2417 murrine_draw_tooltip (cairo_t *cr,
2418                       const MurrineColors    *colors,
2419                       const WidgetParameters *widget,
2420                       int x, int y, int width, int height)
2421 {
2422 	MurrineRGB border;
2423 	MurrineRGB fill = colors->bg[widget->state_type];
2424 	MurrineGradients mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 2.0);
2425 	double glow_shade_new = murrine_get_decreased_shade (widget->glow_shade, 2.0);
2426 	double highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
2427 
2428 	murrine_shade (&fill, murrine_get_contrast(0.6, widget->contrast), &border);
2429 	murrine_get_fill_color (&fill, &mrn_gradient_new);
2430 
2431 	cairo_save (cr);
2432 
2433 	cairo_translate (cr, x, y);
2434 
2435 	cairo_rectangle (cr, 1, 1, width-2, height-2);
2436 
2437 	murrine_draw_glaze (cr, &colors->bg[widget->state_type],
2438 	                    glow_shade_new, highlight_shade_new, widget->lightborder_shade,
2439 	                    mrn_gradient_new, widget, 1, 1, width-2, height-2,
2440 	                    widget->roundness, widget->corners, TRUE);
2441 
2442 	murrine_draw_border (cr, &border,
2443 	                     0.5, 0.5, width-1, height-1,
2444 	                     widget->roundness, widget->corners,
2445 	                     mrn_gradient_new, 1.0);
2446 
2447 	cairo_restore (cr);
2448 }
2449 
2450 static void
murrine_draw_iconview(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)2451 murrine_draw_iconview (cairo_t *cr,
2452                        const MurrineColors    *colors,
2453                        const WidgetParameters *widget,
2454                        int x, int y, int width, int height)
2455 {
2456 	MurrineRGB border;
2457 	MurrineRGB fill = widget->focus ? colors->base[widget->state_type] :
2458 	                                  colors->base[GTK_STATE_ACTIVE];
2459 
2460 	murrine_shade (&fill, murrine_get_contrast(0.6, widget->contrast), &border);
2461 	murrine_get_fill_color (&fill, &widget->mrn_gradient);
2462 
2463 	cairo_save (cr);
2464 
2465 	cairo_translate (cr, x, y);
2466 	cairo_save (cr);
2467 
2468 	murrine_rounded_rectangle_closed (cr, 1, 1, width-2, height-2, widget->roundness-1, widget->corners);
2469 	cairo_clip_preserve (cr);
2470 
2471 	murrine_draw_glaze (cr, &fill,
2472 	                    widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
2473 	                    widget->mrn_gradient, widget, 1, 1, width-2, height-2,
2474 	                    widget->roundness-1, widget->corners, TRUE);
2475 
2476 	cairo_restore (cr);
2477 
2478 	murrine_draw_border (cr, &border,
2479 	                     0.5, 0.5, width-1, height-1,
2480 	                     widget->roundness, widget->corners,
2481 	                     widget->mrn_gradient, 1.0);
2482 
2483 	cairo_restore (cr);
2484 }
2485 
2486 static void
murrine_draw_handle(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const HandleParameters * handle,int x,int y,int width,int height)2487 murrine_draw_handle (cairo_t *cr,
2488                      const MurrineColors    *colors,
2489                      const WidgetParameters *widget,
2490                      const HandleParameters *handle,
2491                      int x, int y, int width, int height)
2492 {
2493 	int bar_height;
2494 	int bar_width = 4;
2495 	int i, bar_y = 1;
2496 	int num_bars, bar_spacing;
2497 	num_bars = 3;
2498 	bar_spacing = 3;
2499 	bar_height = num_bars*bar_spacing;
2500 
2501 	if (handle->horizontal)
2502 	{
2503 		int tmp = height;
2504 		rotate_mirror_translate (cr, M_PI/2, x+0.5+width/2-bar_height/2, y+height/2-bar_width/2, FALSE, FALSE);
2505 		height = width;
2506 		width = tmp;
2507 	}
2508 	else
2509 	{
2510 		cairo_translate (cr, x+width/2-bar_width/2, y+height/2-bar_height/2+0.5);
2511 	}
2512 
2513 	switch (handle->style)
2514 	{
2515 		default:
2516 		case 0:
2517 		{
2518 			for (i=0; i<num_bars; i++)
2519 			{
2520 				cairo_move_to (cr, 0, bar_y);
2521 				cairo_line_to (cr, bar_width, bar_y);
2522 				murrine_set_color_rgb (cr, &colors->shade[4]);
2523 				cairo_stroke (cr);
2524 
2525 				bar_y += bar_spacing;
2526 			}
2527 			break;
2528 		}
2529 		case 1:
2530 		{
2531 			for (i=0; i<num_bars; i++)
2532 			{
2533 				cairo_move_to (cr, 0, bar_y);
2534 				cairo_line_to (cr, bar_width, bar_y);
2535 				murrine_set_color_rgb (cr, &colors->shade[4]);
2536 				cairo_stroke (cr);
2537 
2538 				cairo_move_to (cr, 0, bar_y+1);
2539 				cairo_line_to (cr, bar_width, bar_y+1);
2540 				murrine_set_color_rgb (cr, &colors->shade[0]);
2541 				cairo_stroke (cr);
2542 
2543 				bar_y += bar_spacing;
2544 			}
2545 			break;
2546 		}
2547 		case 2:
2548 		{
2549 			bar_y++;
2550 
2551 			for (i=0; i<num_bars; i++)
2552 			{
2553 				cairo_move_to (cr, 0, bar_y);
2554 				cairo_line_to (cr, bar_width, bar_y);
2555 				murrine_set_color_rgb (cr, &colors->shade[4]);
2556 				cairo_stroke (cr);
2557 
2558 				cairo_move_to (cr, 0, bar_y+1);
2559 				cairo_line_to (cr, bar_width, bar_y+1);
2560 				murrine_set_color_rgb (cr, &colors->shade[0]);
2561 				cairo_stroke (cr);
2562 
2563 				bar_y += 2;
2564 			}
2565 			break;
2566 		}
2567 	}
2568 }
2569 
2570 static void
murrine_draw_normal_arrow(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2571 murrine_draw_normal_arrow (cairo_t *cr,
2572                            const MurrineRGB *color,
2573                            double x, double y, double width, double height)
2574 {
2575 	double arrow_width;
2576 	double arrow_height;
2577 	double line_width_2;
2578 
2579 	cairo_save (cr);
2580 
2581 	arrow_width = MIN (height*2.0 + MAX (1.0, ceil (height*2.0/6.0*2.0)/2.0)/2.0, width);
2582 	line_width_2 = MAX (1.0, ceil (arrow_width/6.0*2.0)/2.0)/2.0;
2583 	arrow_height = arrow_width/2.0+line_width_2;
2584 
2585 	cairo_translate (cr, x, y-arrow_height/2.0);
2586 
2587 	cairo_move_to (cr, -arrow_width/2.0, line_width_2);
2588 	cairo_line_to (cr, -arrow_width/2.0 + line_width_2, 0);
2589 	cairo_arc_negative (cr, 0, arrow_height-2*line_width_2-2*line_width_2*sqrt(2), 2*line_width_2, M_PI_2+M_PI_4, M_PI_4);
2590 	cairo_line_to (cr, arrow_width/2.0-line_width_2, 0);
2591 	cairo_line_to (cr, arrow_width/2.0, line_width_2);
2592 	cairo_line_to (cr, 0, arrow_height);
2593 	cairo_close_path (cr);
2594 
2595 	murrine_set_color_rgb (cr, color);
2596 	cairo_fill (cr);
2597 
2598 	cairo_restore (cr);
2599 }
2600 
2601 static void
murrine_draw_normal_arrow_filled(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2602 murrine_draw_normal_arrow_filled (cairo_t *cr,
2603                                   const MurrineRGB *color,
2604                                   double x, double y, double width, double height)
2605 {
2606 	int arrow_width = width;
2607 	int arrow_height = height;
2608 	cairo_pattern_t *pat;
2609 
2610 	cairo_save (cr);
2611 
2612 	cairo_translate (cr, 0, -0.5);
2613 	cairo_move_to (cr, -arrow_width/2, -arrow_height/2);
2614 	cairo_line_to (cr, 0, arrow_height/2);
2615 	cairo_line_to (cr, arrow_width/2, -arrow_height/2);
2616 	cairo_close_path (cr);
2617 
2618 	pat = cairo_pattern_create_linear (0, -arrow_height/2, 0, arrow_height/2);
2619 	murrine_pattern_add_color_stop_rgba (pat, 0.0, color, 0.6);
2620 	murrine_pattern_add_color_stop_rgba (pat, 1.0, color, 0.8);
2621 	cairo_set_source (cr, pat);
2622 	cairo_fill_preserve (cr);
2623 	cairo_pattern_destroy (pat);
2624 
2625 	murrine_set_color_rgb (cr, color);
2626 	cairo_stroke (cr);
2627 
2628 	cairo_restore (cr);
2629 }
2630 
2631 static void
murrine_draw_normal_arrow_filled_equilateral(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2632 murrine_draw_normal_arrow_filled_equilateral (cairo_t *cr,
2633                                               const MurrineRGB *color,
2634                                               double x, double y, double width, double height)
2635 {
2636 	int arrow_width = width+2;
2637 	int arrow_height = height;
2638 	cairo_pattern_t *pat;
2639 
2640 	cairo_save (cr);
2641 
2642 	cairo_translate (cr, 0, -0.5);
2643 	cairo_move_to (cr, -arrow_width/2, -arrow_height/2);
2644 	cairo_line_to (cr, 0, arrow_height/2);
2645 	cairo_line_to (cr, arrow_width/2, -arrow_height/2);
2646 	cairo_close_path (cr);
2647 
2648 	pat = cairo_pattern_create_linear (0, -arrow_height/2, 0, arrow_height/2);
2649 	murrine_pattern_add_color_stop_rgba (pat, 0.0, color, 0.6);
2650 	murrine_pattern_add_color_stop_rgba (pat, 1.0, color, 0.8);
2651 	cairo_set_source (cr, pat);
2652 	cairo_fill_preserve (cr);
2653 	cairo_pattern_destroy (pat);
2654 
2655 	murrine_set_color_rgb (cr, color);
2656 	cairo_stroke (cr);
2657 
2658 	cairo_restore (cr);
2659 }
2660 
2661 static void
murrine_draw_combo_arrow(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2662 murrine_draw_combo_arrow (cairo_t *cr,
2663                           const MurrineRGB *color,
2664                           double x, double y, double width, double height)
2665 {
2666 	double arrow_width = MIN (height*2/3.0, width);
2667 	double arrow_height = arrow_width/2.0;
2668 	double gap_size = arrow_height;
2669 
2670 	cairo_save (cr);
2671 	cairo_translate (cr, x, y-(arrow_height+gap_size)/2.0);
2672 	cairo_rotate (cr, M_PI);
2673 	murrine_draw_normal_arrow (cr, color, 0, 0, arrow_width, arrow_height);
2674 	cairo_restore (cr);
2675 
2676 	murrine_draw_normal_arrow (cr, color, x, y+(arrow_height+gap_size)/2.0, arrow_width, arrow_height);
2677 }
2678 
2679 static void
murrine_draw_combo_arrow_filled(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2680 murrine_draw_combo_arrow_filled (cairo_t *cr,
2681                                  const MurrineRGB *color,
2682                                  double x, double y, double width, double height)
2683 {
2684 	double arrow_width = 4;
2685 	double arrow_height = 5;
2686 
2687 	cairo_save (cr);
2688 	cairo_translate (cr, x, y-5.5);
2689 	cairo_rotate (cr, M_PI);
2690 	murrine_draw_normal_arrow_filled (cr, color, 0, 0, arrow_width, arrow_height);
2691 	cairo_restore (cr);
2692 
2693 	cairo_translate (cr, x, y+5.5);
2694 
2695 	murrine_draw_normal_arrow_filled (cr, color, 0, 0, arrow_width, arrow_height);
2696 }
2697 
2698 static void
murrine_draw_combo_arrow_filled_equilateral(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height)2699 murrine_draw_combo_arrow_filled_equilateral (cairo_t *cr,
2700                                              const MurrineRGB *color,
2701                                              double x, double y, double width, double height)
2702 {
2703 	double arrow_width = 3;
2704 	double arrow_height = 3;
2705 
2706 	cairo_save (cr);
2707 	cairo_translate (cr, x-1, y-5.5);
2708 	cairo_rotate (cr, M_PI);
2709 	murrine_draw_normal_arrow_filled_equilateral (cr, color, 0, 0, arrow_width, arrow_height);
2710 	cairo_restore (cr);
2711 
2712 	cairo_translate (cr, x-1, y+4.5);
2713 
2714 	murrine_draw_normal_arrow_filled_equilateral (cr, color, 0, 0, arrow_width, arrow_height);
2715 }
2716 
2717 static void
_murrine_draw_arrow(cairo_t * cr,const MurrineRGB * color,const ArrowParameters * arrow,double x,double y,double width,double height)2718 _murrine_draw_arrow (cairo_t *cr,
2719                      const MurrineRGB *color,
2720                      const ArrowParameters *arrow,
2721                      double x, double y, double width, double height)
2722 {
2723 	double rotate;
2724 
2725 	switch (arrow->direction)
2726 	{
2727 		default:
2728 		case MRN_DIRECTION_DOWN:
2729 			rotate = 0;
2730 			break;
2731 		case MRN_DIRECTION_UP:
2732 			rotate = M_PI;
2733 			break;
2734 		case MRN_DIRECTION_LEFT:
2735 			rotate = M_PI*1.5;
2736 			break;
2737 		case MRN_DIRECTION_RIGHT:
2738 			rotate = M_PI*0.5;
2739 			break;
2740 	}
2741 
2742 	if (arrow->type == MRN_ARROW_NORMAL)
2743 	{
2744 		cairo_translate (cr, x, y);
2745 		cairo_rotate (cr, -rotate);
2746 		switch (arrow->style)
2747 		{
2748 			default:
2749 			case 0:
2750 				murrine_draw_normal_arrow (cr, color, 0, 0, width, height);
2751 				break;
2752 			case 1:
2753 				murrine_draw_normal_arrow_filled (cr, color, 0, 0, width, height);
2754 				break;
2755 			case 2:
2756 				cairo_translate (cr, 0, 1.0);
2757 				murrine_draw_normal_arrow_filled_equilateral (cr, color, 1, 1, width-2, height-2);
2758 				break;
2759 		}
2760 	}
2761 	else if (arrow->type == MRN_ARROW_COMBO)
2762 	{
2763 		cairo_translate (cr, x, y);
2764 		switch (arrow->style)
2765 		{
2766 			default:
2767 			case 0:
2768 				murrine_draw_combo_arrow (cr, color, 0, 0, width, height);
2769 				break;
2770 			case 1:
2771 				murrine_draw_combo_arrow_filled (cr, color, 0, 0, width, height);
2772 				break;
2773 			case 2:
2774 				murrine_draw_combo_arrow_filled_equilateral (cr, color, 1, 1, width-2, height-2);
2775 				break;
2776 		}
2777 	}
2778 }
2779 
2780 static void
murrine_draw_arrow(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ArrowParameters * arrow,int x,int y,int width,int height)2781 murrine_draw_arrow (cairo_t *cr,
2782                     const MurrineColors    *colors,
2783                     const WidgetParameters *widget,
2784                     const ArrowParameters  *arrow,
2785                     int x, int y, int width, int height)
2786 {
2787 	MurrineRGB color = colors->fg[widget->state_type];
2788 	murrine_mix_color (&color, &colors->bg[widget->state_type], 0.2, &color);
2789 	gdouble tx, ty;
2790 
2791 	tx = x+width/2.0;
2792 	ty = y+height/2.0;
2793 
2794 	if (widget->disabled)
2795 	{
2796 		_murrine_draw_arrow (cr, &colors->shade[0], arrow,
2797 		                     tx+0.5, ty+0.5, width, height);
2798 	}
2799 
2800 	cairo_identity_matrix (cr);
2801 
2802 	_murrine_draw_arrow (cr, &color, arrow,
2803 	                     tx, ty, width, height);
2804 }
2805 
2806 static void
murrine_draw_radiobutton(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height,double trans)2807 murrine_draw_radiobutton (cairo_t *cr,
2808                           const MurrineColors      *colors,
2809                           const WidgetParameters   *widget,
2810                           const CheckboxParameters *checkbox,
2811                           int x, int y, int width, int height,
2812                           double trans)
2813 {
2814 	const MurrineRGB *border;
2815 	const MurrineRGB *dot;
2816 	const MurrineRGB *bg = &colors->base[0];
2817 	gboolean inconsistent = FALSE;
2818 	gboolean draw_box = !checkbox->in_menu;
2819 	gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
2820 	int roundness = width+height;
2821 	double highlight_shade_new = widget->highlight_shade;
2822 	double lightborder_shade_new = widget->lightborder_shade;
2823 	MurrineGradients mrn_gradient_new = widget->mrn_gradient;
2824 
2825 	inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
2826 	draw_bullet |= inconsistent;
2827 
2828 	if (widget->state_type == GTK_STATE_INSENSITIVE)
2829 	{
2830 		border = &colors->shade[3];
2831 		dot    = &colors->shade[3];
2832 		bg     = &colors->bg[0];
2833 
2834 		mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
2835 		mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 3.0);
2836 		mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 3.0);
2837 		highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
2838 		lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
2839 	}
2840 	else
2841 	{
2842 		border = &colors->shade[5];
2843 		if (draw_bullet)
2844 		{
2845 			border = &colors->spot[2];
2846 			bg     = &colors->spot[1];
2847 		}
2848 		dot    = &colors->text[widget->state_type];
2849 	}
2850 
2851 	cairo_translate (cr, x, y);
2852 
2853 	if (draw_box)
2854 	{
2855 		if (widget->xthickness > 2 && widget->ythickness > 2)
2856 		{
2857 			if (widget->reliefstyle > 1 && draw_bullet && widget->state_type != GTK_STATE_INSENSITIVE)
2858 			{
2859 				if (widget->reliefstyle == 5)
2860 					murrine_draw_shadow (cr, &widget->parentbg,
2861 					                     0.5, 0.5, width-1, height-1,
2862 					                     roundness+1, widget->corners,
2863 					                     widget->reliefstyle,
2864 					                     mrn_gradient_new, 0.5);
2865 				else
2866 				{
2867 					MurrineRGB shadow;
2868 					murrine_shade (border, 0.9, &shadow);
2869 
2870 					murrine_draw_shadow (cr, &shadow,
2871 					                     0.5, 0.5, width-1, height-1,
2872 					                     roundness+1, widget->corners,
2873 					                     widget->reliefstyle,
2874 					                     mrn_gradient_new, 0.08);
2875 				}
2876 			}
2877 			else if (widget->reliefstyle != 0)
2878 				murrine_draw_inset (cr, &widget->parentbg, 0.5, 0.5, width-1, height-1, roundness+1, widget->corners);
2879 		}
2880 
2881 		cairo_save (cr);
2882 
2883 		murrine_rounded_rectangle_closed (cr, 1.5, 1.5, width-3, height-3, roundness, widget->corners);
2884 		cairo_clip_preserve (cr);
2885 
2886 		if (draw_bullet)
2887 		{
2888 			murrine_draw_glaze (cr, bg,
2889 				            widget->glow_shade, highlight_shade_new, lightborder_shade_new,
2890 				            mrn_gradient_new, widget, 2, 2, width-4, height-4,
2891 				            roundness, widget->corners, TRUE);
2892 		}
2893 		else
2894 		{
2895 			murrine_set_color_rgb (cr, bg);
2896 			cairo_fill (cr);
2897 		}
2898 
2899 		cairo_restore (cr);
2900 
2901 		if (checkbox->in_cell)
2902 		{
2903 			mrn_gradient_new.border_shades[0] = 1.0;
2904 			mrn_gradient_new.border_shades[1] = 1.0;
2905 			if (!draw_bullet)
2906 				mrn_gradient_new.has_border_colors = FALSE;
2907 		}
2908 		else if (!draw_bullet)
2909 		{
2910 			mrn_gradient_new = murrine_get_inverted_border_shades (mrn_gradient_new);
2911 			mrn_gradient_new.has_border_colors = FALSE;
2912 		}
2913 
2914 		murrine_draw_border (cr, border,
2915 			             1.5, 1.5, width-3, height-3,
2916 			             roundness, widget->corners,
2917 			             mrn_gradient_new, 1.0);
2918 	}
2919 
2920 	if (draw_bullet)
2921 	{
2922 		if (inconsistent)
2923 		{
2924 			cairo_save (cr);
2925 			cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
2926 			cairo_set_line_width (cr, 2.0);
2927 
2928 			cairo_move_to(cr, 5, (double)height/2);
2929 			cairo_line_to(cr, width-5, (double)height/2);
2930 
2931 			murrine_set_color_rgba (cr, dot, trans);
2932 			cairo_stroke (cr);
2933 			cairo_restore (cr);
2934 		}
2935 		else
2936 		{
2937 			if (!draw_box)
2938 			{
2939 				cairo_arc (cr, (double)width/2, (double)height/2, (double)(width+height)/4-4, 0, G_PI*2);
2940 			}
2941 			else
2942 			{
2943 				MurrineRGB outline;
2944 				murrine_invert_text (dot, &outline);
2945 
2946 				cairo_arc (cr, (double)width/2, (double)height/2, (double)(width+height)/4-4, 0, G_PI*2);
2947 				murrine_set_color_rgba (cr, &outline, 0.3*trans*(widget->state_type == GTK_STATE_INSENSITIVE? 0.2 : 1.0));
2948 				cairo_fill (cr);
2949 
2950 				cairo_arc (cr, (double)width/2, (double)height/2, (double)(width+height)/4-5, 0, G_PI*2);
2951 			}
2952 
2953 			murrine_set_color_rgba (cr, dot, trans);
2954 			cairo_fill (cr);
2955 		}
2956 	}
2957 }
2958 
2959 static void
murrine_draw_checkbox(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height,double trans)2960 murrine_draw_checkbox (cairo_t *cr,
2961                        const MurrineColors      *colors,
2962                        const WidgetParameters   *widget,
2963                        const CheckboxParameters *checkbox,
2964                        int x, int y, int width, int height,
2965                        double trans)
2966 {
2967 	const MurrineRGB *border;
2968 	const MurrineRGB *dot;
2969 	const MurrineRGB *bg = &colors->base[0];
2970 	gboolean inconsistent = FALSE;
2971 	gboolean draw_box = !checkbox->in_menu;
2972 	gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
2973 	int roundness = CLAMP (widget->roundness, 0, 2);
2974 	double highlight_shade_new = widget->highlight_shade;
2975 	double lightborder_shade_new = widget->lightborder_shade;
2976 	MurrineGradients mrn_gradient_new = widget->mrn_gradient;
2977 
2978 	inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
2979 	draw_bullet |= inconsistent;
2980 
2981 	if (widget->state_type == GTK_STATE_INSENSITIVE)
2982 	{
2983 		border = &colors->shade[3];
2984 		dot    = &colors->shade[3];
2985 		bg     = &colors->bg[0];
2986 
2987 		mrn_gradient_new = murrine_get_decreased_gradient_shades (widget->mrn_gradient, 3.0);
2988 		mrn_gradient_new.border_shades[0] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[0], 3.0);
2989 		mrn_gradient_new.border_shades[1] = murrine_get_decreased_shade (widget->mrn_gradient.border_shades[1], 3.0);
2990 		highlight_shade_new = murrine_get_decreased_shade (widget->highlight_shade, 2.0);
2991 		lightborder_shade_new = murrine_get_decreased_shade (widget->lightborder_shade, 2.0);
2992 	}
2993 	else
2994 	{
2995 		border = &colors->shade[5];
2996 		if (draw_bullet)
2997 		{
2998 			border = &colors->spot[2];
2999 			bg     = &colors->spot[1];
3000 		}
3001 		dot    = &colors->text[widget->state_type];
3002 	}
3003 
3004 	cairo_translate (cr, x, y);
3005 
3006 	if (draw_box)
3007 	{
3008 		if (widget->xthickness > 2 && widget->ythickness > 2)
3009 		{
3010 			if (widget->reliefstyle > 1 && draw_bullet && widget->state_type != GTK_STATE_INSENSITIVE)
3011 			{
3012 				if (widget->reliefstyle == 5)
3013 					murrine_draw_shadow (cr, &widget->parentbg,
3014 					                     0.5, 0.5, width-1, height-1,
3015 					                     roundness+1, widget->corners,
3016 					                     widget->reliefstyle,
3017 					                     mrn_gradient_new, 0.5);
3018 				else
3019 				{
3020 					MurrineRGB shadow;
3021 					murrine_shade (border, 0.9, &shadow);
3022 
3023 					murrine_draw_shadow (cr, &shadow,
3024 					                     0.5, 0.5, width-1, height-1,
3025 					                     roundness+1, widget->corners,
3026 					                     widget->reliefstyle,
3027 					                     mrn_gradient_new, 0.08);
3028 				}
3029 			}
3030 			else if (widget->reliefstyle != 0)
3031 				murrine_draw_inset (cr, &widget->parentbg, 0.5, 0.5, width-1, height-1, roundness+1, widget->corners);
3032 		}
3033 
3034 		cairo_save (cr);
3035 
3036 		murrine_rounded_rectangle_closed (cr, 1.5, 1.5, width-3, height-3, roundness, widget->corners);
3037 		cairo_clip_preserve (cr);
3038 
3039 		if (draw_bullet)
3040 		{
3041 			murrine_draw_glaze (cr, bg,
3042 				            widget->glow_shade, highlight_shade_new, lightborder_shade_new,
3043 				            mrn_gradient_new, widget, 2, 2, width-4, height-4,
3044 				            roundness, widget->corners, TRUE);
3045 		}
3046 		else
3047 		{
3048 			murrine_set_color_rgb (cr, bg);
3049 			cairo_fill (cr);
3050 		}
3051 
3052 		cairo_restore (cr);
3053 
3054 		if (checkbox->in_cell)
3055 		{
3056 			mrn_gradient_new.border_shades[0] = 1.0;
3057 			mrn_gradient_new.border_shades[1] = 1.0;
3058 			if (!draw_bullet)
3059 				mrn_gradient_new.has_border_colors = FALSE;
3060 		}
3061 		else if (!draw_bullet)
3062 		{
3063 			mrn_gradient_new = murrine_get_inverted_border_shades (mrn_gradient_new);
3064 			mrn_gradient_new.has_border_colors = FALSE;
3065 		}
3066 
3067 		murrine_draw_border (cr, border,
3068 		                     1.5, 1.5, width-3, height-3,
3069 		                     roundness, widget->corners,
3070 		                     mrn_gradient_new, 1.0);
3071 	}
3072 
3073 	if (draw_bullet)
3074 	{
3075 		if (inconsistent)
3076 		{
3077 			cairo_save (cr);
3078 			cairo_set_line_width (cr, 2.0);
3079 			cairo_move_to (cr, 3, (double)height/2);
3080 			cairo_line_to (cr, width-3, (double)height/2);
3081 			cairo_restore (cr);
3082 		}
3083 		else
3084 		{
3085 
3086 			if (!draw_box)
3087 			{
3088 				cairo_scale (cr, (double)width/18.0, (double)height/18.0);
3089 				cairo_translate (cr, 2.0, 3.0);
3090 			}
3091 			else
3092 			{
3093 				MurrineRGB outline;
3094 				murrine_invert_text (dot, &outline);
3095 
3096 				cairo_scale (cr, (double)width/18.0, (double)height/18.0);
3097 
3098 				cairo_move_to (cr, 5.0, 5.65);
3099 				cairo_line_to (cr, 8.95, 9.57);
3100 				cairo_line_to (cr, 16.0, 2.54);
3101 				cairo_line_to (cr, 16.0, 8.36);
3102 				cairo_line_to (cr, 10.6, 15.1);
3103 				cairo_line_to (cr, 7.6, 15.1);
3104 				cairo_line_to (cr, 2.95, 10.48);
3105 				cairo_line_to (cr, 2.95, 7.65);
3106 				cairo_close_path (cr);
3107 
3108 				murrine_set_color_rgba (cr, &outline, 0.5*trans*(widget->state_type == GTK_STATE_INSENSITIVE ? 0.2 : 1.0));
3109 				cairo_fill (cr);
3110 
3111 				cairo_translate (cr, 4.0, 2.0);
3112 			}
3113 
3114 			cairo_move_to (cr, 0.0, 6.0);
3115 			cairo_line_to (cr, 0.0, 8.0);
3116 			cairo_line_to (cr, 4.0, 12.0);
3117 			cairo_line_to (cr, 6.0, 12.0);
3118 			cairo_line_to (cr, 15.0, 1.0);
3119 			cairo_line_to (cr, 15.0, 0.0);
3120 			cairo_line_to (cr, 14.0, 0.0);
3121 			cairo_line_to (cr, 5.0, 9.0);
3122 			cairo_line_to (cr, 1.0, 5.0);
3123 			cairo_close_path (cr);
3124 		}
3125 
3126 		murrine_set_color_rgba (cr, dot, trans);
3127 		cairo_fill (cr);
3128 	}
3129 }
3130 
3131 static void
murrine_draw_resize_grip(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ResizeGripParameters * grip,int x,int y,int width,int height)3132 murrine_draw_resize_grip (cairo_t *cr,
3133                           const MurrineColors        *colors,
3134                           const WidgetParameters     *widget,
3135                           const ResizeGripParameters *grip,
3136                           int x, int y, int width, int height)
3137 {
3138 	const MurrineRGB *dark = &colors->shade[3];
3139 	const MurrineRGB *highlight = &colors->shade[0];
3140 	int lx, ly;
3141 
3142 	for (ly=0; ly<4; ly++) /* vertically, four rows of dots */
3143 	{
3144 		for (lx=0; lx<=ly; lx++) /* horizontally */
3145 		{
3146 			int ny = (3.5-ly)*3;
3147 			int nx = lx*3;
3148 
3149 			murrine_set_color_rgb (cr, highlight);
3150 			cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 2, 2);
3151 			cairo_fill (cr);
3152 
3153 			murrine_set_color_rgb (cr, dark);
3154 			cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 1, 1);
3155 			cairo_fill (cr);
3156 		}
3157 	}
3158 }
3159 
3160 static void
murrine_draw_expander_arrow(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ExpanderParameters * expander,int x,int y)3161 murrine_draw_expander_arrow (cairo_t *cr,
3162 	                     const MurrineColors    *colors,
3163 	                     const WidgetParameters *widget,
3164 	                     const ExpanderParameters *expander,
3165 	                     int x, int y)
3166 {
3167 	MurrineRGB color;
3168 	cairo_pattern_t *pat;
3169 
3170 	int diameter;
3171 	int offset = (expander->arrowstyle == 2) ? 1 : 0;
3172 	double vertical_overshoot;
3173 	double radius;
3174 	double interp; /* interpolation factor for center position */
3175 	double x_double_horz, y_double_horz;
3176 	double x_double_vert, y_double_vert;
3177 	double x_double, y_double;
3178 	gint degrees = 0;
3179 	gint line_width = 1;
3180 
3181 	switch (expander->expander_style)
3182 	{
3183 		case GTK_EXPANDER_COLLAPSED:
3184 			degrees = (expander->text_direction == GTK_TEXT_DIR_RTL) ? 180 : 0;
3185 			interp = 0.0;
3186 			break;
3187 		case GTK_EXPANDER_SEMI_COLLAPSED:
3188 			degrees = (expander->text_direction == GTK_TEXT_DIR_RTL) ? 150 : 30;
3189 			interp = 0.25;
3190 			break;
3191 		case GTK_EXPANDER_SEMI_EXPANDED:
3192 			degrees = (expander->text_direction == GTK_TEXT_DIR_RTL) ? 120 : 60;
3193 			interp = 0.75;
3194 			break;
3195 		case GTK_EXPANDER_EXPANDED:
3196 			degrees = 90;
3197 			interp = 1.0;
3198 			break;
3199 		default:
3200 			g_assert_not_reached ();
3201 	}
3202 
3203 	/* Compute distance that the stroke extends beyonds the end
3204 	* of the triangle we draw.
3205 	*/
3206 	vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
3207 
3208 	/* For odd line widths, we end the vertical line of the triangle
3209 	* at a half pixel, so we round differently.
3210 	*/
3211 	if (line_width % 2 == 1)
3212 		vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
3213 	else
3214 		vertical_overshoot = ceil (vertical_overshoot);
3215 
3216 	/* Adjust the size of the triangle we draw so that the entire stroke fits
3217 	*/
3218 	diameter = MAX (3, expander->size - 2 * vertical_overshoot);
3219 
3220 	/* If the line width is odd, we want the diameter to be even,
3221 	* and vice versa, so force the sum to be odd. This relationship
3222 	* makes the point of the triangle look right.
3223 	*/
3224 	diameter -= (1 - (diameter + line_width) % 2);
3225 
3226 	radius = diameter / 2. + 4;
3227 
3228 	/* Adjust the center so that the stroke is properly aligned with
3229 	* the pixel grid. The center adjustment is different for the
3230 	* horizontal and vertical orientations. For intermediate positions
3231 	* we interpolate between the two.
3232 	*/
3233 	x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2. + ceil (radius / 8.0);
3234 	y_double_vert = y - 0.5;
3235 
3236 	x_double_horz = x - 0.5 + ceil (radius / 8.0);
3237 	y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
3238 
3239 	x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
3240 	y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
3241 
3242 	cairo_translate (cr, x_double, y_double);
3243 	cairo_rotate (cr, degrees * G_PI / 180);
3244 
3245 	cairo_move_to (cr, -radius / 2.0, -radius / 2.0);
3246 	cairo_line_to (cr,  radius / 2.0 - offset,  0);
3247 	cairo_line_to (cr, -radius / 2.0,  radius / 2.0);
3248 	cairo_close_path (cr);
3249 
3250 	if (expander->in_treeview)
3251 		color = colors->text[widget->state_type];
3252 	else
3253 		color = colors->fg[widget->state_type];
3254 
3255 	pat = cairo_pattern_create_linear (-radius/2.0, 0, radius/2.0, 0);
3256 	murrine_pattern_add_color_stop_rgba (pat, 0.0, &color, 0.6);
3257 	murrine_pattern_add_color_stop_rgba (pat, 1.0, &color, 0.8);
3258 	cairo_set_source (cr, pat);
3259 	cairo_fill_preserve (cr);
3260 	cairo_pattern_destroy (pat);
3261 
3262 	murrine_set_color_rgb (cr, &color);
3263 	cairo_stroke (cr);
3264 }
3265 
3266 static void
murrine_draw_expander_circle(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ExpanderParameters * expander,int x,int y)3267 murrine_draw_expander_circle (cairo_t *cr,
3268 	                      const MurrineColors    *colors,
3269 	                      const WidgetParameters *widget,
3270 	                      const ExpanderParameters *expander,
3271 	                      int x, int y)
3272 {
3273 	int expander_size = expander->size;
3274 
3275 	if (expander_size % 2 != 0)
3276 		expander_size--;
3277 
3278 	cairo_translate (cr, x-expander_size/2, y-expander_size/2);
3279 
3280 	cairo_arc (cr, expander_size/2.0, expander_size/2.0, expander_size/2.0, 0, G_PI*2);
3281 
3282 	if (expander->in_treeview)
3283 		murrine_set_color_rgb (cr, &colors->text[widget->state_type]);
3284 	else
3285 		murrine_set_color_rgb (cr, &colors->fg[widget->state_type]);
3286 
3287 	cairo_fill (cr);
3288 
3289 	cairo_set_line_width (cr, 2.0);
3290 
3291 	switch (expander->expander_style)
3292 	{
3293 		case GTK_EXPANDER_SEMI_COLLAPSED:
3294 		case GTK_EXPANDER_COLLAPSED:
3295 			cairo_move_to (cr, (double)expander_size/2-expander_size/4-0.5, (double)expander_size/2);
3296 			cairo_line_to (cr, (double)expander_size/2+expander_size/4+0.5, (double)expander_size/2);
3297 			cairo_move_to (cr, (double)expander_size/2, (double)expander_size/2-expander_size/4-0.5);
3298 			cairo_line_to (cr, (double)expander_size/2, (double)expander_size/2+expander_size/4+0.5);
3299 		break;
3300 		case GTK_EXPANDER_SEMI_EXPANDED:
3301 		case GTK_EXPANDER_EXPANDED:
3302 			cairo_move_to (cr, (double)expander_size/2-expander_size/4-0.5, (double)expander_size/2);
3303 			cairo_line_to (cr, (double)expander_size/2+expander_size/4+0.5, (double)expander_size/2);
3304 		break;
3305 		default:
3306 			g_assert_not_reached ();
3307 	}
3308 
3309 	if (expander->in_treeview)
3310 		murrine_set_color_rgb (cr, &colors->base[widget->state_type]);
3311 	else
3312 		murrine_set_color_rgb (cr, &colors->bg[widget->state_type]);
3313 	cairo_stroke (cr);
3314 }
3315 
3316 static void
murrine_draw_expander_button(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ExpanderParameters * expander,int x,int y)3317 murrine_draw_expander_button (cairo_t *cr,
3318 	                      const MurrineColors    *colors,
3319 	                      const WidgetParameters *widget,
3320 	                      const ExpanderParameters *expander,
3321 	                      int x, int y)
3322 {
3323 	int expander_size = expander->size;
3324 
3325 	if (expander_size % 2 == 0)
3326 		expander_size--;
3327 
3328 	cairo_translate (cr, x-expander_size/2, y-expander_size/2);
3329 
3330 	cairo_save (cr);
3331 
3332 	murrine_rounded_rectangle_closed (cr, 1, 1, expander_size-2, expander_size-2, widget->roundness-1, widget->corners);
3333 	cairo_clip_preserve (cr);
3334 
3335 	murrine_draw_glaze (cr, &colors->bg[widget->state_type],
3336 	                    widget->glow_shade, widget->highlight_shade, widget->lightborder_shade,
3337 	                    widget->mrn_gradient, widget, 1, 1, expander_size-2, expander_size-2,
3338 	                    widget->roundness, widget->corners, TRUE);
3339 
3340 	cairo_restore (cr);
3341 
3342 	switch (expander->expander_style)
3343 	{
3344 		case GTK_EXPANDER_SEMI_COLLAPSED:
3345 		case GTK_EXPANDER_COLLAPSED:
3346 			cairo_move_to (cr, (double)expander_size/2-expander_size/4-0.5, (double)expander_size/2);
3347 			cairo_line_to (cr, (double)expander_size/2+expander_size/4+0.5, (double)expander_size/2);
3348 			cairo_move_to (cr, (double)expander_size/2, (double)expander_size/2-expander_size/4-0.5);
3349 			cairo_line_to (cr, (double)expander_size/2, (double)expander_size/2+expander_size/4+0.5);
3350 		break;
3351 		case GTK_EXPANDER_SEMI_EXPANDED:
3352 		case GTK_EXPANDER_EXPANDED:
3353 			cairo_move_to (cr, (double)expander_size/2-expander_size/4-0.5, (double)expander_size/2);
3354 			cairo_line_to (cr, (double)expander_size/2+expander_size/4+0.5, (double)expander_size/2);
3355 		break;
3356 		default:
3357 			g_assert_not_reached ();
3358 	}
3359 	murrine_set_color_rgb  (cr, &colors->fg[widget->state_type]);
3360 	cairo_stroke (cr);
3361 
3362 	murrine_rounded_rectangle (cr, 0.5, 0.5, expander_size-1, expander_size-1, widget->roundness, widget->corners);
3363 	murrine_set_color_rgb (cr, &colors->shade[4]);
3364 	cairo_stroke (cr);
3365 }
3366 
3367 void
murrine_draw_expander(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const ExpanderParameters * expander,int x,int y)3368 murrine_draw_expander (cairo_t *cr,
3369                        const MurrineColors    *colors,
3370                        const WidgetParameters *widget,
3371                        const ExpanderParameters *expander,
3372                        int x, int y)
3373 {
3374 	switch (expander->style)
3375 	{
3376 		default:
3377 		case 0:
3378 			murrine_draw_expander_arrow (cr, colors, widget, expander, x, y);
3379 			break;
3380 		case 1:
3381 			murrine_draw_expander_circle (cr, colors, widget, expander, x, y);
3382 			break;
3383 		case 2:
3384 			murrine_draw_expander_button (cr, colors, widget, expander, x, y);
3385 			break;
3386 	}
3387 }
3388 
3389 static void
murrine_draw_focus_classic(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3390 murrine_draw_focus_classic (cairo_t *cr,
3391                             const MurrineColors    *colors,
3392                             const WidgetParameters *widget,
3393                             const FocusParameters  *focus,
3394                             int x, int y, int width, int height)
3395 {
3396 	cairo_set_line_width (cr, focus->line_width);
3397 
3398 	if (focus->has_color)
3399 		murrine_set_color_rgb (cr, &focus->color);
3400 	else if (focus->type == MRN_FOCUS_COLOR_WHEEL_LIGHT)
3401 		cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
3402 	else if (focus->type == MRN_FOCUS_COLOR_WHEEL_DARK)
3403 		cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
3404 	else
3405 		murrine_set_color_rgba (cr, &colors->fg[widget->state_type], 0.7);
3406 
3407 	if (focus->dash_list[0])
3408 	{
3409 		gint n_dashes = strlen ((gchar *)focus->dash_list);
3410 		gdouble *dashes = g_new (gdouble, n_dashes);
3411 		gdouble total_length = 0;
3412 		gdouble dash_offset;
3413 		gint i;
3414 
3415 		for (i = 0; i < n_dashes; i++)
3416 		{
3417 			dashes[i] = focus->dash_list[i];
3418 			total_length += focus->dash_list[i];
3419 		}
3420 
3421 		dash_offset = -focus->line_width / 2.0;
3422 		while (dash_offset < 0)
3423 			dash_offset += total_length;
3424 
3425 		cairo_set_dash (cr, dashes, n_dashes, dash_offset);
3426 		g_free (dashes);
3427 	}
3428 
3429 	cairo_rectangle (cr, x+focus->line_width/2.0, y+focus->line_width/2.0,
3430 	                     width-focus->line_width, height-focus->line_width);
3431 	cairo_stroke (cr);
3432 }
3433 
3434 static void
murrine_draw_tab_focus(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3435 murrine_draw_tab_focus (cairo_t *cr,
3436                         const MurrineColors    *colors,
3437                         const WidgetParameters *widget,
3438                         const FocusParameters  *focus,
3439                         int x, int y, int width, int height)
3440 {
3441 
3442 }
3443 
3444 static void
murrine_draw_focus_border(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3445 murrine_draw_focus_border (cairo_t *cr,
3446                            const MurrineColors    *colors,
3447                            const WidgetParameters *widget,
3448                            const FocusParameters  *focus,
3449                            int x, int y, int width, int height)
3450 {
3451 	MurrineRGB fill = focus->color;
3452 
3453 	/* Default values */
3454 	int radius = 0;
3455 	double xoffset = 1.0;
3456 	double yoffset = 1.0;
3457 	double border_alpha = 0.72;
3458 	double fill_alpha = 0.18;
3459 	double shadow_alpha = 0.36;
3460 	boolean focus_fill = TRUE;
3461 	boolean focus_border = TRUE;
3462 	boolean focus_shadow = FALSE;
3463 
3464 	/* Do some useful things to adjust focus */
3465 	switch (focus->type)
3466 	{
3467 		case MRN_FOCUS_BUTTON_DEFAULT:
3468 			xoffset = -(focus->padding)-2.0;
3469 			yoffset = -(focus->padding)-2.0;
3470 			radius = widget->roundness;
3471 			focus_fill = FALSE;
3472 			focus_shadow = TRUE;
3473 			border_alpha = 0.2;
3474 			shadow_alpha = 0.4;
3475 			break;
3476 		case MRN_FOCUS_BUTTON:
3477 			xoffset = -(focus->padding)-2.0;
3478 			yoffset = -(focus->padding)-2.0;
3479 			radius = widget->roundness;
3480 			focus_fill = FALSE;
3481 			focus_shadow = TRUE;
3482 			border_alpha = 0.8;
3483 			shadow_alpha = 0.4;
3484 			break;
3485 		case MRN_FOCUS_BUTTON_FLAT:
3486 			xoffset = -(focus->padding)-2.0;
3487 			yoffset = -(focus->padding)-2.0;
3488 			radius = widget->roundness;
3489 			break;
3490 		case MRN_FOCUS_LABEL:
3491 			xoffset = 0.0;
3492 			yoffset = 0.0;
3493 			radius = widget->roundness;
3494 			break;
3495 		case MRN_FOCUS_TREEVIEW:
3496 			xoffset = -1.0;
3497 			yoffset = -1.0;
3498 			focus_border = FALSE;
3499 			break;
3500 		case MRN_FOCUS_TREEVIEW_DND:
3501 			radius = widget->roundness;
3502 			break;
3503 		case MRN_FOCUS_TREEVIEW_HEADER:
3504 			cairo_translate (cr, -1, 0);
3505 			radius = widget->roundness-1;
3506 			break;
3507 		case MRN_FOCUS_TREEVIEW_ROW:
3508 			if (widget->state_type == GTK_STATE_SELECTED)
3509 			{
3510 				/* Fallback to classic function, dots */
3511 				murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3512 				return;
3513 			}
3514 			xoffset = 1.0;
3515 			yoffset = 1.0;
3516 			radius = widget->roundness;
3517 			break;
3518 		case MRN_FOCUS_TAB:
3519 			xoffset = CLAMP (-(widget->xthickness)-1.0, -3.0, 0);
3520 			yoffset = CLAMP (-(widget->ythickness)-1.0, -3.0, 0);
3521 			radius = widget->roundness-1;
3522 			focus_border = FALSE;
3523 			break;
3524 		case MRN_FOCUS_SCALE:
3525 			radius = widget->roundness;
3526 			break;
3527 		case MRN_FOCUS_ICONVIEW:
3528 			return;
3529 			break;
3530 		case MRN_FOCUS_UNKNOWN:
3531 			/* Fallback to classic function, dots */
3532 			murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3533 			return;
3534 			break;
3535 		default:
3536 			break;
3537 	};
3538 
3539 	cairo_translate (cr, x, y);
3540 	cairo_set_line_width (cr, focus->line_width);
3541 
3542 	if (focus_fill)
3543 	{
3544 		clearlooks_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), radius, widget->corners);
3545 		murrine_set_color_rgba (cr, &fill, fill_alpha);
3546 		cairo_fill (cr);
3547 	}
3548 
3549 	if (focus_border)
3550 	{
3551 		clearlooks_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, radius, widget->corners);
3552 		murrine_set_color_rgba (cr, &fill, border_alpha);
3553 		cairo_stroke (cr);
3554 	}
3555 
3556 	if (focus_shadow)
3557 	{
3558 		clearlooks_rounded_rectangle (cr, xoffset-0.5, yoffset-0.5, width-(xoffset*2)+1, height-(yoffset*2)+1, radius+1, widget->corners);
3559 		murrine_set_color_rgba (cr, &fill, shadow_alpha);
3560 		cairo_stroke (cr);
3561 	}
3562 
3563 }
3564 
3565 static void
murrine_draw_focus_inner(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3566 murrine_draw_focus_inner (cairo_t *cr,
3567                           const MurrineColors    *colors,
3568                           const WidgetParameters *widget,
3569                           const FocusParameters  *focus,
3570                           int x, int y, int width, int height)
3571 {
3572 	MurrineRGB fill = focus->color;
3573 
3574 	/* Default values */
3575 	int radius = 0;
3576 	double xoffset = 1.0;
3577 	double yoffset = 1.0;
3578 	double border_alpha = 0.72;
3579 	double fill_alpha = 0.18;
3580 	boolean focus_fill = TRUE;
3581 	boolean focus_border = TRUE;
3582 
3583 	/* Do some useful things to adjust focus */
3584 	switch (focus->type)
3585 	{
3586 		case MRN_FOCUS_BUTTON_DEFAULT:
3587 		case MRN_FOCUS_BUTTON:
3588 			xoffset = -(focus->padding)+1.0;
3589 			yoffset = -(focus->padding)+1.0;
3590 			radius = widget->roundness-1;
3591 			break;
3592 		case MRN_FOCUS_BUTTON_FLAT:
3593 			xoffset = -(focus->padding)+1.0;
3594 			yoffset = -(focus->padding)+1.0;
3595 			radius = widget->roundness-1;
3596 			break;
3597 		case MRN_FOCUS_LABEL:
3598 			xoffset = 0.0;
3599 			yoffset = 0.0;
3600 			radius = widget->roundness;
3601 			break;
3602 		case MRN_FOCUS_TREEVIEW:
3603 			xoffset = -1.0;
3604 			yoffset = -1.0;
3605 			focus_border = FALSE;
3606 			break;
3607 		case MRN_FOCUS_TREEVIEW_DND:
3608 			radius = widget->roundness;
3609 			break;
3610 		case MRN_FOCUS_TREEVIEW_HEADER:
3611 			cairo_translate (cr, -1, 0);
3612 			radius = widget->roundness-1;
3613 			break;
3614 		case MRN_FOCUS_TREEVIEW_ROW:
3615 			if (widget->state_type == GTK_STATE_SELECTED)
3616 			{
3617 				/* Fallback to classic function, dots */
3618 				murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3619 				return;
3620 			}
3621 			xoffset = 1.0;
3622 			yoffset = 1.0;
3623 			radius = widget->roundness;
3624 			break;
3625 		case MRN_FOCUS_TAB:
3626 			xoffset = 0.0;
3627 			yoffset = 0.0;
3628 			radius = widget->roundness-1;
3629 			break;
3630 		case MRN_FOCUS_SCALE:
3631 			radius = widget->roundness;
3632 			break;
3633 		case MRN_FOCUS_ICONVIEW:
3634 			return;
3635 			break;
3636 		case MRN_FOCUS_UNKNOWN:
3637 			/* Fallback to classic function, dots */
3638 			murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3639 			return;
3640 			break;
3641 		default:
3642 			break;
3643 	};
3644 
3645 	cairo_translate (cr, x, y);
3646 	cairo_set_line_width (cr, focus->line_width);
3647 
3648 	if (focus_fill)
3649 	{
3650 		clearlooks_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), radius, widget->corners);
3651 		murrine_set_color_rgba (cr, &fill, fill_alpha);
3652 		cairo_fill (cr);
3653 	}
3654 
3655 	if (focus_border)
3656 	{
3657 		clearlooks_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, radius, widget->corners);
3658 		murrine_set_color_rgba (cr, &fill, border_alpha);
3659 		cairo_stroke (cr);
3660 	}
3661 }
3662 
3663 void
murrine_draw_focus(cairo_t * cr,const MurrineColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)3664 murrine_draw_focus (cairo_t *cr,
3665                     const MurrineColors    *colors,
3666                     const WidgetParameters *widget,
3667                     const FocusParameters  *focus,
3668                     int x, int y, int width, int height)
3669 {
3670 	switch (focus->style)
3671 	{
3672 		default:
3673 		case 1:
3674 			murrine_draw_focus_classic (cr, colors, widget, focus, x, y, width, height);
3675 			break;
3676 		case 2:
3677 			murrine_draw_focus_inner (cr, colors, widget, focus, x, y, width, height);
3678 			break;
3679 		case 3:
3680 			murrine_draw_focus_border (cr, colors, widget, focus, x, y, width, height);
3681 			break;
3682 	}
3683 }
3684 
3685 void
murrine_register_style_murrine(MurrineStyleFunctions * functions)3686 murrine_register_style_murrine (MurrineStyleFunctions *functions)
3687 {
3688 	g_assert (functions);
3689 
3690 	functions->draw_button             = murrine_draw_button;
3691 	functions->draw_combobox           = murrine_draw_combobox;
3692 	functions->draw_scale_trough       = murrine_draw_scale_trough;
3693 	functions->draw_progressbar_trough = murrine_draw_progressbar_trough;
3694 	functions->draw_progressbar_fill   = murrine_draw_progressbar_fill;
3695 	functions->draw_entry              = murrine_draw_entry;
3696 	functions->draw_entry_progress     = murrine_draw_entry_progress;
3697 	functions->draw_expander           = murrine_draw_expander;
3698 	functions->draw_slider             = murrine_draw_slider;
3699 	functions->draw_slider_handle      = murrine_draw_slider_handle;
3700 	functions->draw_spinbutton         = murrine_draw_spinbutton;
3701 	functions->draw_spinbutton_down    = murrine_draw_spinbutton_down;
3702 	functions->draw_optionmenu         = murrine_draw_optionmenu;
3703 	functions->draw_combo_separator    = murrine_draw_combo_separator;
3704 	functions->draw_menubar	           = murrine_draw_menubar;
3705 	functions->draw_tab                = murrine_draw_tab;
3706 	functions->draw_frame              = murrine_draw_frame;
3707 	functions->draw_separator          = murrine_draw_separator;
3708 	functions->draw_list_view_header   = murrine_draw_list_view_header;
3709 	functions->draw_toolbar            = murrine_draw_toolbar;
3710 	functions->draw_tooltip            = murrine_draw_tooltip;
3711 	functions->draw_menuitem           = murrine_draw_menuitem;
3712 	functions->draw_selected_cell      = murrine_draw_selected_cell;
3713 	functions->draw_scrollbar_stepper  = murrine_draw_scrollbar_stepper;
3714 	functions->draw_scrollbar_slider   = murrine_draw_scrollbar_slider;
3715 	functions->draw_scrollbar_trough   = murrine_draw_scrollbar_trough;
3716 	functions->draw_statusbar          = murrine_draw_statusbar;
3717 	functions->draw_menu_frame         = murrine_draw_menu_frame;
3718 	functions->draw_tooltip            = murrine_draw_tooltip;
3719 	functions->draw_iconview           = murrine_draw_iconview;
3720 	functions->draw_handle             = murrine_draw_handle;
3721 	functions->draw_resize_grip        = murrine_draw_resize_grip;
3722 	functions->draw_arrow              = murrine_draw_arrow;
3723 	functions->draw_checkbox           = murrine_draw_checkbox;
3724 	functions->draw_radiobutton        = murrine_draw_radiobutton;
3725 	functions->draw_focus              = murrine_draw_focus;
3726 }
3727