Support for Proxy Objects (and others)

Proxy objects allow you to use another image as the source of an image.
Essentially allowing the same object to be rendered multiple times.  One
object (the source) is the original, each additional 'copy' is an image with
evas_object_image_source_set.

This is complete.

Also add partially working arbitrary maps, and arbitrary clipping.
Unfortunately both have some issues yet to be resolved (waiting on the next
feature to get merged together).

SVN revision: 56777
This commit is contained in:
Brett Nash 2011-02-06 23:52:17 +00:00
parent 3cece3340b
commit aa59164001
19 changed files with 331 additions and 87 deletions

View File

@ -7,6 +7,7 @@
Makefile
Makefile.in
*.so
.*.sw[po]
/README
/aclocal.m4
/autom4te.cache/
@ -25,3 +26,5 @@ Makefile.in
/ltmain.sh
/missing
/stamp-h1
tags
cscope.out

View File

@ -164,7 +164,7 @@ typedef enum _Evas_Colorspace
EVAS_COLORSPACE_YCBCR422P601_PL, /**< YCbCr 4:2:2 Planar, ITU.BT-601 specifications. The data poitned to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
EVAS_COLORSPACE_YCBCR422P709_PL,/**< YCbCr 4:2:2 Planar, ITU.BT-709 specifications. The data poitned to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
EVAS_COLORSPACE_RGB565_A5P, /**< 16bit rgb565 + Alpha plane at end - 5 bits of the 8 being used per alpha byte */
EVAS_COLORSPACE_GRY8 /**< 8bit grayscale */
EVAS_COLORSPACE_GRY8, /**< 8bit grayscale */
} Evas_Colorspace; /**< Colorspaces for pixel data supported by Evas */
/**
@ -331,7 +331,7 @@ typedef enum _Evas_Pixel_Import_Pixel_Format
{
EVAS_PIXEL_FORMAT_NONE = 0, /**< No pixel format */
EVAS_PIXEL_FORMAT_ARGB32 = 1, /**< ARGB 32bit pixel format with A in the high byte per 32bit pixel word */
EVAS_PIXEL_FORMAT_YUV420P_601 = 2 /**< YUV 420 Planar format with CCIR 601 color encoding wuth contiguous planes in the order Y, U and V */
EVAS_PIXEL_FORMAT_YUV420P_601 = 2, /**< YUV 420 Planar format with CCIR 601 color encoding wuth contiguous planes in the order Y, U and V */
} Evas_Pixel_Import_Pixel_Format; /**< Pixel format for import call. See evas_object_image_pixels_import() */
struct _Evas_Pixel_Import_Source
@ -995,6 +995,7 @@ typedef void (*Evas_Async_Events_Put_Cb)(void *target, Evas_Callback_Type t
EAPI Eina_Bool evas_map_alpha_get (const Evas_Map *m);
EAPI Evas_Map *evas_map_dup (const Evas_Map *m);
EAPI void evas_map_free (Evas_Map *m);
EAPI int evas_map_count_get (const Evas_Map *m) EINA_CONST;
EAPI void evas_map_point_coord_set (Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_Coord z);
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);
@ -1229,6 +1230,11 @@ typedef void (*Evas_Object_Intercept_Clip_Unset_Cb) (void *data, Evas_Object *ob
*
* R = (r * a) / 32; G = (g * a) / 32; B = (b * a) / 32;
*
* EVAS_COLORSPACE_A8:
*
* The image is just a alpha mask (8 bit's per pixel). This is used for alpha
* masking.
*
* @ingroup Evas_Object_Specific
*/
typedef void (*Evas_Object_Image_Pixels_Get_Cb) (void *data, Evas_Object *o);
@ -1287,6 +1293,8 @@ typedef void (*Evas_Object_Image_Pixels_Get_Cb) (void *data, Evas_Object *o);
EAPI void evas_object_image_content_hint_set (Evas_Object *obj, Evas_Image_Content_Hint hint) EINA_ARG_NONNULL(1);
EAPI Evas_Image_Content_Hint evas_object_image_content_hint_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
EAPI void evas_object_image_alpha_mask_set (Evas_Object *, Eina_Bool) EINA_ARG_NONNULL(1);
/**
* @defgroup Evas_Object_Text Text Object Functions
*
@ -2091,7 +2099,13 @@ struct _Evas_Smart_Cb_Description
/**
* @defgroup Evas_Proxy Evas Proxy Objects
*
* Provides a way of applying effects to complete objects.
* @brief Provides a way of applying effects to complete objects.
*
* A proxy object is a visible copy of another object. Generally a map or
* similar effect will be applied to the proxy to apply some sort of rendering
* effect to.
*
* Proxies are generally used for special effects.
*/
EAPI Evas_Object *evas_object_proxy_add (Evas *e) EINA_MALLOC;
EAPI Eina_Bool evas_object_proxy_source_set (Evas_Object *o, Evas_Object *source);

View File

@ -96,7 +96,15 @@ static inline Evas_Map *
_evas_map_new(int count)
{
int i;
Evas_Map *m = calloc(1, sizeof(Evas_Map) + (count * sizeof(Evas_Map_Point)));
int alloc;
Evas_Map *m;
/* Adjust allocation such that: at least 4 points, and always an even
* number: this allows the software engine to work efficiently */
alloc = (count < 4) ? 4 : count;
if (alloc & 0x1) alloc ++;
m = calloc(1, sizeof(Evas_Map) + (alloc * sizeof(Evas_Map_Point)));
if (!m) return NULL;
m->count = count;
m->persp.foc = 0;
@ -155,24 +163,24 @@ Eina_Bool
evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
Evas_Coord *mx, Evas_Coord *my, int grab)
{
int i, j, edges, edge[4][2], douv;
int i, j, edges, edge[m->count][2], douv;
Evas_Coord xe[2];
double u[2] = { 0.0, 0.0 };
double v[2] = { 0.0, 0.0 };
if (m->count != 4) return 0;
if (m->count < 4) return 0;
// FIXME need to handle grab mode and extrapolte coords outside
// map
if (grab)
{
Evas_Coord ymin, ymax;
ymin = m->points[0].y;
ymax = m->points[0].y;
for (i = 1; i < m->count; i++)
{
if (m->points[i].y < ymin) ymin = m->points[i].y;
else if (m->points[i].y > ymax) ymax = m->points[i].y;
if (m->points[i].y < ymin) ymin = m->points[i].y;
else if (m->points[i].y > ymax) ymax = m->points[i].y;
}
if (y <= ymin) y = ymin + 1;
if (y >= ymax) y = ymax - 1;
@ -250,12 +258,12 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
if (xe[0] > xe[1])
{
int ti;
ti = xe[0]; xe[0] = xe[1]; xe[1] = ti;
if (douv)
{
double td;
td = u[0]; u[0] = u[1]; u[1] = td;
td = v[0]; v[0] = v[1]; v[1] = td;
}
@ -264,11 +272,11 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
{
if (douv)
{
if (mx)
*mx = u[0] + (((x - xe[0]) * (u[1] - u[0])) /
if (mx)
*mx = u[0] + (((x - xe[0]) * (u[1] - u[0])) /
(xe[1] - xe[0]));
if (my)
*my = v[0] + (((x - xe[0]) * (v[1] - v[0])) /
*my = v[0] + (((x - xe[0]) * (v[1] - v[0])) /
(xe[1] - xe[0]));
}
return 1;
@ -277,11 +285,11 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
{
if (douv)
{
if (mx)
*mx = u[0] + (((x - xe[0]) * (u[1] - u[0])) /
if (mx)
*mx = u[0] + (((x - xe[0]) * (u[1] - u[0])) /
(xe[1] - xe[0]));
if (my)
*my = v[0] + (((x - xe[0]) * (v[1] - v[0])) /
*my = v[0] + (((x - xe[0]) * (v[1] - v[0])) /
(xe[1] - xe[0]));
}
return 1;
@ -471,21 +479,23 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
}
return;
}
if (!obj->cur.map)
{
obj->cur.map = _evas_map_dup(map);
if (obj->cur.usemap)
evas_object_mapped_clip_across_mark(obj);
}
else
if (obj->cur.map && obj->cur.map->count == map->count)
{
Evas_Map *omap = obj->cur.map;
obj->cur.map = _evas_map_new(4);
memcpy(obj->cur.map, omap, sizeof(Evas_Map) + (4 * sizeof(Evas_Map_Point)));
obj->cur.map = _evas_map_new(map->count);
memcpy(obj->cur.map, omap, sizeof(Evas_Map) + (map->count * sizeof(Evas_Map_Point)));
_evas_map_copy(obj->cur.map, map);
if (obj->prev.map == omap) obj->prev.map = NULL;
free(omap);
}
else
{
if (obj->cur.map) evas_map_free(obj->cur.map);
obj->cur.map = _evas_map_dup(map);
if (obj->cur.usemap)
evas_object_mapped_clip_across_mark(obj);
}
_evas_map_calc_map_geometry(obj);
}
@ -543,9 +553,9 @@ evas_object_map_get(const Evas_Object *obj)
EAPI Evas_Map *
evas_map_new(int count)
{
if (count != 4)
if (count < 4)
{
ERR("num (%i) != 4 is unsupported!", count);
ERR("num (%i) < 4 is unsupported!", count);
return NULL;
}
return _evas_map_new(count);
@ -644,6 +654,21 @@ evas_map_free(Evas_Map *m)
_evas_map_free(NULL, m);
}
/**
* Get a maps size.
*
* Returns the number of points in a map. Should be at least 4.
*
* @param m map to get size.
* @return -1 on error, points otherwise.
*/
EAPI int
evas_map_count_get(const Evas_Map *m)
{
if (!m) return -1;
return m->count;
}
/**
* Change the map point's coordinate.
*
@ -1216,10 +1241,11 @@ evas_map_util_3d_lighting(Evas_Map *m,
x = m->points[i].x;
y = m->points[i].y;
z = m->points[i].z;
printf("Normal %d\n",i);
// calc normal
h = (i + m->count - 1) % m->count; // prev point
j = (i + 1) % m->count; // next point
h = (i - 1 + 4) % 4 + (i & ~0x3); // prev point
j = (i + 1) % 4 + (i & ~0x3); // next point
printf("\tNext/Prev: %2d/%2d\n",h,j);
x1 = m->points[h].x - x;
y1 = m->points[h].y - y;
@ -1228,13 +1254,16 @@ evas_map_util_3d_lighting(Evas_Map *m,
x2 = m->points[j].x - x;
y2 = m->points[j].y - y;
z2 = m->points[j].z - z;
printf("\tX: %3.2lf,%3.2lf,%3.2lf\n",x,y,z);
printf("\tX1: %3.2lf,%3.2lf,%3.2lf\n",x1,y1,z1);
printf("\tX2: %3.2lf,%3.2lf,%3.2lf\n",x2,y2,z2);
nx = (y1 * z2) - (z1 * y2);
ny = (z1 * x2) - (x1 * z2);
nz = (x1 * y2) - (y1 * x2);
ln = (nx * nx) + (ny * ny) + (nz * nz);
ln = sqrt(ln);
printf("\tLength: %3.2lf\n",ln);
if (ln != 0.0)
{
@ -1242,7 +1271,8 @@ evas_map_util_3d_lighting(Evas_Map *m,
ny /= ln;
nz /= ln;
}
printf("\tpoint %2d: %3.2lf,%3.2lf,%3.2lf normal: %3.2lf %3.2lf %3.2lf\n",i,x,y,z,nx,ny,nz);
// calc point -> light vector
x = lx - x;
y = ly - y;
@ -1265,9 +1295,11 @@ evas_map_util_3d_lighting(Evas_Map *m,
mr = ar + ((lr - ar) * br);
mg = ag + ((lg - ag) * br);
mb = ab + ((lb - ab) * br);
mr = (mr * m->points[i].a) / 255;
mg = (mg * m->points[i].a) / 255;
mb = (mb * m->points[i].a) / 255;
if (m->points[i].a != 255){
mr = (mr * m->points[i].a) / 255;
mg = (mg * m->points[i].a) / 255;
mb = (mb * m->points[i].a) / 255;
}
m->points[i].r = (m->points[i].r * mr) / 255;
m->points[i].g = (m->points[i].g * mg) / 255;
m->points[i].b = (m->points[i].b * mb) / 255;

View File

@ -2049,6 +2049,39 @@ evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hin
}
}
/**
* Enable an image to be used as an alpha mask.
*
* This will set any flags, and discard any excess image data not used as an
* alpha mask.
*
* Note there is little point in using a image as alpha mask unless it has an
* alpha channel.
*
* @param obj Object to use as an alpha mask.
* @param ismask Use image as alphamask, must be true.
*/
EAPI void
evas_object_image_alpha_mask_set(Evas_Object *obj, Eina_Bool ismask)
{
Evas_Object_Image *o;
if (!ismask) return;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return;
MAGIC_CHECK_END();
o = (Evas_Object_Image *)(obj->object_data);
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
return;
MAGIC_CHECK_END();
/* Convert to A8 if not already */
/* done */
}
/**
* Get the content hint of a given image of the canvas.
*
@ -2453,13 +2486,13 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
}
o->dirty_pixels = 0;
}
if ((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap))
if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
{
const Evas_Map_Point *p, *p_end;
RGBA_Map_Point pts[4], *pt;
RGBA_Map_Point pts[obj->cur.map->count], *pt;
p = obj->cur.map->points;
p_end = p + 4;
p_end = p + obj->cur.map->count;
pt = pts;
pts[0].px = obj->cur.map->persp.px << FP;
@ -2483,9 +2516,14 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
else if (pt->v > (o->cur.image.h * FP1)) pt->v = (o->cur.image.h * FP1);
pt->col = ARGB_JOIN(p->a, p->r, p->g, 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);
if (obj->cur.map->count & 0x1)
{
pts[obj->cur.map->count] = pts[obj->cur.map->count -1];
}
obj->layer->evas->engine.func->image_map_draw
(output, context, surface, o->engine_data, obj->cur.map->count,
pts, o->cur.smooth_scale | obj->cur.map->smooth, 0);
}
else
{
@ -3256,3 +3294,5 @@ evas_object_image_filled_resize_listener(void *data __UNUSED__, Evas *e __UNUSED
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
evas_object_image_fill_set(obj, 0, 0, w, h);
}
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/

View File

@ -21,6 +21,7 @@ typedef struct _Evas_Object_Proxy
Evas_Map *defmap;
Eina_Bool mapupdate;
Eina_Bool rendering;
} Evas_Object_Proxy;
@ -98,6 +99,14 @@ static const Evas_Object_Func object_func =
};
/**
* Add a new proxy object.
*
* The proxy object must have a source set before it is useful.
*
* @param e Evas canvas to add proxy too.
* @return New proxy object.
*/
EAPI Evas_Object *
evas_object_proxy_add(Evas *e)
{
@ -119,32 +128,33 @@ evas_object_proxy_add(Evas *e)
return obj;
}
/**
* Set the source object on a proxy object.
*
* Any existing source object will be removed. Setting the src to NULL clears
* the proxy object.
*
* You cannot set a proxy on a proxy.
*
* @param obj Proxy object.
* @param src Source of the proxy.
* @return EINA_TRUE on success, EINA_FALSE on error.
*/
EAPI Eina_Bool
evas_object_proxy_source_set(Evas_Object *obj, Evas_Object *src)
{
Evas_Object_Proxy *o,*so;
Evas_Object_Proxy *o;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return false;
return EINA_FALSE;
MAGIC_CHECK_END();
o = obj->object_data;
MAGIC_CHECK(o, Evas_Object_Proxy, MAGIC_OBJ_PROXY);
return false;
return EINA_FALSE;
MAGIC_CHECK_END();
if (o->source == src) return true;
if (src)
{
MAGIC_CHECK(src, Evas_Object, MAGIC_OBJ);
return false;
MAGIC_CHECK_END();
so = src->object_data;
/* Stop the loop _now_ */
/* FIXME: Should I check for smarts that contain proxies too? */
if (so->magic == MAGIC_OBJ_PROXY)
return false;
}
if (src == obj) return EINA_FALSE;
if (o->source == src) return EINA_TRUE;
if (o->source)
{
@ -156,9 +166,15 @@ evas_object_proxy_source_set(Evas_Object *obj, Evas_Object *src)
_proxy_set(obj, src);
}
return true;
return EINA_TRUE;
}
/**
* Get the current source object of a proxy.
*
* @param obj Proxy object
* @return Source object, or NULL on error.
*/
EAPI Evas_Object *
evas_object_proxy_source_get(Evas_Object *obj)
{
@ -175,15 +191,23 @@ evas_object_proxy_source_get(Evas_Object *obj)
return o->source;
}
/**
* Clear the source on a proxy.
*
* This is equivalent to calling evas_object_proxy_source_set with a NULL
* source.
*
* @param obj Proxy object to clear source of.
* @return EINA_TRUE on success, EINA_FALSE on error.
*/
EAPI Eina_Bool
evas_object_proxy_source_unset(Evas_Object *o)
evas_object_proxy_source_unset(Evas_Object *obj)
{
return evas_object_proxy_source_set(o, NULL);
return evas_object_proxy_source_set(obj, NULL);
}
/* Internal helpers */
static void
evas_object_proxy_init(Evas_Object *obj)
@ -313,6 +337,30 @@ _proxy_render(Evas_Object *obj, void *output, void *context,
o = obj->object_data;
if (o->rendering)
{
int r = rand() % 255;
int g = rand() % 255;
int b = rand() % 255;
printf("Ahh: Recursive proxies: Go away!\n");
obj->layer->evas->engine.func->context_color_set(output,
context,
r,g,b,255);
obj->layer->evas->engine.func->context_multiplier_unset(output,
context);
obj->layer->evas->engine.func->context_render_op_set(output, context,
obj->cur.render_op);
obj->layer->evas->engine.func->rectangle_draw(output,
context,
surface,
obj->cur.geometry.x + x,
obj->cur.geometry.y + y,
obj->cur.geometry.w,
obj->cur.geometry.h);
return;
}
if (!o->source) return;
// ENFN->context_multiplier_unset(output, context);
@ -331,8 +379,10 @@ _proxy_render(Evas_Object *obj, void *output, void *context,
}
else
{
o->rendering = true;
_proxy_subrender(obj->layer->evas, o->source);
pixels = o->source->proxy.surface;
o->rendering = false;
}
if (o->mapupdate) _proxy_map_update(obj);
@ -383,8 +433,9 @@ _proxy_render(Evas_Object *obj, void *output, void *context,
pt->v = p->v * FP1;
pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
}
obj->layer->evas->engine.func->image_map4_draw
(output, context, surface, pixels, pts, map->smooth, 0);
obj->layer->evas->engine.func->image_map_draw
(output, context, surface, pixels, map->count, pts,
map->smooth, 0);
}
else
{

View File

@ -703,7 +703,10 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
// set render_pre - for child objs that may not have gotten it.
obj->pre_render_done = 1;
RD(" Hasmap: %p (%d) %p %d -> %d\n",obj->func->can_map,
obj->func->can_map ? obj->func->can_map(obj): -1,
obj->cur.map, obj->cur.usemap,
_evas_render_has_map(obj));
if (_evas_render_has_map(obj))
{
const Evas_Map_Point *p, *p_end;
@ -730,7 +733,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
pts[0].z0 = obj->cur.map->persp.z0 << FP;
p = obj->cur.map->points;
p_end = p + 4;
p_end = p + obj->cur.map->count;
pt = pts;
for (; p < p_end; p++, pt++)
{
@ -748,6 +751,12 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
else if (pt->v > (sh * FP1)) pt->v = (sh * FP1);
pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
}
/* Copy last for software engine */
if (obj->cur.map->count & 0x1)
{
pts[obj->cur.map->count] = pts[obj->cur.map->count - 1];
}
if (obj->cur.map->surface)
{
@ -937,9 +946,10 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
}
}
if (obj->cur.cache.clip.visible)
obj->layer->evas->engine.func->image_map4_draw
obj->layer->evas->engine.func->image_map_draw
(e->engine.data.output, e->engine.data.context, surface,
obj->cur.map->surface, pts, obj->cur.map->smooth, 0);
obj->cur.map->surface, obj->cur.map->count, pts,
obj->cur.map->smooth, 0);
// FIXME: needs to cache these maps and
// keep them only rendering updates
// obj->layer->evas->engine.func->image_map_surface_free

View File

@ -9,6 +9,9 @@
#define CONVERT_A5P_TO_A8(s) \
((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7))
#define CONVERT_ARGB_8888_TO_A_8(s) ((s) >> 24)
static inline void *
evas_common_convert_argb8888_to_rgb565_a5p(void *data __UNUSED__, int w __UNUSED__, int h __UNUSED__, int stride __UNUSED__, Eina_Bool has_alpha __UNUSED__)
{
@ -43,6 +46,28 @@ evas_common_convert_rgb565_a5p_to_argb8888(void *data, int w, int h, int stride,
return ret;
}
static inline void *
evas_common_convert_argb8888_to_a8(void *data, int w, int h, int stride, Eina_Bool has_alpha)
{
uint32_t *src, *end;
uint8_t *ret, *dst;
src = data;
end = src + (stride * h);
ret = malloc(w * h);
if (!has_alpha)
{
return memset(ret,0xff, w * h);
}
for ( ; src < end ; src ++, dst ++)
*dst = CONVERT_ARGB_8888_TO_A_8(*src);
return ret;
}
EAPI void *
evas_common_convert_argb8888_to(void *data, int w, int h, int stride, Eina_Bool has_alpha, Evas_Colorspace cspace)
{
@ -50,6 +75,8 @@ evas_common_convert_argb8888_to(void *data, int w, int h, int stride, Eina_Bool
{
case EVAS_COLORSPACE_RGB565_A5P:
return evas_common_convert_argb8888_to_rgb565_a5p(data, w, h, stride, has_alpha);
case EVAS_COLORSPACE_A8:
return evas_common_convert_argb8888_to_a8(data, w, h, stride, has_alpha);
default:
break;
}
@ -68,3 +95,6 @@ evas_common_convert_rgb565_a5p_to(void *data, int w, int h, int stride, Eina_Boo
}
return NULL;
}
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/

View File

@ -325,23 +325,23 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
#ifdef BUILD_SCALE_SMOOTH
# ifdef BUILD_MMX
# undef FUNC_NAME
# define FUNC_NAME evas_common_map4_rgba_internal_mmx
# define FUNC_NAME evas_common_map_rgba_internal_mmx
# undef SCALE_USING_MMX
# define SCALE_USING_MMX
# include "evas_map_image_internal.c"
# endif
# ifdef BUILD_C
# undef FUNC_NAME
# define FUNC_NAME evas_common_map4_rgba_internal
# define FUNC_NAME evas_common_map_rgba_internal
# undef SCALE_USING_MMX
# include "evas_map_image_internal.c"
# endif
#endif
EAPI void
evas_common_map4_rgba(RGBA_Image *src, RGBA_Image *dst,
evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
RGBA_Map_Point *p,
int npoints, RGBA_Map_Point *p,
int smooth, int level)
{
#ifdef BUILD_MMX
@ -363,11 +363,11 @@ evas_common_map4_rgba(RGBA_Image *src, RGBA_Image *dst,
{
#ifdef BUILD_MMX
if (mmx)
evas_common_map4_rgba_internal_mmx(src, dst, dc, p, smooth, level);
evas_common_map_rgba_internal_mmx(src, dst, dc, p, smooth, level);
else
#endif
#ifdef BUILD_C
evas_common_map4_rgba_internal(src, dst, dc, p, smooth, level);
evas_common_map_rgba_internal(src, dst, dc, p, smooth, level);
#endif
return;
}
@ -387,11 +387,11 @@ evas_common_map4_rgba(RGBA_Image *src, RGBA_Image *dst,
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
#ifdef BUILD_MMX
if (mmx)
evas_common_map4_rgba_internal_mmx(src, dst, dc, p, smooth, level);
evas_common_map_rgba_internal_mmx(src, dst, dc, p, smooth, level);
else
#endif
#ifdef BUILD_C
evas_common_map4_rgba_internal(src, dst, dc, p, smooth, level);
evas_common_map_rgba_internal(src, dst, dc, p, smooth, level);
#endif
}
evas_common_draw_context_apply_clear_cutouts(rects);

View File

@ -2,9 +2,9 @@
#define _EVAS_MAP_H
EAPI void
evas_common_map4_rgba(RGBA_Image *src, RGBA_Image *dst,
evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
RGBA_Map_Point *points,
int npoints, RGBA_Map_Point *points,
int smooth, int level);
#endif /* _EVAS_MAP_H */

View File

@ -95,8 +95,8 @@ EAPI void evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGB
EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, const Evas_Text_Props *intl_props);
EAPI void evas_common_pipe_image_load(RGBA_Image *im);
EAPI void evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int smooth, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
EAPI void evas_common_pipe_map4_begin(RGBA_Image *root);
EAPI void evas_common_pipe_map4_draw(RGBA_Image *src, RGBA_Image *dst,
EAPI void evas_common_pipe_map_begin(RGBA_Image *root);
EAPI void evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc, RGBA_Map_Point *p,
int smooth, int level);
EAPI void evas_common_pipe_flush(RGBA_Image *im);

View File

@ -664,6 +664,7 @@ struct _RGBA_Draw_Context
DATA32 col;
} col;
struct RGBA_Draw_Context_clip {
DATA8 *mask;
int x, y, w, h;
Eina_Bool use : 1;
} clip;

View File

@ -672,7 +672,7 @@ struct _Evas_Func
int (*image_scale_hint_get) (void *data, void *image);
int (*font_last_up_to_pos) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y);
void (*image_map4_draw) (void *data, void *context, void *surface, void *image, RGBA_Map_Point *p, int smooth, int level);
void (*image_map_draw) (void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level);
void *(*image_map_surface_new) (void *data, int w, int h, int alpha);
void (*image_map_surface_free) (void *data, void *surface);

View File

@ -0,0 +1 @@
.*.swp

View File

@ -0,0 +1,11 @@
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"uniform sampler2D tex, texm;\n"
"varying vec4 col;\n"
"varying vec2 tex_c, tex_cm;\n"
"void main()\n"
"{\n"
" gl_FragColor = texture2D(texm, tex_cm.xy).aaaa * texture2D(tex, tex_c.xy).rgba * col;\n"
"}\n"
"\n"

View File

@ -0,0 +1,11 @@
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D tex, texm;
varying vec4 col;
varying vec2 tex_c, tex_cm;
void main()
{
gl_FragColor = texture2D(texm, tex_cm.xy).aaaa * texture2D(tex, tex_c.xy).rgba * col;
}

View File

@ -0,0 +1,16 @@
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"attribute vec4 vertex;\n"
"attribute vec4 color;\n"
"attribute vec2 tex_coord, tex_coordm;\n"
"uniform mat4 mvp;\n"
"varying vec4 col;\n"
"varying vec2 tex_c, tex_cm;\n"
"void main()\n"
"{\n"
" gl_Position = mvp * vertex;\n"
" col = color;\n"
" tex_c = tex_coord;\n"
" tex_cm = tex_coordm;\n"
"}\n"

View File

@ -0,0 +1,16 @@
#ifdef GL_ES
precision mediump float;
#endif
attribute vec4 vertex;
attribute vec4 color;
attribute vec2 tex_coord, tex_coordm;
uniform mat4 mvp;
varying vec4 col;
varying vec2 tex_c, tex_cm;
void main()
{
gl_Position = mvp * vertex;
col = color;
tex_c = tex_coord;
tex_cm = tex_coordm;
}

View File

@ -1738,7 +1738,7 @@ eng_image_scale_hint_get(void *data __UNUSED__, void *image)
}
static void
eng_image_map4_draw(void *data __UNUSED__, void *context, void *surface, void *image, RGBA_Map_Point *p, int smooth, int level)
eng_image_map_draw(void *data __UNUSED__, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
{
Evas_GL_Image *gim = image;
Render_Engine *re;
@ -1942,7 +1942,7 @@ module_open(Evas_Module *em)
ORD(image_scale_hint_get);
ORD(image_stride_get);
ORD(image_map4_draw);
ORD(image_map_draw);
ORD(image_map_surface_new);
ORD(image_map_surface_free);

View File

@ -506,12 +506,14 @@ eng_image_draw(void *data __UNUSED__, void *context, void *surface, void *image,
}
static void
eng_image_map4_draw(void *data __UNUSED__, void *context, void *surface, void *image, RGBA_Map_Point *p, int smooth, int level)
eng_image_map_draw(void *data __UNUSED__, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
{
RGBA_Image *im;
if (!image) return;
if (npoints < 3) return;
im = image;
if ((p[0].x == p[3].x) &&
(p[1].x == p[2].x) &&
(p[0].y == p[1].y) &&
@ -550,12 +552,18 @@ eng_image_map4_draw(void *data __UNUSED__, void *context, void *surface, void *i
&& evas_common_frameq_enabled()
# endif
)
evas_common_pipe_map4_draw(im, surface, context, p, smooth, level);
evas_common_pipe_map_draw(im, surface, context, npoints, p, smooth, level);
else
#endif
evas_common_map4_rgba(im, surface, context, p, smooth, level);
evas_common_map_rgba(im, surface, context, npoints, p, smooth, level);
}
evas_common_cpu_end_opt();
if (npoints > 4)
{
eng_image_map_draw(data, context, surface, image, npoints - 2, p + 2,
smooth, level);
}
}
static void *
@ -907,7 +915,7 @@ static Evas_Func func =
/* more font draw functions */
eng_font_last_up_to_pos,
/* FUTURE software generic calls go here (done) */
eng_image_map4_draw,
eng_image_map_draw,
eng_image_map_surface_new,
eng_image_map_surface_free,
NULL, // eng_image_content_hint_set - software doesn't use it