eina: add eina_matrix.
authorCedric BAIL <cedric@osg.samsung.com>
Fri, 3 Apr 2015 14:12:48 +0000 (16:12 +0200)
committerCedric BAIL <cedric@osg.samsung.com>
Fri, 3 Apr 2015 14:12:48 +0000 (16:12 +0200)
This code come from Enesim and was done by Jorge. I did just take care
of changing the namespace and coding style.

src/Makefile_Eina.am
src/lib/eina/Eina.h
src/lib/eina/eina_matrix.c [new file with mode: 0644]
src/lib/eina/eina_matrix.h [new file with mode: 0644]
src/lib/eina/eina_quad.c [new file with mode: 0644]
src/lib/eina/eina_quad.h [new file with mode: 0644]

index 6341cd1..ae41cc8 100644 (file)
@@ -85,7 +85,9 @@ lib/eina/eina_tmpstr.h \
 lib/eina/eina_alloca.h \
 lib/eina/eina_cow.h \
 lib/eina/eina_inline_unicode.x \
-lib/eina/eina_thread_queue.h
+lib/eina/eina_thread_queue.h \
+lib/eina/eina_matrix.h \
+lib/eina/eina_quad.h
 
 # Will be back for developper after 1.2.
 # lib/eina/eina_model.h
@@ -144,7 +146,9 @@ lib/eina/eina_xattr.c \
 lib/eina/eina_share_common.h \
 lib/eina/eina_private.h \
 lib/eina/eina_strbuf_common.h \
-lib/eina/eina_thread_queue.c
+lib/eina/eina_thread_queue.c \
+lib/eina/eina_matrix.c \
+lib/eina/eina_quad.c
 
 # Will be back for developper after 1.2
 # lib/eina/eina_model.c \
index f7283f7..0f6851a 100644 (file)
@@ -262,6 +262,7 @@ extern "C" {
 #include <eina_value_util.h>
 #include <eina_cow.h>
 #include <eina_thread_queue.h>
+#include <eina_matrix.h>
 
 #ifdef __cplusplus
 }
diff --git a/src/lib/eina/eina_matrix.c b/src/lib/eina/eina_matrix.c
new file mode 100644 (file)
index 0000000..dc2e65c
--- /dev/null
@@ -0,0 +1,586 @@
+/* EINA - Drawing Library
+ * Copyright (C) 2007-2014 Jorge Luis Zapata
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "eina_private.h"
+
+#include <math.h>
+
+#include "eina_fp.h"
+#include "eina_rectangle.h"
+#include "eina_quad.h"
+#include "eina_matrix.h"
+
+#define MATRIX_XX(m) (m)->xx
+#define MATRIX_XY(m) (m)->xy
+#define MATRIX_XZ(m) (m)->xz
+#define MATRIX_YX(m) (m)->yx
+#define MATRIX_YY(m) (m)->yy
+#define MATRIX_YZ(m) (m)->yz
+#define MATRIX_ZX(m) (m)->zx
+#define MATRIX_ZY(m) (m)->zy
+#define MATRIX_ZZ(m) (m)->zz
+#define MATRIX_SIZE 9
+
+#define QUAD_X0(q) q->x0
+#define QUAD_Y0(q) q->y0
+#define QUAD_X1(q) q->x1
+#define QUAD_Y1(q) q->y1
+#define QUAD_X2(q) q->x2
+#define QUAD_Y2(q) q->y2
+#define QUAD_X3(q) q->x3
+#define QUAD_Y3(q) q->y3
+
+/*============================================================================*
+ *                                  Local                                     *
+ *============================================================================*/
+/** @cond internal */
+/*
+ * In the range [-pi pi]
+ * (4/pi)*x - ((4/(pi*pi))*x*abs(x))
+ * http://www.devmaster.net/forums/showthread.php?t=5784
+ */
+#define EXTRA_PRECISION
+static inline double
+  _sin(double x)
+{
+   const double B = 4/M_PI;
+   const double C = -4/(M_PI*M_PI);
+
+   double y = (B * x) + (C * x * fabsf(x));
+
+#ifdef EXTRA_PRECISION
+   //  const float Q = 0.775;
+   const double P = 0.225;
+
+   y = P * (y * fabsf(y) - y) + y; // Q * y + P * y * abs(y)
+#endif
+   return y;
+}
+
+static inline double
+_cos(double x)
+{
+   x += M_PI_2;
+
+   if (x > M_PI)   // Original x > pi/2
+     {
+        x -= 2 * M_PI;   // Wrap: cos(x) = cos(x - 2 pi)
+     }
+
+   return _sin(x);
+}
+/** @endcond */
+
+/*============================================================================*
+ *                                   API                                      *
+ *============================================================================*/
+EAPI Eina_Matrix_Type
+eina_matrix3_type_get(const Eina_Matrix3 *m)
+{
+   if ((MATRIX_ZX(m) != 0) || (MATRIX_ZY(m) != 0) || (MATRIX_ZZ(m) != 1))
+     return EINA_MATRIX_TYPE_PROJECTIVE;
+   else
+     {
+        if ((MATRIX_XX(m) == 1) && (MATRIX_XY(m) == 0) && (MATRIX_XZ(m) == 0) &&
+            (MATRIX_YX(m) == 0) && (MATRIX_YY(m) == 1) && (MATRIX_YZ(m) == 0))
+          return EINA_MATRIX_TYPE_IDENTITY;
+        else
+          return EINA_MATRIX_TYPE_AFFINE;
+     }
+}
+
+EAPI Eina_Matrix_Type
+eina_matrix3_f16p16_type_get(const Eina_Matrix3_F16p16 *m)
+{
+   if ((MATRIX_ZX(m) != 0) || (MATRIX_ZY(m) != 0) || (MATRIX_ZZ(m) != 65536))
+     return EINA_MATRIX_TYPE_PROJECTIVE;
+   else
+     {
+        if ((MATRIX_XX(m) == 65536) && (MATRIX_XY(m) == 0) && (MATRIX_XZ(m) == 0) &&
+            (MATRIX_YX(m) == 0) && (MATRIX_YY(m) == 65536) && (MATRIX_YZ(m) == 0))
+          return EINA_MATRIX_TYPE_IDENTITY;
+        else
+          return EINA_MATRIX_TYPE_AFFINE;
+     }
+}
+
+EAPI void
+eina_matrix3_values_set(Eina_Matrix3 *m,
+                        double xx, double xy, double xz,
+                        double yx, double yy, double yz,
+                        double zx, double zy, double zz)
+{
+   MATRIX_XX(m) = xx;
+   MATRIX_XY(m) = xy;
+   MATRIX_XZ(m) = xz;
+   MATRIX_YX(m) = yx;
+   MATRIX_YY(m) = yy;
+   MATRIX_YZ(m) = yz;
+   MATRIX_ZX(m) = zx;
+   MATRIX_ZY(m) = zy;
+   MATRIX_ZZ(m) = zz;
+}
+
+EAPI void
+eina_matrix3_values_get(const Eina_Matrix3 *m,
+                        double *xx, double *xy, double *xz,
+                        double *yx, double *yy, double *yz,
+                        double *zx, double *zy, double *zz)
+{
+   if (xx) *xx = MATRIX_XX(m);
+   if (xy) *xy = MATRIX_XY(m);
+   if (xz) *xz = MATRIX_XZ(m);
+   if (yx) *yx = MATRIX_YX(m);
+   if (yy) *yy = MATRIX_YY(m);
+   if (yz) *yz = MATRIX_YZ(m);
+   if (zx) *zx = MATRIX_ZX(m);
+   if (zy) *zy = MATRIX_ZY(m);
+   if (zz) *zz = MATRIX_ZZ(m);
+}
+
+EAPI void
+eina_matrix3_fixed_values_get(const Eina_Matrix3 *m,
+                              Eina_F16p16 *xx, Eina_F16p16 *xy, Eina_F16p16 *xz,
+                              Eina_F16p16 *yx, Eina_F16p16 *yy, Eina_F16p16 *yz,
+                              Eina_F16p16 *zx, Eina_F16p16 *zy, Eina_F16p16 *zz)
+{
+   if (xx) *xx = eina_f16p16_double_from(MATRIX_XX(m));
+   if (xy) *xy = eina_f16p16_double_from(MATRIX_XY(m));
+   if (xz) *xz = eina_f16p16_double_from(MATRIX_XZ(m));
+   if (yx) *yx = eina_f16p16_double_from(MATRIX_YX(m));
+   if (yy) *yy = eina_f16p16_double_from(MATRIX_YY(m));
+   if (yz) *yz = eina_f16p16_double_from(MATRIX_YZ(m));
+   if (zx) *zx = eina_f16p16_double_from(MATRIX_ZX(m));
+   if (zy) *zy = eina_f16p16_double_from(MATRIX_ZY(m));
+   if (zz) *zz = eina_f16p16_double_from(MATRIX_ZZ(m));
+}
+
+EAPI void
+eina_matrix3_matrix3_f16p16_to(const Eina_Matrix3 *m,
+                               Eina_Matrix3_F16p16 *fm)
+{
+   eina_matrix3_fixed_values_get(m,
+                                 &fm->xx, &fm->xy, &fm->xz,
+                                 &fm->yx, &fm->yy, &fm->yz,
+                                 &fm->zx, &fm->zy, &fm->zz);
+}
+
+EAPI void
+eina_matrix3_point_transform(const Eina_Matrix3 *m,
+                             double x, double y,
+                             double *xr, double *yr)
+{
+   double xrr, yrr;
+
+   if (!MATRIX_ZX(m) && !MATRIX_ZY(m))
+     {
+        xrr = (x * MATRIX_XX(m) + y * MATRIX_XY(m) + MATRIX_XZ(m));
+        yrr = (x * MATRIX_YX(m) + y * MATRIX_YY(m) + MATRIX_YZ(m));
+     }
+   else
+     {
+        xrr = (x * MATRIX_XX(m) + y * MATRIX_XY(m) + MATRIX_XZ(m)) /
+          (x * MATRIX_ZX(m) + y * MATRIX_ZY(m) + MATRIX_ZZ(m));
+        yrr = (x * MATRIX_YX(m) + y * MATRIX_YY(m) + MATRIX_YZ(m)) /
+          (x * MATRIX_ZX(m) + y * MATRIX_ZY(m) + MATRIX_ZZ(m));
+     }
+
+   if (xr) *xr = xrr;
+   if (yr) *yr = yrr;
+}
+
+EAPI void
+eina_matrix3_rectangle_transform(const Eina_Matrix3 *m,
+                                 const Eina_Rectangle *r,
+                                 const Eina_Quad *q)
+{
+   eina_matrix3_point_transform(m, r->x, r->y, &((Eina_Quad *)q)->x0, &((Eina_Quad *)q)->y0);
+   eina_matrix3_point_transform(m, r->x + r->w, r->y, &((Eina_Quad *)q)->x1, &((Eina_Quad *)q)->y1);
+   eina_matrix3_point_transform(m, r->x + r->w, r->y + r->h, &((Eina_Quad *)q)->x2, &((Eina_Quad *)q)->y2);
+   eina_matrix3_point_transform(m, r->x, r->y + r->h, &((Eina_Quad *)q)->x3, &((Eina_Quad *)q)->y3);
+}
+
+EAPI void
+eina_matrix3_cofactor(const Eina_Matrix3 *m, Eina_Matrix3 *a)
+{
+   double a11, a12, a13, a21, a22, a23, a31, a32, a33;
+
+   a11 = (MATRIX_YY(m) * MATRIX_ZZ(m)) - (MATRIX_YZ(m) * MATRIX_ZY(m));
+   a12 = -1 * ((MATRIX_YX(m) * MATRIX_ZZ(m)) - (MATRIX_YZ(m) * MATRIX_ZX(m)));
+   a13 = (MATRIX_YX(m) * MATRIX_ZY(m)) - (MATRIX_YY(m) * MATRIX_ZX(m));
+
+   a21 = -1 * ((MATRIX_XY(m) * MATRIX_ZZ(m)) - (MATRIX_XZ(m) * MATRIX_ZY(m)));
+   a22 = (MATRIX_XX(m) * MATRIX_ZZ(m)) - (MATRIX_XZ(m) * MATRIX_ZX(m));
+   a23 = -1 * ((MATRIX_XX(m) * MATRIX_ZY(m)) - (MATRIX_XY(m) * MATRIX_ZX(m)));
+
+   a31 = (MATRIX_XY(m) * MATRIX_YZ(m)) - (MATRIX_XZ(m) * MATRIX_YY(m));
+   a32 = -1 * ((MATRIX_XX(m) * MATRIX_YZ(m)) - (MATRIX_XZ(m) * MATRIX_YX(m)));
+   a33 = (MATRIX_XX(m) * MATRIX_YY(m)) - (MATRIX_XY(m) * MATRIX_YX(m));
+
+   MATRIX_XX(a) = a11;
+   MATRIX_XY(a) = a12;
+   MATRIX_XZ(a) = a13;
+
+   MATRIX_YX(a) = a21;
+   MATRIX_YY(a) = a22;
+   MATRIX_YZ(a) = a23;
+
+   MATRIX_ZX(a) = a31;
+   MATRIX_ZY(a) = a32;
+   MATRIX_ZZ(a) = a33;
+}
+
+EAPI void
+eina_matrix3_transpose(const Eina_Matrix3 *m, Eina_Matrix3 *a)
+{
+   MATRIX_XX(a) = MATRIX_XX(m);
+   MATRIX_XY(a) = MATRIX_YX(m);
+   MATRIX_XZ(a) = MATRIX_ZX(m);
+
+   MATRIX_YX(a) = MATRIX_XY(m);
+   MATRIX_YY(a) = MATRIX_YY(m);
+   MATRIX_YZ(a) = MATRIX_ZY(m);
+
+   MATRIX_ZX(a) = MATRIX_XZ(m);
+   MATRIX_ZY(a) = MATRIX_YZ(m);
+   MATRIX_ZZ(a) = MATRIX_ZZ(m);
+}
+
+EAPI void
+eina_matrix3_adjoint(const Eina_Matrix3 *m, Eina_Matrix3 *a)
+{
+   Eina_Matrix3 cofactor;
+
+   /* cofactor */
+   eina_matrix3_cofactor(m, &cofactor);
+   /* transpose */
+   eina_matrix3_transpose(&cofactor, a);
+}
+
+EAPI double
+eina_matrix3_determinant(const Eina_Matrix3 *m)
+{
+   double det;
+
+   det = MATRIX_XX(m) * ((MATRIX_YY(m) * MATRIX_ZZ(m)) - (MATRIX_YZ(m) * MATRIX_ZY(m)));
+   det -= MATRIX_XY(m) * ((MATRIX_YX(m) * MATRIX_ZZ(m)) - (MATRIX_YZ(m) * MATRIX_ZX(m)));
+   det += MATRIX_XZ(m) * ((MATRIX_YX(m) * MATRIX_ZY(m)) - (MATRIX_YY(m) * MATRIX_ZX(m)));
+
+   return det;
+}
+
+EAPI void
+eina_matrix3_divide(Eina_Matrix3 *m, double scalar)
+{
+   MATRIX_XX(m) /= scalar;
+   MATRIX_XY(m) /= scalar;
+   MATRIX_XZ(m) /= scalar;
+
+   MATRIX_YX(m) /= scalar;
+   MATRIX_YY(m) /= scalar;
+   MATRIX_YZ(m) /= scalar;
+
+   MATRIX_ZX(m) /= scalar;
+   MATRIX_ZY(m) /= scalar;
+   MATRIX_ZZ(m) /= scalar;
+}
+
+EAPI void
+eina_matrix3_inverse(const Eina_Matrix3 *m, Eina_Matrix3 *m2)
+{
+   double scalar;
+
+   /* determinant */
+   scalar = eina_matrix3_determinant(m);
+   if (!scalar)
+     {
+        eina_matrix3_identity(m2);
+        return;
+     }
+   /* do its adjoint */
+   eina_matrix3_adjoint(m, m2);
+   /* divide */
+   eina_matrix3_divide(m2, scalar);
+}
+
+EAPI void
+eina_matrix3_compose(const Eina_Matrix3 *m1,
+                     const Eina_Matrix3 *m2,
+                     Eina_Matrix3 *dst)
+{
+   double a11, a12, a13, a21, a22, a23, a31, a32, a33;
+
+   a11 = (MATRIX_XX(m1) * MATRIX_XX(m2)) + (MATRIX_XY(m1) * MATRIX_YX(m2)) + (MATRIX_XZ(m1) * MATRIX_ZX(m2));
+   a12 = (MATRIX_XX(m1) * MATRIX_XY(m2)) + (MATRIX_XY(m1) * MATRIX_YY(m2)) + (MATRIX_XZ(m1) * MATRIX_ZY(m2));
+   a13 = (MATRIX_XX(m1) * MATRIX_XZ(m2)) + (MATRIX_XY(m1) * MATRIX_YZ(m2)) + (MATRIX_XZ(m1) * MATRIX_ZZ(m2));
+
+   a21 = (MATRIX_YX(m1) * MATRIX_XX(m2)) + (MATRIX_YY(m1) * MATRIX_YX(m2)) + (MATRIX_YZ(m1) * MATRIX_ZX(m2));
+   a22 = (MATRIX_YX(m1) * MATRIX_XY(m2)) + (MATRIX_YY(m1) * MATRIX_YY(m2)) + (MATRIX_YZ(m1) * MATRIX_ZY(m2));
+   a23 = (MATRIX_YX(m1) * MATRIX_XZ(m2)) + (MATRIX_YY(m1) * MATRIX_YZ(m2)) + (MATRIX_YZ(m1) * MATRIX_ZZ(m2));
+
+   a31 = (MATRIX_ZX(m1) * MATRIX_XX(m2)) + (MATRIX_ZY(m1) * MATRIX_YX(m2)) + (MATRIX_ZZ(m1) * MATRIX_ZX(m2));
+   a32 = (MATRIX_ZX(m1) * MATRIX_XY(m2)) + (MATRIX_ZY(m1) * MATRIX_YY(m2)) + (MATRIX_ZZ(m1) * MATRIX_ZY(m2));
+   a33 = (MATRIX_ZX(m1) * MATRIX_XZ(m2)) + (MATRIX_ZY(m1) * MATRIX_YZ(m2)) + (MATRIX_ZZ(m1) * MATRIX_ZZ(m2));
+
+   MATRIX_XX(dst) = a11;
+   MATRIX_XY(dst) = a12;
+   MATRIX_XZ(dst) = a13;
+   MATRIX_YX(dst) = a21;
+   MATRIX_YY(dst) = a22;
+   MATRIX_YZ(dst) = a23;
+   MATRIX_ZX(dst) = a31;
+   MATRIX_ZY(dst) = a32;
+   MATRIX_ZZ(dst) = a33;
+}
+
+EAPI Eina_Bool
+eina_matrix3_equal(const Eina_Matrix3 *m1, const Eina_Matrix3 *m2)
+{
+   if (m1->xx != m2->xx ||
+       m1->xy != m2->xy ||
+       m1->xz != m2->xz ||
+       m1->yx != m2->yx ||
+       m1->yy != m2->yy ||
+       m1->yz != m2->yz ||
+       m1->zx != m2->zx ||
+       m1->zy != m2->zy ||
+       m1->zz != m2->zz)
+     return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+EAPI void
+eina_matrix3_f16p16_compose(const Eina_Matrix3_F16p16 *m1,
+                            const Eina_Matrix3_F16p16 *m2,
+                            Eina_Matrix3_F16p16 *dst)
+{
+   Eina_F16p16 a11, a12, a13, a21, a22, a23, a31, a32, a33;
+
+   a11 = eina_f16p16_mul(MATRIX_XX(m1), MATRIX_XX(m2)) +
+     eina_f16p16_mul(MATRIX_XY(m1), MATRIX_YX(m2)) +
+     eina_f16p16_mul(MATRIX_XZ(m1), MATRIX_ZX(m2));
+   a12 = eina_f16p16_mul(MATRIX_XX(m1), MATRIX_XY(m2)) +
+     eina_f16p16_mul(MATRIX_XY(m1), MATRIX_YY(m2)) +
+     eina_f16p16_mul(MATRIX_XZ(m1), MATRIX_ZY(m2));
+   a13 = eina_f16p16_mul(MATRIX_XX(m1), MATRIX_XZ(m2)) +
+     eina_f16p16_mul(MATRIX_XY(m1), MATRIX_YZ(m2)) +
+     eina_f16p16_mul(MATRIX_XZ(m1), MATRIX_ZZ(m2));
+
+   a21 = eina_f16p16_mul(MATRIX_YX(m1), MATRIX_XX(m2)) +
+     eina_f16p16_mul(MATRIX_YY(m1), MATRIX_YX(m2)) +
+     eina_f16p16_mul(MATRIX_YZ(m1), MATRIX_ZX(m2));
+   a22 = eina_f16p16_mul(MATRIX_YX(m1), MATRIX_XY(m2)) +
+     eina_f16p16_mul(MATRIX_YY(m1), MATRIX_YY(m2)) +
+     eina_f16p16_mul(MATRIX_YZ(m1), MATRIX_ZY(m2));
+   a23 = eina_f16p16_mul(MATRIX_YX(m1), MATRIX_XZ(m2)) +
+     eina_f16p16_mul(MATRIX_YY(m1), MATRIX_YZ(m2)) +
+     eina_f16p16_mul(MATRIX_YZ(m1), MATRIX_ZZ(m2));
+
+   a31 = eina_f16p16_mul(MATRIX_ZX(m1), MATRIX_XX(m2)) +
+     eina_f16p16_mul(MATRIX_ZY(m1), MATRIX_YX(m2)) +
+     eina_f16p16_mul(MATRIX_ZZ(m1), MATRIX_ZX(m2));
+   a32 = eina_f16p16_mul(MATRIX_ZX(m1), MATRIX_XY(m2)) +
+     eina_f16p16_mul(MATRIX_ZY(m1), MATRIX_YY(m2)) +
+     eina_f16p16_mul(MATRIX_ZZ(m1), MATRIX_ZY(m2));
+   a33 = eina_f16p16_mul(MATRIX_ZX(m1), MATRIX_XZ(m2)) +
+     eina_f16p16_mul(MATRIX_ZY(m1), MATRIX_YZ(m2)) +
+     eina_f16p16_mul(MATRIX_ZZ(m1), MATRIX_ZZ(m2));
+
+   MATRIX_XX(dst) = a11;
+   MATRIX_XY(dst) = a12;
+   MATRIX_XZ(dst) = a13;
+   MATRIX_YX(dst) = a21;
+   MATRIX_YY(dst) = a22;
+   MATRIX_YZ(dst) = a23;
+   MATRIX_ZX(dst) = a31;
+   MATRIX_ZY(dst) = a32;
+   MATRIX_ZZ(dst) = a33;
+}
+
+EAPI void
+eina_matrix3_translate(Eina_Matrix3 *m, double tx, double ty)
+{
+   MATRIX_XX(m) = 1;
+   MATRIX_XY(m) = 0;
+   MATRIX_XZ(m) = tx;
+   MATRIX_YX(m) = 0;
+   MATRIX_YY(m) = 1;
+   MATRIX_YZ(m) = ty;
+   MATRIX_ZX(m) = 0;
+   MATRIX_ZY(m) = 0;
+   MATRIX_ZZ(m) = 1;
+}
+
+EAPI void
+eina_matrix3_scale(Eina_Matrix3 *m, double sx, double sy)
+{
+   MATRIX_XX(m) = sx;
+   MATRIX_XY(m) = 0;
+   MATRIX_XZ(m) = 0;
+   MATRIX_YX(m) = 0;
+   MATRIX_YY(m) = sy;
+   MATRIX_YZ(m) = 0;
+   MATRIX_ZX(m) = 0;
+   MATRIX_ZY(m) = 0;
+   MATRIX_ZZ(m) = 1;
+}
+
+EAPI void
+eina_matrix3_rotate(Eina_Matrix3 *m, double rad)
+{
+   double c, s;
+#if 0
+   c = cosf(rad);
+   s = sinf(rad);
+#else
+   /* normalize the angle between -pi,pi */
+   rad = fmod(rad + M_PI, 2 * M_PI) - M_PI;
+   c = _cos(rad);
+   s = _sin(rad);
+#endif
+
+   MATRIX_XX(m) = c;
+   MATRIX_XY(m) = -s;
+   MATRIX_XZ(m) = 0;
+   MATRIX_YX(m) = s;
+   MATRIX_YY(m) = c;
+   MATRIX_YZ(m) = 0;
+   MATRIX_ZX(m) = 0;
+   MATRIX_ZY(m) = 0;
+   MATRIX_ZZ(m) = 1;
+}
+
+EAPI void
+eina_matrix3_identity(Eina_Matrix3 *m)
+{
+   MATRIX_XX(m) = 1;
+   MATRIX_XY(m) = 0;
+   MATRIX_XZ(m) = 0;
+   MATRIX_YX(m) = 0;
+   MATRIX_YY(m) = 1;
+   MATRIX_YZ(m) = 0;
+   MATRIX_ZX(m) = 0;
+   MATRIX_ZY(m) = 0;
+   MATRIX_ZZ(m) = 1;
+}
+
+EAPI void
+eina_matrix3_f16p16_identity(Eina_Matrix3_F16p16 *m)
+{
+   MATRIX_XX(m) = 65536;
+   MATRIX_XY(m) = 0;
+   MATRIX_XZ(m) = 0;
+   MATRIX_YX(m) = 0;
+   MATRIX_YY(m) = 65536;
+   MATRIX_YZ(m) = 0;
+   MATRIX_ZX(m) = 0;
+   MATRIX_ZY(m) = 0;
+   MATRIX_ZZ(m) = 65536;
+}
+
+EAPI Eina_Bool
+eina_matrix3_square_quad_map(Eina_Matrix3 *m, const Eina_Quad *q)
+{
+   // x0 - x1 + x2 - x3
+   double ex = QUAD_X0(q) - QUAD_X1(q) + QUAD_X2(q) - QUAD_X3(q);
+   // y0 - y1 + y2 - y3
+   double ey = QUAD_Y0(q) - QUAD_Y1(q) + QUAD_Y2(q) - QUAD_Y3(q);
+
+   /* paralellogram */
+   if (!ex && !ey)
+     {
+        /* create the affine matrix */
+        MATRIX_XX(m) = QUAD_X1(q) - QUAD_X0(q);
+        MATRIX_XY(m) = QUAD_X2(q) - QUAD_X1(q);
+        MATRIX_XZ(m) = QUAD_X0(q);
+
+        MATRIX_YX(m) = QUAD_Y1(q) - QUAD_Y0(q);
+        MATRIX_YY(m) = QUAD_Y2(q) - QUAD_Y1(q);
+        MATRIX_YZ(m) = QUAD_Y0(q);
+
+        MATRIX_ZX(m) = 0;
+        MATRIX_ZY(m) = 0;
+        MATRIX_ZZ(m) = 1;
+
+        return EINA_TRUE;
+     }
+   else
+     {
+        double dx1 = QUAD_X1(q) - QUAD_X2(q); // x1 - x2
+        double dx2 = QUAD_X3(q) - QUAD_X2(q); // x3 - x2
+        double dy1 = QUAD_Y1(q) - QUAD_Y2(q); // y1 - y2
+        double dy2 = QUAD_Y3(q) - QUAD_Y2(q); // y3 - y2
+        double den = (dx1 * dy2) - (dx2 * dy1);
+
+        if (!den)
+          return EINA_FALSE;
+
+        MATRIX_ZX(m) = ((ex * dy2) - (dx2 * ey)) / den;
+        MATRIX_ZY(m) = ((dx1 * ey) - (ex * dy1)) / den;
+        MATRIX_ZZ(m) = 1;
+        MATRIX_XX(m) = QUAD_X1(q) - QUAD_X0(q) + (MATRIX_ZX(m) * QUAD_X1(q));
+        MATRIX_XY(m) = QUAD_X3(q) - QUAD_X0(q) + (MATRIX_ZY(m) * QUAD_X3(q));
+        MATRIX_XZ(m) = QUAD_X0(q);
+        MATRIX_YX(m) = QUAD_Y1(q) - QUAD_Y0(q) + (MATRIX_ZX(m) * QUAD_Y1(q));
+        MATRIX_YY(m) = QUAD_Y3(q) - QUAD_Y0(q) + (MATRIX_ZY(m) * QUAD_Y3(q));
+        MATRIX_YZ(m) = QUAD_Y0(q);
+
+        return EINA_TRUE;
+     }
+}
+
+EAPI Eina_Bool
+eina_matrix3_quad_square_map(Eina_Matrix3 *m,
+                             const Eina_Quad *q)
+{
+   Eina_Matrix3 tmp;
+
+   /* compute square to quad */
+   if (!eina_matrix3_square_quad_map(&tmp, q))
+     return EINA_FALSE;
+
+   eina_matrix3_inverse(&tmp, m);
+   /* make the projective matrix3 always have 1 on zz */
+   if (MATRIX_ZZ(m) != 1)
+     {
+        eina_matrix3_divide(m, MATRIX_ZZ(m));
+     }
+
+   return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+eina_matrix3_quad_quad_map(Eina_Matrix3 *m,
+                           const Eina_Quad *src,
+                           const Eina_Quad *dst)
+{
+   Eina_Matrix3 tmp;
+
+   /* TODO check that both are actually quadrangles */
+   if (!eina_matrix3_quad_square_map(m, src))
+     return EINA_FALSE;
+   if (!eina_matrix3_square_quad_map(&tmp, dst))
+     return EINA_FALSE;
+   eina_matrix3_compose(&tmp, m, m);
+
+   return EINA_TRUE;
+}
diff --git a/src/lib/eina/eina_matrix.h b/src/lib/eina/eina_matrix.h
new file mode 100644 (file)
index 0000000..57b5bab
--- /dev/null
@@ -0,0 +1,339 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2007-2014 Jorge Luis Zapata
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef EINA_MATRIX3_H_
+#define EINA_MATRIX3_H_
+
+#include "eina_quad.h"
+
+/**
+ * @file
+ * @ender_group{Eina_Matrix_Type}
+ * @ender_group{Eina_Matrix3_F16p16}
+ * @ender_group{Eina_Matrix3}
+ */
+
+/**
+ * @defgroup Eina_Matrix_Type Matrices type
+ * @ingroup Eina_Basic
+ * @brief Matrix3 types
+ * @{
+ */
+typedef enum _Eina_Matrix_Type
+  {
+    EINA_MATRIX_TYPE_IDENTITY, /**< Identity matrix3 type */
+    EINA_MATRIX_TYPE_AFFINE, /**< Affine matrix3 type */
+    EINA_MATRIX_TYPE_PROJECTIVE, /**< Projective matrix3 type */
+    EINA_MATRIX_TYPE_LAST /**< The total number of matrix3 types */
+  } Eina_Matrix_Type;
+
+/**
+ * @}
+ * @defgroup Eina_Matrix3_F16p16 Matrices in fixed point
+ * @ingroup Eina_Basic
+ * @brief Fixed point matrices operations
+ * @{
+ */
+
+/**
+ * Fixed point matrix3 handler
+ */
+typedef struct _Eina_Matrix3_F16p16 Eina_Matrix3_F16p16;
+
+struct _Eina_Matrix3_F16p16
+{
+   Eina_F16p16 xx; /**< xx in x' = (x * xx) + (y * xy) + xz */
+   Eina_F16p16 xy; /**< xy in x' = (x * xx) + (y * xy) + xz */
+   Eina_F16p16 xz; /**< xz in x' = (x * xx) + (y * xy) + xz */
+
+   Eina_F16p16 yx; /**< yx in y' = (x * yx) + (y * yy) + yz */
+   Eina_F16p16 yy; /**< yy in y' = (x * yx) + (y * yy) + yz */
+   Eina_F16p16 yz; /**< yz in y' = (x * yx) + (y * yy) + yz */
+
+   Eina_F16p16 zx; /**< zx in z' = (x * zx) + (y * zy) + zz */
+   Eina_F16p16 zy; /**< zy in z' = (x * zx) + (y * zy) + zz */
+   Eina_F16p16 zz; /**< zz in z' = (x * zx) + (y * zy) + zz */
+};
+
+/**
+ * @brief Set the given fixed point matrix to the identity matrix.
+ *
+ * @param m The fixed point matrix to set
+ *
+ * This function sets @p m to the identity matrix. No check is done on
+ * @p m.
+ */
+EAPI void eina_matrix3_f16p16_identity(Eina_Matrix3_F16p16 *m);
+
+EAPI void eina_matrix3_f16p16_compose(const Eina_Matrix3_F16p16 *m1,
+                                      const Eina_Matrix3_F16p16 *m2,
+                                      Eina_Matrix3_F16p16 *dst);
+
+/**
+ * @brief Return the type of the given fixed point matrix.
+ *
+ * @param m The fixed point matrix.
+ * @return The type of the matrix.
+ *
+ * This function returns the type of the matrix @p m. No check is done
+ * on @p m.
+ */
+EAPI Eina_Matrix_Type eina_matrix3_f16p16_type_get(const Eina_Matrix3_F16p16 *m);
+
+/**
+ * @}
+ * @defgroup Eina_Matrix3 Matrices in floating point
+ * @ingroup Eina_Basic
+ * @brief Matrix definition and operations
+ * @{
+ */
+
+/** Helper macro for printf formatting */
+#define EINA_MATRIX3_FORMAT "g %g %g | %g %g %g | %g %g %g"
+/** Helper macro for printf formatting arg */
+#define EINA_MATRIX3_ARGS(m) (m)->xx, (m)->xy, (m)->xz, \
+    (m)->yx, (m)->yy, (m)->yz,                          \
+    (m)->zx, (m)->zy, (m)->zz
+
+
+/**
+ * Floating point matrix3 handler
+ */
+typedef struct _Eina_Matrix3 Eina_Matrix3;
+
+struct _Eina_Matrix3
+{
+   double xx; /**< xx in x' = (x * xx) + (y * xy) + xz */
+   double xy; /**< xy in x' = (x * xx) + (y * xy) + xz */
+   double xz; /**< xz in x' = (x * xx) + (y * xy) + xz */
+
+   double yx; /**< yx in y' = (x * yx) + (y * yy) + yz */
+   double yy; /**< yy in y' = (x * yx) + (y * yy) + yz */
+   double yz; /**< yz in y' = (x * yx) + (y * yy) + yz */
+
+   double zx; /**< zx in z' = (x * zx) + (y * zy) + zz */
+   double zy; /**< zy in z' = (x * zx) + (y * zy) + zz */
+   double zz; /**< zz in z' = (x * zx) + (y * zy) + zz */
+};
+
+/**
+ * @brief Return the type of the given floating point matrix.
+ *
+ * @param m The floating point matrix.
+ * @return The type of the matrix.
+ *
+ * This function returns the type of the matrix @p m. No check is done
+ * on @p m.
+ */
+EAPI Eina_Matrix_Type eina_matrix3_type_get(const Eina_Matrix3 *m);
+
+/**
+ * @brief Set the values of the coefficients of the given floating
+ * point matrix.
+ *
+ * @param m The floating point matrix.
+ * @param xx The first coefficient value.
+ * @param xy The second coefficient value.
+ * @param xz The third coefficient value.
+ * @param yx The fourth coefficient value.
+ * @param yy The fifth coefficient value.
+ * @param yz The sixth coefficient value.
+ * @param zx The seventh coefficient value.
+ * @param zy The heighth coefficient value.
+ * @param zz The nineth coefficient value.
+ *
+ * This function sets the values of the coefficients of the matrix
+ * @p m. No check is done on @p m.
+ *
+ * @see eina_matrix3_values_get()
+ */
+EAPI void eina_matrix3_values_set(Eina_Matrix3 *m,
+                                  double xx, double xy, double xz,
+                                  double yx, double yy, double yz,
+                                  double zx, double zy, double zz);
+
+/**
+ * @brief Get the values of the coefficients of the given floating
+ * point matrix.
+ *
+ * @param m The floating point matrix.
+ * @param xx The first coefficient value.
+ * @param xy The second coefficient value.
+ * @param xz The third coefficient value.
+ * @param yx The fourth coefficient value.
+ * @param yy The fifth coefficient value.
+ * @param yz The sixth coefficient value.
+ * @param zx The seventh coefficient value.
+ * @param zy The heighth coefficient value.
+ * @param zz The nineth coefficient value.
+ *
+ * This function gets the values of the coefficients of the matrix
+ * @p m. No check is done on @p m.
+ *
+ * @see eina_matrix3_values_set()
+ */
+EAPI void eina_matrix3_values_get(const Eina_Matrix3 *m,
+                                  double *xx, double *xy, double *xz,
+                                  double *yx, double *yy, double *yz,
+                                  double *zx, double *zy, double *zz);
+
+/**
+ * @brief Get the values of the coefficients of the given fixed
+ * point matrix.
+ *
+ * @param m The fixed point matrix.
+ * @param xx The first coefficient value.
+ * @param xy The second coefficient value.
+ * @param xz The third coefficient value.
+ * @param yx The fourth coefficient value.
+ * @param yy The fifth coefficient value.
+ * @param yz The sixth coefficient value.
+ * @param zx The seventh coefficient value.
+ * @param zy The heighth coefficient value.
+ * @param zz The nineth coefficient value.
+ *
+ * This function gets the values of the coefficients of the matrix
+ * @p m. No check is done on @p m.
+ *
+ * @see eina_matrix3_values_set()
+ */
+EAPI void eina_matrix3_fixed_values_get(const Eina_Matrix3 *m,
+                                        Eina_F16p16 *xx, Eina_F16p16 *xy, Eina_F16p16 *xz,
+                                        Eina_F16p16 *yx, Eina_F16p16 *yy, Eina_F16p16 *yz,
+                                        Eina_F16p16 *zx, Eina_F16p16 *zy, Eina_F16p16 *zz);
+
+/**
+ * @brief Transform the given floating point matrix to the given fixed
+ * point matrix.
+ *
+ * @param m The floating point matrix.
+ * @param fm The fixed point matrix.
+ *
+ * This function transforms the floating point matrix @p m to a fixed
+ * point matrix and store the coefficients into the fixed point matrix
+ * @p fm.
+ */
+EAPI void eina_matrix3_matrix3_f16p16_to(const Eina_Matrix3 *m,
+                                         Eina_Matrix3_F16p16 *fm);
+
+/**
+ * @brief Check whether the two given matrices are equal or not.
+ *
+ * @param m1 The first matrix.
+ * @param m2 The second matrix.
+ * @return EINA_TRUE if the two matrices are equal, 0 otherwise.
+ *
+ * This function return EINA_TRUE if thematrices @p m1 and @p m2 are
+ * equal, EINA_FALSE otherwise. No check is done on the matrices.
+ */
+EAPI Eina_Bool eina_matrix3_equal(const Eina_Matrix3 *m1, const Eina_Matrix3 *m2);
+EAPI void eina_matrix3_compose(const Eina_Matrix3 *m1,
+                               const Eina_Matrix3 *m2,
+                               Eina_Matrix3 *dst);
+
+/**
+ * Set the matrix values for a translation
+ * @param[in] m The matrix to set the translation values
+ * @param[in] tx The X coordinate translate
+ * @param[in] ty The Y coordinate translate
+ */
+EAPI void eina_matrix3_translate(Eina_Matrix3 *t, double tx, double ty);
+
+/**
+ * Set the matrix values for a scale
+ * @param[in] m The matrix to set the scale values
+ * @param[in] sx The X coordinate scale
+ * @param[in] sy The Y coordinate scale
+ */
+EAPI void eina_matrix3_scale(Eina_Matrix3 *t, double sx, double sy);
+
+/**
+ * Set the matrix values for a rotation
+ * @param[in] m The matrix to set the rotation values
+ * @param[in] rad The radius to rotate the matrix
+ */
+EAPI void eina_matrix3_rotate(Eina_Matrix3 *t, double rad);
+
+/**
+ * @brief Set the given floating point matrix to the identity matrix.
+ *
+ * @param m The floating point matrix to set
+ *
+ * This function sets @p m to the identity matrix. No check is done on
+ * @p m.
+ */
+EAPI void eina_matrix3_identity(Eina_Matrix3 *t);
+
+/**
+ * @brief Return the determinant of the given matrix.
+ *
+ * @param m The matrix.
+ * @return The determinant.
+ *
+ * This function returns the determinant of the matrix @p m. No check
+ * is done on @p m.
+ */
+EAPI double eina_matrix3_determinant(const Eina_Matrix3 *m);
+
+/**
+ * @brief Divide the given matrix by the given scalar.
+ *
+ * @param m The matrix.
+ * @param scalar The scalar number.
+ *
+ * This function divides the matrix @p m by @p scalar. No check
+ * is done on @p m.
+ */
+EAPI void eina_matrix3_divide(Eina_Matrix3 *m, double scalar);
+
+/**
+ * @brief Compute the inverse of the given matrix.
+ *
+ * @param m The matrix to inverse.
+ * @param m2 The inverse matrix.
+ *
+ * This function inverse the matrix @p m and stores the result in
+ * @p m2. No check is done on @p m or @p m2. If @p m can not be
+ * invertible, then @p m2 is set to the identity matrix.
+ */
+EAPI void eina_matrix3_inverse(const Eina_Matrix3 *m, Eina_Matrix3 *m2);
+EAPI void eina_matrix3_transpose(const Eina_Matrix3 *m, Eina_Matrix3 *a);
+EAPI void eina_matrix3_cofactor(const Eina_Matrix3 *m, Eina_Matrix3 *a);
+EAPI void eina_matrix3_adjoint(const Eina_Matrix3 *m, Eina_Matrix3 *a);
+
+EAPI void eina_matrix3_point_transform(const Eina_Matrix3 *m,
+                                       double x, double y,
+                                       double *xr, double *yr);
+EAPI void eina_matrix3_rectangle_transform(const Eina_Matrix3 *m,
+                                           const Eina_Rectangle *r,
+                                           const Eina_Quad *q);
+
+/**
+ * @brief Creates a projective matrix that maps a quadrangle to a quadrangle
+ */
+EAPI Eina_Bool eina_matrix3_quad_quad_map(Eina_Matrix3 *m,
+                                          const Eina_Quad *src,
+                                          const Eina_Quad *dst);
+EAPI Eina_Bool eina_matrix3_square_quad_map(Eina_Matrix3 *m,
+                                            const Eina_Quad *q);
+EAPI Eina_Bool eina_matrix3_quad_square_map(Eina_Matrix3 *m,
+                                            const Eina_Quad *q);
+
+/**
+ * @}
+ */
+#endif /*EINA_MATRIX3_H_*/
diff --git a/src/lib/eina/eina_quad.c b/src/lib/eina/eina_quad.c
new file mode 100644 (file)
index 0000000..d2874c0
--- /dev/null
@@ -0,0 +1,127 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2007-2014 Jorge Luis Zapata
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "eina_private.h"
+
+#include <math.h>
+#include <stdio.h>
+
+#include "eina_rectangle.h"
+#include "eina_quad.h"
+
+#define QUAD_X0(q) q->x0
+#define QUAD_Y0(q) q->y0
+#define QUAD_X1(q) q->x1
+#define QUAD_Y1(q) q->y1
+#define QUAD_X2(q) q->x2
+#define QUAD_Y2(q) q->y2
+#define QUAD_X3(q) q->x3
+#define QUAD_Y3(q) q->y3
+
+/*============================================================================*
+ *                                  Local                                     *
+ *============================================================================*/
+/** @cond internal */
+/* FIXME make this function on API */
+static inline void _quad_dump(Eina_Quad *q)
+{
+   printf("Q = %f %f, %f %f, %f %f, %f %f\n", QUAD_X0(q), QUAD_Y0(q), QUAD_X1(q), QUAD_Y1(q), QUAD_X2(q), QUAD_Y2(q), QUAD_X3(q), QUAD_Y3(q));
+}
+/** @endcond */
+
+/*============================================================================*
+ *                                   API                                      *
+ *============================================================================*/
+EAPI void
+eina_quad_rectangle_to(const Eina_Quad *q,
+                       Eina_Rectangle *r)
+{
+   double xmin, ymin, xmax, ymax;
+   /* FIXME this code is very ugly, for sure there must be a better
+    * implementation */
+   xmin = QUAD_X0(q) < QUAD_X1(q) ? QUAD_X0(q) : QUAD_X1(q);
+   xmin = xmin < QUAD_X2(q) ? xmin : QUAD_X2(q);
+   xmin = xmin < QUAD_X3(q) ? xmin : QUAD_X3(q);
+
+   ymin = QUAD_Y0(q) < QUAD_Y1(q) ? QUAD_Y0(q) : QUAD_Y1(q);
+   ymin = ymin < QUAD_Y2(q) ? ymin : QUAD_Y2(q);
+   ymin = ymin < QUAD_Y3(q) ? ymin : QUAD_Y3(q);
+
+   xmax = QUAD_X0(q) > QUAD_X1(q) ? QUAD_X0(q) : QUAD_X1(q);
+   xmax = xmax > QUAD_X2(q) ? xmax : QUAD_X2(q);
+   xmax = xmax > QUAD_X3(q) ? xmax : QUAD_X3(q);
+
+   ymax = QUAD_Y0(q) > QUAD_Y1(q) ? QUAD_Y0(q) : QUAD_Y1(q);
+   ymax = ymax > QUAD_Y2(q) ? ymax : QUAD_Y2(q);
+   ymax = ymax > QUAD_Y3(q) ? ymax : QUAD_Y3(q);
+
+   r->x = lround(xmin);
+   r->w = lround(xmax) - r->x;
+   r->y = lround(ymin);
+   r->h = lround(ymax) - r->y;
+}
+
+EAPI void
+eina_quad_rectangle_from(Eina_Quad *q,
+                         const Eina_Rectangle *r)
+{
+   QUAD_X0(q) = r->x;
+   QUAD_Y0(q) = r->y;
+   QUAD_X1(q) = r->x + r->w;
+   QUAD_Y1(q) = r->y;
+   QUAD_X2(q) = r->x + r->w;
+   QUAD_Y2(q) = r->y + r->h;
+   QUAD_X3(q) = r->x;
+   QUAD_Y3(q) = r->y + r->h;
+}
+
+EAPI void eina_quad_coords_get(const Eina_Quad *q,
+                               double *qx0, double *qy0,
+                               double *qx1, double *qy1,
+                               double *qx2, double *qy2,
+                               double *qx3, double *qy3)
+{
+   if (qx0) *qx0 = q->x0;
+   if (qy0) *qy0 = q->y0;
+   if (qx1) *qx1 = q->x1;
+   if (qy1) *qy1 = q->y1;
+   if (qx2) *qx2 = q->x2;
+   if (qy2) *qy2 = q->y2;
+   if (qx3) *qx3 = q->x3;
+   if (qy3) *qy3 = q->y3;
+}
+
+EAPI void eina_quad_coords_set(Eina_Quad *q,
+                               double qx0, double qy0,
+                               double qx1, double qy1,
+                               double qx2, double qy2,
+                               double qx3, double qy3)
+{
+   QUAD_X0(q) = qx0;
+   QUAD_Y0(q) = qy0;
+   QUAD_X1(q) = qx1;
+   QUAD_Y1(q) = qy1;
+   QUAD_X2(q) = qx2;
+   QUAD_Y2(q) = qy2;
+   QUAD_X3(q) = qx3;
+   QUAD_Y3(q) = qy3;
+}
diff --git a/src/lib/eina/eina_quad.h b/src/lib/eina/eina_quad.h
new file mode 100644 (file)
index 0000000..2abbc34
--- /dev/null
@@ -0,0 +1,67 @@
+/* EINA - EFL data type library
+ * Copyright (C) 2007-2014 Jorge Luis Zapata
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef EINA_QUAD_H_
+#define EINA_QUAD_H_
+
+/**
+ * @file
+ * @ender_group{Eina_Quad}
+ */
+
+/**
+ * @defgroup Eina_Quad Quadrangles
+ * @ingroup Eina_Basic
+ * @brief Quadrangles operations
+ * @{
+ */
+
+/**
+ * Quadrangle definition
+ */
+typedef struct _Eina_Quad
+{
+   double x0; /**< Top left x coordinate */
+   double y0; /**< Top left y coordinate */
+   double x1; /**< Top right x coordinate */
+   double y1; /**< Top right y coordinate */
+   double x2; /**< Bottom right x coordinate */
+   double y2; /**< Bottom right y coordinate */
+   double x3; /**< Bottom left x coordinate */
+   double y3; /**< Bottom left y coordinate */
+} Eina_Quad;
+
+EAPI void eina_quad_rectangle_to(const Eina_Quad *q,
+                                 Eina_Rectangle *r);
+EAPI void eina_quad_rectangle_from(Eina_Quad *q,
+                                   const Eina_Rectangle *r);
+EAPI void eina_quad_coords_set(Eina_Quad *q,
+                               double x1, double y1,
+                               double x2, double y2,
+                               double x3, double y3,
+                               double x4, double y4);
+EAPI void eina_quad_coords_get(const Eina_Quad *q,
+                               double *x1, double *y1,
+                               double *x2, double *y2,
+                               double *x3, double *y3,
+                               double *x4, double *y4);
+
+/**
+ * @}
+ */
+
+#endif