Toma wrote:

I think the most recent patches for gradients have totally destroyed
all gradients in E. Poor lil Edjy is ruined and so is the Gradient
wallpaper selector and all the things associated with that.

  Attached (I hope) is a patch to fix those 'old' grads.. they should be back,
for now. :)

  The patch contains some further improvements on the new grads, and the start
of some new things to come for evas, so let me briefly go over some of them 
here.

1. The start of adding 'fill-transforms' and 'fill-spread' modes to evas image
objects. I've added the api and implemented the basic canvas level stuff. Here
are the api functions for that (set ones only here), just like the grad2 ones:

EAPI void evas_object_image_fill_transform_set(Evas_Object *obj, Evas_Transform 
*t);
EAPI void evas_object_image_fill_spread_set(Evas_Object *obj, int tile_mode);

  Hopefully by sometime next week I'll have a chance to finish off the software
engines implementation of this.

  The semantics of the fill-transform is simple: First, border-scale the image
to the current fill size, then apply the combined transform of the current fill-
transform and the translation to the current fill origin, where the translation
to the fill origin is done first (note though that transforms are really used
as the inverse transformations of what one wants, so the given fill translation
is composed on the left with the given fill-transform). All fill-transforms are
taken relative to the image object's top-left as the coordinate system origin,
of course.

  Shortly after this is done, I'll add the basics of stroke/fill texturing of
'shape' objects with images and grad2s. Again, as before, I'll do a sample
software implementation for (rounded) rects and for lines (with caps).

  This is great opportunity for those who are evas engineers to start thinking/
working on 'native' implementations for their engine of interest -- I can't do
*all* engines in x amount of time.. and while a simple mechanism to implicitly
'fall-back' to software easily would be nice, that's not quite available right
now and in any case the point of much of this is to have as 'native' versions
of things as much as possible.


2. I've also added some api functions for working with transforms.. these will
grow over time, but the given ones are all that's likely needed right now.
They are:

EAPI void evas_transform_identity_set(Evas_Transform *t);
EAPI void evas_transform_rotate(double angle, Evas_Transform *t);
EAPI void evas_transform_translate(float dx, float dy, Evas_Transform *t);
EAPI void evas_transform_scale(float sx, float sy, Evas_Transform *t);
EAPI void evas_transform_shear(float sh, float sv, Evas_Transform *t);
EAPI void evas_transform_compose(Evas_Transform *l, Evas_Transform *t);

  The semantics for these is described in comments above their declaration in
Evas.h, but basically (except for the first one which sets a transform to the
identity one), they *left-multiply* the given transform t by a suitable 
transform
obtained from the input data (eg. by a translation by some dx,dy, or by a 
rotation
by some angle, etc). These are implemented in a new "evas_transform.c" file 
which
I've attached, and is to go into the evas 'canvas' dir (added to Makefile.am 
there).

     Any comments, suggestions, or help with implementing things for the various
engines, are highly welcome.


____________________________________________________________
Get educated.  Click here for Adult Education programs.
http://thirdpartyoffers.juno.com/TGL2141/fc/Ioyw6i3nNbXdry8jLkUb84w1HNK75GcE4zYVfvya4wTPHD5bg1ZgKE/
Index: evas/src/lib/include/evas_private.h
===================================================================
--- evas/src/lib/include/evas_private.h	(revision 35699)
+++ evas/src/lib/include/evas_private.h	(working copy)
@@ -489,7 +489,8 @@
    void (*render_pre) (Evas_Object *obj);
    void (*render_post) (Evas_Object *obj);
 
-   int  (*visual_id_get) (Evas_Object *obj);
+   unsigned int  (*type_id_get) (Evas_Object *obj);
+   unsigned int  (*visual_id_get) (Evas_Object *obj);
    void *(*engine_data_get) (Evas_Object *obj);
 
    void (*store) (Evas_Object *obj);
Index: evas/src/lib/Evas.h
===================================================================
--- evas/src/lib/Evas.h	(revision 35699)
+++ evas/src/lib/Evas.h	(working copy)
@@ -500,6 +500,10 @@
    EAPI Evas_Bool         evas_object_image_border_center_fill_get(const Evas_Object *obj);
    EAPI void              evas_object_image_fill_set        (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
    EAPI void              evas_object_image_fill_get        (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
+   EAPI void              evas_object_image_fill_spread_set   (Evas_Object *obj, int tile_mode);
+   EAPI int               evas_object_image_fill_spread_get   (const Evas_Object *obj);
+   EAPI void              evas_object_image_fill_transform_set (Evas_Object *obj, Evas_Transform *t);
+   EAPI void              evas_object_image_fill_transform_get (const Evas_Object *obj, Evas_Transform *t);
    EAPI void              evas_object_image_size_set        (Evas_Object *obj, int w, int h);
    EAPI void              evas_object_image_size_get        (const Evas_Object *obj, int *w, int *h);
    EAPI int               evas_object_image_stride_get      (const Evas_Object *obj);
@@ -865,6 +869,20 @@
    EAPI void              evas_data_argb_premul             (unsigned int *data, unsigned int len);
    EAPI void              evas_data_argb_unpremul           (unsigned int *data, unsigned int len);
 
+/* Evas utility routines for working with transforms */
+   /* Set t to the identity */
+   EAPI void              evas_transform_identity_set       (Evas_Transform *t);
+   /* Left-multiply t by an xy rotation defined by the given angle (in degrees) */
+   EAPI void              evas_transform_rotate             (double angle, Evas_Transform *t);
+   /* Left-multiply t by an xy translation defined by the given dx, dy values */
+   EAPI void              evas_transform_translate          (float dx, float dy, Evas_Transform *t);
+   /* Left-multiply t by an xy scaling defined by the given sx, sy factors */
+   EAPI void              evas_transform_scale              (float sx, float sy, Evas_Transform *t);
+   /* Left-multiply t by an xy shearing defined by the given sh, sv values */
+   EAPI void              evas_transform_shear              (float sh, float sv, Evas_Transform *t);
+   /* Left-multiply t by the given transform l */
+   EAPI void              evas_transform_compose            (Evas_Transform *l, Evas_Transform *t);
+
 /* Evas imaging api - exports some of the comon gfx engine routines */
 /* this is not complete and should be considered experimental. use at your */
 /* own risk */
Index: evas/src/lib/engines/common/evas_gradient2_radial.c
===================================================================
--- evas/src/lib/engines/common/evas_gradient2_radial.c	(revision 35699)
+++ evas/src/lib/engines/common/evas_gradient2_radial.c	(working copy)
@@ -2,13 +2,14 @@
 #include "evas_private.h"
 #include <math.h>
 
+#define RADIAL_EPSILON 0.000030517578125
 
 typedef struct _Radial_Data   Radial_Data;
 
 struct _Radial_Data
 {
-   int    axx, axy, axz;
-   int    ayx, ayy, ayz;
+   int    axx, axy;
+   int    ayx, ayy;
    float  cx, cy, rx, ry;
    float  cx0, cy0;
    int    len;
@@ -79,8 +80,9 @@
    if (gr->type.geometer != &radial) return;
    radial_data = (Radial_Data *)gr->type.gdata;
    if (!radial_data) return;
+   if (rx < 0) rx = -rx;  if (ry < 0) ry = -ry;
    radial_data->cx = cx;  radial_data->cy = cy;
-   radial_data->rx = rx;  radial_data->ry = ry;
+   radial_data->rx = 1 + rx;  radial_data->ry = 1 + ry;
 }
 
 
@@ -88,23 +90,23 @@
 
 static void
 radial_reflect_aa(DATA32 *src, int src_len, DATA32 *dst, DATA8 *mask, int dst_len,
-                          int x, int y, void *params_data);
+                  int x, int y, void *params_data);
 
 static void
 radial_repeat_aa(DATA32 *src, int src_len, DATA32 *dst, DATA8 *mask, int dst_len,
-                         int x, int y, void *params_data);
+                 int x, int y, void *params_data);
 
 static void
 radial_restrict_aa(DATA32 *src, int src_len, DATA32 *dst, DATA8 *mask, int dst_len,
-                                int x, int y, void *params_data);
+                   int x, int y, void *params_data);
 
 static void
 radial_restrict_masked_aa(DATA32 *src, int src_len, DATA32 *dst, DATA8 *mask, int dst_len,
-                                int x, int y, void *params_data);
+                          int x, int y, void *params_data);
 
 static void
 radial_pad_aa(DATA32 *src, int src_len, DATA32 *dst, DATA8 *mask, int dst_len,
-                      int x, int y, void *params_data);
+              int x, int y, void *params_data);
 
 
 static void 
@@ -138,8 +140,8 @@
 	if (!radial_data)  return;
 	radial_data->cx = radial_data->cy = 0;
 	radial_data->rx = radial_data->ry = 0;
-	radial_data->axx = 65536;  radial_data->axy = 0;  radial_data->axz = 0;
-	radial_data->ayx = 0;  radial_data->ayy = 65536;  radial_data->ayz = 0;
+	radial_data->axx = 65536;  radial_data->axy = 0;
+	radial_data->ayx = 0;  radial_data->ayy = 65536;
 	radial_data->len = 0;
     }
    gr->type.gdata = radial_data;
@@ -150,40 +152,42 @@
 {
    Radial_Data   *radial_data;
    double f, flen;
+   double  fx1, fy1;
    int len;
-   float  fx1, fy1;
 
    if (!gr || (gr->type.geometer != &radial)) return;
 
    radial_data = (Radial_Data *)gr->type.gdata;
    if (!radial_data) return;
 
+   if ((radial_data->rx < RADIAL_EPSILON) || (radial_data->ry < RADIAL_EPSILON)) return;
+
    radial_data->len = 0;
-   f = (gr->fill.transform.mxx * gr->fill.transform.myy) - (gr->fill.transform.mxy * gr->fill.transform.myx);
-   if (!f) return;
+   f = (gr->fill.transform.mxx * (double)gr->fill.transform.myy) - (gr->fill.transform.mxy * (double)gr->fill.transform.myx);
+   if (fabs(f) < RADIAL_EPSILON) return;
 
    f = 1.0 / f;
-   radial_data->cx0 = (((gr->fill.transform.myy * radial_data->cx) - (gr->fill.transform.mxy * radial_data->cy)) * f) - gr->fill.transform.mxz;
-   radial_data->cy0 = ((-(gr->fill.transform.myx * radial_data->cx) + (gr->fill.transform.mxx * radial_data->cy)) * f) - gr->fill.transform.myz;
+   radial_data->cx0 = (((gr->fill.transform.myy * (double)radial_data->cx) - (gr->fill.transform.mxy * (double)radial_data->cy)) * f) - gr->fill.transform.mxz;
+   radial_data->cy0 = ((-(gr->fill.transform.myx * (double)radial_data->cx) + (gr->fill.transform.mxx * (double)radial_data->cy)) * f) - gr->fill.transform.myz;
 
-   fx1 = (((gr->fill.transform.myy * (radial_data->cx + radial_data->rx)) - (gr->fill.transform.mxy * (radial_data->cy))) * f)  - gr->fill.transform.mxz;
-   fy1 = ((-(gr->fill.transform.myx * (radial_data->cx + radial_data->rx)) + (gr->fill.transform.mxx * (radial_data->cy))) * f) - gr->fill.transform.myz;
+   fx1 = (gr->fill.transform.myy * (double)radial_data->rx) * f;
+   fy1 = (gr->fill.transform.myx * (double)radial_data->rx) * f;
 
-   flen = hypot(radial_data->cx0 - fx1, radial_data->cy0 - fy1);
+   flen = hypot(fx1, fy1);
 
-   fx1 = (((gr->fill.transform.myy * (radial_data->cx)) - (gr->fill.transform.mxy * (radial_data->cy + radial_data->ry))) * f)  - gr->fill.transform.mxz;
-   fy1 = ((-(gr->fill.transform.myx * (radial_data->cx)) + (gr->fill.transform.mxx * (radial_data->cy + radial_data->ry))) * f) - gr->fill.transform.myz;
+   fx1 = (gr->fill.transform.mxy * (double)radial_data->ry) * f;
+   fy1 = (gr->fill.transform.mxx * (double)radial_data->ry) * f;
 
-   flen = MAX(flen,hypot(radial_data->cx0 - fx1, radial_data->cy0 - fy1));
-   radial_data->len = len = flen;
+   flen = sqrt(flen * hypot(fx1, fy1));
+
+   radial_data->len = len = flen + 0.5;
    if (!len) return;
 
    radial_data->axx = (((double)gr->fill.transform.mxx * 65536) * flen) / radial_data->rx;
    radial_data->axy = (((double)gr->fill.transform.mxy * 65536) * flen) / radial_data->rx;
-   radial_data->axz = (((double)gr->fill.transform.mxz * 65536) * flen) / radial_data->rx;
+
    radial_data->ayx = (((double)gr->fill.transform.myx * 65536) * flen) / radial_data->ry;
    radial_data->ayy = (((double)gr->fill.transform.myy * 65536) * flen) / radial_data->ry;
-   radial_data->ayz = (((double)gr->fill.transform.myz * 65536) * flen) / radial_data->ry;
 }
 
 static int
@@ -281,8 +285,8 @@
    int  xx, yy;
 
    evas_common_cpu_end_opt();
-   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5)) + gdata->axz;
-   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5)) + gdata->ayz;
+   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5));
+   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5));
 
    while (dst < dst_end)
      {
@@ -290,7 +294,7 @@
 	unsigned int  l = (ll >> 16);
 	int  a = 1 + ((ll & 0xffff) >> 8);
 
-	if (l > (src_len - 1))
+	if (l >= src_len)
 	    l = l % src_len;
 	*dst = src[l];
 	if (l + 1 < src_len)
@@ -315,8 +319,8 @@
    int  xx, yy;
 
    evas_common_cpu_end_opt();
-   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5)) + gdata->axz;
-   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5)) + gdata->ayz;
+   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5));
+   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5));
 
    while (dst < dst_end)
      {
@@ -350,8 +354,8 @@
    int  xx, yy;
 
    evas_common_cpu_end_opt();
-   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5)) + gdata->axz;
-   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5)) + gdata->ayz;
+   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5));
+   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5));
 
    while (dst < dst_end)
      {
@@ -386,8 +390,8 @@
    int  xx, yy;
 
    evas_common_cpu_end_opt();
-   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5)) + gdata->axz;
-   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5)) + gdata->ayz;
+   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5));
+   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5));
 
    while (dst < dst_end)
      {
@@ -422,8 +426,8 @@
    int  xx, yy;
 
    evas_common_cpu_end_opt();
-   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5)) + gdata->axz;
-   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5)) + gdata->ayz;
+   xx = (gdata->axx * (x - gdata->cx0 + 0.5)) + (gdata->axy * (y - gdata->cy0 + 0.5));
+   yy = (gdata->ayx * (x - gdata->cx0 + 0.5)) + (gdata->ayy * (y - gdata->cy0 + 0.5));
 
    while (dst < dst_end)
      {
Index: evas/src/lib/engines/common/evas_gradient2_linear.c
===================================================================
--- evas/src/lib/engines/common/evas_gradient2_linear.c	(revision 35699)
+++ evas/src/lib/engines/common/evas_gradient2_linear.c	(working copy)
@@ -2,12 +2,17 @@
 #include "evas_private.h"
 #include <math.h>
 
+#define LINEAR_EPSILON 0.000030517578125
+#define LINEAR_INT_TOLERANCE 0.001953125
+// 1/512 = 0.001953125 <-- will use this one as our subpixel pos tolerance.
+// 1/256 = 0.00390625  <-- though this one would be ok too for our uses.
+
 typedef struct _Linear_Data   Linear_Data;
 
 struct _Linear_Data
 {
    float    x0, y0, x1, y1;
-   float    fx0, fy0, fx1, fy1;
+   float    fx0, fy0;
    int      ayx, ayy;
    int      len;
    unsigned char int_axis_aligned : 1;
@@ -147,6 +152,7 @@
 {
    Linear_Data *linear_data;
    double f;
+   double fx0, fy0, fx1, fy1;
    int len;
 
    if (!gr || (gr->type.geometer != &linear)) return;
@@ -155,38 +161,37 @@
 
    linear_data->int_axis_aligned = 0;
    linear_data->len = 0;
-   f = (gr->fill.transform.mxx * gr->fill.transform.myy) - (gr->fill.transform.mxy * gr->fill.transform.myx);
-   if (!f) return;
+   f = (gr->fill.transform.mxx * (double)gr->fill.transform.myy) - (gr->fill.transform.mxy * (double)gr->fill.transform.myx);
+   if (fabs(f) < LINEAR_EPSILON) return;
 
    f = 1.0 / f;
-   linear_data->fx0 = (((gr->fill.transform.myy * linear_data->x0) - (gr->fill.transform.mxy * linear_data->y0)) * f) - gr->fill.transform.mxz;
-   linear_data->fy0 = ((-(gr->fill.transform.myx * linear_data->x0) + (gr->fill.transform.mxx * linear_data->y0)) * f) - gr->fill.transform.myz;
+   fx0 = (((gr->fill.transform.myy * (double)linear_data->x0) - (gr->fill.transform.mxy * (double)linear_data->y0)) * f) - gr->fill.transform.mxz;
+   fy0 = ((-(gr->fill.transform.myx * (double)linear_data->x0) + (gr->fill.transform.mxx * (double)linear_data->y0)) * f) - gr->fill.transform.myz;
 
-   linear_data->fx1 = (((gr->fill.transform.myy * linear_data->x1) - (gr->fill.transform.mxy * linear_data->y1)) * f)  - gr->fill.transform.mxz;
-   linear_data->fy1 = ((-(gr->fill.transform.myx * linear_data->x1) + (gr->fill.transform.mxx * linear_data->y1)) * f) - gr->fill.transform.myz;
+   fx1 = (((gr->fill.transform.myy * (double)linear_data->x1) - (gr->fill.transform.mxy * (double)linear_data->y1)) * f) - gr->fill.transform.mxz;
+   fy1 = ((-(gr->fill.transform.myx * (double)linear_data->x1) + (gr->fill.transform.mxx * (double)linear_data->y1)) * f) - gr->fill.transform.myz;
 
-   f = hypot(linear_data->fx0 - linear_data->fx1, linear_data->fy0 - linear_data->fy1);
-   linear_data->len = len = f;
+   f = hypot(fx1 - fx0, fy1 - fy0);
+   linear_data->len = len = f + 0.5;
    if (!len) return;
 
-   linear_data->ayx = ((double)(linear_data->fx1 - linear_data->fx0) * 65536) / f;
-   linear_data->ayy = ((double)(linear_data->fy1 - linear_data->fy0) * 65536) / f;
+   linear_data->ayx = ((fx1 - fx0) / f) * 65536;
+   linear_data->ayy = ((fy1 - fy0) / f) * 65536;
 
-// 1/512 = 0.001953125 <-- will use this one as our subpixel pos tolerance.
-// 1/256 = 0.00390625  <-- though this one would be ok too for our uses.
-
-   if (fabs(linear_data->fy0 - linear_data->fy1) < 0.001953125)
+   if (fabs(fy0 - fy1) < LINEAR_INT_TOLERANCE)
      {
-	if ( (fabs(((int)linear_data->fy0) - linear_data->fy0) < 0.001953125) &&
-	    (fabs(((int)linear_data->fy1) - linear_data->fy1) < 0.001953125) )
+	if ( (fabs(((int)fy0) - fy0) < LINEAR_INT_TOLERANCE) &&
+	    (fabs(((int)fy1) - fy1) < LINEAR_INT_TOLERANCE) )
 	   { linear_data->int_axis_aligned = 1;  linear_data->ayy = 0; }
      }
-   else if (fabs(linear_data->fx0 - linear_data->fx1) < 0.001953125)
+   else if (fabs(fx0 - fx1) < LINEAR_INT_TOLERANCE)
      {
-	if ( (fabs(((int)linear_data->fx0) - linear_data->fx0) < 0.001953125) &&
-	    (fabs(((int)linear_data->fx1) - linear_data->fx1) < 0.001953125) )
+	if ( (fabs(((int)fx0) - fx0) < LINEAR_INT_TOLERANCE) &&
+	    (fabs(((int)fx1) - fx1) < LINEAR_INT_TOLERANCE) )
 	   { linear_data->int_axis_aligned = 1;  linear_data->ayx = 0; }
      }
+   linear_data->fx0 = fx0;
+   linear_data->fy0 = fy0;
 }
 
 static int
@@ -348,9 +353,9 @@
 	int  l = (yy >> 16);
 	int  a = 1 + ((yy & 0xffff) >> 8);
 
-	l = l % src_len;
-	if (l < 0)
-	   l += src_len;
+	if ((l >= src_len) || (l < 0))
+	   { l = l % src_len;  if (l < 0) l += src_len; }
+
 #ifdef BUILD_MMX
 	MOV_P2R(src[l], mm1, mm0)
 #else
@@ -581,7 +586,7 @@
 	if ((unsigned)(l + 1) < (src_len + 1))
 	  {
 	    int  a = 1 + ((yy & 0xffff) >> 8);
-	    int    lp = l;
+	    int  lp = l;
 
 	    if (l == -1) lp = 0;
 #ifdef BUILD_MMX
@@ -646,7 +651,7 @@
 	if ((unsigned)(l + 1) < (src_len + 1))
 	  {
 	    int  a = 1 + ((yy & 0xffff) >> 8);
-	    int    lp = l;
+	    int  lp = l;
 
 	    if (l == -1) lp = 0;
 
Index: evas/src/lib/canvas/evas_object_gradient2_radial.c
===================================================================
--- evas/src/lib/canvas/evas_object_gradient2_radial.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_gradient2_radial.c	(working copy)
@@ -34,7 +34,8 @@
 static void evas_object_gradient2_radial_render_pre(Evas_Object *obj);
 static void evas_object_gradient2_radial_render_post(Evas_Object *obj);
 
-static int evas_object_gradient2_radial_visual_type_get(Evas_Object *obj);
+static unsigned int evas_object_gradient2_radial_id_get(Evas_Object *obj);
+static unsigned int evas_object_gradient2_radial_visual_id_get(Evas_Object *obj);
 static void *evas_object_gradient2_radial_engine_data_get(Evas_Object *obj);
 
 static int evas_object_gradient2_radial_is_opaque(Evas_Object *obj);
@@ -47,7 +48,8 @@
      evas_object_gradient2_radial_render,
      evas_object_gradient2_radial_render_pre,
      evas_object_gradient2_radial_render_post,
-     evas_object_gradient2_radial_visual_type_get,
+     evas_object_gradient2_radial_id_get,
+     evas_object_gradient2_radial_visual_id_get,
      evas_object_gradient2_radial_engine_data_get,
    /* these are optional. NULL = nothing */
      NULL,
@@ -417,12 +419,21 @@
    og->gradient_changed = 0;
 }
 
-static int evas_object_gradient2_radial_visual_type_get(Evas_Object *obj)
+static unsigned int evas_object_gradient2_radial_id_get(Evas_Object *obj)
 {
    Evas_Object_Gradient2_Radial *o;
 
    o = (Evas_Object_Gradient2_Radial *)(obj->object_data);
    if (!o) return 0;
+   return MAGIC_OBJ_GRADIENT_RADIAL;
+}
+
+static unsigned int evas_object_gradient2_radial_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Gradient2_Radial *o;
+
+   o = (Evas_Object_Gradient2_Radial *)(obj->object_data);
+   if (!o) return 0;
    return MAGIC_OBJ_GRADIENT;
 }
 
Index: evas/src/lib/canvas/evas_object_textblock.c
===================================================================
--- evas/src/lib/canvas/evas_object_textblock.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_textblock.c	(working copy)
@@ -143,7 +143,8 @@
 static void evas_object_textblock_render_pre(Evas_Object *obj);
 static void evas_object_textblock_render_post(Evas_Object *obj);
 
-static int evas_object_textblock_visual_type_get(Evas_Object *obj);
+static unsigned int evas_object_textblock_id_get(Evas_Object *obj);
+static unsigned int evas_object_textblock_visual_id_get(Evas_Object *obj);
 static void *evas_object_textblock_engine_data_get(Evas_Object *obj);
 
 static int evas_object_textblock_is_opaque(Evas_Object *obj);
@@ -158,7 +159,8 @@
      evas_object_textblock_render,
      evas_object_textblock_render_pre,
      evas_object_textblock_render_post,
-     evas_object_textblock_visual_type_get,
+     evas_object_textblock_id_get,
+     evas_object_textblock_visual_id_get,
      evas_object_textblock_engine_data_get,
    /* these are optional. NULL = nothing */
      NULL,
@@ -4878,12 +4880,21 @@
 /*   o->changed = 0; */
 }
 
-static int evas_object_textblock_visual_type_get(Evas_Object *obj)
+static unsigned int evas_object_textblock_id_get(Evas_Object *obj)
 {
    Evas_Object_Textblock *o;
 
    o = (Evas_Object_Textblock *)(obj->object_data);
    if (!o) return 0;
+   return MAGIC_OBJ_TEXTBLOCK;
+}
+
+static unsigned int evas_object_textblock_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Textblock *o;
+
+   o = (Evas_Object_Textblock *)(obj->object_data);
+   if (!o) return 0;
    return MAGIC_OBJ_CUSTOM;
 }
 
Index: evas/src/lib/canvas/evas_object_rectangle.c
===================================================================
--- evas/src/lib/canvas/evas_object_rectangle.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_rectangle.c	(working copy)
@@ -21,7 +21,8 @@
 static void evas_object_rectangle_render_pre(Evas_Object *obj);
 static void evas_object_rectangle_render_post(Evas_Object *obj);
 
-static int evas_object_rectangle_visual_type_get(Evas_Object *obj);
+static unsigned int evas_object_rectangle_id_get(Evas_Object *obj);
+static unsigned int evas_object_rectangle_visual_id_get(Evas_Object *obj);
 static void *evas_object_rectangle_engine_data_get(Evas_Object *obj);
 
 static int evas_object_rectangle_is_opaque(Evas_Object *obj);
@@ -43,7 +44,8 @@
      evas_object_rectangle_render,
      evas_object_rectangle_render_pre,
      evas_object_rectangle_render_post,
-     evas_object_rectangle_visual_type_get,
+     evas_object_rectangle_id_get,
+     evas_object_rectangle_visual_id_get,
      evas_object_rectangle_engine_data_get,
    /* these are optional. NULL = nothing */
      NULL,
@@ -318,12 +320,21 @@
    return 1;
 }
 
-static int evas_object_rectangle_visual_type_get(Evas_Object *obj)
+static unsigned int evas_object_rectangle_id_get(Evas_Object *obj)
 {
    Evas_Object_Rectangle *o;
 
    o = (Evas_Object_Rectangle *)(obj->object_data);
    if (!o) return 0;
+   return MAGIC_OBJ_RECTANGLE;
+}
+
+static unsigned int evas_object_rectangle_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Rectangle *o;
+
+   o = (Evas_Object_Rectangle *)(obj->object_data);
+   if (!o) return 0;
    return MAGIC_OBJ_SHAPE;
 }
 
Index: evas/src/lib/canvas/evas_object_gradient2_linear.c
===================================================================
--- evas/src/lib/canvas/evas_object_gradient2_linear.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_gradient2_linear.c	(working copy)
@@ -34,7 +34,8 @@
 static void evas_object_gradient2_linear_render_pre(Evas_Object *obj);
 static void evas_object_gradient2_linear_render_post(Evas_Object *obj);
 
-static int evas_object_gradient2_linear_visual_type_get(Evas_Object *obj);
+static unsigned int evas_object_gradient2_linear_id_get(Evas_Object *obj);
+static unsigned int evas_object_gradient2_linear_visual_id_get(Evas_Object *obj);
 static void *evas_object_gradient2_linear_engine_data_get(Evas_Object *obj);
 
 static int evas_object_gradient2_linear_is_opaque(Evas_Object *obj);
@@ -47,7 +48,8 @@
      evas_object_gradient2_linear_render,
      evas_object_gradient2_linear_render_pre,
      evas_object_gradient2_linear_render_post,
-     evas_object_gradient2_linear_visual_type_get,
+     evas_object_gradient2_linear_id_get,
+     evas_object_gradient2_linear_visual_id_get,
      evas_object_gradient2_linear_engine_data_get,
    /* these are optional. NULL = nothing */
      NULL,
@@ -418,12 +420,21 @@
    og->gradient_changed = 0;
 }
 
-static int evas_object_gradient2_linear_visual_type_get(Evas_Object *obj)
+static unsigned int evas_object_gradient2_linear_id_get(Evas_Object *obj)
 {
    Evas_Object_Gradient2_Linear *o;
 
    o = (Evas_Object_Gradient2_Linear *)(obj->object_data);
    if (!o) return 0;
+   return MAGIC_OBJ_GRADIENT_LINEAR;
+}
+
+static unsigned int evas_object_gradient2_linear_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Gradient2_Linear *o;
+
+   o = (Evas_Object_Gradient2_Linear *)(obj->object_data);
+   if (!o) return 0;
    return MAGIC_OBJ_GRADIENT;
 }
 
Index: evas/src/lib/canvas/evas_object_line.c
===================================================================
--- evas/src/lib/canvas/evas_object_line.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_line.c	(working copy)
@@ -33,7 +33,8 @@
 static void evas_object_line_render_pre(Evas_Object *obj);
 static void evas_object_line_render_post(Evas_Object *obj);
 
-static int evas_object_line_visual_type_get(Evas_Object *obj);
+static unsigned int evas_object_line_id_get(Evas_Object *obj);
+static unsigned int evas_object_line_visual_id_get(Evas_Object *obj);
 static void *evas_object_line_engine_data_get(Evas_Object *obj);
 
 static int evas_object_line_is_opaque(Evas_Object *obj);
@@ -49,7 +50,8 @@
      evas_object_line_render,
      evas_object_line_render_pre,
      evas_object_line_render_post,
-     evas_object_line_visual_type_get,
+     evas_object_line_id_get,
+     evas_object_line_visual_id_get,
      evas_object_line_engine_data_get,
    /* these are optional. NULL = nothing */
      NULL,
@@ -408,12 +410,21 @@
    o->changed = 0;
 }
 
-static int evas_object_line_visual_type_get(Evas_Object *obj)
+static unsigned int evas_object_line_id_get(Evas_Object *obj)
 {
    Evas_Object_Line *o;
 
    o = (Evas_Object_Line *)(obj->object_data);
    if (!o) return 0;
+   return MAGIC_OBJ_LINE;
+}
+
+static unsigned int evas_object_line_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Line *o;
+
+   o = (Evas_Object_Line *)(obj->object_data);
+   if (!o) return 0;
    return MAGIC_OBJ_SHAPE;
 }
 
Index: evas/src/lib/canvas/evas_object_polygon.c
===================================================================
--- evas/src/lib/canvas/evas_object_polygon.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_polygon.c	(working copy)
@@ -31,7 +31,8 @@
 static void evas_object_polygon_render_pre(Evas_Object *obj);
 static void evas_object_polygon_render_post(Evas_Object *obj);
 
-static int evas_object_polygon_visual_type_get(Evas_Object *obj);
+static unsigned int evas_object_polygon_id_get(Evas_Object *obj);
+static unsigned int evas_object_polygon_visual_id_get(Evas_Object *obj);
 static void *evas_object_polygon_engine_data_get(Evas_Object *obj);
 
 static int evas_object_polygon_is_opaque(Evas_Object *obj);
@@ -46,7 +47,8 @@
      evas_object_polygon_render,
      evas_object_polygon_render_pre,
      evas_object_polygon_render_post,
-     evas_object_polygon_visual_type_get,
+     evas_object_polygon_id_get,
+     evas_object_polygon_visual_id_get,
      evas_object_polygon_engine_data_get,
    /* these are optional. NULL = nothing */
      NULL,
@@ -414,12 +416,21 @@
    o->changed = 0;
 }
 
-static int evas_object_polygon_visual_type_get(Evas_Object *obj)
+static unsigned int evas_object_polygon_id_get(Evas_Object *obj)
 {
    Evas_Object_Polygon *o;
 
    o = (Evas_Object_Polygon *)(obj->object_data);
    if (!o) return 0;
+   return MAGIC_OBJ_POLYGON;
+}
+
+static unsigned int evas_object_polygon_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Polygon *o;
+
+   o = (Evas_Object_Polygon *)(obj->object_data);
+   if (!o) return 0;
    return MAGIC_OBJ_SHAPE;
 }
 
Index: evas/src/lib/canvas/evas_object_gradient.c
===================================================================
--- evas/src/lib/canvas/evas_object_gradient.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_gradient.c	(working copy)
@@ -49,6 +49,10 @@
 static void evas_object_gradient_render_pre(Evas_Object *obj);
 static void evas_object_gradient_render_post(Evas_Object *obj);
 
+static unsigned int evas_object_gradient_id_get(Evas_Object *obj);
+static unsigned int evas_object_gradient_visual_id_get(Evas_Object *obj);
+static void *evas_object_gradient_engine_data_get(Evas_Object *obj);
+
 static int evas_object_gradient_is_opaque(Evas_Object *obj);
 static int evas_object_gradient_was_opaque(Evas_Object *obj);
 
@@ -59,6 +63,9 @@
      evas_object_gradient_render,
      evas_object_gradient_render_pre,
      evas_object_gradient_render_post,
+     evas_object_gradient_id_get,
+     evas_object_gradient_visual_id_get,
+     evas_object_gradient_engine_data_get,
    /* these are optional. NULL = nothing */
      NULL,
      NULL,
@@ -1066,6 +1073,33 @@
    o->type_changed = 0;
 }
 
+static unsigned int evas_object_gradient_id_get(Evas_Object *obj)
+{
+   Evas_Object_Gradient *o;
+
+   o = (Evas_Object_Gradient *)(obj->object_data);
+   if (!o) return 0;
+   return MAGIC_OBJ_GRADIENT;
+}
+
+static unsigned int evas_object_gradient_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Gradient *o;
+
+   o = (Evas_Object_Gradient *)(obj->object_data);
+   if (!o) return 0;
+   return MAGIC_OBJ_GRADIENT;
+}
+
+static void *evas_object_gradient_engine_data_get(Evas_Object *obj)
+{
+   Evas_Object_Gradient *o;
+
+   o = (Evas_Object_Gradient *)(obj->object_data);
+   if (!o) return NULL;
+   return o->engine_data;
+}
+
 static int
 evas_object_gradient_is_opaque(Evas_Object *obj)
 {
Index: evas/src/lib/canvas/evas_object_image.c
===================================================================
--- evas/src/lib/canvas/evas_object_image.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_image.c	(working copy)
@@ -19,6 +19,8 @@
    DATA32            magic;
 
    struct {
+      Evas_Common_Transform  transform;
+      int         spread;
       Evas_Coord_Rectangle fill;
       struct {
 	 short       w, h, stride;
@@ -70,7 +72,8 @@
 static void evas_object_image_render_pre(Evas_Object *obj);
 static void evas_object_image_render_post(Evas_Object *obj);
 
-static int evas_object_image_visual_type_get(Evas_Object *obj);
+static unsigned int evas_object_image_id_get(Evas_Object *obj);
+static unsigned int evas_object_image_visual_id_get(Evas_Object *obj);
 static void *evas_object_image_engine_data_get(Evas_Object *obj);
 
 static int evas_object_image_is_opaque(Evas_Object *obj);
@@ -86,8 +89,9 @@
    evas_object_image_render,
    evas_object_image_render_pre,
    evas_object_image_render_post,
-     evas_object_image_visual_type_get,
-     evas_object_image_engine_data_get,
+   evas_object_image_id_get,
+   evas_object_image_visual_id_get,
+   evas_object_image_engine_data_get,
    /* these are optional. NULL = nothing */
    NULL,
    NULL,
@@ -564,7 +568,133 @@
    if (h) *h = o->cur.fill.h;
 }
 
+
 /**
+ * Sets the tiling mode for the given evas image object's fill.
+ * @param   obj   The given evas image object.
+ * @param   spread One of EVAS_TEXTURE_REFLECT, EVAS_TEXTURE_REPEAT,
+ * EVAS_TEXTURE_RESTRICT, or EVAS_TEXTURE_PAD.
+ * @ingroup Evas_Object_Image_Fill_Group
+ */
+EAPI void
+evas_object_image_fill_spread_set(Evas_Object *obj, int spread)
+{
+   Evas_Object_Image *o;
+
+   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();
+   if (spread == o->cur.spread) return;
+   o->cur.spread = spread;
+   o->changed = 1;
+   evas_object_change(obj);
+}
+
+/**
+ * Retrieves the spread (tiling mode) for the given image object's fill.
+ * @param   obj The given evas image object.
+ * @return  The current spread mode of the image object.
+ * @ingroup Evas_Object_Image_Fill_Group
+ */
+EAPI int
+evas_object_image_fill_spread_get(const Evas_Object *obj)
+{
+   Evas_Object_Image *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return EVAS_TEXTURE_REPEAT;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Image *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
+   return EVAS_TEXTURE_REPEAT;
+   MAGIC_CHECK_END();
+   return o->cur.spread;
+}
+
+EAPI void
+evas_object_image_fill_transform_set (Evas_Object *obj, Evas_Transform *t)
+{
+   Evas_Object_Image *o;
+
+   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();
+   if (!t)
+     {
+	o->cur.transform.mxx = 1;
+	o->cur.transform.mxy = 0;
+	o->cur.transform.mxz = 0;
+	o->cur.transform.myx = 0;
+	o->cur.transform.myy = 1;
+	o->cur.transform.myz = 0;
+	o->cur.transform.mzx = 0;
+	o->cur.transform.mzy = 0;
+	o->cur.transform.mzz = 1;
+
+	o->changed;
+	evas_object_change(obj);
+	return;
+     }
+   if ( (o->cur.transform.mxx == t->mxx) ||
+	 (o->cur.transform.mxy == t->mxy) ||
+	 (o->cur.transform.mxy == t->mxy) ||
+	 (o->cur.transform.mxy == t->mxy) ||
+	 (o->cur.transform.mxy == t->mxy) ||
+	 (o->cur.transform.mxy == t->mxy) ||
+	 (o->cur.transform.mxy == t->mxy) ||
+	 (o->cur.transform.mxy == t->mxy) ||
+	 (o->cur.transform.mxy == t->mxy) )
+	    return;
+
+   o->cur.transform.mxx = t->mxx;
+   o->cur.transform.mxy = t->mxy;
+   o->cur.transform.mxz = t->mxz;
+   o->cur.transform.myx = t->myx;
+   o->cur.transform.myy = t->myy;
+   o->cur.transform.myz = t->myz;
+   o->cur.transform.mzx = t->mzx;
+   o->cur.transform.mzy = t->mzy;
+   o->cur.transform.mzz = t->mzz;
+
+   o->changed;
+   evas_object_change(obj);
+}
+
+EAPI void
+evas_object_image_fill_transform_get (const Evas_Object *obj, Evas_Transform *t)
+{
+   Evas_Object_Image *o;
+
+   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();
+   if (t)
+     {
+        t->mxx = o->cur.transform.mxx;
+        t->mxy = o->cur.transform.mxy;
+        t->mxz = o->cur.transform.mxz;
+        t->myx = o->cur.transform.myx;
+        t->myy = o->cur.transform.myy;
+        t->myz = o->cur.transform.myz;
+        t->mzx = o->cur.transform.mzx;
+        t->mzy = o->cur.transform.mzy;
+        t->mzz = o->cur.transform.mzz;
+     }
+}
+
+/**
  * @defgroup Evas_Object_Image_Size Image Object Image Size Functions
  *
  * Functions that change the size of the image used by an image object.
@@ -1858,6 +1988,8 @@
    o->cur.smooth_scale = 1;
    o->cur.border.fill = 1;
    o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
+   o->cur.transform.mxx = o->cur.transform.myy = o->cur.transform.mzz = 1;
+   o->cur.spread = EVAS_TEXTURE_REPEAT;
    o->prev = o->cur;
    return o;
 }
@@ -2341,7 +2473,7 @@
    /* FIXME: copy strings across */
 }
 
-static int evas_object_image_visual_type_get(Evas_Object *obj)
+static unsigned int evas_object_image_id_get(Evas_Object *obj)
 {
    Evas_Object_Image *o;
 
@@ -2350,6 +2482,15 @@
    return MAGIC_OBJ_IMAGE;
 }
 
+static unsigned int evas_object_image_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Image *o;
+
+   o = (Evas_Object_Image *)(obj->object_data);
+   if (!o) return 0;
+   return MAGIC_OBJ_IMAGE;
+}
+
 static void *evas_object_image_engine_data_get(Evas_Object *obj)
 {
    Evas_Object_Image *o;
Index: evas/src/lib/canvas/Makefile.am
===================================================================
--- evas/src/lib/canvas/Makefile.am	(revision 35699)
+++ evas/src/lib/canvas/Makefile.am	(working copy)
@@ -39,7 +39,8 @@
 evas_render.c \
 evas_smart.c \
 evas_stack.c \
-evas_async_events.c
+evas_async_events.c \
+evas_transform.c
 
 EXTRA_DIST = \
 evas_object_gradient2_linear.c \
Index: evas/src/lib/canvas/evas_object_text.c
===================================================================
--- evas/src/lib/canvas/evas_object_text.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_text.c	(working copy)
@@ -43,7 +43,8 @@
 static void evas_object_text_render_pre(Evas_Object *obj);
 static void evas_object_text_render_post(Evas_Object *obj);
 
-static int evas_object_text_visual_type_get(Evas_Object *obj);
+static unsigned int evas_object_text_id_get(Evas_Object *obj);
+static unsigned int evas_object_text_visual_id_get(Evas_Object *obj);
 static void *evas_object_text_engine_data_get(Evas_Object *obj);
 
 static int evas_object_text_is_opaque(Evas_Object *obj);
@@ -56,7 +57,8 @@
      evas_object_text_render,
      evas_object_text_render_pre,
      evas_object_text_render_post,
-     evas_object_text_visual_type_get,
+     evas_object_text_id_get,
+     evas_object_text_visual_id_get,
      evas_object_text_engine_data_get,
    /* these are optional. NULL = nothing */
      NULL,
@@ -1669,12 +1671,21 @@
    o->changed = 0;
 }
 
-static int evas_object_text_visual_type_get(Evas_Object *obj)
+static unsigned int evas_object_text_id_get(Evas_Object *obj)
 {
    Evas_Object_Text *o;
 
    o = (Evas_Object_Text *)(obj->object_data);
    if (!o) return 0;
+   return MAGIC_OBJ_TEXT;
+}
+
+static unsigned int evas_object_text_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Text *o;
+
+   o = (Evas_Object_Text *)(obj->object_data);
+   if (!o) return 0;
    return MAGIC_OBJ_SHAPE;
 }
 
Index: evas/src/lib/canvas/evas_object_smart.c
===================================================================
--- evas/src/lib/canvas/evas_object_smart.c	(revision 35699)
+++ evas/src/lib/canvas/evas_object_smart.c	(working copy)
@@ -32,7 +32,8 @@
 static void evas_object_smart_render_pre(Evas_Object *obj);
 static void evas_object_smart_render_post(Evas_Object *obj);
 
-static int evas_object_smart_visual_type_get(Evas_Object *obj);
+static unsigned int evas_object_smart_id_get(Evas_Object *obj);
+static unsigned int evas_object_smart_visual_id_get(Evas_Object *obj);
 static void *evas_object_smart_engine_data_get(Evas_Object *obj);
 
 static const Evas_Object_Func object_func =
@@ -42,7 +43,8 @@
      evas_object_smart_render,
      evas_object_smart_render_pre,
      evas_object_smart_render_post,
-     evas_object_smart_visual_type_get,
+     evas_object_smart_id_get,
+     evas_object_smart_visual_id_get,
      evas_object_smart_engine_data_get,
      /* these are optional. NULL = nothing */
      NULL,
@@ -632,12 +634,21 @@
    obj->prev = obj->cur;
 }
 
-static int evas_object_smart_visual_type_get(Evas_Object *obj)
+static unsigned int evas_object_smart_id_get(Evas_Object *obj)
 {
    Evas_Object_Smart *o;
 
    o = (Evas_Object_Smart *)(obj->object_data);
    if (!o) return 0;
+   return MAGIC_OBJ_SMART;
+}
+
+static unsigned int evas_object_smart_visual_id_get(Evas_Object *obj)
+{
+   Evas_Object_Smart *o;
+
+   o = (Evas_Object_Smart *)(obj->object_data);
+   if (!o) return 0;
    return MAGIC_OBJ_CONTAINER;
 }
 
#include "evas_common.h"
#include "evas_private.h"
#include <math.h>

EAPI void
evas_transform_identity_set(Evas_Transform *t)
{
   if (t)
     {
	t->mxx = t->myy = t->mzz = 1;
	t->mxy = t->mxz = 0;
	t->myx = t->myz = 0;
	t->mzx = t->mzy = 0;
     }
}

EAPI void
evas_transform_rotate(double angle, Evas_Transform *t)
{
   double ca, sa;
   float mxx, mxy, mxz;
   float myx, myy, myz;

   if (!t) return;

   angle = (angle * M_PI) / 180.0;
   ca = cos(angle);  sa = sin(angle);
   if ((ca == 1) && (sa == 0)) return;

   mxx = t->mxx;  mxy = t->mxy;  mxz = t->mxz;
   myx = t->myx;  myy = t->myy;  myz = t->myz;

   t->mxx = (ca * mxx) + (sa * myx);
   t->mxy = (ca * mxy) + (sa * myy);
   t->mxz = (ca * mxz) + (sa * myz);

   t->myx = (-sa * mxx) + (ca * myx);
   t->myy = (-sa * mxy) + (ca * myy);
   t->myz = (-sa * mxz) + (ca * myz);
}

EAPI void
evas_transform_translate(float dx, float dy, Evas_Transform *t)
{
   if (!t) return;
   if (!dx && !dy) return;

   t->mxx = dx * t->mzx;
   t->mxy = dx * t->mzy;
   t->mxz = dx * t->mzz;

   t->myx = dy * t->mzx;
   t->myy = dy * t->mzy;
   t->myz = dy * t->mzz;
}

EAPI void
evas_transform_scale(float sx, float sy, Evas_Transform *t)
{
   if (!t) return;
   if ((sx == 1) && (sy == 1)) return;

   t->mxx = sx * t->mxx;
   t->mxy = sx * t->mxy;
   t->mxz = sx * t->mxz;

   t->myx = sy * t->myx;
   t->myy = sy * t->myy;
   t->myz = sy * t->myz;
}

EAPI void
evas_transform_shear(float sh, float sv, Evas_Transform *t)
{
   float mxx, mxy, mxz;
   float myx, myy, myz;

   if (!t) return;
   if ((sh == 1) && (sv == 1)) return;

   mxx = t->mxx;  mxy = t->mxy;  mxz = t->mxz;
   myx = t->myx;  myy = t->myy;  myz = t->myz;

   t->mxx = mxx + (sh * myx);
   t->mxy = mxy + (sh * myy);
   t->mxz = mxz + (sh * myz);

   t->myx = (sv * mxx) + myx;
   t->myy = (sv * mxy) + myy;
   t->myz = (sv * mxz) + myz;
}

EAPI void
evas_transform_compose(Evas_Transform *l, Evas_Transform *t)
{
   float mxx, mxy, mxz;
   float myx, myy, myz;
   float mzx, mzy, mzz;

   if (!t || !l) return;

   mxx = t->mxx;  mxy = t->mxy;  mxz = t->mxz;
   myx = t->myx;  myy = t->myy;  myz = t->myz;
   mzx = t->mzx;  mzy = t->mzy;  mzz = t->mzz;

   t->mxx = (l->mxx * mxx) + (l->mxy * myx) + (l->mxz * mzx);
   t->mxy = (l->mxx * mxy) + (l->mxy * myy) + (l->mxz * mzy);
   t->mxz = (l->mxx * mxz) + (l->mxy * myz) + (l->mxz * mzz);

   t->myx = (l->myx * mxx) + (l->myy * myx) + (l->myz * mzx);
   t->myy = (l->myx * mxy) + (l->myy * myy) + (l->myz * mzy);
   t->myz = (l->myx * mxz) + (l->myy * myz) + (l->myz * mzz);

   t->mzx = (l->mzx * mxx) + (l->mzy * myx) + (l->mzz * mzx);
   t->mzy = (l->mzx * mxy) + (l->mzy * myy) + (l->mzz * mzy);
   t->mzz = (l->mzx * mxz) + (l->mzy * myz) + (l->mzz * mzz);
}
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to