forked from enlightenment/efl
add color to the vertexes in map. this allows for fading/shading of
reflections, goraud shading for smooth 3d surfaces, mor realistic lighting etc. etc. it comes at a small cost, but worth it. SVN revision: 43384
This commit is contained in:
parent
e014cd7d72
commit
069de70853
|
@ -104,8 +104,7 @@ typedef enum _Evas_Object_Table_Homogeneous_Mode
|
|||
typedef struct _Evas_Transform Evas_Transform; /**< An Evas projective or affine transform */
|
||||
typedef struct _Evas_Coord_Rectangle Evas_Coord_Rectangle; /**< A generic rectangle handle */
|
||||
typedef struct _Evas_Smart_Class Evas_Smart_Class; /**< A smart object base class */
|
||||
typedef struct _Evas_Map_Point Evas_Map_Point; /**< A point with attributes for x, y, z texture u & v etc. */
|
||||
typedef struct _Evas_Map Evas_Map; /**< An array of map points */
|
||||
typedef struct _Evas_Map Evas_Map; /**< An array of map points */
|
||||
|
||||
typedef struct _Evas Evas; /**< An Evas canvas handle */
|
||||
typedef struct _Evas_Object Evas_Object; /**< An Evas Object handle */
|
||||
|
@ -868,7 +867,9 @@ extern "C" {
|
|||
EAPI void evas_map_point_coord_get (const Evas_Map *m, int idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z);
|
||||
EAPI void evas_map_point_image_uv_set (Evas_Map *m, int idx, double u, double v);
|
||||
EAPI void evas_map_point_image_uv_get (const Evas_Map *m, int idx, double *u, double *v);
|
||||
|
||||
EAPI void evas_map_point_color_set (Evas_Map *m, int idx, int r, int g, int b, int a);
|
||||
EAPI void evas_map_point_color_get (const Evas_Map *m, int idx, int *r, int *g, int *b, int *a);
|
||||
|
||||
/* smart objects */
|
||||
EINA_DEPRECATED EAPI Evas_Smart *evas_smart_new (const char *name, void (*func_add) (Evas_Object *obj), void (*func_del) (Evas_Object *obj), void (*func_layer_set) (Evas_Object *obj, int l), void (*func_raise) (Evas_Object *obj), void (*func_lower) (Evas_Object *obj), void (*func_stack_above) (Evas_Object *obj, Evas_Object *above), void (*func_stack_below) (Evas_Object *obj, Evas_Object *below), void (*func_move) (Evas_Object *obj, Evas_Coord x, Evas_Coord y), void (*func_resize) (Evas_Object *obj, Evas_Coord w, Evas_Coord h), void (*func_show) (Evas_Object *obj), void (*func_hide) (Evas_Object *obj), void (*func_color_set) (Evas_Object *obj, int r, int g, int b, int a), void (*func_clip_set) (Evas_Object *obj, Evas_Object *clip), void (*func_clip_unset) (Evas_Object *obj), const void *data) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
||||
EAPI void evas_smart_free (Evas_Smart *s) EINA_ARG_NONNULL(1);
|
||||
|
|
|
@ -63,23 +63,23 @@ _evas_map_calc_map_geometry(Evas_Object *obj)
|
|||
static inline Evas_Map *
|
||||
_evas_map_new(int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
Evas_Map *m = calloc(1, sizeof(Evas_Map) + count * sizeof(Evas_Map_Point));
|
||||
if (!m) return NULL;
|
||||
m->count = count;
|
||||
m->alpha = 1;
|
||||
m->smooth = 1;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
m->points[i].r = 255;
|
||||
m->points[i].g = 255;
|
||||
m->points[i].b = 255;
|
||||
m->points[i].a = 255;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
static inline Evas_Map *
|
||||
_evas_map_dup(const Evas_Map *orig)
|
||||
{
|
||||
Evas_Map *copy = _evas_map_new(orig->count);
|
||||
if (!copy) return NULL;
|
||||
memcpy(copy->points, orig->points, orig->count * sizeof(Evas_Map_Point));
|
||||
return copy;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_evas_map_copy(Evas_Map *dst, const Evas_Map *src)
|
||||
{
|
||||
|
@ -94,6 +94,17 @@ _evas_map_copy(Evas_Map *dst, const Evas_Map *src)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static inline Evas_Map *
|
||||
_evas_map_dup(const Evas_Map *orig)
|
||||
{
|
||||
Evas_Map *copy = _evas_map_new(orig->count);
|
||||
if (!copy) return NULL;
|
||||
memcpy(copy->points, orig->points, orig->count * sizeof(Evas_Map_Point));
|
||||
copy->smooth = orig->smooth;
|
||||
copy->alpha = orig->alpha;
|
||||
return copy;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_evas_map_free(Evas_Map *m)
|
||||
{
|
||||
|
@ -516,6 +527,67 @@ evas_map_point_image_uv_get(const Evas_Map *m, int idx, double *u, double *v)
|
|||
if (v) *v = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of a vertex in the map
|
||||
*
|
||||
* This sets the color of the vertex in the map. Colors will be linearly
|
||||
* interpolated between vertex points through the map. Color will multiply
|
||||
* the "texture" pixels (like GL_MODULATE in OpenGL). The default color of
|
||||
* a vertex in a map is white solid (255, 255, 255, 255) which means it will
|
||||
* have no affect on modifying the texture pixels.
|
||||
*
|
||||
* @param m map to change the color of.
|
||||
* @param idx index of point to change. Must be smaller than map size.
|
||||
* @param r red (0 - 255)
|
||||
* @param g green (0 - 255)
|
||||
* @param b blue (0 - 255)
|
||||
* @param a alpha (0 - 255)
|
||||
*
|
||||
* @see evas_map_point_coord_set()
|
||||
* @see evas_object_map_set()
|
||||
*/
|
||||
EAPI void
|
||||
evas_map_point_color_set(Evas_Map *m, int idx, int r, int g, int b, int a)
|
||||
{
|
||||
Evas_Map_Point *p;
|
||||
if (!m) return;
|
||||
if (idx >= m->count) return;
|
||||
p = m->points + idx;
|
||||
p->r = r;
|
||||
p->g = g;
|
||||
p->b = b;
|
||||
p->a = a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color set on a vertex in the map
|
||||
*
|
||||
* This gets the color set by evas_map_point_color_set() on the given vertex
|
||||
* of the map.
|
||||
*
|
||||
* @param m map to get the color of the vertex from.
|
||||
* @param idx index of point get. Must be smaller than map size.
|
||||
* @param r pointer to red return
|
||||
* @param g pointer to green return
|
||||
* @param b pointer to blue return
|
||||
* @param a pointer to alpha return (0 - 255)
|
||||
*
|
||||
* @see evas_map_point_coord_set()
|
||||
* @see evas_object_map_set()
|
||||
*/
|
||||
EAPI void
|
||||
evas_map_point_color_get(const Evas_Map *m, int idx, int *r, int *g, int *b, int *a)
|
||||
{
|
||||
Evas_Map_Point *p;
|
||||
if (!m) return;
|
||||
if (idx >= m->count) return;
|
||||
p = m->points + idx;
|
||||
if (r) *r = p->r;
|
||||
if (g) *g = p->g;
|
||||
if (b) *b = p->b;
|
||||
if (a) *a = p->a;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* util functions for manipulating maps, so you don't need to know the math */
|
||||
/****************************************************************************/
|
||||
|
|
|
@ -2346,7 +2346,10 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
|
|||
pt->z = (p->z) << FP;
|
||||
pt->u = p->u * FP1;
|
||||
pt->v = p->v * FP1;
|
||||
}
|
||||
pt->col =
|
||||
(((DATA32)p->a) << 24) | (((DATA32)p->r) << 16) |
|
||||
(((DATA32)p->g) << 8) | (((DATA32)p->b));
|
||||
}
|
||||
obj->layer->evas->engine.func->image_map4_draw
|
||||
(output, context, surface, o->engine_data, pts,
|
||||
o->cur.smooth_scale | obj->cur.map->smooth, 0);
|
||||
|
|
|
@ -383,7 +383,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int
|
|||
{
|
||||
const Evas_Map_Point *p, *p_end;
|
||||
RGBA_Map_Point pts[4], *pt;
|
||||
void *ctx, *ctx2;
|
||||
void *ctx;
|
||||
int sw, sh;
|
||||
int changed = 0;
|
||||
|
||||
|
@ -401,6 +401,9 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int
|
|||
pt->z = (p->z) << FP;
|
||||
pt->u = p->u * FP1;
|
||||
pt->v = p->v * FP1;
|
||||
pt->col =
|
||||
(((DATA32)p->a) << 24) | (((DATA32)p->r) << 16) |
|
||||
(((DATA32)p->g) << 8) | (((DATA32)p->b));
|
||||
}
|
||||
|
||||
if (obj->cur.map->surface)
|
||||
|
@ -448,21 +451,22 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int
|
|||
// clear surface before re-render
|
||||
if ((changed) && (obj->cur.map->surface))
|
||||
{
|
||||
ctx2 = e->engine.func->context_new(e->engine.data.output);
|
||||
e->engine.func->context_color_set
|
||||
(e->engine.data.output, ctx2, 0, 0, 0, 0);
|
||||
e->engine.func->context_render_op_set
|
||||
(e->engine.data.output, ctx2, EVAS_RENDER_COPY);
|
||||
e->engine.func->rectangle_draw(e->engine.data.output,
|
||||
ctx2,
|
||||
obj->cur.map->surface,
|
||||
0, 0,
|
||||
obj->cur.map->surface_w,
|
||||
obj->cur.map->surface_h);
|
||||
e->engine.func->context_free(e->engine.data.output, ctx2);
|
||||
|
||||
if (obj->cur.map->alpha)
|
||||
{
|
||||
ctx = e->engine.func->context_new(e->engine.data.output);
|
||||
e->engine.func->context_color_set
|
||||
(e->engine.data.output, ctx, 0, 0, 0, 0);
|
||||
e->engine.func->context_render_op_set
|
||||
(e->engine.data.output, ctx, EVAS_RENDER_COPY);
|
||||
e->engine.func->rectangle_draw(e->engine.data.output,
|
||||
ctx,
|
||||
obj->cur.map->surface,
|
||||
0, 0,
|
||||
obj->cur.map->surface_w,
|
||||
obj->cur.map->surface_h);
|
||||
e->engine.func->context_free(e->engine.data.output, ctx);
|
||||
}
|
||||
ctx = e->engine.func->context_new(e->engine.data.output);
|
||||
|
||||
// FIXME: only re-render if obj changed or smart children or size changed etc.
|
||||
if (obj->smart.smart)
|
||||
{
|
||||
|
|
|
@ -109,7 +109,9 @@ evas_scale_smooth_scaler_up.c \
|
|||
evas_scale_span.h \
|
||||
evas_pipe.h \
|
||||
evas_intl_utils.h \
|
||||
evas_map_image_internal.c
|
||||
evas_map_image_internal.c \
|
||||
evas_map_image_core.c \
|
||||
evas_map_image_loop.c
|
||||
|
||||
libevas_engine_common_la_DEPENDENCIES = \
|
||||
$(top_builddir)/config.h
|
||||
|
|
|
@ -26,6 +26,7 @@ struct _Span
|
|||
int x1, x2;
|
||||
FPc o1, o2;
|
||||
FPc u[2], v[2];
|
||||
DATA32 col[2];
|
||||
};
|
||||
|
||||
struct _Line
|
||||
|
@ -45,13 +46,26 @@ _interp(int x1, int x2, int p, FPc u1, FPc u2)
|
|||
return u1 + u;
|
||||
}
|
||||
|
||||
static DATA32
|
||||
_interp_col(int x1, int x2, int p, DATA32 col1, DATA32 col2)
|
||||
{
|
||||
DATA32 col;
|
||||
|
||||
x2 -= x1;
|
||||
p -= x1;
|
||||
p = (p << 8) / (x2 + 1);
|
||||
return INTERP_256(p, col2, col1);
|
||||
}
|
||||
|
||||
static void
|
||||
_limit(Span *s, int c1, int c2)
|
||||
_limit(Span *s, int c1, int c2, int nocol)
|
||||
{
|
||||
if (s->x1 < c1)
|
||||
{
|
||||
s->u[0] = _interp(s->x1, s->x2, c1, s->u[0], s->u[1]);
|
||||
s->v[0] = _interp(s->x1, s->x2, c1, s->v[0], s->v[1]);
|
||||
if (!nocol)
|
||||
s->col[0] = _interp_col(s->x1, s->x2, c1, s->col[0], s->col[1]);
|
||||
s->x1 = c1;
|
||||
s->o1 = c1 << FP;
|
||||
}
|
||||
|
@ -59,6 +73,8 @@ _limit(Span *s, int c1, int c2)
|
|||
{
|
||||
s->u[1] = _interp(s->x1, s->x2, c2, s->u[0], s->u[1]);
|
||||
s->v[1] = _interp(s->x1, s->x2, c2, s->v[0], s->v[1]);
|
||||
if (!nocol)
|
||||
s->col[1] = _interp_col(s->x1, s->x2, c2, s->col[0], s->col[1]);
|
||||
s->x2 = c2;
|
||||
s->o2 = c2 << FP;
|
||||
}
|
||||
|
@ -72,6 +88,7 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
|||
int py[4];
|
||||
int edge[4][4], edge_num, swapped, order[4];
|
||||
FPc uv[4][2], u, v, x, h, t;
|
||||
DATA32 col[4];
|
||||
|
||||
#if 1 // maybe faster on x86?
|
||||
for (i = 0; i < 4; i++) py[i] = p[i].y >> FP;
|
||||
|
@ -83,12 +100,14 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
|||
if ((PY(0) == PY(1)) && (PY(0) == PY(2)) && (PY(0) == PY(3)))
|
||||
{
|
||||
int leftp, rightp;
|
||||
int nocol = 1;
|
||||
|
||||
leftp = rightp = 0;
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
if (p[i].x < p[leftp].x) leftp = i;
|
||||
if (p[i].x > p[rightp].x) rightp = i;
|
||||
if (p[i].col != 0xffffffff) nocol = 0;
|
||||
}
|
||||
for (y = ystart; y <= yend; y++)
|
||||
{
|
||||
|
@ -100,16 +119,18 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
|||
spans[yp].span[i].o1 = p[leftp].x;
|
||||
spans[yp].span[i].u[0] = p[leftp].u;
|
||||
spans[yp].span[i].v[0] = p[leftp].v;
|
||||
spans[yp].span[i].col[0] = p[leftp].col;
|
||||
spans[yp].span[i].x2 = p[rightp].x >> FP;
|
||||
spans[yp].span[i].o2 = p[rightp].x;
|
||||
spans[yp].span[i].u[1] = p[rightp].u;
|
||||
spans[yp].span[i].v[1] = p[rightp].v;
|
||||
spans[yp].span[i].col[1] = p[rightp].col;
|
||||
if ((spans[yp].span[i].x1 >= (cx + cw)) ||
|
||||
(spans[yp].span[i].x2 < cx))
|
||||
spans[yp].span[i].x1 = -1;
|
||||
else
|
||||
{
|
||||
_limit(&(spans[yp].span[i]), cx, cx + cw);
|
||||
_limit(&(spans[yp].span[i]), cx, cx + cw, nocol);
|
||||
i++;
|
||||
spans[yp].span[i].x1 = -1;
|
||||
}
|
||||
|
@ -122,6 +143,8 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
|||
|
||||
for (y = ystart; y <= yend; y++)
|
||||
{
|
||||
int nocol = 1;
|
||||
|
||||
yp = y - ystart;
|
||||
edge_num = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
|
@ -138,12 +161,14 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
|||
edge[edge_num][1] = i;
|
||||
edge_num++;
|
||||
}
|
||||
if (p[i].col != 0xffffffff) nocol = 0;
|
||||
}
|
||||
// calculate line x points for each edge
|
||||
for (i = 0; i < edge_num; i++)
|
||||
{
|
||||
int e1 = edge[i][0];
|
||||
int e2 = edge[i][1];
|
||||
FPc t256;
|
||||
|
||||
h = (p[e2].y - p[e1].y) >> FP; // height of edge
|
||||
t = (((y << FP) + (FP1 - 1)) - p[e1].y) >> FP;
|
||||
|
@ -156,6 +181,9 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
|||
v = p[e2].v - p[e1].v;
|
||||
v = p[e1].v + ((v * t) / h);
|
||||
|
||||
t256 = (t << 8) / h; // maybe * 255?
|
||||
col[i] = INTERP_256(t256, p[e2].col, p[e1].col);
|
||||
|
||||
uv[i][1] = v;
|
||||
uv[i][0] = u;
|
||||
edge[i][2] = x >> FP;
|
||||
|
@ -186,16 +214,19 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
|||
spans[yp].span[i].o1 = edge[order[0]][3];
|
||||
spans[yp].span[i].u[0] = uv[order[0]][0];
|
||||
spans[yp].span[i].v[0] = uv[order[0]][1];
|
||||
spans[yp].span[i].col[0] = col[order[0]];
|
||||
|
||||
spans[yp].span[i].x2 = edge[order[1]][2];
|
||||
spans[yp].span[i].o2 = edge[order[1]][3];
|
||||
spans[yp].span[i].u[1] = uv[order[1]][0];
|
||||
spans[yp].span[i].v[1] = uv[order[1]][1];
|
||||
spans[yp].span[i].col[1] = col[order[1]];
|
||||
if ((spans[yp].span[i].x1 >= (cx + cw)) ||
|
||||
(spans[yp].span[i].x2 < cx))
|
||||
spans[yp].span[i].x1 = -1;
|
||||
else
|
||||
{
|
||||
_limit(&(spans[yp].span[i]), cx, cx + cw);
|
||||
_limit(&(spans[yp].span[i]), cx, cx + cw, nocol);
|
||||
i++;
|
||||
spans[yp].span[i].x1 = -1;
|
||||
}
|
||||
|
@ -206,23 +237,29 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
|||
spans[yp].span[i].x1 = edge[order[0]][2];
|
||||
spans[yp].span[i].u[0] = uv[order[0]][0];
|
||||
spans[yp].span[i].v[0] = uv[order[0]][1];
|
||||
spans[yp].span[i].col[0] = col[order[0]];
|
||||
|
||||
spans[yp].span[i].x2 = edge[order[1]][2];
|
||||
spans[yp].span[i].u[1] = uv[order[1]][0];
|
||||
spans[yp].span[i].v[1] = uv[order[1]][1];
|
||||
spans[yp].span[i].col[1] = col[order[1]];
|
||||
if ((spans[yp].span[i].x1 >= (cx + cw)) ||
|
||||
(spans[yp].span[i].x2 < cx))
|
||||
spans[yp].span[i].x1 = -1;
|
||||
else
|
||||
{
|
||||
_limit(&(spans[yp].span[i]), cx, cx + cw);
|
||||
_limit(&(spans[yp].span[i]), cx, cx + cw, nocol);
|
||||
i++;
|
||||
}
|
||||
spans[yp].span[i].x1 = edge[order[2]][2];
|
||||
spans[yp].span[i].u[0] = uv[order[2]][0];
|
||||
spans[yp].span[i].v[0] = uv[order[2]][1];
|
||||
spans[yp].span[i].col[0] = col[order[2]];
|
||||
|
||||
spans[yp].span[i].x2 = edge[order[3]][2];
|
||||
spans[yp].span[i].u[1] = uv[order[3]][0];
|
||||
spans[yp].span[i].v[1] = uv[order[3]][1];
|
||||
spans[yp].span[i].col[1] = col[order[3]];
|
||||
if ((spans[yp].span[i].x1 >= (cx + cw)) ||
|
||||
(spans[yp].span[i].x2 < cx))
|
||||
spans[yp].span[i].x1 = -1;
|
||||
|
@ -231,7 +268,7 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
|||
int l = cx;
|
||||
|
||||
if (i > 0) l = spans[yp].span[i - 1].x2;
|
||||
_limit(&(spans[yp].span[i]), l, cx + cw);
|
||||
_limit(&(spans[yp].span[i]), l, cx + cw, nocol);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -22,6 +22,7 @@ struct _RGBA_Map_Point
|
|||
FPc x, y; // x, y screenspace
|
||||
FPc z; // z in world space. optional
|
||||
FPc u, v; // u, v in tex coords
|
||||
DATA32 col; // color at this point
|
||||
};
|
||||
|
||||
EAPI void
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
#undef SCALE_USING_MMX
|
||||
{
|
||||
if (smooth)
|
||||
{
|
||||
for (y = ystart; y <= yend; y++)
|
||||
{
|
||||
int x, w, ww;
|
||||
FPc u, v, ud, vd, dv;
|
||||
DATA32 *d, *s, *so[4], val1, val2;
|
||||
#ifdef COLMUL
|
||||
FPc cv, cd, cc; // col
|
||||
DATA32 c1, c2; // col
|
||||
#endif
|
||||
Line *line;
|
||||
|
||||
#ifdef SCALE_USING_MMX
|
||||
pxor_r2r(mm0, mm0);
|
||||
MOV_A2R(ALPHA_255, mm5)
|
||||
#endif
|
||||
|
||||
line = &(spans[y - ystart]);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
Span *span;
|
||||
|
||||
span = &(line->span[i]);
|
||||
if (span->x1 >= 0)
|
||||
{
|
||||
long long tl;
|
||||
|
||||
x = span->x1;
|
||||
w = (span->x2 - x);
|
||||
if (w <= 0) continue;
|
||||
dv = (span->o2 - span->o1);
|
||||
if (dv <= 0) continue;
|
||||
|
||||
ww = w;
|
||||
u = span->u[0] << FPI;
|
||||
v = span->v[0] << FPI;
|
||||
ud = ((span->u[1] << FPI) - u) / w;
|
||||
vd = ((span->v[1] << FPI) - v) / w;
|
||||
tl = (long long)ud * (w << FP);
|
||||
tl = tl / dv;
|
||||
ud = tl;
|
||||
u -= (ud * (span->o1 - (span->x1 << FP))) / FP1;
|
||||
|
||||
tl = (long long)vd * (w << FP);
|
||||
tl = tl / dv;
|
||||
vd = tl;
|
||||
v -= (vd * (span->o1 - (span->x1 << FP))) / FP1;
|
||||
|
||||
if (ud < 0) u -= 1;
|
||||
if (vd < 0) v -= 1;
|
||||
|
||||
if (direct)
|
||||
d = dst->image.data + (y * dst->cache_entry.w) + x;
|
||||
else
|
||||
d = buf;
|
||||
|
||||
#define SMOOTH 1
|
||||
#ifdef COLMUL
|
||||
c1 = span->col[0]; // col
|
||||
c2 = span->col[1]; // col
|
||||
cv = 0; // col
|
||||
cd = (255 << 16) / w; // col
|
||||
|
||||
if (c1 == c2)
|
||||
{
|
||||
if (c1 == 0xffffffff)
|
||||
{
|
||||
#endif
|
||||
#include "evas_map_image_loop.c"
|
||||
#ifdef COLMUL
|
||||
}
|
||||
else if ((c1 == 0x0000ff) && (!src->cache_entry.flags.alpha))
|
||||
{
|
||||
// all black line
|
||||
# define COLBLACK 1
|
||||
# include "evas_map_image_loop.c"
|
||||
# undef COLBLACK
|
||||
}
|
||||
else if (c1 == 0x000000)
|
||||
{
|
||||
// skip span
|
||||
}
|
||||
else
|
||||
{
|
||||
// generic loop
|
||||
# include "evas_map_image_loop.c"
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# include "evas_map_image_loop.c"
|
||||
}
|
||||
#endif
|
||||
if (!direct)
|
||||
{
|
||||
d = dst->image.data;
|
||||
d += (y * dst->cache_entry.w) + x;
|
||||
func(buf, NULL, dc->mul.col, d, w);
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = ystart; y <= yend; y++)
|
||||
{
|
||||
int x, w, ww;
|
||||
FPc u, v, ud, vd;
|
||||
DATA32 *d, *s;
|
||||
#ifdef COLMUL
|
||||
FPc cv, cd, cc; // col
|
||||
DATA32 c1, c2; // col
|
||||
#endif
|
||||
Line *line;
|
||||
|
||||
line = &(spans[y - ystart]);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
Span *span;
|
||||
|
||||
span = &(line->span[i]);
|
||||
if (span->x1 >= 0)
|
||||
{
|
||||
x = span->x1;
|
||||
w = (span->x2 - x);
|
||||
|
||||
if (w <= 0) continue;
|
||||
ww = w;
|
||||
u = span->u[0] << FPI;
|
||||
v = span->v[0] << FPI;
|
||||
ud = ((span->u[1] << FPI) - u) / w;
|
||||
vd = ((span->v[1] << FPI) - v) / w;
|
||||
if (ud < 0) u -= 1;
|
||||
if (vd < 0) v -= 1;
|
||||
|
||||
if (direct)
|
||||
d = dst->image.data + (y * dst->cache_entry.w) + x;
|
||||
else
|
||||
d = buf;
|
||||
|
||||
#undef SMOOTH
|
||||
#ifdef COLMUL
|
||||
c1 = span->col[0]; // col
|
||||
c2 = span->col[1]; // col
|
||||
cv = 0; // col
|
||||
cd = (255 << 16) / w; // col
|
||||
|
||||
if (c1 == c2)
|
||||
{
|
||||
if (c1 == 0xffffffff)
|
||||
{
|
||||
#endif
|
||||
#include "evas_map_image_loop.c"
|
||||
#ifdef COLMUL
|
||||
}
|
||||
else if ((c1 == 0x0000ff) && (!src->cache_entry.flags.alpha))
|
||||
{
|
||||
// all black line
|
||||
# define COLBLACK 1
|
||||
# include "evas_map_image_loop.c"
|
||||
# undef COLBLACK
|
||||
}
|
||||
else if (c1 == 0x000000)
|
||||
{
|
||||
// skip span
|
||||
}
|
||||
else
|
||||
{
|
||||
// generic loop
|
||||
# include "evas_map_image_loop.c"
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// generic loop
|
||||
# include "evas_map_image_loop.c"
|
||||
}
|
||||
#endif
|
||||
if (!direct)
|
||||
{
|
||||
d = dst->image.data;
|
||||
d += (y * dst->cache_entry.w) + x;
|
||||
func(buf, NULL, dc->mul.col, d, w);
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,8 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
|
|||
Line *spans;
|
||||
DATA32 *buf, *sp;
|
||||
RGBA_Gfx_Func func;
|
||||
int havea = 0;
|
||||
int havecol = 4;
|
||||
|
||||
// get the clip
|
||||
c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
|
||||
|
@ -27,10 +29,15 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
|
|||
|
||||
// find y yop line and y bottom line
|
||||
ytop = p[0].y;
|
||||
if ((p[0].col >> 24) < 0xff) havea = 1;
|
||||
if (p[0].col == 0xffffffff) havecol--;
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
if (p[i].y < ytop) ytop = p[i].y;
|
||||
if ((p[i].col >> 24) < 0xff) havea = 1;
|
||||
if (p[i].col == 0xffffffff) havecol--;
|
||||
}
|
||||
|
||||
ybottom = p[0].y;
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
|
@ -81,198 +88,33 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
|
|||
// if operation is solid, bypass buf and draw func and draw direct to dst
|
||||
direct = 0;
|
||||
if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) &&
|
||||
(!dc->mul.use))
|
||||
direct = 1;
|
||||
(!dc->mul.use) && (!havea))
|
||||
{
|
||||
direct = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int pa;
|
||||
|
||||
buf = alloca(cw * sizeof(DATA32));
|
||||
if (!buf) return;
|
||||
|
||||
pa = src->cache_entry.flags.alpha;
|
||||
if (havea) src->cache_entry.flags.alpha = 1;
|
||||
if (dc->mul.use)
|
||||
func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
|
||||
else
|
||||
func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
|
||||
src->cache_entry.flags.alpha = pa;
|
||||
}
|
||||
if (smooth)
|
||||
|
||||
if (!havecol)
|
||||
{
|
||||
for (y = ystart; y <= yend; y++)
|
||||
{
|
||||
int x, w, ww;
|
||||
FPc u, v, ud, vd, dv;
|
||||
DATA32 *d, *s, *so[4], val1, val2;
|
||||
Line *line;
|
||||
#ifdef SCALE_USING_MMX
|
||||
pxor_r2r(mm0, mm0);
|
||||
MOV_A2R(ALPHA_255, mm5)
|
||||
#endif
|
||||
|
||||
line = &(spans[y - ystart]);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
Span *span;
|
||||
|
||||
span = &(line->span[i]);
|
||||
if (span->x1 >= 0)
|
||||
{
|
||||
long long tl;
|
||||
|
||||
x = span->x1;
|
||||
w = (span->x2 - x);
|
||||
if (w <= 0) continue;
|
||||
dv = (span->o2 - span->o1);
|
||||
if (dv <= 0) continue;
|
||||
|
||||
ww = w;
|
||||
u = span->u[0] << FPI;
|
||||
v = span->v[0] << FPI;
|
||||
ud = ((span->u[1] << FPI) - u) / w;
|
||||
vd = ((span->v[1] << FPI) - v) / w;
|
||||
tl = (long long)ud * (w << FP);
|
||||
tl = tl / dv;
|
||||
ud = tl;
|
||||
u -= (ud * (span->o1 - (span->x1 << FP))) / FP1;
|
||||
|
||||
tl = (long long)vd * (w << FP);
|
||||
tl = tl / dv;
|
||||
vd = tl;
|
||||
v -= (vd * (span->o1 - (span->x1 << FP))) / FP1;
|
||||
|
||||
if (ud < 0) u -= 1;
|
||||
if (vd < 0) v -= 1;
|
||||
|
||||
if (direct)
|
||||
d = dst->image.data + (y * dst->cache_entry.w) + x;
|
||||
else
|
||||
d = buf;
|
||||
|
||||
while (ww > 0)
|
||||
{
|
||||
FPc u1, v1, u2, v2;
|
||||
FPc rv, ru;
|
||||
DATA32 val1, val2, val3, val4;
|
||||
|
||||
u1 = u;
|
||||
if (u1 < 0) u1 = 0;
|
||||
else if (u1 >= swp) u1 = swp - 1;
|
||||
|
||||
v1 = v;
|
||||
if (v1 < 0) v1 = 0;
|
||||
else if (v1 >= shp) v1 = shp - 1;
|
||||
|
||||
u2 = u1 + FPFPI1;
|
||||
if (u2 >= swp) u2 = swp - 1;
|
||||
|
||||
v2 = v1 + FPFPI1;
|
||||
if (v2 >= shp) v2 = shp - 1;
|
||||
|
||||
ru = (u >> (FP + FPI - 8)) & 0xff;
|
||||
rv = (v >> (FP + FPI - 8)) & 0xff;
|
||||
|
||||
s = sp + ((v1 >> (FP + FPI)) * sw) +
|
||||
(u1 >> (FP + FPI));
|
||||
val1 = *s;
|
||||
s = sp + ((v1 >> (FP + FPI)) * sw) +
|
||||
(u2 >> (FP + FPI));
|
||||
val2 = *s;
|
||||
|
||||
s = sp + ((v2 >> (FP + FPI)) * sw) +
|
||||
(u1 >> (FP + FPI));
|
||||
val3 = *s;
|
||||
s = sp + ((v2 >> (FP + FPI)) * sw) +
|
||||
(u2 >> (FP + FPI));
|
||||
val4 = *s;
|
||||
#ifdef SCALE_USING_MMX
|
||||
MOV_A2R(rv, mm4);
|
||||
MOV_A2R(ru, mm6);
|
||||
MOV_P2R(val1, mm1, mm0);
|
||||
if (val1 | val2)
|
||||
{
|
||||
MOV_P2R(val2, mm2, mm0);
|
||||
INTERP_256_R2R(mm6, mm2, mm1, mm5);
|
||||
}
|
||||
MOV_P2R(val3, mm2, mm0);
|
||||
if (val3 | val4)
|
||||
{
|
||||
MOV_P2R(val4, mm3, mm0);
|
||||
INTERP_256_R2R(mm6, mm3, mm2, mm5);
|
||||
}
|
||||
INTERP_256_R2R(mm4, mm2, mm1, mm5);
|
||||
MOV_R2P(mm1, *d, mm0);
|
||||
d++;
|
||||
#else
|
||||
val1 = INTERP_256(ru, val2, val1);
|
||||
val3 = INTERP_256(ru, val4, val3);
|
||||
*d++ = INTERP_256(rv, val3, val1);
|
||||
#endif
|
||||
u += ud;
|
||||
v += vd;
|
||||
ww--;
|
||||
}
|
||||
|
||||
if (!direct)
|
||||
{
|
||||
d = dst->image.data;
|
||||
d += (y * dst->cache_entry.w) + x;
|
||||
func(buf, NULL, dc->mul.col, d, w);
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
#undef COLMUL
|
||||
#include "evas_map_image_core.c"
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = ystart; y <= yend; y++)
|
||||
{
|
||||
int x, w, ww;
|
||||
FPc u, v, ud, vd;
|
||||
DATA32 *d, *s;
|
||||
Line *line;
|
||||
|
||||
line = &(spans[y - ystart]);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
Span *span;
|
||||
|
||||
span = &(line->span[i]);
|
||||
if (span->x1 >= 0)
|
||||
{
|
||||
x = span->x1;
|
||||
w = (span->x2 - x);
|
||||
|
||||
if (w <= 0) continue;
|
||||
ww = w;
|
||||
u = span->u[0] << FPI;
|
||||
v = span->v[0] << FPI;
|
||||
ud = ((span->u[1] << FPI) - u) / w;
|
||||
vd = ((span->v[1] << FPI) - v) / w;
|
||||
if (ud < 0) u -= 1;
|
||||
if (vd < 0) v -= 1;
|
||||
|
||||
if (direct)
|
||||
d = dst->image.data + (y * dst->cache_entry.w) + x;
|
||||
else
|
||||
d = buf;
|
||||
|
||||
while (ww > 0)
|
||||
{
|
||||
s = sp + ((v >> (FP + FPI)) * sw) +
|
||||
(u >> (FP + FPI));
|
||||
*d++ = *s;
|
||||
u += ud;
|
||||
v += vd;
|
||||
ww--;
|
||||
}
|
||||
|
||||
if (!direct)
|
||||
{
|
||||
d = dst->image.data;
|
||||
d += (y * dst->cache_entry.w) + x;
|
||||
func(buf, NULL, dc->mul.col, d, w);
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
#define COLMUL 1
|
||||
#include "evas_map_image_core.c"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
#ifdef SMOOTH
|
||||
{
|
||||
while (ww > 0)
|
||||
{
|
||||
# ifdef COLBLACK
|
||||
*d = 0xff000000; // col
|
||||
# else
|
||||
FPc u1, v1, u2, v2;
|
||||
FPc rv, ru;
|
||||
DATA32 val1, val2, val3, val4;
|
||||
|
||||
u1 = u;
|
||||
if (u1 < 0) u1 = 0;
|
||||
else if (u1 >= swp) u1 = swp - 1;
|
||||
|
||||
v1 = v;
|
||||
if (v1 < 0) v1 = 0;
|
||||
else if (v1 >= shp) v1 = shp - 1;
|
||||
|
||||
u2 = u1 + FPFPI1;
|
||||
if (u2 >= swp) u2 = swp - 1;
|
||||
|
||||
v2 = v1 + FPFPI1;
|
||||
if (v2 >= shp) v2 = shp - 1;
|
||||
|
||||
ru = (u >> (FP + FPI - 8)) & 0xff;
|
||||
rv = (v >> (FP + FPI - 8)) & 0xff;
|
||||
|
||||
s = sp + ((v1 >> (FP + FPI)) * sw) +
|
||||
(u1 >> (FP + FPI));
|
||||
val1 = *s;
|
||||
s = sp + ((v1 >> (FP + FPI)) * sw) +
|
||||
(u2 >> (FP + FPI));
|
||||
val2 = *s;
|
||||
|
||||
s = sp + ((v2 >> (FP + FPI)) * sw) +
|
||||
(u1 >> (FP + FPI));
|
||||
val3 = *s;
|
||||
s = sp + ((v2 >> (FP + FPI)) * sw) +
|
||||
(u2 >> (FP + FPI));
|
||||
val4 = *s;
|
||||
# ifdef SCALE_USING_MMX
|
||||
MOV_A2R(rv, mm4);
|
||||
MOV_A2R(ru, mm6);
|
||||
MOV_P2R(val1, mm1, mm0);
|
||||
if (val1 | val2)
|
||||
{
|
||||
MOV_P2R(val2, mm2, mm0);
|
||||
INTERP_256_R2R(mm6, mm2, mm1, mm5);
|
||||
}
|
||||
MOV_P2R(val3, mm2, mm0);
|
||||
if (val3 | val4)
|
||||
{
|
||||
MOV_P2R(val4, mm3, mm0);
|
||||
INTERP_256_R2R(mm6, mm3, mm2, mm5);
|
||||
}
|
||||
INTERP_256_R2R(mm4, mm2, mm1, mm5);
|
||||
# ifdef COLMUL
|
||||
cc = cv >> 16; // col
|
||||
MOV_A2R(cc, mm2); // col
|
||||
MOV_A2R(c1, mm3); // col
|
||||
MOV_A2R(c2, mm4); // col
|
||||
INTERP_256_R2R(mm2, mm4, mm3, mm5); // col
|
||||
MUL4_256_R2R(mm3, mm1);
|
||||
# endif
|
||||
MOV_R2P(mm1, *d, mm0);
|
||||
# else
|
||||
val1 = INTERP_256(ru, val2, val1);
|
||||
val3 = INTERP_256(ru, val4, val3);
|
||||
val1 = INTERP_256(rv, val3, val1); // col
|
||||
# ifdef COLMUL
|
||||
val2 = INTERP_256((cv >> 16), c2, c1); // col
|
||||
*d = MUL4_SYM(val2, val1); // col
|
||||
cv += cd; // col
|
||||
# else
|
||||
*d = INTERP_256(rv, val3, val1);
|
||||
# endif
|
||||
# endif
|
||||
u += ud;
|
||||
v += vd;
|
||||
# endif
|
||||
d++;
|
||||
ww--;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
while (ww > 0)
|
||||
{
|
||||
# ifdef COLMUL
|
||||
DATA32 val1, cval; // col
|
||||
# endif
|
||||
# ifdef COLBLACK
|
||||
*d = 0xff000000; // col
|
||||
# else
|
||||
s = sp + ((v >> (FP + FPI)) * sw) +
|
||||
(u >> (FP + FPI));
|
||||
# ifdef COLMUL
|
||||
val1 = *s; // col
|
||||
cval = INTERP_256((cv >> 16), c2, c1); // col
|
||||
*d = MUL4_SYM(cval, val1);
|
||||
cv += cd; // col
|
||||
# else
|
||||
*d = *s;
|
||||
# endif
|
||||
u += ud;
|
||||
v += vd;
|
||||
# endif
|
||||
d++;
|
||||
ww--;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -48,6 +48,7 @@ typedef struct _Evas_Intercept_Func_Color Evas_Intercept_Func_Color;
|
|||
typedef struct _Evas_Key_Grab Evas_Key_Grab;
|
||||
typedef struct _Evas_Callbacks Evas_Callbacks;
|
||||
typedef struct _Evas_Format Evas_Format;
|
||||
typedef struct _Evas_Map_Point Evas_Map_Point;
|
||||
|
||||
#define MAGIC_EVAS 0x70777770
|
||||
#define MAGIC_OBJ 0x71777770
|
||||
|
@ -361,7 +362,7 @@ struct _Evas_Map_Point
|
|||
{
|
||||
Evas_Coord x, y, z;
|
||||
double u, v;
|
||||
// FIXME: add color?
|
||||
unsigned char r, g, b, a;
|
||||
};
|
||||
|
||||
struct _Evas_Map
|
||||
|
|
Loading…
Reference in New Issue