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 <math.h>
22
23 #include "cairo-support.h"
24 #include "support.h"
25 #include "murrine_types.h"
26 #include "raico-blur.h"
27
28 G_GNUC_INTERNAL void
murrine_rgb_to_hls(gdouble * r,gdouble * g,gdouble * b)29 murrine_rgb_to_hls (gdouble *r,
30 gdouble *g,
31 gdouble *b)
32 {
33 gdouble min;
34 gdouble max;
35 gdouble red;
36 gdouble green;
37 gdouble blue;
38 gdouble h, l, s;
39 gdouble delta;
40
41 red = *r;
42 green = *g;
43 blue = *b;
44
45 if (red > green)
46 {
47 if (red > blue)
48 max = red;
49 else
50 max = blue;
51
52 if (green < blue)
53 min = green;
54 else
55 min = blue;
56 }
57 else
58 {
59 if (green > blue)
60 max = green;
61 else
62 max = blue;
63
64 if (red < blue)
65 min = red;
66 else
67 min = blue;
68 }
69
70 l = (max+min)/2;
71 if (fabs (max-min) < 0.0001)
72 {
73 h = 0;
74 s = 0;
75 }
76 else
77 {
78 if (l <= 0.5)
79 s = (max-min)/(max+min);
80 else
81 s = (max-min)/(2-max-min);
82
83 delta = max -min;
84 if (red == max)
85 h = (green-blue)/delta;
86 else if (green == max)
87 h = 2+(blue-red)/delta;
88 else if (blue == max)
89 h = 4+(red-green)/delta;
90
91 h *= 60;
92 if (h < 0.0)
93 h += 360;
94 }
95
96 *r = h;
97 *g = l;
98 *b = s;
99 }
100
101 G_GNUC_INTERNAL void
murrine_hls_to_rgb(gdouble * h,gdouble * l,gdouble * s)102 murrine_hls_to_rgb (gdouble *h,
103 gdouble *l,
104 gdouble *s)
105 {
106 gdouble hue;
107 gdouble lightness;
108 gdouble saturation;
109 gdouble m1, m2;
110 gdouble r, g, b;
111
112 lightness = *l;
113 saturation = *s;
114
115 if (lightness <= 0.5)
116 m2 = lightness*(1+saturation);
117 else
118 m2 = lightness+saturation-lightness*saturation;
119
120 m1 = 2*lightness-m2;
121
122 if (saturation == 0)
123 {
124 *h = lightness;
125 *l = lightness;
126 *s = lightness;
127 }
128 else
129 {
130 hue = *h+120;
131 while (hue > 360)
132 hue -= 360;
133 while (hue < 0)
134 hue += 360;
135
136 if (hue < 60)
137 r = m1+(m2-m1)*hue/60;
138 else if (hue < 180)
139 r = m2;
140 else if (hue < 240)
141 r = m1+(m2-m1)*(240-hue)/60;
142 else
143 r = m1;
144
145 hue = *h;
146 while (hue > 360)
147 hue -= 360;
148 while (hue < 0)
149 hue += 360;
150
151 if (hue < 60)
152 g = m1+(m2-m1)*hue/60;
153 else if (hue < 180)
154 g = m2;
155 else if (hue < 240)
156 g = m1+(m2-m1)*(240-hue)/60;
157 else
158 g = m1;
159
160 hue = *h-120;
161 while (hue > 360)
162 hue -= 360;
163 while (hue < 0)
164 hue += 360;
165
166 if (hue < 60)
167 b = m1+(m2-m1)*hue/60;
168 else if (hue < 180)
169 b = m2;
170 else if (hue < 240)
171 b = m1+(m2-m1)*(240-hue)/60;
172 else
173 b = m1;
174
175 *h = r;
176 *l = g;
177 *s = b;
178 }
179 }
180
181 void
murrine_shade(const MurrineRGB * a,float k,MurrineRGB * b)182 murrine_shade (const MurrineRGB *a, float k, MurrineRGB *b)
183 {
184 double red;
185 double green;
186 double blue;
187
188 red = a->r;
189 green = a->g;
190 blue = a->b;
191
192 if (k == 1.0)
193 {
194 b->r = red;
195 b->g = green;
196 b->b = blue;
197 return;
198 }
199
200 murrine_rgb_to_hls (&red, &green, &blue);
201
202 green *= k;
203 if (green > 1.0)
204 green = 1.0;
205 else if (green < 0.0)
206 green = 0.0;
207
208 blue *= k;
209 if (blue > 1.0)
210 blue = 1.0;
211 else if (blue < 0.0)
212 blue = 0.0;
213
214 murrine_hls_to_rgb (&red, &green, &blue);
215
216 b->r = red;
217 b->g = green;
218 b->b = blue;
219 }
220
221 void
murrine_invert_text(const MurrineRGB * a,MurrineRGB * b)222 murrine_invert_text (const MurrineRGB *a, MurrineRGB *b)
223 {
224 double red;
225 double green;
226 double blue;
227
228 red = a->r;
229 green = a->g;
230 blue = a->b;
231
232 murrine_rgb_to_hls (&red, &green, &blue);
233
234 if (green < 0.8)
235 green = 1.0;
236 else
237 green = 0.0;
238
239 murrine_hls_to_rgb (&red, &green, &blue);
240
241 b->r = red;
242 b->g = green;
243 b->b = blue;
244 }
245
246 void
murrine_mix_color(const MurrineRGB * color1,const MurrineRGB * color2,gdouble mix_factor,MurrineRGB * composite)247 murrine_mix_color (const MurrineRGB *color1, const MurrineRGB *color2,
248 gdouble mix_factor, MurrineRGB *composite)
249 {
250 g_return_if_fail (color1 && color2 && composite);
251
252 composite->r = color1->r*(1-mix_factor)+color2->r*mix_factor;
253 composite->g = color1->g*(1-mix_factor)+color2->g*mix_factor;
254 composite->b = color1->b*(1-mix_factor)+color2->b*mix_factor;
255 }
256
257 void
murrine_gdk_color_to_rgb(GdkColor * c,double * r,double * g,double * b)258 murrine_gdk_color_to_rgb (GdkColor *c, double *r, double *g, double *b)
259 {
260 *r = (double)c->red/(double)65535;
261 *g = (double)c->green/(double)65535;
262 *b = (double)c->blue/(double)65535;
263 }
264
265 void
murrine_get_parent_bg(const GtkWidget * widget,MurrineRGB * color)266 murrine_get_parent_bg (const GtkWidget *widget, MurrineRGB *color)
267 {
268 GtkStateType state_type;
269 const GtkWidget *parent;
270 GdkColor *gcolor;
271 gboolean stop;
272
273 if (widget == NULL)
274 return;
275
276 parent = widget->parent;
277 stop = FALSE;
278
279 while (parent && !stop)
280 {
281 stop = FALSE;
282
283 stop |= !GTK_WIDGET_NO_WINDOW (parent);
284 stop |= GTK_IS_NOTEBOOK (parent) &&
285 gtk_notebook_get_show_tabs (GTK_NOTEBOOK (parent)) &&
286 gtk_notebook_get_show_border (GTK_NOTEBOOK (parent));
287
288 if (GTK_IS_TOOLBAR (parent))
289 {
290 GtkShadowType shadow = GTK_SHADOW_OUT;
291 gtk_widget_style_get (GTK_WIDGET (parent), "shadow-type", &shadow, NULL);
292
293 stop |= (shadow != GTK_SHADOW_NONE);
294 }
295
296 if (!stop)
297 parent = parent->parent;
298 }
299
300 if (parent == NULL)
301 return;
302
303 state_type = GTK_WIDGET_STATE (parent);
304
305 gcolor = &parent->style->bg[state_type];
306
307 murrine_gdk_color_to_rgb (gcolor, &color->r, &color->g, &color->b);
308 }
309
310 void
murrine_set_color_rgb(cairo_t * cr,const MurrineRGB * color)311 murrine_set_color_rgb (cairo_t *cr, const MurrineRGB *color)
312 {
313 g_return_if_fail (cr && color);
314
315 cairo_set_source_rgb (cr, color->r, color->g, color->b);
316 }
317
318 void
murrine_set_color_rgba(cairo_t * cr,const MurrineRGB * color,double alpha)319 murrine_set_color_rgba (cairo_t *cr, const MurrineRGB *color, double alpha)
320 {
321 g_return_if_fail (cr && color);
322
323 cairo_set_source_rgba (cr, color->r, color->g, color->b, alpha);
324 }
325
326 void
murrine_pattern_add_color_stop_rgb(cairo_pattern_t * pat,double pos,const MurrineRGB * color)327 murrine_pattern_add_color_stop_rgb (cairo_pattern_t *pat, double pos,
328 const MurrineRGB *color)
329 {
330 g_return_if_fail (pat && color);
331
332 cairo_pattern_add_color_stop_rgb (pat, pos, color->r, color->g, color->b);
333 }
334
335 void
murrine_pattern_add_color_stop_rgba(cairo_pattern_t * pat,double pos,const MurrineRGB * color,double alpha)336 murrine_pattern_add_color_stop_rgba (cairo_pattern_t *pat, double pos,
337 const MurrineRGB *color, double alpha)
338 {
339 g_return_if_fail (pat && color);
340
341 cairo_pattern_add_color_stop_rgba (pat, pos, color->r, color->g, color->b, alpha);
342 }
343
344 void
murrine_rounded_corner(cairo_t * cr,double x,double y,int radius,uint8 corner)345 murrine_rounded_corner (cairo_t *cr,
346 double x,
347 double y,
348 int radius, uint8 corner)
349 {
350 if (radius < 1)
351 {
352 cairo_line_to (cr, x, y);
353 }
354 else
355 {
356 switch (corner)
357 {
358 case MRN_CORNER_NONE:
359 cairo_line_to (cr, x, y);
360 break;
361 case MRN_CORNER_TOPLEFT:
362 cairo_arc (cr, x+radius, y+radius, radius, G_PI, G_PI*3/2);
363 break;
364 case MRN_CORNER_TOPRIGHT:
365 cairo_arc (cr, x-radius, y+radius, radius, G_PI*3/2, G_PI*2);
366 break;
367 case MRN_CORNER_BOTTOMRIGHT:
368 cairo_arc (cr, x-radius, y-radius, radius, 0, G_PI*1/2);
369 break;
370 case MRN_CORNER_BOTTOMLEFT:
371 cairo_arc (cr, x+radius, y-radius, radius, G_PI*1/2, G_PI);
372 break;
373
374 default:
375 /* A bitfield and not a sane value ... */
376 g_assert_not_reached ();
377 cairo_line_to (cr, x, y);
378 return;
379 }
380 }
381 }
382
383 void
murrine_rounded_rectangle_fast(cairo_t * cr,double x,double y,double w,double h,uint8 corners)384 murrine_rounded_rectangle_fast (cairo_t *cr,
385 double x, double y, double w, double h,
386 uint8 corners)
387 {
388 const float RADIUS_CORNERS = 0.35;
389
390 if (corners & MRN_CORNER_TOPLEFT)
391 cairo_move_to (cr, x+RADIUS_CORNERS, y);
392 else
393 cairo_move_to (cr, x, y);
394
395 if (corners & MRN_CORNER_TOPRIGHT)
396 {
397 cairo_line_to (cr, x+w-RADIUS_CORNERS, y);
398 cairo_move_to (cr, x+w, y+RADIUS_CORNERS);
399 }
400 else
401 cairo_line_to (cr, x+w, y);
402
403 if (corners & MRN_CORNER_BOTTOMRIGHT)
404 {
405 cairo_line_to (cr, x+w, y+h-RADIUS_CORNERS);
406 cairo_move_to (cr, x+w-RADIUS_CORNERS, y+h);
407 }
408 else
409 cairo_line_to (cr, x+w, y+h);
410
411 if (corners & MRN_CORNER_BOTTOMLEFT)
412 {
413 cairo_line_to (cr, x+RADIUS_CORNERS, y+h);
414 cairo_move_to (cr, x, y+h-RADIUS_CORNERS);
415 }
416 else
417 cairo_line_to (cr, x, y+h);
418
419 if (corners & MRN_CORNER_TOPLEFT)
420 cairo_line_to (cr, x, y+RADIUS_CORNERS);
421 else
422 {
423 if (corners == MRN_CORNER_NONE)
424 cairo_close_path (cr);
425 else
426 cairo_line_to (cr, x, y);
427 }
428 }
429
430 void
clearlooks_rounded_rectangle(cairo_t * cr,double x,double y,double w,double h,int radius,uint8 corners)431 clearlooks_rounded_rectangle (cairo_t *cr,
432 double x, double y, double w, double h,
433 int radius, uint8 corners)
434 {
435 if (radius < 1)
436 {
437 cairo_rectangle (cr, x, y, w, h);
438 return;
439 }
440
441 radius = MIN (radius, MIN (w/2.0, h/2.0));
442
443 if (corners & MRN_CORNER_TOPLEFT)
444 cairo_move_to (cr, x+radius, y);
445 else
446 cairo_move_to (cr, x, y);
447
448 if (corners & MRN_CORNER_TOPRIGHT)
449 cairo_arc (cr, x+w-radius, y+radius, radius, M_PI*1.5, M_PI*2);
450 else
451 cairo_line_to (cr, x+w, y);
452
453 if (corners & MRN_CORNER_BOTTOMRIGHT)
454 cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI*0.5);
455 else
456 cairo_line_to (cr, x+w, y+h);
457
458 if (corners & MRN_CORNER_BOTTOMLEFT)
459 cairo_arc (cr, x+radius, y+h-radius, radius, M_PI*0.5, M_PI);
460 else
461 cairo_line_to (cr, x, y+h);
462
463 if (corners & MRN_CORNER_TOPLEFT)
464 cairo_arc (cr, x+radius, y+radius, radius, M_PI, M_PI*1.5);
465 else
466 cairo_line_to (cr, x, y);
467 }
468
469 void
murrine_rounded_rectangle_inverted(cairo_t * cr,double x,double y,double w,double h,int radius,uint8 corners)470 murrine_rounded_rectangle_inverted (cairo_t *cr,
471 double x, double y, double w, double h,
472 int radius, uint8 corners)
473 {
474 radius = MIN (radius, MIN (w/2.0, h/2.0));
475
476 cairo_translate(cr, x, y);
477
478 if (corners & MRN_CORNER_TOPLEFT)
479 cairo_move_to(cr, 0, -radius);
480 else
481 cairo_move_to(cr, 0, 0);
482
483 if (corners & MRN_CORNER_BOTTOMLEFT)
484 cairo_arc(cr, radius, h + radius, radius, M_PI * 1.0, M_PI * 1.5);
485 else
486 cairo_line_to(cr, 0, h);
487
488 if (corners & MRN_CORNER_BOTTOMRIGHT)
489 cairo_arc(cr, w - radius, h + radius, radius, M_PI * 1.5, M_PI * 2.0);
490 else
491 cairo_line_to(cr, w, h);
492
493 if (corners & MRN_CORNER_TOPRIGHT)
494 cairo_arc(cr, w - radius, -radius, radius, M_PI * 0.0, M_PI * 0.5);
495 else
496 cairo_line_to(cr, w, 0);
497
498 if (corners & MRN_CORNER_TOPLEFT)
499 cairo_arc(cr, radius, -radius, radius, M_PI * 0.5, M_PI * 1.0);
500 else
501 cairo_line_to(cr, 0, 0);
502
503 cairo_translate(cr, -x, -y);
504 }
505
506 void
murrine_rounded_rectangle(cairo_t * cr,double x,double y,double w,double h,int radius,uint8 corners)507 murrine_rounded_rectangle (cairo_t *cr,
508 double x, double y, double w, double h,
509 int radius, uint8 corners)
510 {
511 radius < 2 ? radius < 1 ? cairo_rectangle (cr, x, y, w, h) :
512 murrine_rounded_rectangle_fast (cr, x, y, w, h, corners) :
513 clearlooks_rounded_rectangle (cr, x, y, w, h, radius, corners);
514 }
515
516 void
murrine_rounded_rectangle_closed(cairo_t * cr,double x,double y,double w,double h,int radius,uint8 corners)517 murrine_rounded_rectangle_closed (cairo_t *cr,
518 double x, double y, double w, double h,
519 int radius, uint8 corners)
520 {
521 radius < 2 ? cairo_rectangle (cr, x, y, w, h) :
522 clearlooks_rounded_rectangle (cr, x, y, w, h, radius, corners);
523 }
524
525 static void
murrine_draw_flat_highlight(cairo_t * cr,int x,int y,int width,int height)526 murrine_draw_flat_highlight (cairo_t *cr,
527 int x, int y, int width, int height)
528 {
529 cairo_rectangle (cr, x, y, width, height/2);
530 }
531
532 static void
murrine_draw_curved_highlight(cairo_t * cr,int x,int y,int width,int height)533 murrine_draw_curved_highlight (cairo_t *cr,
534 int x, int y, int width, int height)
535 {
536 int w = width+x*2;
537 int h = height+y*2;
538
539 cairo_move_to (cr, x, h-y);
540 cairo_curve_to (cr, x, h/2+h/5, h/5, h/2, h/2, h/2);
541 cairo_line_to (cr, w-h/2, h/2);
542 cairo_curve_to (cr, w-x-h/5, h/2, w-x-0.5, h/2-h/5, w-x, y);
543 cairo_line_to (cr, x, y);
544 cairo_line_to (cr, x, h-y);
545 cairo_close_path (cr);
546 }
547
548 static void
murrine_draw_curved_highlight_top(cairo_t * cr,int x,int y,int width,int height)549 murrine_draw_curved_highlight_top (cairo_t *cr,
550 int x, int y, int width, int height)
551 {
552 int w = width+x*2;
553 int h = height+y*2;
554
555 cairo_move_to (cr, x, y);
556 cairo_curve_to (cr, x, h/2-h/5, h/5, h/2, h/2, h/2);
557 cairo_line_to (cr, w-h/2, h/2);
558 cairo_curve_to (cr, w-x-h/5, h/2, w-x-0.5, h/2-h/5, w-x, y);
559 cairo_close_path (cr);
560 }
561
562 static void
murrine_draw_curved_highlight_bottom(cairo_t * cr,int x,int y,int width,int height)563 murrine_draw_curved_highlight_bottom (cairo_t *cr,
564 int x, int y, int width, int height)
565 {
566 int w = width+x*2;
567 int h = height+y*2;
568
569 cairo_move_to (cr, x, h-y);
570 cairo_curve_to (cr, x, h/2+h/5, h/5, h/2, h/2, h/2);
571 cairo_line_to (cr, w-h/2, h/2);
572 cairo_curve_to (cr, w-x-h/5, h/2, w-x-0.5, h/2+h/5, w-x, h-y);
573 cairo_close_path (cr);
574 }
575
576 /*
577 * Test new glazestyles here :)
578 */
579 static void
murrine_draw_new_glossy_highlight(cairo_t * cr,int x,int y,int width,int height)580 murrine_draw_new_glossy_highlight (cairo_t *cr,
581 int x, int y, int width, int height)
582 {
583 double gloss_height = .5;
584 int gloss_angle = 3;
585 int local_gloss_height = (int) (height*gloss_height);
586
587 cairo_move_to (cr, x, y);
588 cairo_line_to (cr, x+width, y);
589 cairo_line_to (cr, x+width, local_gloss_height);
590 cairo_curve_to (cr, x+2*width/3, local_gloss_height+gloss_angle, x+width/3,
591 local_gloss_height+gloss_angle, x, local_gloss_height);
592 cairo_close_path (cr);
593 }
594
595 static void
murrine_draw_bottom_glow(cairo_t * cr,const MurrineRGB * glow,int x,int y,int width,int height)596 murrine_draw_bottom_glow (cairo_t *cr,
597 const MurrineRGB *glow,
598 int x, int y, int width, int height)
599 {
600 cairo_pattern_t *pat;
601 double scaling_factor = (double)1.2*width/height;
602
603 cairo_rectangle (cr, x, y, width, height);
604 cairo_save (cr);
605 cairo_scale (cr, scaling_factor, 1);
606 pat = cairo_pattern_create_radial ((x+width/2.0)/scaling_factor, y+height, 0,
607 (x+width/2.0)/scaling_factor, y+height, height/2);
608 murrine_pattern_add_color_stop_rgba (pat, 0.0, glow, 0.5);
609 murrine_pattern_add_color_stop_rgba (pat, 1.0, glow, 0.0);
610 cairo_set_source (cr, pat);
611 cairo_pattern_destroy (pat);
612 cairo_fill (cr);
613 cairo_restore (cr);
614 }
615
616 static void
murrine_draw_centered_glow(cairo_t * cr,const MurrineRGB * glow,int x,int y,int width,int height)617 murrine_draw_centered_glow (cairo_t *cr,
618 const MurrineRGB *glow,
619 int x, int y, int width, int height)
620 {
621 cairo_pattern_t *pat;
622 double scaling_factor = (double)1.2*width/height;
623
624 cairo_rectangle (cr, x, y, width, height);
625 cairo_save (cr);
626 cairo_scale (cr, scaling_factor, 1);
627 pat = cairo_pattern_create_radial ((x+width/2.0)/scaling_factor, y+height/2, 0,
628 (x+width/2.0)/scaling_factor, y+height/2, height/2);
629 murrine_pattern_add_color_stop_rgba (pat, 0.0, glow, 0.5);
630 murrine_pattern_add_color_stop_rgba (pat, 1.0, glow, 0.0);
631 cairo_set_source (cr, pat);
632 cairo_pattern_destroy (pat);
633 cairo_fill (cr);
634 cairo_restore (cr);
635 }
636
637 static void
murrine_draw_horizontal_glow(cairo_t * cr,const MurrineRGB * glow,int x,int y,int width,int height)638 murrine_draw_horizontal_glow (cairo_t *cr,
639 const MurrineRGB *glow,
640 int x, int y, int width, int height)
641 {
642 cairo_pattern_t *pat;
643
644 cairo_rectangle (cr, x, y, width, height);
645 pat = cairo_pattern_create_linear (x, y, width, 0);
646 murrine_pattern_add_color_stop_rgba (pat, 0.0, glow, 0.0);
647 murrine_pattern_add_color_stop_rgba (pat, 0.5, glow, 0.5);
648 murrine_pattern_add_color_stop_rgba (pat, 1.0, glow, 0.0);
649 cairo_set_source (cr, pat);
650 cairo_pattern_destroy (pat);
651 cairo_fill (cr);
652 }
653
654 static void
murrine_draw_top_glow(cairo_t * cr,const MurrineRGB * glow,int x,int y,int width,int height)655 murrine_draw_top_glow (cairo_t *cr,
656 const MurrineRGB *glow,
657 int x, int y, int width, int height)
658 {
659 cairo_pattern_t *pat;
660 double scaling_factor = (double)1.2*width/height;
661
662 cairo_rectangle (cr, x, y, width, height);
663 cairo_save (cr);
664 cairo_scale (cr, scaling_factor, 1);
665 pat = cairo_pattern_create_radial ((x+width/2.0)/scaling_factor, y, 0,
666 (x+width/2.0)/scaling_factor, y, height/2);
667 murrine_pattern_add_color_stop_rgba (pat, 0.0, glow, 0.5);
668 murrine_pattern_add_color_stop_rgba (pat, 1.0, glow, 0.0);
669 cairo_set_source (cr, pat);
670 cairo_pattern_destroy (pat);
671 cairo_fill (cr);
672 cairo_restore (cr);
673 }
674
675 static void
murrine_draw_blur_glow(cairo_t * cr,const MurrineRGB * glow,int x,int y,int width,int height,int roundness,uint8 corners)676 murrine_draw_blur_glow (cairo_t *cr,
677 const MurrineRGB *glow,
678 int x, int y, int width, int height,
679 int roundness, uint8 corners)
680 {
681 raico_blur_t* blur = NULL;
682 cairo_t *cr_surface;
683 cairo_surface_t *surface;
684 double bradius = 6;
685
686 /* draw glow */
687 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width+bradius*2, height+bradius*2);
688 cr_surface = cairo_create (surface);
689 blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW);
690 raico_blur_set_radius (blur, bradius);
691 cairo_set_line_width (cr_surface, 4.0);
692 murrine_rounded_rectangle_closed (cr_surface, bradius, bradius, width, height, roundness, corners);
693 murrine_set_color_rgb (cr_surface, glow);
694 cairo_stroke (cr_surface);
695 raico_blur_apply (blur, surface);
696 cairo_set_source_surface (cr, surface, -bradius+2, -bradius+2);
697 cairo_paint (cr);
698 cairo_surface_destroy (surface);
699 cairo_destroy (cr_surface);
700 }
701
702 static void
murrine_draw_lightborder(cairo_t * cr,const MurrineRGB * fill,MurrineGradients mrn_gradient,double x,double y,int width,int height,boolean gradients,int glazestyle,int lightborderstyle,double lightborder_shade,int radius,uint8 corners)703 murrine_draw_lightborder (cairo_t *cr,
704 const MurrineRGB *fill,
705 MurrineGradients mrn_gradient,
706 double x, double y, int width, int height,
707 boolean gradients,
708 int glazestyle, int lightborderstyle,
709 double lightborder_shade, int radius, uint8 corners)
710 {
711 cairo_pattern_t *pat;
712 MurrineRGB shade1, shade2, shade3, shade4;
713 double alpha_value = mrn_gradient.use_rgba ? mrn_gradient.rgba_opacity : 1.0;
714 double top_alpha, mid_alpha, bottom_alpha, lower_alpha;
715 radius = MIN (radius, MIN ((double)width/2.0, (double)height/2.0));
716
717 if (mrn_gradient.has_gradient_colors)
718 {
719 murrine_shade (&mrn_gradient.gradient_colors[0], lightborder_shade*mrn_gradient.gradient_shades[0], &shade1);
720 murrine_shade (&mrn_gradient.gradient_colors[1], lightborder_shade*mrn_gradient.gradient_shades[1], &shade2);
721 murrine_shade (&mrn_gradient.gradient_colors[2], lightborder_shade*mrn_gradient.gradient_shades[2], &shade3);
722 murrine_shade (&mrn_gradient.gradient_colors[3], lightborder_shade*mrn_gradient.gradient_shades[3], &shade4);
723 }
724 else
725 {
726 murrine_shade (fill, lightborder_shade*mrn_gradient.gradient_shades[0], &shade1);
727 murrine_shade (fill, lightborder_shade*mrn_gradient.gradient_shades[1], &shade2);
728 murrine_shade (fill, lightborder_shade*mrn_gradient.gradient_shades[2], &shade3);
729 murrine_shade (fill, lightborder_shade*mrn_gradient.gradient_shades[3], &shade4);
730 }
731
732 cairo_save (cr);
733
734 double fill_pos = 1.0-1.0/(double)height;
735 if (corners == MRN_CORNER_ALL && radius > 2)
736 fill_pos = 1.0-(((double)radius-1.0)/2.0)/(double)height;
737
738 radius < 2 ? cairo_rectangle (cr, x, y, width, height) :
739 clearlooks_rounded_rectangle (cr, x, y, width, height, radius-1, corners);
740
741 pat = cairo_pattern_create_linear (x, y, x, height+y);
742
743 switch (lightborderstyle)
744 {
745 default:
746 case 0:
747 top_alpha = mid_alpha = bottom_alpha = 0.5;
748 lower_alpha = 0.0;
749 break;
750 case 1:
751 top_alpha = mid_alpha = bottom_alpha = lower_alpha = 0.5;
752 break;
753 case 2:
754 top_alpha = 0.5;
755 mid_alpha = 0.3;
756 bottom_alpha = 0.1;
757 lower_alpha = 0.0;
758 break;
759 case 3:
760 top_alpha = 0.5;
761 mid_alpha = 0.3;
762 bottom_alpha = 0.1;
763 lower_alpha = 0.1;
764 break;
765 }
766
767 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, top_alpha*alpha_value);
768 murrine_pattern_add_color_stop_rgba (pat, 0.49, &shade2, mid_alpha*alpha_value);
769 murrine_pattern_add_color_stop_rgba (pat, 0.49, &shade3, mid_alpha*alpha_value);
770 murrine_pattern_add_color_stop_rgba (pat, fill_pos, &shade4, bottom_alpha*alpha_value);
771 murrine_pattern_add_color_stop_rgba (pat, fill_pos, &shade4, lower_alpha*alpha_value);
772 murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade4, lower_alpha*alpha_value);
773 cairo_set_source (cr, pat);
774 cairo_pattern_destroy (pat);
775
776 cairo_stroke (cr);
777
778 if (glazestyle == 2)
779 {
780 murrine_set_gradient (cr, fill, mrn_gradient, x, y, 0, height, mrn_gradient.gradients, FALSE);
781 cairo_move_to (cr, width+x, y+0.5);
782 cairo_line_to (cr, width+x, height+y);
783 cairo_line_to (cr, x-0.5, height+y);
784 cairo_stroke (cr);
785 }
786
787 cairo_restore (cr);
788 }
789
790 void
murrine_draw_glaze(cairo_t * cr,const MurrineRGB * fill,double glow_shade,double highlight_shade,double lightborder_shade,MurrineGradients mrn_gradient,const WidgetParameters * widget,int x,int y,int width,int height,int radius,uint8 corners,boolean horizontal)791 murrine_draw_glaze (cairo_t *cr,
792 const MurrineRGB *fill,
793 double glow_shade,
794 double highlight_shade,
795 double lightborder_shade,
796 MurrineGradients mrn_gradient,
797 const WidgetParameters *widget,
798 int x, int y, int width, int height,
799 int radius, uint8 corners, boolean horizontal)
800 {
801 MurrineRGB highlight;
802 murrine_shade (fill, highlight_shade, &highlight);
803
804 murrine_set_gradient (cr, fill, mrn_gradient, x, y, 0, height, mrn_gradient.gradients, FALSE);
805 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
806 switch (widget->glazestyle)
807 {
808 default:
809 case 0:
810 cairo_fill (cr);
811 murrine_draw_flat_highlight (cr, x, y, width, height);
812 break;
813 case 1:
814 cairo_fill (cr);
815 murrine_draw_curved_highlight (cr, x, y, width, height);
816 break;
817 case 2:
818 cairo_fill_preserve (cr);
819 murrine_draw_curved_highlight (cr, x, y, width, height);
820 break;
821 case 3:
822 case 4:
823 cairo_fill (cr);
824 murrine_draw_curved_highlight_top (cr, x, y, width, height);
825 break;
826 case 5:
827 cairo_fill (cr);
828 murrine_draw_new_glossy_highlight (cr, x, y, width, height);
829 break;
830 }
831 murrine_set_gradient (cr, &highlight, mrn_gradient, x, y, 0, height, mrn_gradient.gradients, TRUE);
832 cairo_fill (cr);
833 if (widget->glazestyle == 4)
834 {
835 MurrineRGB shadow;
836 murrine_shade (fill, 1.0/highlight_shade, &shadow);
837
838 murrine_draw_curved_highlight_bottom (cr, x, y, width, height);
839 murrine_set_gradient (cr, &shadow, mrn_gradient, x, y, 0, height, mrn_gradient.gradients, TRUE);
840 cairo_fill (cr);
841 }
842
843 if (glow_shade != 1.0)
844 {
845 MurrineRGB glow;
846 murrine_shade (fill, glow_shade, &glow);
847
848 if (mrn_gradient.use_rgba)
849 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
850
851 switch (widget->glowstyle)
852 {
853 default:
854 case 0:
855 murrine_draw_top_glow (cr, &glow, x, y, width, height);
856 break;
857 case 1:
858 murrine_draw_bottom_glow (cr, &glow, x, y, width, height);
859 break;
860 case 2:
861 murrine_draw_top_glow (cr, &glow, x, y, width, height);
862 murrine_draw_bottom_glow (cr, &glow, x, y, width, height);
863 break;
864 case 3:
865 murrine_draw_horizontal_glow (cr, &glow, x, y, width, height);
866 break;
867 case 4:
868 murrine_draw_centered_glow (cr, &glow, x, y, width, height);
869 break;
870 case 5:
871 murrine_draw_blur_glow (cr, &glow, x, y, width, height, radius, corners);
872 break;
873 }
874 }
875
876 if (widget->glazestyle != 4 && lightborder_shade != 1.0)
877 {
878 if (mrn_gradient.use_rgba)
879 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
880
881 murrine_draw_lightborder (cr, fill, mrn_gradient,
882 x+0.5, y+0.5, width-1, height-1,
883 mrn_gradient.gradients,
884 widget->glazestyle, widget->lightborderstyle,
885 lightborder_shade*highlight_shade, radius, corners);
886 }
887 }
888
889 void
murrine_set_gradient(cairo_t * cr,const MurrineRGB * color,MurrineGradients mrn_gradient,int x,int y,int width,int height,boolean gradients,boolean alpha)890 murrine_set_gradient (cairo_t *cr,
891 const MurrineRGB *color,
892 MurrineGradients mrn_gradient,
893 int x, int y, int width, int height,
894 boolean gradients, boolean alpha)
895 {
896 double alpha_value = 1.0;
897 if (mrn_gradient.use_rgba)
898 {
899 alpha_value = mrn_gradient.rgba_opacity;
900 }
901 else if (alpha)
902 {
903 alpha_value *= 0.8;
904 }
905
906 if (mrn_gradient.has_gradient_colors)
907 {
908 cairo_pattern_t *pat;
909 MurrineRGB shade1, shade2, shade3, shade4;
910
911 murrine_shade (&mrn_gradient.gradient_colors[0], mrn_gradient.gradient_shades[0], &shade1);
912 murrine_shade (&mrn_gradient.gradient_colors[1], mrn_gradient.gradient_shades[1], &shade2);
913 murrine_shade (&mrn_gradient.gradient_colors[2], mrn_gradient.gradient_shades[2], &shade3);
914 murrine_shade (&mrn_gradient.gradient_colors[3], mrn_gradient.gradient_shades[3], &shade4);
915
916 pat = cairo_pattern_create_linear (x, y, width+x, height+y);
917
918 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, alpha_value);
919 murrine_pattern_add_color_stop_rgba (pat, 0.49, &shade2, alpha_value);
920 murrine_pattern_add_color_stop_rgba (pat, 0.49, &shade3, alpha_value);
921 murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade4, alpha_value);
922
923 cairo_set_source (cr, pat);
924 cairo_pattern_destroy (pat);
925 }
926 else if (gradients)
927 {
928 cairo_pattern_t *pat;
929 MurrineRGB shade1, shade2, shade3, shade4;
930
931 murrine_shade (color, mrn_gradient.gradient_shades[0], &shade1);
932 murrine_shade (color, mrn_gradient.gradient_shades[1], &shade2);
933 murrine_shade (color, mrn_gradient.gradient_shades[2], &shade3);
934 murrine_shade (color, mrn_gradient.gradient_shades[3], &shade4);
935
936 pat = cairo_pattern_create_linear (x, y, width+x, height+y);
937
938 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, alpha_value);
939 murrine_pattern_add_color_stop_rgba (pat, 0.49, &shade2, alpha_value);
940 murrine_pattern_add_color_stop_rgba (pat, 0.49, &shade3, alpha_value);
941 murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade4, alpha_value);
942
943 cairo_set_source (cr, pat);
944 cairo_pattern_destroy (pat);
945 }
946 else
947 {
948 murrine_set_color_rgba (cr, color, alpha_value);
949 }
950 }
951
952 void
murrine_draw_border_from_path(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height,MurrineGradients mrn_gradient,double alpha)953 murrine_draw_border_from_path (cairo_t *cr,
954 const MurrineRGB *color,
955 double x, double y, double width, double height,
956 MurrineGradients mrn_gradient, double alpha)
957 {
958 if (mrn_gradient.has_border_colors)
959 {
960 cairo_pattern_t *pat;
961 MurrineRGB shade1, shade2;
962
963 murrine_shade (&mrn_gradient.border_colors[0], mrn_gradient.border_shades[0], &shade1);
964 murrine_shade (&mrn_gradient.border_colors[1], mrn_gradient.border_shades[1], &shade2);
965
966 pat = cairo_pattern_create_linear (x, y, x, height+y);
967 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, alpha);
968 murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade2, alpha);
969
970 cairo_set_source (cr, pat);
971 cairo_pattern_destroy (pat);
972 }
973 else if (mrn_gradient.border_shades[0] != 1.0 ||
974 mrn_gradient.border_shades[1] != 1.0) // improve
975 {
976 cairo_pattern_t *pat;
977 MurrineRGB shade1, shade2;
978
979 murrine_shade (color, mrn_gradient.border_shades[0], &shade1);
980 murrine_shade (color, mrn_gradient.border_shades[1], &shade2);
981
982 pat = cairo_pattern_create_linear (x, y, x, height+y);
983 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, alpha);
984 murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade2, alpha);
985
986 cairo_set_source (cr, pat);
987 cairo_pattern_destroy (pat);
988 }
989 else
990 murrine_set_color_rgba (cr, color, alpha);
991
992 cairo_stroke (cr);
993 }
994
995 void
murrine_draw_border(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height,int roundness,uint8 corners,MurrineGradients mrn_gradient,double alpha)996 murrine_draw_border (cairo_t *cr,
997 const MurrineRGB *color,
998 double x, double y, double width, double height,
999 int roundness, uint8 corners,
1000 MurrineGradients mrn_gradient, double alpha)
1001 {
1002 murrine_rounded_rectangle (cr, x, y, width, height, roundness, corners);
1003 murrine_draw_border_from_path (cr, color, x, y, width, height, mrn_gradient, alpha);
1004 }
1005
1006 void
murrine_draw_shadow_from_path(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height,int reliefstyle,MurrineGradients mrn_gradient,double alpha)1007 murrine_draw_shadow_from_path (cairo_t *cr,
1008 const MurrineRGB *color,
1009 double x, double y, double width, double height,
1010 int reliefstyle,
1011 MurrineGradients mrn_gradient, double alpha)
1012 {
1013 if (mrn_gradient.shadow_shades[0] != 1.0 ||
1014 mrn_gradient.shadow_shades[1] != 1.0 ||
1015 reliefstyle > 2) // improve
1016 {
1017 cairo_pattern_t *pat;
1018 MurrineRGB shade1, shade2;
1019
1020 murrine_shade (color, mrn_gradient.shadow_shades[0], &shade1);
1021 murrine_shade (color, mrn_gradient.shadow_shades[1], &shade2);
1022
1023 pat = cairo_pattern_create_linear (x, y, x, height+y);
1024 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, reliefstyle == 3 ? 0.5*alpha : alpha);
1025 murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade2, reliefstyle >= 3 && reliefstyle != 5 ? 2.0*alpha : alpha);
1026
1027 cairo_set_source (cr, pat);
1028 cairo_pattern_destroy (pat);
1029 }
1030 else
1031 murrine_set_color_rgba (cr, color, alpha);
1032
1033 cairo_stroke (cr);
1034 }
1035
1036 void
murrine_draw_shadow(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height,int roundness,uint8 corners,int reliefstyle,MurrineGradients mrn_gradient,double alpha)1037 murrine_draw_shadow (cairo_t *cr,
1038 const MurrineRGB *color,
1039 double x, double y, double width, double height,
1040 int roundness, uint8 corners,
1041 int reliefstyle,
1042 MurrineGradients mrn_gradient, double alpha)
1043 {
1044 murrine_rounded_rectangle (cr, x, y, width, height, roundness, corners);
1045 murrine_draw_shadow_from_path (cr, color, x, y, width, height, reliefstyle, mrn_gradient, alpha);
1046 }
1047
1048 void
murrine_draw_trough_from_path(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height,MurrineGradients mrn_gradient,double alpha,boolean horizontal)1049 murrine_draw_trough_from_path (cairo_t *cr,
1050 const MurrineRGB *color,
1051 double x, double y, double width, double height,
1052 MurrineGradients mrn_gradient, double alpha,
1053 boolean horizontal)
1054 {
1055 if (mrn_gradient.trough_shades[0] != 1.0 ||
1056 mrn_gradient.trough_shades[1] != 1.0) // improve
1057 {
1058 cairo_pattern_t *pat;
1059 MurrineRGB shade1, shade2;
1060
1061 murrine_shade (color, mrn_gradient.trough_shades[0], &shade1);
1062 murrine_shade (color, mrn_gradient.trough_shades[1], &shade2);
1063
1064 pat = cairo_pattern_create_linear (x, y, horizontal ? x : width+x, horizontal ? height+y : y);
1065 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, alpha);
1066 murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade2, alpha);
1067
1068 cairo_set_source (cr, pat);
1069 cairo_pattern_destroy (pat);
1070 }
1071 else
1072 murrine_set_color_rgba (cr, color, alpha);
1073
1074 cairo_fill (cr);
1075 }
1076
1077 void
murrine_draw_trough(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height,int roundness,uint8 corners,MurrineGradients mrn_gradient,double alpha,boolean horizontal)1078 murrine_draw_trough (cairo_t *cr,
1079 const MurrineRGB *color,
1080 double x, double y, double width, double height,
1081 int roundness, uint8 corners,
1082 MurrineGradients mrn_gradient, double alpha,
1083 boolean horizontal)
1084 {
1085 murrine_rounded_rectangle_closed (cr, x, y, width, height, roundness, corners);
1086 murrine_draw_trough_from_path (cr, color, x, y, width, height, mrn_gradient, alpha, horizontal);
1087 }
1088
1089 void
murrine_draw_trough_border_from_path(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height,MurrineGradients mrn_gradient,double alpha,boolean horizontal)1090 murrine_draw_trough_border_from_path (cairo_t *cr,
1091 const MurrineRGB *color,
1092 double x, double y, double width, double height,
1093 MurrineGradients mrn_gradient, double alpha,
1094 boolean horizontal)
1095 {
1096 if (mrn_gradient.trough_border_shades[0] != 1.0 ||
1097 mrn_gradient.trough_border_shades[1] != 1.0 ||
1098 mrn_gradient.trough_shades[0] != 1.0 ||
1099 mrn_gradient.trough_shades[1] != 1.0) // improve
1100 {
1101 cairo_pattern_t *pat;
1102 MurrineRGB shade1, shade2;
1103
1104 murrine_shade (color, mrn_gradient.trough_shades[0]*mrn_gradient.trough_border_shades[0], &shade1);
1105 murrine_shade (color, mrn_gradient.trough_shades[1]*mrn_gradient.trough_border_shades[1], &shade2);
1106
1107 pat = cairo_pattern_create_linear (x, y, horizontal ? x : width+x, horizontal ? height+y : y);
1108 murrine_pattern_add_color_stop_rgba (pat, 0.00, &shade1, alpha);
1109 murrine_pattern_add_color_stop_rgba (pat, 1.00, &shade2, alpha);
1110
1111 cairo_set_source (cr, pat);
1112 cairo_pattern_destroy (pat);
1113 }
1114 else
1115 murrine_set_color_rgba (cr, color, alpha);
1116
1117 cairo_stroke (cr);
1118 }
1119
1120 void
murrine_draw_trough_border(cairo_t * cr,const MurrineRGB * color,double x,double y,double width,double height,int roundness,uint8 corners,MurrineGradients mrn_gradient,double alpha,boolean horizontal)1121 murrine_draw_trough_border (cairo_t *cr,
1122 const MurrineRGB *color,
1123 double x, double y, double width, double height,
1124 int roundness, uint8 corners,
1125 MurrineGradients mrn_gradient, double alpha,
1126 boolean horizontal)
1127 {
1128 murrine_rounded_rectangle (cr, x, y, width, height, roundness, corners);
1129 murrine_draw_trough_border_from_path (cr, color, x, y, width, height, mrn_gradient, alpha, horizontal);
1130 }
1131
1132 void
rotate_mirror_translate(cairo_t * cr,double radius,double x,double y,boolean mirror_horizontally,boolean mirror_vertically)1133 rotate_mirror_translate (cairo_t *cr,
1134 double radius, double x, double y,
1135 boolean mirror_horizontally, boolean mirror_vertically)
1136 {
1137 cairo_matrix_t matrix_rotate;
1138 cairo_matrix_t matrix_mirror;
1139 cairo_matrix_t matrix_result;
1140
1141 double r_cos = cos(radius);
1142 double r_sin = sin(radius);
1143
1144 cairo_matrix_init (&matrix_rotate, r_cos, r_sin, r_sin, r_cos, x, y);
1145
1146 cairo_matrix_init (&matrix_mirror,
1147 mirror_horizontally ? -1 : 1, 0, 0,
1148 mirror_vertically ? -1 : 1, 0, 0);
1149
1150 cairo_matrix_multiply (&matrix_result, &matrix_mirror, &matrix_rotate);
1151
1152 cairo_set_matrix (cr, &matrix_result);
1153 }
1154
1155 void
murrine_exchange_axis(cairo_t * cr,gint * x,gint * y,gint * width,gint * height)1156 murrine_exchange_axis (cairo_t *cr,
1157 gint *x,
1158 gint *y,
1159 gint *width,
1160 gint *height)
1161 {
1162 gint tmp;
1163 cairo_matrix_t matrix;
1164
1165 cairo_translate (cr, *x, *y);
1166 cairo_matrix_init (&matrix, 0, 1, 1, 0, 0, 0);
1167
1168 cairo_transform (cr, &matrix);
1169
1170 /* swap width/height */
1171 tmp = *width;
1172 *x = 0;
1173 *y = 0;
1174 *width = *height;
1175 *height = tmp;
1176 }
1177
1178 void
murrine_get_fill_color(MurrineRGB * color,const MurrineGradients * mrn_gradient)1179 murrine_get_fill_color (MurrineRGB *color,
1180 const MurrineGradients *mrn_gradient)
1181 {
1182 if (mrn_gradient->has_gradient_colors)
1183 {
1184 murrine_mix_color (&mrn_gradient->gradient_colors[1],
1185 &mrn_gradient->gradient_colors[2],
1186 0.5, color);
1187 }
1188 }
1189
1190 double
murrine_get_decreased_shade(double old,double factor)1191 murrine_get_decreased_shade (double old, double factor)
1192 {
1193 if (old > 1.0)
1194 return ((old-1.0)/factor+1.0);
1195 else if (old < 1.0)
1196 return (1.0-(1.0-old)/factor);
1197
1198 return old;
1199 }
1200
1201 double
murrine_get_increased_shade(double old,double factor)1202 murrine_get_increased_shade (double old, double factor)
1203 {
1204 if (old > 1.0)
1205 return ((old-1.0)*factor+1.0);
1206 else if (old < 1.0)
1207 return (1.0-(1.0-old)*factor);
1208
1209 return old;
1210 }
1211
1212 double
murrine_get_contrast(double old,double factor)1213 murrine_get_contrast (double old, double factor)
1214 {
1215 if (factor == 1.0)
1216 return old;
1217
1218 if (factor < 1.0)
1219 {
1220 if (old < 1.0)
1221 return old+(1.0-old)*(1.0-factor);
1222 else
1223 return old-(old-1.0)*(1.0-factor);
1224 }
1225 else
1226 {
1227 if (old < 1.0)
1228 return old-old*(factor-1.0);
1229 else
1230 return old+(old-1.0)*(factor-1.0);
1231 }
1232 }
1233
1234 double
murrine_get_inverted_shade(double old)1235 murrine_get_inverted_shade (double old)
1236 {
1237 if (old == 1.0)
1238 return old;
1239
1240 return CLAMP (2.0-old, 0.0, 2.0);
1241 }
1242
1243 MurrineGradients
murrine_get_inverted_border_shades(MurrineGradients mrn_gradient)1244 murrine_get_inverted_border_shades (MurrineGradients mrn_gradient)
1245 {
1246 MurrineGradients mrn_gradient_new = mrn_gradient;
1247
1248 mrn_gradient_new.border_shades[0] = mrn_gradient.border_shades[1];
1249 mrn_gradient_new.border_shades[1] = mrn_gradient.border_shades[0];
1250
1251 return mrn_gradient_new;
1252 }
1253
1254 MurrineGradients
murrine_get_decreased_gradient_shades(MurrineGradients mrn_gradient,double factor)1255 murrine_get_decreased_gradient_shades (MurrineGradients mrn_gradient, double factor)
1256 {
1257 MurrineGradients mrn_gradient_new = mrn_gradient;
1258
1259 mrn_gradient_new.gradient_shades[0] = murrine_get_decreased_shade (mrn_gradient.gradient_shades[0], factor);
1260 mrn_gradient_new.gradient_shades[1] = murrine_get_decreased_shade (mrn_gradient.gradient_shades[1], factor);
1261 mrn_gradient_new.gradient_shades[2] = murrine_get_decreased_shade (mrn_gradient.gradient_shades[2], factor);
1262 mrn_gradient_new.gradient_shades[3] = murrine_get_decreased_shade (mrn_gradient.gradient_shades[3], factor);
1263
1264 return mrn_gradient_new;
1265 }
1266