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 */
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);
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)
{
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)
{
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 */
/****************************************************************************/
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);
{
const Evas_Map_Point *p, *p_end;
RGBA_Map_Point pts[4], *pt;
- void *ctx, *ctx2;
+ void *ctx;
int sw, sh;
int changed = 0;
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)
// 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)
{
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
int x1, x2;
FPc o1, o2;
FPc u[2], v[2];
+ DATA32 col[2];
};
struct _Line
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;
}
{
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;
}
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;
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++)
{
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;
}
for (y = ystart; y <= yend; y++)
{
+ int nocol = 1;
+
yp = y - ystart;
edge_num = 0;
for (i = 0; i < 4; i++)
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;
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;
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;
}
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;
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
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
--- /dev/null
+/*
+ * 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;
+ }
+ }
+ }
+}
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;
// 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++)
{
// 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"
}
}
--- /dev/null
+/*
+ * 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
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
{
Evas_Coord x, y, z;
double u, v;
- // FIXME: add color?
+ unsigned char r, g, b, a;
};
struct _Evas_Map