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 Evas; /**< An Evas canvas handle */
typedef struct _Evas_Object Evas_Object; /**< An Evas Object handle */
EAPI Eina_List *evas_objects_at_xy_get (const Evas *e, Evas_Coord x, Evas_Coord y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
EAPI Eina_List *evas_objects_in_rectangle_get (const Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
-
+
EAPI void evas_object_map_enable_set (Evas_Object *obj, Eina_Bool enabled);
EAPI Eina_Bool evas_object_map_enable_get (const Evas_Object *obj);
- EAPI void evas_object_map_set (Evas_Object *obj, const Evas_Map_Point *points);
- EAPI void evas_object_map_get (const Evas_Object *obj, Evas_Map_Point *points);
-
- EAPI void evas_map_util_rotate (Evas_Map_Point *mp, double degrees, Evas_Coord cx, Evas_Coord cy);
- EAPI void evas_map_util_zoom (Evas_Map_Point *mp, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
-
- EAPI Evas_Map_Point *evas_map_new (int num);
- EAPI void evas_map_free (Evas_Map_Point *mp);
- EAPI void evas_map_point_coord_set (Evas_Map_Point *mp, int n, Evas_Coord x, Evas_Coord y, Evas_Coord z);
- EAPI void evas_map_point_coord_get (const Evas_Map_Point *mp, int n, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z);
- EAPI void evas_map_point_image_uv_set (Evas_Map_Point *mp, int n, double u, double v);
- EAPI void evas_map_point_image_uv_get (const Evas_Map_Point *mp, int n, double *u, double *v);
-
+ EAPI void evas_object_map_set (Evas_Object *obj, const Evas_Map *map);
+ EAPI const Evas_Map *evas_object_map_get (const Evas_Object *obj);
+
+ EAPI void evas_map_util_rotate (Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy);
+ EAPI void evas_map_util_zoom (Evas_Map *m, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
+
+ EAPI Evas_Map *evas_map_new (unsigned long count);
+ EAPI Evas_Map *evas_map_dup (const Evas_Map *m);
+ EAPI void evas_map_free (Evas_Map *m);
+ EAPI void evas_map_point_coord_set (Evas_Map *m, unsigned long idx, Evas_Coord x, Evas_Coord y, Evas_Coord z);
+ EAPI void evas_map_point_coord_get (const Evas_Map *m, unsigned long idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z);
+ EAPI void evas_map_point_image_uv_set (Evas_Map *m, unsigned long idx, double u, double v);
+ EAPI void evas_map_point_image_uv_get (const Evas_Map *m, unsigned long idx, double *u, double *v);
+
/* 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 void
_calc_map_geometry(Evas_Object *obj)
{
- int i;
int is, was = 0, pass = 0;
Evas_Coord x1, x2, y1, y2;
-
- if (!obj->cur.mappoints) return;
- x1 = obj->cur.mappoints[0].x;
- x2 = obj->cur.mappoints[0].x;
- y1 = obj->cur.mappoints[0].y;
- y2 = obj->cur.mappoints[0].y;
- for (i = 1; i < 4; i++)
+ const Evas_Map_Point *p, *p_end;
+
+ if (!obj->cur.map) return;
+ p = obj->cur.map->points;
+ p_end = p + 4;
+ x1 = p->x;
+ x2 = p->x;
+ y1 = p->y;
+ y2 = p->y;
+ p++;
+ for (; p < p_end; p++)
{
- if (obj->cur.mappoints[i].x < x1) x1 = obj->cur.mappoints[i].x;
- if (obj->cur.mappoints[i].x > x2) x2 = obj->cur.mappoints[i].x;
- if (obj->cur.mappoints[i].y < y1) y1 = obj->cur.mappoints[i].y;
- if (obj->cur.mappoints[i].y > y2) y2 = obj->cur.mappoints[i].y;
+ if (p->x < x1) x1 = p->x;
+ if (p->x > x2) x2 = p->x;
+ if (p->y < y1) y1 = p->y;
+ if (p->y > y2) y2 = p->y;
}
obj->cur.geometry.x = x1;
obj->cur.geometry.y = y1;
return obj->cur.usemap;
}
+static inline Evas_Map *
+_evas_map_new(unsigned long count)
+{
+ Evas_Map *m = malloc(sizeof(Evas_Map) + count * sizeof(Evas_Map_Point));
+ if (!m)
+ return NULL;
+ m->count = count;
+ return m;
+}
+
+static inline Evas_Map *
+_evas_map_dup(const Evas_Map *orig)
+{
+ Evas_Map *copy = _evas_map_new(orig->count);
+ if (!orig)
+ 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)
+{
+ if (dst->count != src->count)
+ {
+ ERR("cannot copy map of different sizes: dst=%lu, src=%lu",
+ dst->count, src->count);
+ return EINA_FALSE;
+ }
+ memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point));
+ return EINA_TRUE;
+}
+
+static inline void
+_evas_map_free(Evas_Map *m)
+{
+ free(m);
+}
+
+/**
+ * Set current object transformation map (or unset if it's @c NULL).
+ *
+ * @param obj object to change transformation map.
+ * @param map new map to use or @c NULL to unset map. This function
+ * will copy the given map, so it's safe to destroy it
+ * afterwards.
+ *
+ * @see evas_map_new()
+ */
EAPI void
-evas_object_map_set(Evas_Object *obj, const Evas_Map_Point *points)
+evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
{
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return;
MAGIC_CHECK_END();
- if (!points)
+ if (!map)
{
- if (obj->cur.mappoints)
+ if (obj->cur.map)
{
- if (!obj->prev.mappoints)
+ if (!obj->prev.map)
{
- free(obj->cur.mappoints);
- obj->cur.mappoints = NULL;
+ _evas_map_free(obj->cur.map);
+ obj->cur.map = NULL;
return;
}
- obj->cur.mappoints = NULL;
+ obj->cur.map = NULL;
}
return;
}
- if (!obj->cur.mappoints)
+ if (!obj->cur.map)
{
- obj->cur.mappoints = malloc(4 * sizeof(Evas_Map_Point));
- if (obj->cur.mappoints)
- {
- memcpy(obj->cur.mappoints, points, 4 * sizeof(Evas_Map_Point));
- }
- obj->prev.mappoints = NULL;
+ obj->cur.map = _evas_map_dup(map);
+ obj->prev.map = NULL;
}
else
{
- memcpy(obj->cur.mappoints, points, 4 * sizeof(Evas_Map_Point));
- obj->prev.mappoints = NULL;
+ _evas_map_copy(obj->cur.map, map);
+ obj->prev.map = NULL;
}
if (obj->cur.usemap) _calc_map_geometry(obj);
}
-EAPI void
-evas_object_map_get(const Evas_Object *obj, Evas_Map_Point *points)
+/**
+ * Get current object transformation map.
+ *
+ * @param obj object to query transformation map.
+ * @return map reference to map in use. This is an internal reference,
+ * don't change it anyhow. Use evas_map_dup() if you want to
+ * change it and use somewhere else, or even take reference
+ * for long time. The returned reference may go away when
+ * another map is set or object is destroyed.
+ *
+ * @see evas_object_map_set()
+ */
+EAPI const Evas_Map *
+evas_object_map_get(const Evas_Object *obj)
{
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
- return;
+ return NULL;
MAGIC_CHECK_END();
- if (obj->cur.mappoints)
+ if (obj->cur.map)
+ return obj->cur.map;
+ else
+ return NULL;
+}
+
+/**
+ * Creates map of transformation points to be later used with an evas object.
+ *
+ * @param count number of points in the map. So far it @b must be 4 as
+ * evas will use that exact number. The parameter is for
+ * extensibility. Giving any value other than 4 will return @c NULL.
+ *
+ * @return a newly allocated map or @c NULL on errors.
+ *
+ * @see evas_map_free()
+ * @see evas_map_dup()
+ * @see evas_map_point_coord_set()
+ * @see evas_map_point_image_uv_set()
+ *
+ * @see evas_object_map_set()
+ */
+EAPI Evas_Map *
+evas_map_new(unsigned long count)
+{
+ if (count != 4)
{
- memcpy(points, obj->cur.mappoints, 4 * sizeof(Evas_Map_Point));
+ ERR("num (%lu) != 4 is unsupported!", count);
+ return NULL;
}
+ return _evas_map_new(count);
}
-
-EAPI Evas_Map_Point *
-evas_map_new(int num)
+/**
+ * Copy a previously allocated map.
+ *
+ * @param m map to copy. Must not be @c NULL.
+ *
+ * @return newly allocated map with the same count and contents as @a m.
+ */
+EAPI Evas_Map *
+evas_map_dup(const Evas_Map *m)
{
- return calloc(num, sizeof(Evas_Map_Point));
+ if (!m) return NULL;
+ return _evas_map_dup(m);
}
+/**
+ * Destroys a previously allocated map.
+ *
+ * @param m map to destroy. Must not be @c NULL.
+ */
EAPI void
-evas_map_free(Evas_Map_Point *mp)
+evas_map_free(Evas_Map *m)
{
- if (!mp) return;
- free(mp);
+ if (!m) return;
+ _evas_map_free(m);
}
+/**
+ * Change the map point's coordinate.
+ *
+ * @param m map to change point. Must not be @c NULL.
+ * @param idx index of point to change. Must be smaller than map size.
+ * @param x TODO
+ * @param y TODO
+ * @param z TODO
+ *
+ * @see evas_map_util_rotate()
+ * @see evas_map_util_zoom()
+ */
EAPI void
-evas_map_point_coord_set(Evas_Map_Point *mp, int n, Evas_Coord x, Evas_Coord y, Evas_Coord z)
+evas_map_point_coord_set(Evas_Map *m, unsigned long idx, Evas_Coord x, Evas_Coord y, Evas_Coord z)
{
- if (!mp) return;
- mp[n].x = x;
- mp[n].y = y;
- mp[n].z = z;
+ Evas_Map_Point *p;
+ if (!m) return;
+ if (idx >= m->count) return;
+ p = m->points + idx;
+ p->x = x;
+ p->y = y;
+ p->z = z;
}
+/**
+ * Get the map point's coordinate.
+ *
+ * @param m map to query point. Must not be @c NULL.
+ * @param idx index of point to query. Must be smaller than map size.
+ * @param x where to return TODO. If non @c NULL, it's guaranteed to
+ * be set (on error it's set to zero).
+ * @param y where to return TODO. If non @c NULL, it's guaranteed to
+ * be set (on error it's set to zero).
+ * @param z where to return TODO. If non @c NULL, it's guaranteed to
+ * be set (on error it's set to zero).
+ */
EAPI void
-evas_map_point_coord_get(const Evas_Map_Point *mp, int n, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z)
+evas_map_point_coord_get(const Evas_Map *m, unsigned long idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z)
{
- if (!mp) return;
- if (x) *x = mp[n].x;
- if (y) *y = mp[n].y;
- if (z) *z = mp[n].z;
+ const Evas_Map_Point *p;
+ if (!m) goto error;
+ if (idx >= m->count) goto error;
+ p = m->points + idx;
+ if (x) *x = p->x;
+ if (y) *y = p->y;
+ if (z) *z = p->z;
+ return;
+
+ error:
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (z) *z = 0;
}
+/**
+ * Change the map point's TODO.
+ *
+ * @param m map to change point. Must not be @c NULL.
+ * @param idx index of point to change. Must be smaller than map size.
+ * @param u TODO
+ * @param v TODO
+ */
EAPI void
-evas_map_point_image_uv_set(Evas_Map_Point *mp, int n, double u, double v)
+evas_map_point_image_uv_set(Evas_Map *m, unsigned long idx, double u, double v)
{
- if (!mp) return;
- mp[n].u = u;
- mp[n].v = v;
+ Evas_Map_Point *p;
+ if (!m) return;
+ if (idx >= m->count) return;
+ p = m->points + idx;
+ p->u = u;
+ p->v = v;
}
+/**
+ * Get the map point's TODO.
+ *
+ * @param m map to query point. Must not be @c NULL.
+ * @param idx index of point to query. Must be smaller than map size.
+ * @param u where to return TODO. If non @c NULL, it's guaranteed to
+ * be set (on error it's set to zero).
+ * @param v where to return TODO. If non @c NULL, it's guaranteed to
+ * be set (on error it's set to zero).
+ */
EAPI void
-evas_map_point_image_uv_get(const Evas_Map_Point *mp, int n, double *u, double *v)
+evas_map_point_image_uv_get(const Evas_Map *m, unsigned long idx, double *u, double *v)
{
- if (!mp) return;
- if (u) *u = mp[n].u;
- if (v) *v = mp[n].v;
+ const Evas_Map_Point *p;
+ if (!m) goto error;
+ if (idx >= m->count) goto error;
+ p = m->points + idx;
+ if (u) *u = p->u;
+ if (v) *v = p->v;
+ return;
+
+ error:
+ if (u) *u = 0.0;
+ if (v) *v = 0.0;
}
+/**
+ * Change the map to apply the given rotation to object.
+ *
+ * @param m map to change. Must not be @c NULL.
+ * @param degrees amount of degrees from 0.0 to 360.0 to rotate the
+ * object. This is the canonical reference, counter-clockwise. TODO
+ * @param cx rotation's center horizontal positon. TODO (offset from object center? left?)
+ * @param cy rotation's center vertical positon. TODO (offset from object center? top?)
+ *
+ * @see evas_map_point_coord_set()
+ */
EAPI void
-evas_map_util_rotate(Evas_Map_Point *mp, double degrees, Evas_Coord cx, Evas_Coord cy)
+evas_map_util_rotate(Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy)
{
double r = (degrees * M_PI) / 180.0;
- int i;
+ Evas_Map_Point *p, *p_end;
+
+ if (!m) return;
+ if (m->count != 4) return;
- for (i = 0; i < 4; i++)
+ p = m->points;
+ p_end = p + 4;
+
+ for (; p < p_end; p++)
{
Evas_Coord x, y, xx, yy;
-
- xx = x = mp[i].x - cx;
- yy = y = mp[i].y - cy;
-
+
+ xx = x = p->x - cx;
+ yy = y = p->y - cy;
+
xx = (x * cos(r));
yy = (x * sin(r));
x = xx + (y * cos(r + (M_PI / 2.0)));
y = yy + (y * sin(r + (M_PI / 2.0)));
-
- mp[i].x = x + cx;
- mp[i].y = y + cy;
+
+ p->x = x + cx;
+ p->y = y + cy;
}
}
+/**
+ * Change the map to apply the given zooming to object.
+ *
+ * @param m map to change. Must not be @c NULL.
+ * @param zoomx horizontal zoom to use.
+ * @param zoomy vertical zoom to use.
+ * @param cx zooming center horizontal positon. TODO (offset from object center? left?)
+ * @param cy zooming center vertical positon. TODO (offset from object center? top?)
+ *
+ * @see evas_map_point_coord_set()
+ */
EAPI void
-evas_map_util_zoom(Evas_Map_Point *mp, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy)
+evas_map_util_zoom(Evas_Map *m, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy)
{
- int i;
+ Evas_Map_Point *p, *p_end;
+
+ if (!m) return;
+ if (m->count != 4) return;
- for (i = 0; i < 4; i++)
+ p = m->points;
+ p_end = p + 4;
+
+ for (; p < p_end; p++)
{
Evas_Coord x, y;
-
- x = mp[i].x - cx;
- y = mp[i].y - cy;
-
+
+ x = p->x - cx;
+ y = p->y - cy;
+
x = (((double)x) * zoomx);
y = (((double)y) * zoomy);
-
- mp[i].x = x + cx;
- mp[i].y = y + cy;
+
+ p->x = x + cx;
+ p->y = y + cy;
}
}
}
o->dirty_pixels = 0;
}
- if ((obj->cur.mappoints) && (obj->cur.usemap))
+ if ((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap))
{
- RGBA_Map_Point pts[4];
- int i;
-
+ const Evas_Map_Point *p, *p_end;
+ RGBA_Map_Point pts[4], *pt;
+
+ p = obj->cur.map->points;
+ p_end = p + 4;
+ pt = pts;
+
// draw geom +x +y
- for (i = 0; i < 4; i++)
+ for (; p < p_end; p++, pt++)
{
- pts[i].x = (obj->cur.mappoints[i].x + x) << FP;
- pts[i].y = (obj->cur.mappoints[i].y + y) << FP;
- pts[i].z = (obj->cur.mappoints[i].z) << FP;
- pts[i].u = obj->cur.mappoints[i].u * FP1;
- pts[i].v = obj->cur.mappoints[i].v * FP1;
+ pt->x = (p->x + x) << FP;
+ pt->y = (p->y + y) << FP;
+ pt->z = (p->z) << FP;
+ pt->u = p->u * FP1;
+ pt->v = p->v * FP1;
}
obj->layer->evas->engine.func->image_map4_draw(output,
context,
evas_object_image_is_opaque(Evas_Object *obj)
{
Evas_Object_Image *o;
- int v;
/* this returns 1 if the internal object data implies that the object is */
/* currently fully opaque over the entire rectangle it occupies */
(o->cur.border.b != 0)) &&
(!o->cur.border.fill)) return 0;
if (!o->engine_data) return 0;
- if ((obj->cur.mappoints) && (obj->cur.usemap)) return 0;
+ if ((obj->cur.map) && (obj->cur.usemap)) return 0;
if (obj->cur.render_op == EVAS_RENDER_COPY) return 1;
if (o->cur.has_alpha) return 0;
return 1;
(o->prev.border.b != 0)) &&
(!o->prev.border.fill)) return 0;
if (!o->engine_data) return 0;
- if ((obj->prev.mappoints) && (obj->prev.usemap)) return 0;
+ if ((obj->prev.map) && (obj->prev.usemap)) return 0;
if (obj->prev.render_op == EVAS_RENDER_COPY) return 1;
if (o->prev.has_alpha) return 0;
if (obj->prev.render_op != EVAS_RENDER_BLEND) return 0;
Evas_Object_Image *o;
o = (Evas_Object_Image *)(obj->object_data);
- if ((obj->cur.mappoints) && (obj->cur.usemap)) return 0;
+ if ((obj->cur.map) && (obj->cur.usemap)) return 0;
if (((o->cur.border.l | o->cur.border.r | o->cur.border.t | o->cur.border.b) != 0) &&
(o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
(obj->cur.render_op == EVAS_RENDER_BLEND) &&