From 8ef8a6fec2631f28be66412eb98cae9e501b3d23 Mon Sep 17 00:00:00 2001 From: raster Date: Wed, 28 Oct 2009 08:59:01 +0000 Subject: [PATCH] the start of other objects being able to map! text objects work.. tested. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@43323 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/Evas.h | 10 +- src/lib/canvas/evas_map.c | 339 ++++++++++++++------- src/lib/canvas/evas_object_gradient.c | 1 + src/lib/canvas/evas_object_gradient2_linear.c | 1 + src/lib/canvas/evas_object_gradient2_radial.c | 1 + src/lib/canvas/evas_object_image.c | 10 +- src/lib/canvas/evas_object_line.c | 1 + src/lib/canvas/evas_object_main.c | 1 + src/lib/canvas/evas_object_polygon.c | 1 + src/lib/canvas/evas_object_rectangle.c | 1 + src/lib/canvas/evas_object_smart.c | 1 + src/lib/canvas/evas_object_textblock.c | 1 + src/lib/canvas/evas_render.c | 169 ++++++++-- src/lib/include/evas_private.h | 8 +- src/modules/engines/cairo_x11/evas_engine.c | 5 +- src/modules/engines/direct3d/evas_engine.c | 4 + src/modules/engines/directfb/evas_engine.c | 5 + src/modules/engines/gl_x11/evas_engine.c | 4 + src/modules/engines/quartz/evas_engine.c | 5 +- src/modules/engines/software_16/evas_engine.c | 4 + src/modules/engines/software_generic/evas_engine.c | 24 +- src/modules/engines/xrender_x11/evas_engine.c | 4 + 22 files changed, 455 insertions(+), 145 deletions(-) diff --git a/src/lib/Evas.h b/src/lib/Evas.h index e2e3ec5..05dd2b7 100644 --- a/src/lib/Evas.h +++ b/src/lib/Evas.h @@ -857,13 +857,13 @@ extern "C" { 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_new (int 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); + 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); + EAPI void evas_map_point_image_uv_get (const Evas_Map *m, int 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; diff --git a/src/lib/canvas/evas_map.c b/src/lib/canvas/evas_map.c index 8f792a4..22f5634 100644 --- a/src/lib/canvas/evas_map.c +++ b/src/lib/canvas/evas_map.c @@ -3,31 +3,10 @@ #include static void -_calc_map_geometry(Evas_Object *obj) +_evas_map_calc_geom_change(Evas_Object *obj) { int is, was = 0, pass = 0; - Evas_Coord x1, x2, y1, y2; - 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 (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; - obj->cur.geometry.w = (x2 - x1) + 1; - obj->cur.geometry.h = (y2 - y1) + 1; evas_object_change(obj); evas_object_clip_dirty(obj); if (obj->layer->evas->events_frozen <= 0) @@ -53,32 +32,39 @@ _calc_map_geometry(Evas_Object *obj) evas_object_inform_call_resize(obj); } -EAPI void -evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled) +static void +_evas_map_calc_map_geometry(Evas_Object *obj) { - MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); - return; - MAGIC_CHECK_END(); - if (obj->cur.usemap == !!enabled) return; - obj->cur.usemap = enabled; - if (obj->cur.usemap) _calc_map_geometry(obj); -} + Evas_Coord x1, x2, y1, y2; + const Evas_Map_Point *p, *p_end; -EAPI Eina_Bool -evas_object_map_enable_get(const Evas_Object *obj) -{ - MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); - return 0; - MAGIC_CHECK_END(); - return obj->cur.usemap; + 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 (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; + obj->cur.geometry.w = (x2 - x1) + 1; + obj->cur.geometry.h = (y2 - y1) + 1; + _evas_map_calc_geom_change(obj); } static inline Evas_Map * -_evas_map_new(unsigned long count) +_evas_map_new(int count) { - Evas_Map *m = malloc(sizeof(Evas_Map) + count * sizeof(Evas_Map_Point)); - if (!m) - return NULL; + Evas_Map *m = calloc(1, sizeof(Evas_Map) + count * sizeof(Evas_Map_Point)); + if (!m) return NULL; m->count = count; return m; } @@ -87,8 +73,7 @@ static inline Evas_Map * _evas_map_dup(const Evas_Map *orig) { Evas_Map *copy = _evas_map_new(orig->count); - if (!orig) - return NULL; + if (!copy) return NULL; memcpy(copy->points, orig->points, orig->count * sizeof(Evas_Map_Point)); return copy; } @@ -113,12 +98,99 @@ _evas_map_free(Evas_Map *m) } /** - * Set current object transformation map (or unset if it's @c NULL). + * Enable or disable the map that is set + * + * This enables the map that is set or disables it. On enable, the object + * geometry will be saved, and the new geometry will change (position and + * size) to reflect the map geometry set. If none is set yet, this may be + * an undefined geometry, unless you have already set the map with + * evas_object_map_set(). It is suggested you first set a map with + * evas_object_map_set() with valid useful coordinatesm then enable and + * disable the map with evas_object_map_enable_set() as needed. + * + * @param obj object to enable the map on + * @param enbled enabled state + */ +EAPI void +evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + if (obj->cur.usemap == !!enabled) return; + obj->cur.usemap = enabled; + if (enabled) + { + if (!obj->cur.map) + obj->cur.map = _evas_map_new(4); + obj->cur.map->normal_geometry = obj->cur.geometry; + } + else + { + if (obj->cur.map) + { + obj->cur.geometry = obj->cur.map->normal_geometry; + _evas_map_calc_geom_change(obj); + } + } + if (obj->cur.usemap) _evas_map_calc_map_geometry(obj); +} + +/** + * Get the map enabled state + * + * This returns the currently enabled state of the map on the object indicated. + * The default map enable state is off. You can enable and disable it with + * evas_object_map_enable_set(). + * + * @param obj object to get the map enabled state from + * @return the map enabled state + */ +EAPI Eina_Bool +evas_object_map_enable_get(const Evas_Object *obj) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return 0; + MAGIC_CHECK_END(); + return obj->cur.usemap; +} + +/** + * Set current object transformation map. + * + * This sets the map on a given object. It is copied from the @p map pointer, + * so there is no need to keep the @p map object if you don't need it anymore. + * + * A map is a set of 4 points which have canvas x, y coordinates per point, + * with an optional z point value as a hint for perspective correction, if it + * is available. As well each point has u and v coordinates. These are like + * "texture coordinates" in OpenGL in that they define a point in the source + * image that is mapped to that map vertex/point. The u corresponds to the x + * coordinate of this mapped point and v, the y coordinate. Note that these + * coordinates describe a bounding region to sample. If you have a 200x100 + * source image and wannt to display it at 200x100 with proper pixel + * precision, then do: + * + * @code + * Evas_Map *m = evas_map_new(4); + * evas_map_point_coord_set(m, 0, 0, 0, 0); + * evas_map_point_coord_set(m, 1, 200, 0, 0); + * evas_map_point_coord_set(m, 2, 200, 100, 0); + * evas_map_point_coord_set(m, 3, 0, 100, 0); + * evas_map_point_image_uv_set(m, 0, 0, 0); + * evas_map_point_image_uv_set(m, 1, 200, 0); + * evas_map_point_image_uv_set(m, 2, 200, 100); + * evas_map_point_image_uv_set(m, 3, 0, 100); + * evas_object_map_set(obj, m); + * evas_map_free(m); + * @endcode + * + * Note that the map points a uv coordinates match the image geometry. If + * the @p map parameter is NULL, the sotred map will be freed and geometry + * prior to enabling/setting a map will be restored. * - * @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. + * @param obj object to change transformation map + * @param map new map to use * * @see evas_map_new() */ @@ -132,6 +204,7 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map) { if (obj->cur.map) { + obj->cur.geometry = obj->cur.map->normal_geometry; if (!obj->prev.map) { _evas_map_free(obj->cur.map); @@ -139,6 +212,8 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map) return; } obj->cur.map = NULL; + if (!obj->cur.usemap) _evas_map_calc_geom_change(obj); + else _evas_map_calc_map_geometry(obj); } return; } @@ -152,18 +227,28 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map) _evas_map_copy(obj->cur.map, map); obj->prev.map = NULL; } - if (obj->cur.usemap) _calc_map_geometry(obj); + if (obj->cur.usemap) _evas_map_calc_map_geometry(obj); } /** * Get current object transformation map. + * + * This returns the current internal map set on the indicated object. It is + * intended for read-only acces and is only valid as long as the object is + * not deleted or the map on the object is not changed. If you wish to modify + * the map and set it back do the following: + * + * @code + * const Evas_Map *m = evas_object_map_get(obj); + * Evas_Map *m2 = evas_map_dup(m); + * evas_map_util_rotate(m2, 30.0, 0, 0); + * evas_object_map_set(obj); + * evas_map_free(m2); + * @endcode * * @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. + * @return map reference to map in use. This is an internal data structure, so + * do not modify it. * * @see evas_object_map_set() */ @@ -173,20 +258,19 @@ evas_object_map_get(const Evas_Object *obj) MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); return NULL; MAGIC_CHECK_END(); - if (obj->cur.map) - return obj->cur.map; - else - return NULL; + if (obj->cur.map) return obj->cur.map; + 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. + * Create map of transformation points to be later used with an evas object. * - * @return a newly allocated map or @c NULL on errors. + * This creates a set of points (currently only 4 is supported. no other + * number for @p count will work). That is empty and ready to be modified + * with evas_map calls. + * + * @param count number of points in the map. * + * @return a newly allocated map or NULL on errors. * * @see evas_map_free() * @see evas_map_dup() @@ -196,7 +280,7 @@ evas_object_map_get(const Evas_Object *obj) * @see evas_object_map_set() */ EAPI Evas_Map * -evas_map_new(unsigned long count) +evas_map_new(int count) { if (count != 4) { @@ -208,10 +292,11 @@ evas_map_new(unsigned long count) /** * Copy a previously allocated map. + * + * This makes a duplicate of the @p m object and returns it. * - * @param m map to copy. Must not be @c NULL. - * - * @return newly allocated map with the same count and contents as @a m. + * @param m map to copy. Must not be NULL. + * @return newly allocated map with the same count and contents as @p m. */ EAPI Evas_Map * evas_map_dup(const Evas_Map *m) @@ -221,9 +306,12 @@ evas_map_dup(const Evas_Map *m) } /** - * Destroys a previously allocated map. + * Free a previously allocated map. * - * @param m map to destroy. Must not be @c NULL. + * This frees a givem map @p m and all memory associated with it. You must NOT + * free a map returned by evas_object_map_get() as this is internal. + * + * @param m map to free. */ EAPI void evas_map_free(Evas_Map *m) @@ -234,18 +322,33 @@ evas_map_free(Evas_Map *m) /** * Change the map point's coordinate. + * + * This sets the fixen point's coordinate in the map. Note that points + * describe the outline of a quadrangle and are ordered either clockwise + * or anit-clock-wise. It is suggested to keep your quadrangles concave and + * non-complex, though these polygon modes may work, they may not render + * a desired set of output. The quadrangle will use points 0 and 1 , 1 and 2, + * 2 and 3, and 3 and 0 to describe the edges of the quandrangle. + * + * The X and Y and Z coordinates are in canvas units. Z is optional and may + * or may not be honored in drawing. Z is a hint and does not affect the + * X and Y rendered coordinates. It may be used for calculating fills with + * perspective correct rendering. + * + * Remember all coordinates are canvas global ones like with move and reize + * in evas. * * @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 + * @param x Point X Coordinate + * @param y Point Y Coordinate + * @param z Point Z Coordinate hint (pre-perspective transform) * * @see evas_map_util_rotate() * @see evas_map_util_zoom() */ EAPI void -evas_map_point_coord_set(Evas_Map *m, unsigned long idx, Evas_Coord x, Evas_Coord y, Evas_Coord z) +evas_map_point_coord_set(Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_Coord z) { Evas_Map_Point *p; if (!m) return; @@ -258,20 +361,20 @@ evas_map_point_coord_set(Evas_Map *m, unsigned long idx, Evas_Coord x, Evas_Coor /** * Get the map point's coordinate. + * + * This returns the coordinates of the given point in the map. * - * @param m map to query point. Must not be @c NULL. + * @param m map to query point. * @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). + * @param x where to return the X coordinate. + * @param y where to return the Y coordinate. + * @param z where to return the Z coordinate. */ EAPI void -evas_map_point_coord_get(const Evas_Map *m, unsigned long idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z) +evas_map_point_coord_get(const Evas_Map *m, int idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z) { const Evas_Map_Point *p; + if (!m) goto error; if (idx >= m->count) goto error; p = m->points + idx; @@ -287,15 +390,24 @@ evas_map_point_coord_get(const Evas_Map *m, unsigned long idx, Evas_Coord *x, Ev } /** - * Change the map point's TODO. + * Change the map point's U and V texture source point * - * @param m map to change point. Must not be @c NULL. + * This sets the U and V coordinates for the point. This determines which + * coordinate in the source image is mapped to the given point, much like + * OpenGL and textures. Notes that these points do select the pixel, but + * are double floating point values to allow for accuracy and sub-pixel + * selection. + * + * @param m map to change the point of. * @param idx index of point to change. Must be smaller than map size. - * @param u TODO - * @param v TODO + * @param u the X coordinate within the image/texture source + * @param v the Y coordinate within the image/texture source + * + * @see evas_map_point_coord_set() + * @see evas_object_map_set() */ EAPI void -evas_map_point_image_uv_set(Evas_Map *m, unsigned long idx, double u, double v) +evas_map_point_image_uv_set(Evas_Map *m, int idx, double u, double v) { Evas_Map_Point *p; if (!m) return; @@ -306,17 +418,17 @@ evas_map_point_image_uv_set(Evas_Map *m, unsigned long idx, double u, double v) } /** - * Get the map point's TODO. + * Get the map point's U and V texture source points * - * @param m map to query point. Must not be @c NULL. + * This returns the texture points set by evas_map_point_image_uv_set(). + * + * @param m map to query point. * @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). + * @param u where to write the X coordinate within the image/texture source + * @param v where to write the Y coordinate within the image/texture source */ EAPI void -evas_map_point_image_uv_get(const Evas_Map *m, unsigned long idx, double *u, double *v) +evas_map_point_image_uv_get(const Evas_Map *m, int idx, double *u, double *v) { const Evas_Map_Point *p; if (!m) goto error; @@ -331,16 +443,26 @@ evas_map_point_image_uv_get(const Evas_Map *m, unsigned long idx, double *u, dou if (v) *v = 0.0; } +/****************************************************************************/ +/* util functions for manipulating maps, so you don't need to know the math */ +/****************************************************************************/ + /** - * Change the map to apply the given rotation to object. + * Change the map to apply the given rotation. + * + * This rotates the indicated map's coordinates around the center coordinate + * given by @p cx and @p cy as the rotation center. The points will have their + * X and Y coordinates rotated clockwise by @p degrees degress (360.0 is a + * full rotation). Negative values for degrees will rotate counter-clockwise + * by that amount. All coordinates are canvas global coordinates. * - * @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?) + * @param m map to change. + * @param degrees amount of degrees from 0.0 to 360.0 to rotate. + * @param cx rotation's center horizontal positon. + * @param cy rotation's center vertical positon. * * @see evas_map_point_coord_set() + * @see evas_map_util_zoom() */ EAPI void evas_map_util_rotate(Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy) @@ -372,15 +494,22 @@ evas_map_util_rotate(Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy) } /** - * Change the map to apply the given zooming to object. + * Change the map to apply the given zooming. * - * @param m map to change. Must not be @c NULL. + * Like evas_map_util_rotate(), this zooms the points of the map from a center + * point. That center is defined by @p cx and @p cy. The @p zoomx and @p zoomy + * parameters specific how much to zoom in the X and Y direction respectively. + * A value of 1.0 means "don't zoom". 2.0 means "dobule the size". 0.5 is + * "half the size" etc. All coordinates are canvas global coordinates. + * + * @param m map to change. * @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?) + * @param cx zooming center horizontal positon. + * @param cy zooming center vertical positon. * * @see evas_map_point_coord_set() + * @see evas_map_util_rotate() */ EAPI void evas_map_util_zoom(Evas_Map *m, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy) diff --git a/src/lib/canvas/evas_object_gradient.c b/src/lib/canvas/evas_object_gradient.c index b7be14e..2cbc606 100644 --- a/src/lib/canvas/evas_object_gradient.c +++ b/src/lib/canvas/evas_object_gradient.c @@ -78,6 +78,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, NULL }; diff --git a/src/lib/canvas/evas_object_gradient2_linear.c b/src/lib/canvas/evas_object_gradient2_linear.c index 3c02a95..a23dda9 100644 --- a/src/lib/canvas/evas_object_gradient2_linear.c +++ b/src/lib/canvas/evas_object_gradient2_linear.c @@ -63,6 +63,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, NULL }; diff --git a/src/lib/canvas/evas_object_gradient2_radial.c b/src/lib/canvas/evas_object_gradient2_radial.c index 1095521..3b6910e 100644 --- a/src/lib/canvas/evas_object_gradient2_radial.c +++ b/src/lib/canvas/evas_object_gradient2_radial.c @@ -63,6 +63,7 @@ static const Evas_Object_Func rg_object_func = NULL, NULL, NULL, + NULL, NULL }; diff --git a/src/lib/canvas/evas_object_image.c b/src/lib/canvas/evas_object_image.c index 6cdf5e1..0e49ca1 100644 --- a/src/lib/canvas/evas_object_image.c +++ b/src/lib/canvas/evas_object_image.c @@ -87,6 +87,7 @@ static int evas_object_image_was_opaque(Evas_Object *obj); static int evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y); static int evas_object_image_has_opaque_rect(Evas_Object *obj); static int evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); +static int evas_object_image_can_map(Evas_Object *obj); static void *evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace); static void evas_object_image_filled_resize_listener(void *data, Evas *e, Evas_Object *obj, void *einfo); @@ -113,7 +114,8 @@ static const Evas_Object_Func object_func = NULL, NULL, evas_object_image_has_opaque_rect, - evas_object_image_get_opaque_rect + evas_object_image_get_opaque_rect, + evas_object_image_can_map }; /** @@ -3004,6 +3006,12 @@ evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y return 1; } +static int +evas_object_image_can_map(Evas_Object *obj) +{ + return 1; +} + static void * evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace) { diff --git a/src/lib/canvas/evas_object_line.c b/src/lib/canvas/evas_object_line.c index 1f3cafc..1539c76 100644 --- a/src/lib/canvas/evas_object_line.c +++ b/src/lib/canvas/evas_object_line.c @@ -65,6 +65,7 @@ static const Evas_Object_Func object_func = evas_object_line_coords_recalc, NULL, NULL, + NULL, NULL }; diff --git a/src/lib/canvas/evas_object_main.c b/src/lib/canvas/evas_object_main.c index a623529..c93383e 100644 --- a/src/lib/canvas/evas_object_main.c +++ b/src/lib/canvas/evas_object_main.c @@ -383,6 +383,7 @@ evas_object_del(Evas_Object *obj) while (obj->clip.clipees) evas_object_clip_unset(obj->clip.clipees->data); if (obj->cur.clipper) evas_object_clip_unset(obj); if (obj->smart.smart) evas_object_smart_del(obj); + evas_object_map_set(obj, NULL); evas_object_event_callback_call(obj, EVAS_CALLBACK_FREE, NULL); evas_object_smart_cleanup(obj); obj->delete_me = 1; diff --git a/src/lib/canvas/evas_object_polygon.c b/src/lib/canvas/evas_object_polygon.c index 44c053f..2b3109e 100644 --- a/src/lib/canvas/evas_object_polygon.c +++ b/src/lib/canvas/evas_object_polygon.c @@ -62,6 +62,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, NULL }; diff --git a/src/lib/canvas/evas_object_rectangle.c b/src/lib/canvas/evas_object_rectangle.c index 9d6b3ce..0b8f06f 100644 --- a/src/lib/canvas/evas_object_rectangle.c +++ b/src/lib/canvas/evas_object_rectangle.c @@ -59,6 +59,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, NULL }; diff --git a/src/lib/canvas/evas_object_smart.c b/src/lib/canvas/evas_object_smart.c index cb9b622..579d3c6 100644 --- a/src/lib/canvas/evas_object_smart.c +++ b/src/lib/canvas/evas_object_smart.c @@ -59,6 +59,7 @@ static const Evas_Object_Func object_func = NULL, NULL, NULL, + NULL, NULL }; diff --git a/src/lib/canvas/evas_object_textblock.c b/src/lib/canvas/evas_object_textblock.c index 39fbf89..b45fb19 100644 --- a/src/lib/canvas/evas_object_textblock.c +++ b/src/lib/canvas/evas_object_textblock.c @@ -185,6 +185,7 @@ static const Evas_Object_Func object_func = evas_object_textblock_coords_recalc, evas_object_textblock_scale_update, NULL, + NULL, NULL }; diff --git a/src/lib/canvas/evas_render.c b/src/lib/canvas/evas_render.c index 99e3277..24a4f40 100644 --- a/src/lib/canvas/evas_render.c +++ b/src/lib/canvas/evas_render.c @@ -2,7 +2,7 @@ #include "evas_private.h" static Eina_List * -evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char do_draw); +evas_render_updates_internal(Evas *e, Evas_Object *smart, unsigned char make_updates, unsigned char do_draw); /** * Add a damage rectangle. @@ -144,6 +144,39 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj, Eina_Array *active obj->changed = 1; clean_them = EINA_TRUE; } + + if (!((obj->func->can_map) && (obj->func->can_map(obj))) && + ((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap))) + { + if (obj->changed) + { + if ((is_active) && (obj->restack) && (!obj->clip.clipees) && + ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || + (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) + eina_array_push(restack_objects, obj); + else if ((is_active) && (!obj->clip.clipees) && + ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || + (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) + { + eina_array_push(render_objects, obj); + obj->render_pre = 1; + } + } + /* for now all mapped objects are no logner opaque + else + { + if (evas_object_is_opaque(obj) && + evas_object_is_visible(obj)) + { + eina_array_push(render_objects, obj); + obj->rect_del = 1; + } + } + */ + } + + /* handle normal rendering. this object knows how to handle maps */ + if (obj->changed) { if (obj->smart.smart) @@ -246,14 +279,14 @@ _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *e) Evas_Object *obj; int ok = 0; int is_active; - + obj = eina_array_data_get(pending_objects, i); - + if (!obj->layer) goto clean_stuff; - + evas_object_clip_recalc(obj); is_active = evas_object_is_active(obj); - + if (!is_active && !obj->is_active && !obj->render_pre && @@ -262,7 +295,7 @@ _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *e) ok = 1; goto clean_stuff; } - + if (obj->is_active == is_active) { if (obj->changed) @@ -279,18 +312,18 @@ _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *e) (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) { if (!(obj->render_pre - || obj->rect_del)) + || obj->rect_del)) ok = 1; } - else - if (is_active && (!obj->clip.clipees) && - ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || - (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) - { - if (obj->render_pre - || obj->rect_del) - ok = 1; - } + else + if (is_active && (!obj->clip.clipees) && + ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || + (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) + { + if (obj->render_pre + || obj->rect_del) + ok = 1; + } } else { @@ -303,18 +336,18 @@ _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *e) } } } - - clean_stuff: + + clean_stuff: if (!ok) { eina_array_clean(&e->active_objects); eina_array_clean(&e->render_objects); - + eina_array_clean(&e->restack_objects); eina_array_clean(&e->delete_objects); - + e->invalidate = 1; - + return ; } } @@ -332,7 +365,10 @@ pending_change(void *data, void *gdata __UNUSED__) } static Eina_List * -evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char do_draw) +evas_render_updates_internal(Evas *e, + Evas_Object *smart, + unsigned char make_updates, + unsigned char do_draw) { Eina_List *updates = NULL; Eina_List *ll; @@ -349,6 +385,11 @@ evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char MAGIC_CHECK_END(); if (!e->changed) return NULL; + if (smart) + { + // FIXME: if smart, only consider child objects + } + evas_call_smarts_calculate(e); /* Check if the modified object mean recalculating every thing */ @@ -588,11 +629,79 @@ evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char } } #endif - obj->func->render(obj, - e->engine.data.output, - e->engine.data.context, - surface, - off_x, off_y); + if (!((obj->func->can_map) && (obj->func->can_map(obj))) && + ((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap))) + { + const Evas_Map_Point *p, *p_end; + RGBA_Map_Point pts[4], *pt; + void *ctx; + + ctx = e->engine.func->context_new(e->engine.data.output); + if (!obj->cur.map->surface) + { + obj->cur.map->surface = + obj->layer->evas->engine.func->image_map_surface_new + (e->engine.data.output, + obj->cur.map->normal_geometry.w, + obj->cur.map->normal_geometry.h, + 1); + } + + if (obj->smart.smart) + { + // FIXME: doesnt work yet + // smart object. draw all children to + // surface (and if they are mapped... + // recurse) + evas_render_updates_internal(e, obj, 0, 1); + } + else + { + obj->func->render(obj, + e->engine.data.output, + ctx, + obj->cur.map->surface, + -obj->cur.cache.clip.x, + -obj->cur.cache.clip.y + ); + } + e->engine.func->context_free(e->engine.data.output, ctx); + + p = obj->cur.map->points; + p_end = p + 4; + pt = pts; + + for (; p < p_end; p++, pt++) + { + pt->x = (p->x + off_x) << FP; + pt->y = (p->y + off_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 + (e->engine.data.output, + e->engine.data.context, + surface, + obj->cur.map->surface, + pts, + 1, // smooth? (on for now) + 0); + // FIXME: needs to cache these maps and + // keep them only rendering updates + obj->layer->evas->engine.func->image_map_surface_free + (e->engine.data.output, + obj->cur.map->surface); + obj->cur.map->surface = NULL; + } + else + { + obj->func->render(obj, + e->engine.data.output, + e->engine.data.context, + surface, + off_x, off_y); + } e->engine.func->context_cutout_clear(e->engine.data.output, e->engine.data.context); } @@ -703,7 +812,7 @@ evas_render_updates(Evas *e) MAGIC_CHECK_END(); if (!e->changed) return NULL; - return evas_render_updates_internal(e, 1, 1); + return evas_render_updates_internal(e, NULL, 1, 1); } /** @@ -722,7 +831,7 @@ evas_render(Evas *e) MAGIC_CHECK_END(); if (!e->changed) return; - evas_render_updates_internal(e, 0, 1); + evas_render_updates_internal(e, NULL, 0, 1); } /** @@ -746,7 +855,7 @@ evas_norender(Evas *e) MAGIC_CHECK_END(); // if (!e->changed) return; - evas_render_updates_internal(e, 0, 0); + evas_render_updates_internal(e, NULL, 0, 0); } /** diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index 9892083..3b19aab 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -366,7 +366,9 @@ struct _Evas_Map_Point struct _Evas_Map { - unsigned long count; + int count; + Evas_Coord_Rectangle normal_geometry; + void *surface; Evas_Map_Point points[]; }; @@ -537,6 +539,8 @@ struct _Evas_Object_Func int (*has_opaque_rect) (Evas_Object *obj); int (*get_opaque_rect) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); + + int (*can_map) (Evas_Object *obj); }; struct _Evas_Func @@ -689,6 +693,8 @@ struct _Evas_Func int (*font_last_up_to_pos) (void *data, void *font, const char *text, 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_surface_new) (void *data, int w, int h, int alpha); + void *(*image_map_surface_free) (void *data, void *surface); }; struct _Evas_Image_Load_Func diff --git a/src/modules/engines/cairo_x11/evas_engine.c b/src/modules/engines/cairo_x11/evas_engine.c index a6a9923..90a4f1a 100644 --- a/src/modules/engines/cairo_x11/evas_engine.c +++ b/src/modules/engines/cairo_x11/evas_engine.c @@ -253,7 +253,10 @@ static Evas_Func eng_func = eng_image_scale_hint_set, eng_image_scale_hint_get, /* more font draw functions */ - eng_font_last_up_to_pos + eng_font_last_up_to_pos, + NULL, // image_map4_draw + NULL, // image_map_surface_new + NULL // image_map_surface_free }; static void * diff --git a/src/modules/engines/direct3d/evas_engine.c b/src/modules/engines/direct3d/evas_engine.c index 35d0683..8514f75 100644 --- a/src/modules/engines/direct3d/evas_engine.c +++ b/src/modules/engines/direct3d/evas_engine.c @@ -580,6 +580,10 @@ module_open(Evas_Module *em) ORD(image_scale_hint_set); ORD(image_scale_hint_get); +// ORD(image_map4_draw); +// ORD(image_map_surface_new); +// ORD(image_map_surface_free); + /* ORD(gradient2_color_np_stop_insert); ORD(gradient2_clear); diff --git a/src/modules/engines/directfb/evas_engine.c b/src/modules/engines/directfb/evas_engine.c index bee8460..91a751e 100644 --- a/src/modules/engines/directfb/evas_engine.c +++ b/src/modules/engines/directfb/evas_engine.c @@ -1679,6 +1679,11 @@ module_open(Evas_Module *em) ORD(gradient_draw); ORD(image_scale_hint_set); ORD(image_scale_hint_get); + +// ORD(image_map4_draw); +// ORD(image_map_surface_new); +// ORD(image_map_surface_free); + /* now advertise out own api */ em->functions = (void *)(&func); return 1; diff --git a/src/modules/engines/gl_x11/evas_engine.c b/src/modules/engines/gl_x11/evas_engine.c index f508f06..eb1f436 100644 --- a/src/modules/engines/gl_x11/evas_engine.c +++ b/src/modules/engines/gl_x11/evas_engine.c @@ -1175,6 +1175,10 @@ module_open(Evas_Module *em) ORD(image_scale_hint_set); ORD(image_scale_hint_get); + //ODR(image_map4_draw); + //ODR(image_map_surface_new); + //ODR(image_map_surface_free); + /* now advertise out own api */ em->functions = (void *)(&func); return 1; diff --git a/src/modules/engines/quartz/evas_engine.c b/src/modules/engines/quartz/evas_engine.c index 5f522ac..22f0e69 100644 --- a/src/modules/engines/quartz/evas_engine.c +++ b/src/modules/engines/quartz/evas_engine.c @@ -1512,7 +1512,10 @@ module_open(Evas_Module *em) ORD(image_scale_hint_set); ORD(image_scale_hint_get); - + +// ORD(image_map4_draw); +// ORD(image_map_surface_new); +// ORD(image_map_surface_free); /* now advertise out our api */ em->functions = (void *)(&func); return 1; diff --git a/src/modules/engines/software_16/evas_engine.c b/src/modules/engines/software_16/evas_engine.c index e366359..3fa448d 100644 --- a/src/modules/engines/software_16/evas_engine.c +++ b/src/modules/engines/software_16/evas_engine.c @@ -1012,6 +1012,10 @@ static Evas_Func func = /* more font draw functions */ eng_font_last_up_to_pos /* FUTURE software generic calls go here */ +// ORD(image_map4_draw); +// ORD(image_map_surface_new); +// ORD(image_map_surface_free); + /* FUTURE software generic calls go here */ }; /* diff --git a/src/modules/engines/software_generic/evas_engine.c b/src/modules/engines/software_generic/evas_engine.c index eded318..e4af6fa 100644 --- a/src/modules/engines/software_generic/evas_engine.c +++ b/src/modules/engines/software_generic/evas_engine.c @@ -787,6 +787,26 @@ eng_image_map4_draw(void *data __UNUSED__, void *context, void *surface, void *i evas_common_cpu_end_opt(); } +static void * +eng_image_map_surface_new(void *data __UNUSED__, int w, int h, int alpha) +{ + void *surface; + DATA32 *pixels; + surface = evas_cache_image_copied_data(evas_common_image_cache_get(), + w, h, NULL, alpha, + EVAS_COLORSPACE_ARGB8888); + pixels = evas_cache_image_pixels(surface); + // FIXME: need a clear call + memset(pixels, 0, (w *h * sizeof(DATA32))); + return surface; +} + +static void +eng_image_map_surface_free(void *data __UNUSED__, void *surface) +{ + evas_cache_image_drop(surface); +} + static void eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) { @@ -1135,7 +1155,9 @@ 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_map4_draw, + eng_image_map_surface_new, + eng_image_map_surface_free /* FUTURE software generic calls go here */ }; diff --git a/src/modules/engines/xrender_x11/evas_engine.c b/src/modules/engines/xrender_x11/evas_engine.c index 3fd4b07..32d9300 100644 --- a/src/modules/engines/xrender_x11/evas_engine.c +++ b/src/modules/engines/xrender_x11/evas_engine.c @@ -1500,6 +1500,10 @@ module_open(Evas_Module *em) ORD(image_scale_hint_set); ORD(image_scale_hint_get); + +// ORD(image_map4_draw); +// ORD(image_map_surface_new); +// ORD(image_map_surface_free); /* now advertise out own api */ em->functions = (void *)(&func); -- 2.7.4