move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / xrender_x11 / evas_engine_gradient.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3 #include "evas_engine.h"
4 #include "Evas_Engine_XRender_X11.h"
5 #include <math.h>
6
7 XR_Gradient *
8 _xre_gradient_new(Ximage_Info *xinf)
9 {
10    XR_Gradient  *gr;
11
12    if (!xinf) return NULL;
13    gr = calloc(1, sizeof(XR_Gradient));
14    if (!gr) return NULL;
15    gr->grad = evas_common_gradient_new();
16    if (!gr->grad)
17      {
18         free(gr);
19         return NULL;
20      }
21    gr->xinf = xinf;
22    gr->xinf->references++;
23    gr->changed = 1;
24    return gr;
25 }
26
27 void
28 _xre_gradient_free(XR_Gradient *gr)
29 {
30    if (!gr) return;
31    if (gr->grad)
32         evas_common_gradient_free(gr->grad);
33    if (gr->surface)
34         _xr_render_surface_free(gr->surface);
35    _xr_image_info_free(gr->xinf);
36    free(gr);
37 }
38
39 void
40 _xre_gradient_color_stop_add(XR_Gradient *gr, int r, int g, int b, int a, int delta)
41 {
42    if (!gr) return;
43    evas_common_gradient_color_stop_add(gr->grad, r, g, b, a, delta);
44    gr->changed = 1;
45 }
46
47 void
48 _xre_gradient_alpha_stop_add(XR_Gradient *gr, int a, int delta)
49 {
50    if (!gr) return;
51    evas_common_gradient_alpha_stop_add(gr->grad, a, delta);
52    gr->changed = 1;
53 }
54
55 void
56 _xre_gradient_clear(XR_Gradient *gr)
57 {
58    if (!gr) return;
59    evas_common_gradient_clear(gr->grad);
60    gr->changed = 1;
61 }
62
63 void
64 _xre_gradient_color_data_set(XR_Gradient *gr, void *map, int len, int has_alpha)
65 {
66    evas_common_gradient_color_data_set(gr->grad, map, len, has_alpha);
67    gr->changed = 1;
68 }
69
70 void
71 _xre_gradient_alpha_data_set(XR_Gradient *gr, void *amap, int len)
72 {
73    evas_common_gradient_alpha_data_set(gr->grad, amap, len);
74    gr->changed = 1;
75 }
76
77 void
78 _xre_gradient_fill_set(XR_Gradient *gr, int x, int y, int w, int h)
79 {
80    if (!gr) return;
81    evas_common_gradient_fill_set(gr->grad, x, y, w, h);
82    gr->changed = 1;
83 }
84
85 void
86 _xre_gradient_fill_angle_set(XR_Gradient *gr, double angle)
87 {
88    if (!gr) return;
89    evas_common_gradient_fill_angle_set(gr->grad, angle);
90    gr->changed = 1;
91 }
92
93 void
94 _xre_gradient_fill_spread_set(XR_Gradient *gr, int spread)
95 {
96    if (!gr) return;
97    evas_common_gradient_fill_spread_set(gr->grad, spread);
98    gr->changed = 1;
99 }
100
101 void
102 _xre_gradient_angle_set(XR_Gradient *gr, double angle)
103 {
104    if (!gr) return;
105    evas_common_gradient_map_angle_set(gr->grad, angle);
106    gr->changed = 1;
107 }
108
109 void
110 _xre_gradient_offset_set(XR_Gradient *gr, float offset)
111 {
112    if (!gr) return;
113    evas_common_gradient_map_offset_set(gr->grad, offset);
114    gr->changed = 1;
115 }
116
117 void
118 _xre_gradient_direction_set(XR_Gradient *gr, int direction)
119 {
120    if (!gr) return;
121    evas_common_gradient_map_direction_set(gr->grad, direction);
122    gr->changed = 1;
123 }
124
125 void
126 _xre_gradient_type_set(XR_Gradient *gr, char *name, char *params)
127 {
128    if (!gr) return;
129    evas_common_gradient_type_set(gr->grad, name, params);
130    gr->changed = 1;
131 }
132
133 void
134 _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h)
135 {
136    int alpha = 0;
137
138    if ((w < 1) || (h < 1)) return;
139    if (!rs || !dc || !gr) return;
140    if (!gr->xinf || !gr->grad || !gr->grad->type.geometer) return;
141
142    if (gr->grad->type.geometer->has_alpha(gr->grad, dc->render_op) ||
143         gr->grad->type.geometer->has_mask(gr->grad, dc->render_op))
144         alpha = 1;
145    if (((gr->sw != w) || (gr->sh != h)) && gr->surface)
146      {
147         _xr_render_surface_free(gr->surface);
148         gr->surface = NULL;
149         gr->changed = 1;
150      }
151    if (!gr->surface)
152      {
153         gr->surface = _xr_render_surface_new(gr->xinf, w, h, gr->xinf->fmt32, 1);
154         if (!gr->surface) return;
155         gr->changed = 1;
156      }
157    if (gr->changed)
158      {
159         int op = dc->render_op, cuse = dc->clip.use;
160         RGBA_Image    *im;
161         Ximage_Image  *xim;
162
163         xim = _xr_image_new(gr->xinf, w, h, gr->surface->depth);
164         if (!xim)
165           {
166             _xr_render_surface_free(gr->surface);
167             gr->surface = NULL;
168             return;
169           }
170
171         im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
172                                                   w, h,
173                                                   (DATA32 *)xim->data,
174                                                   1, EVAS_COLORSPACE_ARGB8888);
175         if (!im)
176           {
177              /* FIXME: xim is leaking. */
178             _xr_render_surface_free(gr->surface);
179             gr->surface = NULL;
180             return;
181           }
182
183         dc->render_op = _EVAS_RENDER_FILL;
184         dc->clip.use = 0;
185         evas_common_gradient_draw(im, dc, 0, 0, w, h, gr->grad);
186         if
187 #ifdef WORDS_BIGENDIAN
188            (xim->xim->byte_order == LSBFirst)
189 #else
190            (xim->xim->byte_order == MSBFirst)
191 #endif
192           {
193              DATA32  *p = im->image.data, *pe = p + (w * h);
194              while (p < pe)
195                {
196                   *p = (*p << 24) + ((*p << 8) & 0xff0000) + ((*p >> 8) & 0xff00) + (*p >> 24);
197                   p++;
198                }
199           }
200         _xr_image_put(xim, gr->surface->draw, 0, 0, w, h);
201         evas_cache_image_drop(&im->cache_entry);
202         dc->render_op = op;
203         dc->clip.use = cuse;
204      }
205    gr->surface->alpha = alpha;
206    _xr_render_surface_composite(gr->surface, rs, dc, 0, 0, gr->surface->w, gr->surface->h, x, y, w, h, 0);
207    gr->changed = 0;
208    gr->sw = w;  gr->sh = h;
209 }