eina: backported eina_bezier and eina_matrix from opensource 81/79981/1
authorSubhransu Mohanty <sub.mohanty@samsung.com>
Thu, 14 Jul 2016 00:58:23 +0000 (09:58 +0900)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Thu, 14 Jul 2016 01:01:05 +0000 (10:01 +0900)
Change-Id: I27d16079ff7da00ef0ca2b4b4139cda55e70dcb3

src/lib/eina/eina_bezier.c
src/lib/eina/eina_bezier.h
src/lib/eina/eina_matrix.c
src/lib/eina/eina_matrix.h

index 4e8ffca..6494551 100644 (file)
@@ -273,3 +273,61 @@ eina_bezier_split_at_length(const Eina_Bezier *b, double len,
    t =  eina_bezier_t_at(right, len);
    _eina_bezier_split_left(right, t, left);
 }
+
+EAPI void
+eina_bezier_bounds_get(const Eina_Bezier *b, double *x, double *y, double *w, double *h)
+{
+   double xmin = b->start.x;
+   double xmax = b->start.x;
+   double ymin = b->start.y;
+   double ymax = b->start.y;
+
+   if (b->ctrl_start.x < xmin)
+     xmin = b->ctrl_start.x;
+   else if (b->ctrl_start.x > xmax)
+     xmax = b->ctrl_start.x;
+   if (b->ctrl_end.x < xmin)
+     xmin = b->ctrl_end.x;
+   else if (b->ctrl_end.x > xmax)
+     xmax = b->ctrl_end.x;
+   if (b->end.x < xmin)
+     xmin = b->end.x;
+   else if (b->end.x > xmax)
+     xmax = b->end.x;
+
+   if (b->ctrl_start.y < ymin)
+     ymin = b->ctrl_start.y;
+   else if (b->ctrl_start.y > ymax)
+     ymax = b->ctrl_start.y;
+   if (b->ctrl_end.y < ymin)
+     ymin = b->ctrl_end.y;
+   else if (b->ctrl_end.y > ymax)
+     ymax = b->ctrl_end.y;
+   if (b->end.y < ymin)
+     ymin = b->end.y;
+   else if (b->end.y > ymax)
+     ymax = b->end.y;
+
+   if (x) *x = xmin;
+   if (y) *y = ymin;
+   if (w) *w = xmax - xmin;
+   if (h) *h = ymax - ymin;
+}
+
+EAPI void
+eina_bezier_on_interval(Eina_Bezier *b, double t0, double t1, Eina_Bezier *result)
+{
+   Eina_Bezier bezier;
+   double t;
+
+   if (t0 == 0 && t1 == 1)
+     {
+        *result = *b;
+        return;
+     }
+
+   bezier = *b;
+   _eina_bezier_split_left(&bezier, t0, result);
+   t = (t1-t0)/(1-t0);
+   _eina_bezier_split_left(&bezier, t, result);
+}
index aef32e4..e8d1a7b 100644 (file)
@@ -143,4 +143,31 @@ EAPI double eina_bezier_angle_at(const Eina_Bezier *b, double t) EINA_ARG_NONNUL
  */
 EAPI void eina_bezier_split_at_length(const Eina_Bezier *b, double len, Eina_Bezier *left, Eina_Bezier *right) EINA_ARG_NONNULL(1);
 
+/**
+ * @brief get the bound of the the bezier.
+ *
+ * @param b The floating point bezier.
+ * @param x x coordinate of bounding box.
+ * @param y y coordinate of bounding box.
+ * @param w width of bounding box.
+ * @param h height of bounding box.
+ *
+ * @p b. No check is done on @p b.
+ * @since 1.17
+ */
+EAPI void eina_bezier_bounds_get(const Eina_Bezier *b, double *x, double *y, double *w, double *h) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief find the bezier at given interval.
+ *
+ * @param b The floating point bezier.
+ * @param t0 The start interval.
+ * @param t1 The end interval.
+ * @param result The result bezier.
+ *
+ * @p b. No check is done on @p b.
+ * @since 1.17
+ */
+EAPI void eina_bezier_on_interval(Eina_Bezier *b, double t0, double t1, Eina_Bezier *result);
+
 #endif // EINA_BEZIER_H
index 4263322..d7aeebf 100644 (file)
@@ -939,113 +939,350 @@ eina_matrix4_transpose(Eina_Matrix4 *out, const Eina_Matrix4 *in)
 }
 
 EAPI void
-eina_matrix4_multiply(Eina_Matrix4 *out,
-                      const Eina_Matrix4 *a, const Eina_Matrix4 *b)
+eina_matrix4_multiply_copy(Eina_Matrix4 *out,
+                      const Eina_Matrix4 *mat_a, const Eina_Matrix4 *mat_b)
 {
-   // FIXME: start implementing SSE multiplication here
-   MATRIX_XX(out) =
-       MATRIX_XX(a) * MATRIX_XX(b)
-     + MATRIX_XY(a) * MATRIX_YX(b)
-     + MATRIX_XZ(a) * MATRIX_ZX(b)
-     + MATRIX_XW(a) * MATRIX_WX(b);
+   if (out != mat_a && out != mat_b)
+     {
+        eina_matrix4_multiply(out, mat_a, mat_b);
+     }
+   else
+     {
+        Eina_Matrix4 result;
 
-   MATRIX_XY(out) =
-       MATRIX_XX(a) * MATRIX_XY(b)
-     + MATRIX_XY(a) * MATRIX_YY(b)
-     + MATRIX_XZ(a) * MATRIX_ZY(b)
-     + MATRIX_XW(a) * MATRIX_WY(b);
+        eina_matrix4_multiply(&result, mat_a, mat_b);
+        eina_matrix4_copy(out, &result);
+     }
+}
 
-   MATRIX_XZ(out) =
-       MATRIX_XX(a) * MATRIX_XZ(b)
-     + MATRIX_XY(a) * MATRIX_YZ(b)
-     + MATRIX_XZ(a) * MATRIX_ZZ(b)
-     + MATRIX_XW(a) * MATRIX_WZ(b);
+EAPI void
+eina_matrix4_identity(Eina_Matrix4 *out)
+{
+   memset(out, 0, sizeof (Eina_Matrix4));
 
-   MATRIX_XW(out) =
-       MATRIX_XX(a) * MATRIX_XW(b)
-     + MATRIX_XY(a) * MATRIX_YW(b)
-     + MATRIX_XZ(a) * MATRIX_ZW(b)
-     + MATRIX_XW(a) * MATRIX_WW(b);
+   MATRIX_XX(out) = 1.0;
+   MATRIX_YY(out) = 1.0;
+   MATRIX_ZZ(out) = 1.0;
+   MATRIX_WW(out) = 1.0;
+}
 
-   MATRIX_YX(out) =
-       MATRIX_YX(a) * MATRIX_XX(b)
-     + MATRIX_YY(a) * MATRIX_YX(b)
-     + MATRIX_YZ(a) * MATRIX_ZX(b)
-     + MATRIX_YW(a) * MATRIX_WX(b);
+EAPI Eina_Matrix_Type
+eina_matrix2_type_get(const Eina_Matrix2 *m)
+{
+   if ((MATRIX_XX(m) == 1) && (MATRIX_XY(m) == 0) &&
+       (MATRIX_YX(m) == 0) && (MATRIX_YY(m) == 1))
+     return EINA_MATRIX_TYPE_IDENTITY;
+   return EINA_MATRIX_TYPE_AFFINE;
+}
 
-   MATRIX_YY(out) =
-       MATRIX_YX(a) * MATRIX_XY(b)
-     + MATRIX_YY(a) * MATRIX_YY(b)
-     + MATRIX_YZ(a) * MATRIX_ZY(b)
-     + MATRIX_YW(a) * MATRIX_WY(b);
+EAPI void
+eina_matrix4_array_set(Eina_Matrix4 *m, const double *v)
+{
+   memcpy(&MATRIX_XX(m), v, sizeof(double) * 16);
+}
 
-   MATRIX_YZ(out) =
-       MATRIX_YX(a) * MATRIX_XZ(b)
-     + MATRIX_YY(a) * MATRIX_YZ(b)
-     + MATRIX_YZ(a) * MATRIX_ZZ(b)
-     + MATRIX_YW(a) * MATRIX_WZ(b);
+EAPI void
+eina_matrix4_copy(Eina_Matrix4 *dst, const Eina_Matrix4 *src)
+{
+   memcpy(dst, src, sizeof(Eina_Matrix4));
+}
 
-   MATRIX_YW(out) =
-       MATRIX_YX(a) * MATRIX_XW(b)
-     + MATRIX_YY(a) * MATRIX_YW(b)
-     + MATRIX_YZ(a) * MATRIX_ZW(b)
-     + MATRIX_YW(a) * MATRIX_WW(b);
+EAPI void
+eina_matrix4_multiply(Eina_Matrix4 *out, const Eina_Matrix4 *mat_a,
+                           const Eina_Matrix4 *mat_b)
+{
+   if (eina_matrix4_type_get(mat_a) == EINA_MATRIX_TYPE_IDENTITY)
+     {
+        eina_matrix4_copy(out, mat_b);
+        return;
+     }
 
-   MATRIX_ZX(out) =
-       MATRIX_ZX(a) * MATRIX_XX(b)
-     + MATRIX_ZY(a) * MATRIX_YX(b)
-     + MATRIX_ZZ(a) * MATRIX_ZX(b)
-     + MATRIX_ZW(a) * MATRIX_WX(b);
+   if (eina_matrix4_type_get(mat_b) == EINA_MATRIX_TYPE_IDENTITY)
+     {
+        eina_matrix4_copy(out, mat_a);
+        return;
+     }
 
-   MATRIX_ZY(out) =
-       MATRIX_ZX(a) * MATRIX_XY(b)
-     + MATRIX_ZY(a) * MATRIX_YY(b)
-     + MATRIX_ZZ(a) * MATRIX_ZY(b)
-     + MATRIX_ZW(a) * MATRIX_WY(b);
+   MATRIX_XX(out) = MATRIX_XX(mat_a) * MATRIX_XX(mat_b) + MATRIX_YX(mat_a) * MATRIX_XY(mat_b) +
+                    MATRIX_ZX(mat_a) * MATRIX_XZ(mat_b) + MATRIX_WX(mat_a) * MATRIX_XW(mat_b);
+   MATRIX_YX(out) = MATRIX_XX(mat_a) * MATRIX_YX(mat_b) + MATRIX_YX(mat_a) * MATRIX_YY(mat_b) +
+                    MATRIX_ZX(mat_a) * MATRIX_YZ(mat_b) + MATRIX_WX(mat_a) * MATRIX_YW(mat_b);
+   MATRIX_ZX(out) = MATRIX_XX(mat_a) * MATRIX_ZX(mat_b) + MATRIX_YX(mat_a) * MATRIX_ZY(mat_b) +
+                    MATRIX_ZX(mat_a) * MATRIX_ZZ(mat_b) + MATRIX_WX(mat_a) * MATRIX_ZW(mat_b);
+   MATRIX_WX(out) = MATRIX_XX(mat_a) * MATRIX_WX(mat_b) + MATRIX_YX(mat_a) * MATRIX_WY(mat_b) +
+                    MATRIX_ZX(mat_a) * MATRIX_WZ(mat_b) + MATRIX_WX(mat_a) * MATRIX_WW(mat_b);
+
+   MATRIX_XY(out) = MATRIX_XY(mat_a) * MATRIX_XX(mat_b) + MATRIX_YY(mat_a) * MATRIX_XY(mat_b) +
+                    MATRIX_ZY(mat_a) * MATRIX_XZ(mat_b) + MATRIX_WY(mat_a) * MATRIX_XW(mat_b);
+   MATRIX_YY(out) = MATRIX_XY(mat_a) * MATRIX_YX(mat_b) + MATRIX_YY(mat_a) * MATRIX_YY(mat_b) +
+                    MATRIX_ZY(mat_a) * MATRIX_YZ(mat_b) + MATRIX_WY(mat_a) * MATRIX_YW(mat_b);
+   MATRIX_ZY(out) = MATRIX_XY(mat_a) * MATRIX_ZX(mat_b) + MATRIX_YY(mat_a) * MATRIX_ZY(mat_b) +
+                    MATRIX_ZY(mat_a) * MATRIX_ZZ(mat_b) + MATRIX_WY(mat_a) * MATRIX_ZW(mat_b);
+   MATRIX_WY(out) = MATRIX_XY(mat_a) * MATRIX_WX(mat_b) + MATRIX_YY(mat_a) * MATRIX_WY(mat_b) +
+                    MATRIX_ZY(mat_a) * MATRIX_WZ(mat_b) + MATRIX_WY(mat_a) * MATRIX_WW(mat_b);
+
+   MATRIX_XZ(out) = MATRIX_XZ(mat_a) * MATRIX_XX(mat_b) + MATRIX_YZ(mat_a) * MATRIX_XY(mat_b) +
+                    MATRIX_ZZ(mat_a) * MATRIX_XZ(mat_b) + MATRIX_WZ(mat_a) * MATRIX_XW(mat_b);
+   MATRIX_YZ(out) = MATRIX_XZ(mat_a) * MATRIX_YX(mat_b) + MATRIX_YZ(mat_a) * MATRIX_YY(mat_b) +
+                    MATRIX_ZZ(mat_a) * MATRIX_YZ(mat_b) + MATRIX_WZ(mat_a) * MATRIX_YW(mat_b);
+   MATRIX_ZZ(out) = MATRIX_XZ(mat_a) * MATRIX_ZX(mat_b) + MATRIX_YZ(mat_a) * MATRIX_ZY(mat_b) +
+                    MATRIX_ZZ(mat_a) * MATRIX_ZZ(mat_b) + MATRIX_WZ(mat_a) * MATRIX_ZW(mat_b);
+   MATRIX_WZ(out) = MATRIX_XZ(mat_a) * MATRIX_WX(mat_b) + MATRIX_YZ(mat_a) * MATRIX_WY(mat_b) +
+                    MATRIX_ZZ(mat_a) * MATRIX_WZ(mat_b) + MATRIX_WZ(mat_a) * MATRIX_WW(mat_b);
+
+   MATRIX_XW(out) = MATRIX_XW(mat_a) * MATRIX_XX(mat_b) + MATRIX_YW(mat_a) * MATRIX_XY(mat_b) +
+                    MATRIX_ZW(mat_a) * MATRIX_XZ(mat_b) + MATRIX_WW(mat_a) * MATRIX_XW(mat_b);
+   MATRIX_YW(out) = MATRIX_XW(mat_a) * MATRIX_YX(mat_b) + MATRIX_YW(mat_a) * MATRIX_YY(mat_b) +
+                    MATRIX_ZW(mat_a) * MATRIX_YZ(mat_b) + MATRIX_WW(mat_a) * MATRIX_YW(mat_b);
+   MATRIX_ZW(out) = MATRIX_XW(mat_a) * MATRIX_ZX(mat_b) + MATRIX_YW(mat_a) * MATRIX_ZY(mat_b) +
+                    MATRIX_ZW(mat_a) * MATRIX_ZZ(mat_b) + MATRIX_WW(mat_a) * MATRIX_ZW(mat_b);
+   MATRIX_WW(out) = MATRIX_XW(mat_a) * MATRIX_WX(mat_b) + MATRIX_YW(mat_a) * MATRIX_WY(mat_b) +
+                    MATRIX_ZW(mat_a) * MATRIX_WZ(mat_b) + MATRIX_WW(mat_a) * MATRIX_WW(mat_b);
+}
 
-   MATRIX_ZZ(out) =
-       MATRIX_ZX(a) * MATRIX_XZ(b)
-     + MATRIX_ZY(a) * MATRIX_YZ(b)
-     + MATRIX_ZZ(a) * MATRIX_ZZ(b)
-     + MATRIX_ZW(a) * MATRIX_WZ(b);
+EAPI void
+eina_matrix4_ortho_set(Eina_Matrix4 *m,
+                    double left, double right, double bottom, double top,
+                    double dnear, double dfar)
+{
+   double   w = right - left;
+   double   h = top - bottom;
+   double   depth = dnear - dfar;
+
+   MATRIX_XX(m) = 2.0f / w;
+   MATRIX_XY(m) = 0.0f;
+   MATRIX_XZ(m) = 0.0f;
+   MATRIX_XW(m) = 0.0f;
+
+   MATRIX_YX(m) = 0.0f;
+   MATRIX_YY(m) = 2.0f / h;
+   MATRIX_YZ(m) = 0.0f;
+   MATRIX_YW(m) = 0.0f;
+
+   MATRIX_ZX(m) = 0.0f;
+   MATRIX_ZY(m) = 0.0f;
+   MATRIX_ZZ(m) = 2.0f / depth;
+   MATRIX_ZW(m) = 0.0f;
+
+   MATRIX_WX(m) = -(right + left) / w;
+   MATRIX_WY(m) = -(top + bottom) / h;
+   MATRIX_WZ(m) = (dfar + dnear) / depth;
+   MATRIX_WW(m) = 1.0f;
+}
 
-   MATRIX_ZW(out) =
-       MATRIX_ZX(a) * MATRIX_XW(b)
-     + MATRIX_ZY(a) * MATRIX_YW(b)
-     + MATRIX_ZZ(a) * MATRIX_ZW(b)
-     + MATRIX_ZW(a) * MATRIX_WW(b);
+EAPI void
+eina_matrix3_array_set(Eina_Matrix3 *m, const double *v)
+{
+   memcpy(&MATRIX_XX(m), v, sizeof(double) * 9);
+}
 
-   MATRIX_WX(out) =
-       MATRIX_WX(a) * MATRIX_XX(b)
-     + MATRIX_WY(a) * MATRIX_YX(b)
-     + MATRIX_WZ(a) * MATRIX_ZX(b)
-     + MATRIX_WW(a) * MATRIX_WX(b);
+EAPI void
+eina_matrix3_copy(Eina_Matrix3 *dst, const Eina_Matrix3 *src)
+{
+   memcpy(dst, src, sizeof(Eina_Matrix3));
+}
 
-   MATRIX_WY(out) =
-       MATRIX_WX(a) * MATRIX_XY(b)
-     + MATRIX_WY(a) * MATRIX_YY(b)
-     + MATRIX_WZ(a) * MATRIX_ZY(b)
-     + MATRIX_WW(a) * MATRIX_WY(b);
+EAPI void
+eina_matrix3_multiply(Eina_Matrix3 *out, const Eina_Matrix3 *mat_a, const Eina_Matrix3 *mat_b)
+{
+   if (eina_matrix3_type_get(mat_a) == EINA_MATRIX_TYPE_IDENTITY)
+     {
+        eina_matrix3_copy(out, mat_b);
+        return;
+     }
 
-   MATRIX_WZ(out) =
-       MATRIX_WX(a) * MATRIX_XZ(b)
-     + MATRIX_WY(a) * MATRIX_YZ(b)
-     + MATRIX_WZ(a) * MATRIX_ZZ(b)
-     + MATRIX_WW(a) * MATRIX_WZ(b);
+   if (eina_matrix3_type_get(mat_b) == EINA_MATRIX_TYPE_IDENTITY)
+     {
+        eina_matrix3_copy(out, mat_a);
+        return;
+     }
 
-   MATRIX_WW(out) =
-       MATRIX_WX(a) * MATRIX_XW(b)
-     + MATRIX_WY(a) * MATRIX_YW(b)
-     + MATRIX_WZ(a) * MATRIX_ZW(b)
-     + MATRIX_WW(a) * MATRIX_WW(b);
+   MATRIX_XX(out) = MATRIX_XX(mat_b) * MATRIX_XX(mat_a) + MATRIX_YX(mat_b) * MATRIX_XY(mat_a) + MATRIX_ZX(mat_b) * MATRIX_XZ(mat_a);
+   MATRIX_XY(out) = MATRIX_XY(mat_b) * MATRIX_XX(mat_a) + MATRIX_YY(mat_b) * MATRIX_XY(mat_a) + MATRIX_ZY(mat_b) * MATRIX_XZ(mat_a);
+   MATRIX_XZ(out) = MATRIX_XZ(mat_b) * MATRIX_XX(mat_a) + MATRIX_YZ(mat_b) * MATRIX_XY(mat_a) + MATRIX_ZZ(mat_b) * MATRIX_XZ(mat_a);
+
+   MATRIX_YX(out) = MATRIX_XX(mat_b) * MATRIX_YX(mat_a) + MATRIX_YX(mat_b) * MATRIX_YY(mat_a) + MATRIX_ZX(mat_b) * MATRIX_YZ(mat_a);
+   MATRIX_YY(out) = MATRIX_XY(mat_b) * MATRIX_YX(mat_a) + MATRIX_YY(mat_b) * MATRIX_YY(mat_a) + MATRIX_ZY(mat_b) * MATRIX_YZ(mat_a);
+   MATRIX_YZ(out) = MATRIX_XZ(mat_b) * MATRIX_YX(mat_a) + MATRIX_YZ(mat_b) * MATRIX_YY(mat_a) + MATRIX_ZZ(mat_b) * MATRIX_YZ(mat_a);
+
+   MATRIX_ZX(out) = MATRIX_XX(mat_b) * MATRIX_ZX(mat_a) + MATRIX_YX(mat_b) * MATRIX_ZY(mat_a) + MATRIX_ZX(mat_b) * MATRIX_ZZ(mat_a);
+   MATRIX_ZY(out) = MATRIX_XY(mat_b) * MATRIX_ZX(mat_a) + MATRIX_YY(mat_b) * MATRIX_ZY(mat_a) + MATRIX_ZY(mat_b) * MATRIX_ZZ(mat_a);
+   MATRIX_ZZ(out) = MATRIX_XZ(mat_b) * MATRIX_ZX(mat_a) + MATRIX_YZ(mat_b) * MATRIX_ZY(mat_a) + MATRIX_ZZ(mat_b) * MATRIX_ZZ(mat_a);
 }
 
 EAPI void
-eina_matrix4_identity(Eina_Matrix4 *out)
+eina_matrix3_multiply_copy(Eina_Matrix3 *out, const Eina_Matrix3 *mat_a, const Eina_Matrix3 *mat_b)
 {
-   memset(out, 0, sizeof (Eina_Matrix4));
-   MATRIX_XX(out) = 1;
-   MATRIX_YY(out) = 1;
-   MATRIX_ZZ(out) = 1;
-   MATRIX_WW(out) = 1;
+   if (out != mat_a && out != mat_b)
+     {
+        eina_matrix3_multiply(out, mat_a, mat_b);
+     }
+   else
+     {
+        Eina_Matrix3 tmp;
+
+        eina_matrix3_multiply(&tmp, mat_a, mat_b);
+        eina_matrix3_copy(out, &tmp);
+     }
+}
+
+EAPI void
+eina_matrix3_position_transform_set(Eina_Matrix3 *out, const double p_x,
+                                                                const double p_y)
+{
+   eina_matrix3_identity(out);
+   MATRIX_XZ(out) = p_x;
+   MATRIX_YZ(out) = p_y;
+}
+
+EAPI void
+eina_matrix3_scale_transform_set(Eina_Matrix3 *out, double s_x, double s_y)
+{
+   eina_matrix3_identity(out);
+   MATRIX_XX(out) = s_x;
+   MATRIX_YY(out) = s_y;
+}
+
+EAPI void
+eina_normal3_matrix_get(Eina_Matrix3 *out, const Eina_Matrix4 *m)
+{
+   /* Normal matrix is a transposed matrix of inversed modelview.
+    * And we need only upper-left 3x3 terms to work with. */
+
+   double   det;
+
+   double   a = MATRIX_XX(m);
+   double   b = MATRIX_YX(m);
+   double   c = MATRIX_ZX(m);
+
+   double   d = MATRIX_XY(m);
+   double   e = MATRIX_YY(m);
+   double   f = MATRIX_ZY(m);
+
+   double   g = MATRIX_XZ(m);
+   double   h = MATRIX_YZ(m);
+   double   i = MATRIX_ZZ(m);
+
+   det = a * e * i + b * f * g + c * d * h - g * e * c - h * f * a - i * d * b;
+
+   if (fabs(det) >= DBL_EPSILON) det = 1.0 / det;
+   else det = 0.0;
+
+   MATRIX_XX(out) = (e * i - f * h) * det;
+   MATRIX_XY(out) = (h * c - i * b) * det;
+   MATRIX_XZ(out) = (b * f - c * e) * det;
+
+   MATRIX_YX(out) = (g * f - d * i) * det;
+   MATRIX_YY(out) = (a * i - g * c) * det;
+   MATRIX_YZ(out) = (d * c - a * f) * det;
+
+   MATRIX_ZX(out) = (d * h - g * e) * det;
+   MATRIX_ZY(out) = (g * b - a * h) * det;
+   MATRIX_ZZ(out) = (a * e - d * b) * det;
+}
+
+EAPI void
+eina_matrix2_values_set(Eina_Matrix2 *m,
+                        double xx, double xy,
+                        double yx, double yy)
+{
+   MATRIX_XX(m) = xx;
+   MATRIX_XY(m) = xy;
+   MATRIX_YX(m) = yx;
+   MATRIX_YY(m) = yy;
+}
+
+EAPI void
+eina_matrix2_values_get(const Eina_Matrix2 *m,
+                        double *xx, double *xy,
+                        double *yx, double *yy)
+{
+   if (xx) *xx = MATRIX_XX(m);
+   if (xy) *xy = MATRIX_XY(m);
+   if (yx) *yx = MATRIX_YX(m);
+   if (yy) *yy = MATRIX_YY(m);
+}
+
+EAPI void
+eina_matrix2_inverse(Eina_Matrix2 *out, const Eina_Matrix2 *mat)
+{
+   double         det;
+
+   if (eina_matrix2_type_get(mat) == EINA_MATRIX_TYPE_IDENTITY)
+     {
+        eina_matrix2_copy(out, mat);
+        return;
+     }
+
+   det = MATRIX_XX(mat) * MATRIX_YY(mat) - MATRIX_YX(mat) * MATRIX_XY(mat);
+
+   if (det == 0.0)
+     return;
+
+   det = 1.0 / det;
+
+   MATRIX_XX(out) =  MATRIX_YY(mat) * det;
+   MATRIX_XY(out) = -MATRIX_XY(mat) * det;
+   MATRIX_YX(out) = -MATRIX_YX(mat) * det;
+   MATRIX_YY(out) =  MATRIX_XX(mat) * det;
+}
+
+EAPI void
+eina_matrix2_identity(Eina_Matrix2 *m)
+{
+   MATRIX_XX(m) = 1.0;
+   MATRIX_XY(m) = 0.0;
+
+   MATRIX_YX(m) = 0.0;
+   MATRIX_YY(m) = 1.0;
+}
+
+EAPI void
+eina_matrix2_array_set(Eina_Matrix2 *m, const double *v)
+{
+   memcpy(&MATRIX_XX(m), v, sizeof(double) * 4);
+}
+
+EAPI void
+eina_matrix2_copy(Eina_Matrix2 *dst, const Eina_Matrix2 *src)
+{
+   memcpy(dst, src, sizeof(Eina_Matrix2));
+}
+
+EAPI void
+eina_matrix2_multiply(Eina_Matrix2 *out, const Eina_Matrix2 *mat_a, const Eina_Matrix2 *mat_b)
+{
+   if (eina_matrix2_type_get(mat_a) == EINA_MATRIX_TYPE_IDENTITY)
+     {
+        eina_matrix2_copy(out, mat_b);
+        return;
+     }
+
+   if (eina_matrix2_type_get(mat_b) == EINA_MATRIX_TYPE_IDENTITY)
+     {
+        eina_matrix2_copy(out, mat_a);
+        return;
+     }
+
+   MATRIX_XX(out) = MATRIX_XX(mat_a) * MATRIX_XX(mat_b) + MATRIX_YX(mat_a) * MATRIX_XY(mat_b);
+   MATRIX_YX(out) = MATRIX_XX(mat_a) * MATRIX_YX(mat_b) + MATRIX_YX(mat_a) * MATRIX_YY(mat_b);
+
+   MATRIX_XY(out) = MATRIX_XY(mat_a) * MATRIX_XX(mat_b) + MATRIX_YY(mat_a) * MATRIX_XY(mat_b);
+   MATRIX_YY(out) = MATRIX_XY(mat_a) * MATRIX_YX(mat_b) + MATRIX_YY(mat_a) * MATRIX_YY(mat_b);
+}
+
+EAPI void
+eina_matrix2_multiply_copy(Eina_Matrix2 *out, const Eina_Matrix2 *mat_a, const Eina_Matrix2 *mat_b)
+{
+   if (out != mat_a && out != mat_b)
+     {
+        eina_matrix2_multiply(out, mat_a, mat_b);
+     }
+   else
+     {
+        Eina_Matrix2 tmp;
+
+        eina_matrix2_multiply(&tmp, mat_a, mat_b);
+        eina_matrix2_copy(out, &tmp);
+     }
 }
index 0558c98..14dcd8e 100644 (file)
@@ -429,6 +429,23 @@ struct _Eina_Matrix4
 };
 
 /**
+ * @}
+ * @defgroup Eina_Matrix2 Matrices in floating point
+ * @ingroup Eina_Basic
+ * @brief Matrix definition and operations
+ * @{
+ */
+
+typedef struct _Eina_Matrix2 Eina_Matrix2;
+struct _Eina_Matrix2
+{
+   double xx;
+   double xy;
+
+   double yx;
+   double yy;
+};
+/**
  * @brief Return the type of the given floating point matrix.
  *
  * @param m The floating point matrix.
@@ -597,11 +614,265 @@ EAPI void eina_matrix4_identity(Eina_Matrix4 *out);
  * @param a The first member of the multiplication
  * @param b The second member of the multiplication
  *
+ * @since 1.17
+ */
+EAPI void eina_matrix4_multiply_copy(Eina_Matrix4 *out,
+                                     const Eina_Matrix4 *mat_a, const Eina_Matrix4 *mat_b);
+
+/**
+ * @brief Set array to matrix.
+ *
+ * @param m The result matrix
+ * @param v The the array[16] for set
+ *
+ * Set to matrix first 16 elements from array
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix4_array_set(Eina_Matrix4 *m, const double *v);
+
+/**
+ * @brief Copy matrix.
+ *
+ * @param dst The matrix copy
+ * @param src The matrix for copy.
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix4_copy(Eina_Matrix4 *dst, const Eina_Matrix4 *src);
+
+/**
+ * @brief Multiply two matrix with check
+ *
+ * @param out The resulting matrix
+ * @param a The first member of the multiplication
+ * @param b The second member of the multiplication
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix4_multiply(Eina_Matrix4 *out, const Eina_Matrix4 *mat_a,
+                                const Eina_Matrix4 *mat_b);
+
+/**
+ * @brief Set orthogonality matrix
+ *
+ * @param m The resulting matrix
+ * @param right The right value
+ * @param left The left value
+ * @param bottom The bottom value
+ * @param top The top value
+ * @param dneat The dnear value
+ * @param dfar The dfar value
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix4_ortho_set(Eina_Matrix4 *m,
+                                 double left, double right, double bottom, double top,
+                                 double dnear, double dfar);
+
+/**
+ * @brief Set array to matrix.
+ *
+ * @param m The result matrix
+ * @param v The the array[9] for set
+ *
+ * Set to matrix first 9 elements from array
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix3_array_set(Eina_Matrix3 *m, const double *v);
+
+/**
+ * @brief Copy matrix.
+ *
+ * @param dst The matrix copy
+ * @param src The matrix for copy.
+ *
  * @since 1.16
  */
-EAPI void eina_matrix4_multiply(Eina_Matrix4 *out,
-                                const Eina_Matrix4 *a, const Eina_Matrix4 *b);
+EAPI void eina_matrix3_copy(Eina_Matrix3 *dst, const Eina_Matrix3 *src);
+
+/*
+ * @brief Multiply two matrix
+ *
+ * @param out The resulting matrix
+ * @param a The first member of the multiplication
+ * @param b The second member of the multiplication
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix3_multiply(Eina_Matrix3 *out, const Eina_Matrix3 *mat_a,
+                                const Eina_Matrix3 *mat_b);
+
+/**
+ * @brief Multiply two matrix
+ *
+ * @param out The resulting matrix
+ * @param a The first member of the multiplication
+ * @param b The second member of the multiplication
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix3_multiply_copy(Eina_Matrix3 *out, const Eina_Matrix3 *mat_a,
+                                     const Eina_Matrix3 *mat_b);
+
+/**
+ * @brief Transform scale of matrix
+ *
+ * @param out The resulting matrix
+ * @param s_x The scale value for x
+ * @param s_y The scale value for y
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix3_scale_transform_set(Eina_Matrix3 *out, double s_x, double s_y);
+
+/**
+ * @brief Transform position of matrix
+ *
+ * @param out The resulting matrix
+ * @param p_x The position value for x
+ * @param p_y The position value for y
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix3_position_transform_set(Eina_Matrix3 *out, const double p_x,
+                                              const double p_y);
+
+/**
+ * @brief Set normal of the given matrix.
+ *
+ * @param out The result mtrix of normal
+ * @param m The matrix
+ *
+ * @since 1.17
+ */
+EAPI void eina_normal3_matrix_get(Eina_Matrix3 *out, const Eina_Matrix4 *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 yx The fourth coefficient value.
+ * @param yy The fifth coefficient value.
+ *
+ * This function sets the values of the coefficients of the matrix
+ * @p m. No check is done on @p m.
+ *
+ * @see eina_matrix2_values_get()
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix2_values_set(Eina_Matrix2 *m, double xx, double xy,
+                    double yx, double yy);
 
+/**
+ * @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 yx The fourth coefficient value.
+ * @param yy The fifth coefficient value.
+ *
+ * This function gets the values of the coefficients of the matrix
+ * @p m. No check is done on @p m.
+ *
+ * @see eina_matrix2_values_set()
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix2_values_get(const Eina_Matrix2 *m, double *xx, double *xy,
+                    double *yx, double *yy);
+
+/**
+ * @brief Compute the inverse with check 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.
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix2_inverse(Eina_Matrix2 *out, const Eina_Matrix2 *mat);
+
+/**
+ * @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.
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix2_identity(Eina_Matrix2 *m);
+
+/**
+ * @brief Set array to matrix.
+ *
+ * @param m The rsult matrix
+ * @param v The the array[4] for set
+ *
+ * Set to matrix first 4 elements from array
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix2_array_set(Eina_Matrix2 *m, const double *v);
+
+/**
+ * @brief Copy matrix.
+ *
+ * @param dst The matrix copy
+ * @param src The matrix for copy.
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix2_copy(Eina_Matrix2 *dst, const Eina_Matrix2 *src);
+
+/**
+ * @brief Multiply two matrix
+ *
+ * @param out The resulting matrix
+ * @param a The first member of the multiplication
+ * @param b The second member of the multiplication
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix2_multiply(Eina_Matrix2 *out, const Eina_Matrix2 *mat_a,
+                                const Eina_Matrix2 *mat_b);
+
+/**
+ * @brief Multiply two matrix with check
+ *
+ * @param out The resulting matrix
+ * @param a The first member of the multiplication
+ * @param b The second member of the multiplication
+ *
+ * @since 1.17
+ */
+EAPI void eina_matrix2_multiply_copy(Eina_Matrix2 *out, const Eina_Matrix2 *mat_a,
+                    const Eina_Matrix2 *mat_b);
+
+/**
+ * @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.
+ *
+ * @since 1.17
+ */
+EAPI Eina_Matrix_Type eina_matrix2_type_get(const Eina_Matrix2 *m);
 
 /**
  * @}