efl/legacy/evas/src/modules/engines/xrender_x11/evas_engine_gradient.c

216 lines
4.8 KiB
C

#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_X11.h"
#include <math.h>
XR_Gradient *
_xre_gradient_new(Ximage_Info *xinf)
{
XR_Gradient *gr;
if (!xinf) return NULL;
gr = calloc(1, sizeof(XR_Gradient));
if (!gr) return NULL;
gr->grad = evas_common_gradient_new();
if (!gr->grad)
{
free(gr);
return NULL;
}
gr->xinf = xinf;
gr->xinf->references++;
gr->changed = 1;
return gr;
}
void
_xre_gradient_free(XR_Gradient *gr)
{
if (!gr) return;
if (gr->grad)
evas_common_gradient_free(gr->grad);
if (gr->surface)
_xr_render_surface_free(gr->surface);
_xr_image_info_free(gr->xinf);
free(gr);
}
void
_xre_gradient_color_stop_add(XR_Gradient *gr, int r, int g, int b, int a, int delta)
{
if (!gr) return;
evas_common_gradient_color_stop_add(gr->grad, r, g, b, a, delta);
gr->changed = 1;
}
void
_xre_gradient_alpha_stop_add(XR_Gradient *gr, int a, int delta)
{
if (!gr) return;
evas_common_gradient_alpha_stop_add(gr->grad, a, delta);
gr->changed = 1;
}
void
_xre_gradient_clear(XR_Gradient *gr)
{
if (!gr) return;
evas_common_gradient_clear(gr->grad);
gr->changed = 1;
}
void
_xre_gradient_color_data_set(XR_Gradient *gr, void *map, int len, int has_alpha)
{
evas_common_gradient_color_data_set(gr->grad, map, len, has_alpha);
gr->changed = 1;
}
void
_xre_gradient_alpha_data_set(XR_Gradient *gr, void *amap, int len)
{
evas_common_gradient_alpha_data_set(gr->grad, amap, len);
gr->changed = 1;
}
void
_xre_gradient_fill_set(XR_Gradient *gr, int x, int y, int w, int h)
{
if (!gr) return;
evas_common_gradient_fill_set(gr->grad, x, y, w, h);
gr->changed = 1;
}
void
_xre_gradient_fill_angle_set(XR_Gradient *gr, double angle)
{
if (!gr) return;
evas_common_gradient_fill_angle_set(gr->grad, angle);
gr->changed = 1;
}
void
_xre_gradient_fill_spread_set(XR_Gradient *gr, int spread)
{
if (!gr) return;
evas_common_gradient_fill_spread_set(gr->grad, spread);
gr->changed = 1;
}
void
_xre_gradient_angle_set(XR_Gradient *gr, double angle)
{
if (!gr) return;
evas_common_gradient_map_angle_set(gr->grad, angle);
gr->changed = 1;
}
void
_xre_gradient_offset_set(XR_Gradient *gr, float offset)
{
if (!gr) return;
evas_common_gradient_map_offset_set(gr->grad, offset);
gr->changed = 1;
}
void
_xre_gradient_direction_set(XR_Gradient *gr, int direction)
{
if (!gr) return;
evas_common_gradient_map_direction_set(gr->grad, direction);
gr->changed = 1;
}
void
_xre_gradient_type_set(XR_Gradient *gr, char *name, char *params)
{
if (!gr) return;
evas_common_gradient_type_set(gr->grad, name, params);
gr->changed = 1;
}
void
_xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h)
{
int alpha = 0;
if ((w < 1) || (h < 1)) return;
if (!rs || !dc || !gr) return;
if (!gr->xinf || !gr->grad || !gr->grad->type.geometer) return;
if (gr->grad->type.geometer->has_alpha(gr->grad, dc->render_op) ||
gr->grad->type.geometer->has_mask(gr->grad, dc->render_op))
alpha = 1;
if (((gr->sw != w) || (gr->sh != h)) && gr->surface)
{
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
gr->changed = 1;
}
if (!gr->surface)
{
gr->surface = _xr_render_surface_new(gr->xinf, w, h, gr->xinf->fmt32, 1);
if (!gr->surface) return;
gr->changed = 1;
}
if (gr->changed)
{
int op = dc->render_op, cuse = dc->clip.use;
RGBA_Image *im;
Ximage_Image *xim;
im = evas_common_image_new();
if (!im)
{
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
return;
}
im->image = evas_common_image_surface_new(im);
if (!im->image)
{
evas_common_image_delete(im);
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
return;
}
xim = _xr_image_new(gr->xinf, w, h, gr->surface->depth);
if (!xim)
{
evas_common_image_delete(im);
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
return;
}
im->image->data = (DATA32 *)xim->data;
im->image->w = w; im->image->h = h;
im->image->no_free = 1;
dc->render_op = _EVAS_RENDER_FILL;
dc->clip.use = 0;
evas_common_gradient_draw(im, dc, 0, 0, w, h, gr->grad);
if
#ifdef WORDS_BIGENDIAN
(xim->xim->byte_order == LSBFirst)
#else
(xim->xim->byte_order == MSBFirst)
#endif
{
DATA32 *p = im->image->data, *pe = p + (w * h);
while (p < pe)
{
*p = (*p << 24) + ((*p << 8) & 0xff0000) + ((*p >> 8) & 0xff00) + (*p >> 24);
p++;
}
}
_xr_image_put(xim, gr->surface->draw, 0, 0, w, h);
evas_common_image_delete(im);
dc->render_op = op;
dc->clip.use = cuse;
}
gr->surface->alpha = alpha;
_xr_render_surface_composite(gr->surface, rs, dc, 0, 0, gr->surface->w, gr->surface->h, x, y, w, h, 0);
gr->changed = 0;
gr->sw = w; gr->sh = h;
}