1 #include "gradient.h"
2 
3 #include <glib.h>
4 #include <stdlib.h>
5 #include <string.h>
6 
7 #include "common.h"
8 
read_double(const char * str,double * value)9 gboolean read_double(const char *str, double *value)
10 {
11     if (!str[0])
12         return FALSE;
13     char *end;
14     *value = strtod(str, &end);
15     if (end[0])
16         return FALSE;
17     return TRUE;
18 }
19 
read_double_with_percent(const char * str,double * value)20 gboolean read_double_with_percent(const char *str, double *value)
21 {
22     if (!str[0])
23         return FALSE;
24     char *end;
25     *value = strtod(str, &end);
26     if (end[0] == '%' && !end[1]) {
27         *value *= 0.01;
28         return TRUE;
29     }
30     if (end[0])
31         return FALSE;
32     return TRUE;
33 }
34 
gradient_type_from_string(const char * str)35 GradientType gradient_type_from_string(const char *str)
36 {
37     if (g_str_equal(str, "horizontal"))
38         return GRADIENT_HORIZONTAL;
39     if (g_str_equal(str, "vertical"))
40         return GRADIENT_VERTICAL;
41     if (g_str_equal(str, "radial"))
42         return GRADIENT_CENTERED;
43     fprintf(stderr, RED "tint2: Invalid gradient type: %s" RESET "\n", str);
44     return GRADIENT_VERTICAL;
45 }
46 
init_gradient(GradientClass * g,GradientType type)47 void init_gradient(GradientClass *g, GradientType type)
48 {
49     memset(g, 0, sizeof(*g));
50     g->type = type;
51     if (g->type == GRADIENT_VERTICAL) {
52         Offset *offset_top = (Offset *)calloc(1, sizeof(Offset));
53         offset_top->constant = TRUE;
54         offset_top->constant_value = 0;
55         g->from.offsets_y = g_list_append(g->from.offsets_y, offset_top);
56         Offset *offset_bottom = (Offset *)calloc(1, sizeof(Offset));
57         offset_bottom->constant = FALSE;
58         offset_bottom->element = ELEMENT_SELF;
59         offset_bottom->variable = SIZE_HEIGHT;
60         offset_bottom->multiplier = 1.0;
61         g->to.offsets_y = g_list_append(g->to.offsets_y, offset_bottom);
62     } else if (g->type == GRADIENT_HORIZONTAL) {
63         Offset *offset_left = (Offset *)calloc(1, sizeof(Offset));
64         offset_left->constant = TRUE;
65         offset_left->constant_value = 0;
66         g->from.offsets_x = g_list_append(g->from.offsets_x, offset_left);
67         Offset *offset_right = (Offset *)calloc(1, sizeof(Offset));
68         offset_right->constant = FALSE;
69         offset_right->element = ELEMENT_SELF;
70         offset_right->variable = SIZE_WIDTH;
71         offset_right->multiplier = 1.0;
72         g->to.offsets_x = g_list_append(g->to.offsets_x, offset_right);
73     } else if (g->type == GRADIENT_CENTERED) {
74         // from
75         Offset *offset_center_x = (Offset *)calloc(1, sizeof(Offset));
76         offset_center_x->constant = FALSE;
77         offset_center_x->element = ELEMENT_SELF;
78         offset_center_x->variable = SIZE_CENTERX;
79         offset_center_x->multiplier = 1.0;
80         g->from.offsets_x = g_list_append(g->from.offsets_x, offset_center_x);
81         Offset *offset_center_y = (Offset *)calloc(1, sizeof(Offset));
82         offset_center_y->constant = FALSE;
83         offset_center_y->element = ELEMENT_SELF;
84         offset_center_y->variable = SIZE_CENTERY;
85         offset_center_y->multiplier = 1.0;
86         g->from.offsets_y = g_list_append(g->from.offsets_y, offset_center_y);
87         Offset *offset_center_r = (Offset *)calloc(1, sizeof(Offset));
88         offset_center_r->constant = TRUE;
89         offset_center_r->constant_value = 0;
90         g->from.offsets_r = g_list_append(g->from.offsets_r, offset_center_r);
91         // to
92         offset_center_x = (Offset *)calloc(1, sizeof(Offset));
93         offset_center_x->constant = FALSE;
94         offset_center_x->element = ELEMENT_SELF;
95         offset_center_x->variable = SIZE_CENTERX;
96         offset_center_x->multiplier = 1.0;
97         g->to.offsets_x = g_list_append(g->to.offsets_x, offset_center_x);
98         offset_center_y = (Offset *)calloc(1, sizeof(Offset));
99         offset_center_y->constant = FALSE;
100         offset_center_y->element = ELEMENT_SELF;
101         offset_center_y->variable = SIZE_CENTERY;
102         offset_center_y->multiplier = 1.0;
103         g->to.offsets_y = g_list_append(g->to.offsets_y, offset_center_y);
104         offset_center_r = (Offset *)calloc(1, sizeof(Offset));
105         offset_center_r->constant = FALSE;
106         offset_center_r->element = ELEMENT_SELF;
107         offset_center_r->variable = SIZE_RADIUS;
108         offset_center_r->multiplier = 1.0;
109         g->to.offsets_r = g_list_append(g->to.offsets_r, offset_center_r);
110     }
111 }
112 
cleanup_gradient(GradientClass * g)113 void cleanup_gradient(GradientClass *g)
114 {
115     g_list_free_full(g->extra_color_stops, free);
116     g_list_free_full(g->from.offsets_x, free);
117     g_list_free_full(g->from.offsets_y, free);
118     g_list_free_full(g->from.offsets_r, free);
119     g_list_free_full(g->to.offsets_x, free);
120     g_list_free_full(g->to.offsets_y, free);
121     g_list_free_full(g->to.offsets_r, free);
122     bzero(g, sizeof(*g));
123 }
124