[gtk/transform-work: 2/4] gsk: Add skew transforms
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/transform-work: 2/4] gsk: Add skew transforms
- Date: Sat, 18 Sep 2021 06:08:57 +0000 (UTC)
commit 1289e68931529a23f45fbd4cc4ffc466b7e42522
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Sep 17 22:01:55 2021 -0400
gsk: Add skew transforms
Add gsk_transform_skew() to make our transform
api more complete wrt to what you would expect
for a graphics api.
gsk/gsktransform.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++------
gsk/gsktransform.h | 4 ++
2 files changed, 179 insertions(+), 20 deletions(-)
---
diff --git a/gsk/gsktransform.c b/gsk/gsktransform.c
index 72ac91caf2..cc30f567d9 100644
--- a/gsk/gsktransform.c
+++ b/gsk/gsktransform.c
@@ -1005,7 +1005,178 @@ gsk_transform_rotate_3d (GskTransform *next,
}
/* }}} */
-/* {{{ SCALE */
+/* {{{ SKEW */
+
+typedef struct _GskSkewTransform GskSkewTransform;
+
+struct _GskSkewTransform
+{
+ GskTransform parent;
+
+ float skew_x;
+ float skew_y;
+};
+
+static void
+gsk_skew_transform_finalize (GskTransform *self)
+{
+}
+
+static void
+gsk_skew_transform_to_matrix (GskTransform *transform,
+ graphene_matrix_t *out_matrix)
+{
+ GskSkewTransform *self = (GskSkewTransform *) transform;
+
+ graphene_matrix_init_skew (out_matrix,
+ self->skew_x / 180.0 * G_PI,
+ self->skew_y / 180.0 * G_PI);
+}
+
+static void
+gsk_skew_transform_apply_2d (GskTransform *transform,
+ float *out_xx,
+ float *out_yx,
+ float *out_xy,
+ float *out_yy,
+ float *out_dx,
+ float *out_dy)
+{
+ graphene_matrix_t sm, mat;
+
+ gsk_skew_transform_to_matrix (transform, &sm);
+ graphene_matrix_init_from_2d (&mat, *out_xx, *out_yx,
+ *out_xy, *out_yy,
+ *out_dx, *out_dy);
+
+ graphene_matrix_multiply (&sm, &mat, &mat);
+
+ *out_xx = graphene_matrix_get_value (&mat, 0, 0);
+ *out_yx = graphene_matrix_get_value (&mat, 0, 1);
+ *out_xy = graphene_matrix_get_value (&mat, 1, 0);
+ *out_yy = graphene_matrix_get_value (&mat, 1, 1);
+ *out_dx = graphene_matrix_get_value (&mat, 3, 0);
+ *out_dy = graphene_matrix_get_value (&mat, 3, 1);
+}
+
+static GskTransform *
+gsk_skew_transform_apply (GskTransform *transform,
+ GskTransform *apply_to)
+{
+ GskSkewTransform *self = (GskSkewTransform *) transform;
+
+ return gsk_transform_skew (apply_to, self->skew_x, self->skew_y);
+}
+
+static void
+gsk_skew_transform_print (GskTransform *transform,
+ GString *string)
+{
+ GskSkewTransform *self = (GskSkewTransform *) transform;
+
+ if (self->skew_y == 0)
+ {
+ g_string_append (string, "skewX(");
+ string_append_double (string, self->skew_x);
+ g_string_append (string, ")");
+ }
+ else if (self->skew_x == 0)
+ {
+ g_string_append (string, "skewY(");
+ string_append_double (string, self->skew_y);
+ g_string_append (string, ")");
+ }
+ else
+ {
+ g_string_append (string, "skew(");
+ string_append_double (string, self->skew_x);
+ g_string_append (string, ", ");
+ string_append_double (string, self->skew_y);
+ g_string_append (string, ")");
+ }
+}
+
+static GskTransform *
+gsk_skew_transform_invert (GskTransform *transform,
+ GskTransform *next)
+{
+ GskSkewTransform *self = (GskSkewTransform *) transform;
+ float tx, ty;
+ graphene_matrix_t matrix;
+
+ tx = tanf (self->skew_x / 180.0 * G_PI);
+ ty = tanf (self->skew_y / 180.0 * G_PI);
+
+ graphene_matrix_init_from_2d (&matrix,
+ 1 / (1 - tx * ty),
+ - ty / (1 - tx * ty),
+ - tx / (1 - tx * ty),
+ 1 / (1 - tx * ty),
+ 0, 0);
+ return gsk_transform_matrix_with_category (next,
+ &matrix,
+ GSK_TRANSFORM_CATEGORY_2D);
+}
+
+static gboolean
+gsk_skew_transform_equal (GskTransform *first_transform,
+ GskTransform *second_transform)
+{
+ GskSkewTransform *first = (GskSkewTransform *) first_transform;
+ GskSkewTransform *second = (GskSkewTransform *) second_transform;
+
+ return G_APPROX_VALUE (first->skew_x, second->skew_x, FLT_EPSILON) &&
+ G_APPROX_VALUE (first->skew_y, second->skew_y, FLT_EPSILON);
+}
+
+static const GskTransformClass GSK_SKEW_TRANSFORM_CLASS =
+{
+ sizeof (GskSkewTransform),
+ "GskSkewTransform",
+ gsk_skew_transform_finalize,
+ gsk_skew_transform_to_matrix,
+ gsk_skew_transform_apply_2d,
+ NULL,
+ NULL,
+ gsk_skew_transform_print,
+ gsk_skew_transform_apply,
+ gsk_skew_transform_invert,
+ gsk_skew_transform_equal,
+};
+
+/**
+ * gsk_transform_skew:
+ * @next: (nullable) (transfer full): the next transform
+ * @skew_x: skew factor, in degrees, on the X axis
+ * @skew_y: skew factor, in degrees, on the Y axis
+ *
+ * Applies a skew transform.
+ *
+ * Returns: The new transform
+ *
+ * Since: 4.6
+ */
+GskTransform *
+gsk_transform_skew (GskTransform *next,
+ float skew_x,
+ float skew_y)
+{
+ GskSkewTransform *result;
+
+ if (skew_x == 0 && skew_y == 0)
+ return next;
+
+ result = gsk_transform_alloc (&GSK_SKEW_TRANSFORM_CLASS,
+ GSK_TRANSFORM_CATEGORY_2D,
+ next);
+
+ result->skew_x = skew_x;
+ result->skew_y = skew_y;
+
+ return &result->parent;
+}
+/* }}} */
+/* {{{ SCALE */
typedef struct _GskScaleTransform GskScaleTransform;
@@ -2057,40 +2228,24 @@ gsk_transform_parser_parse (GtkCssParser *parser,
}
else if (gtk_css_token_is_function (token, "skew"))
{
- graphene_matrix_t matrix;
-
if (!gtk_css_parser_consume_function (parser, 2, 2, gsk_transform_parse_float, f))
goto fail;
- f[0] = f[0] / 180.0 * G_PI;
- f[1] = f[1] / 180.0 * G_PI;
-
- graphene_matrix_init_skew (&matrix, f[0], f[1]);
- transform = gsk_transform_matrix (transform, &matrix);
+ transform = gsk_transform_skew (transform, f[0], f[1]);
}
else if (gtk_css_token_is_function (token, "skewX"))
{
- graphene_matrix_t matrix;
-
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
- f[0] = f[0] / 180.0 * G_PI;
-
- graphene_matrix_init_skew (&matrix, f[0], 0);
- transform = gsk_transform_matrix (transform, &matrix);
+ transform = gsk_transform_skew (transform, f[0], 0);
}
else if (gtk_css_token_is_function (token, "skewY"))
{
- graphene_matrix_t matrix;
-
if (!gtk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
- f[0] = f[0] / 180.0 * G_PI;
-
- graphene_matrix_init_skew (&matrix, 0, f[0]);
- transform = gsk_transform_matrix (transform, &matrix);
+ transform = gsk_transform_skew (transform, 0, f[0]);
}
else
{
diff --git a/gsk/gsktransform.h b/gsk/gsktransform.h
index f3676bca63..a580547331 100644
--- a/gsk/gsktransform.h
+++ b/gsk/gsktransform.h
@@ -92,6 +92,10 @@ GskTransform * gsk_transform_translate (GskTransform
GDK_AVAILABLE_IN_ALL
GskTransform * gsk_transform_translate_3d (GskTransform *next,
const graphene_point3d_t *point)
G_GNUC_WARN_UNUSED_RESULT;
+GDK_AVAILABLE_IN_4_6
+GskTransform * gsk_transform_skew (GskTransform *next,
+ float skew_x,
+ float skew_y)
G_GNUC_WARN_UNUSED_RESULT;
GDK_AVAILABLE_IN_ALL
GskTransform * gsk_transform_rotate (GskTransform *next,
float angle)
G_GNUC_WARN_UNUSED_RESULT;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]