mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-09 10:20:07 +00:00
transform: Add gsk_transform_to_dihedral()
I hate everything about this. Is is xy or yx now? Do I need to combine(a, b) or combine(b, a)?
This commit is contained in:
parent
4cfcc7e521
commit
3bcfc5539c
61
gdk/gdkdihedral.c
Normal file
61
gdk/gdkdihedral.c
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdihedralprivate.h"
|
||||
|
||||
void
|
||||
gdk_dihedral_get_mat2 (GdkDihedral transform,
|
||||
float *xx,
|
||||
float *xy,
|
||||
float *yx,
|
||||
float *yy)
|
||||
{
|
||||
const float mat[8][2][2] = {
|
||||
[GDK_DIHEDRAL_NORMAL] = {
|
||||
{ 1.0, 0.0 },
|
||||
{ 0.0, 1.0 }
|
||||
},
|
||||
[GDK_DIHEDRAL_90] = {
|
||||
{ 0.0, 1.0 },
|
||||
{ -1.0, 0.0 }
|
||||
},
|
||||
[GDK_DIHEDRAL_180] = {
|
||||
{ -1.0, 0.0 },
|
||||
{ 0.0, -1.0 }
|
||||
},
|
||||
[GDK_DIHEDRAL_270] = {
|
||||
{ 0.0, -1.0 },
|
||||
{ 1.0, 0.0 }
|
||||
},
|
||||
[GDK_DIHEDRAL_FLIPPED] = {
|
||||
{ -1.0, 0.0 },
|
||||
{ 0.0, 1.0 }
|
||||
},
|
||||
[GDK_DIHEDRAL_FLIPPED_90] = {
|
||||
{ 0.0, -1.0 },
|
||||
{ -1.0, 0.0 }
|
||||
},
|
||||
[GDK_DIHEDRAL_FLIPPED_180] = {
|
||||
{ 1.0, 0.0 },
|
||||
{ 0.0, -1.0 }
|
||||
},
|
||||
[GDK_DIHEDRAL_FLIPPED_270] = {
|
||||
{ 0.0, 1.0 },
|
||||
{ 1.0, 0.0 }
|
||||
},
|
||||
};
|
||||
|
||||
*xx = mat[transform][0][0];
|
||||
*xy = mat[transform][1][0];
|
||||
*yx = mat[transform][0][1];
|
||||
*yy = mat[transform][1][1];
|
||||
}
|
||||
|
||||
GdkDihedral
|
||||
gdk_dihedral_combine (GdkDihedral first,
|
||||
GdkDihedral second)
|
||||
{
|
||||
return ((first & 4) ^ (second & 4)) |
|
||||
((((first & 3) * (((second & 4) >> 1) + 1)) + second) & 3);
|
||||
}
|
||||
|
@ -32,5 +32,14 @@ typedef enum {
|
||||
GDK_DIHEDRAL_FLIPPED_270,
|
||||
} GdkDihedral;
|
||||
|
||||
void gdk_dihedral_get_mat2 (GdkDihedral transform,
|
||||
float *xx,
|
||||
float *xy,
|
||||
float *yx,
|
||||
float *yy);
|
||||
|
||||
GdkDihedral gdk_dihedral_combine (GdkDihedral first,
|
||||
GdkDihedral second);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -15,6 +15,7 @@ gdk_public_sources = files([
|
||||
'gdkdevice.c',
|
||||
'gdkdevicepad.c',
|
||||
'gdkdevicetool.c',
|
||||
'gdkdihedral.c',
|
||||
'gdkdisplay.c',
|
||||
'gdkdisplaymanager.c',
|
||||
'gdkdmabuf.c',
|
||||
|
@ -53,6 +53,12 @@ struct _GskTransformClass
|
||||
float *out_yy,
|
||||
float *out_dx,
|
||||
float *out_dy);
|
||||
void (* apply_dihedral) (GskTransform *transform,
|
||||
GdkDihedral *dihedral,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y,
|
||||
float *out_dx,
|
||||
float *out_dy);
|
||||
void (* apply_affine) (GskTransform *transform,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y,
|
||||
@ -72,7 +78,6 @@ struct _GskTransformClass
|
||||
GskTransform *second_transform);
|
||||
};
|
||||
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GskTransform, gsk_transform,
|
||||
gsk_transform_ref,
|
||||
gsk_transform_unref)
|
||||
@ -155,6 +160,16 @@ gsk_identity_transform_apply_2d (GskTransform *transform,
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_identity_transform_apply_dihedral (GskTransform *transform,
|
||||
GdkDihedral *dihedral,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y,
|
||||
float *out_dx,
|
||||
float *out_dy)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_identity_transform_apply_affine (GskTransform *transform,
|
||||
float *out_scale_x,
|
||||
@ -218,6 +233,7 @@ static const GskTransformClass GSK_IDENTITY_TRANSFORM_CLASS =
|
||||
gsk_identity_transform_finalize,
|
||||
gsk_identity_transform_to_matrix,
|
||||
gsk_identity_transform_apply_2d,
|
||||
gsk_identity_transform_apply_dihedral,
|
||||
gsk_identity_transform_apply_affine,
|
||||
gsk_identity_transform_apply_translate,
|
||||
gsk_identity_transform_print,
|
||||
@ -300,6 +316,45 @@ gsk_matrix_transform_apply_2d (GskTransform *transform,
|
||||
*out_dy = graphene_matrix_get_value (&mat, 3, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_matrix_transform_apply_dihedral (GskTransform *transform,
|
||||
GdkDihedral *out_dihedral,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y,
|
||||
float *out_dx,
|
||||
float *out_dy)
|
||||
{
|
||||
GskMatrixTransform *self = (GskMatrixTransform *) transform;
|
||||
|
||||
switch (transform->category)
|
||||
{
|
||||
case GSK_FINE_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
case GSK_FINE_TRANSFORM_CATEGORY_ANY:
|
||||
case GSK_FINE_TRANSFORM_CATEGORY_3D:
|
||||
case GSK_FINE_TRANSFORM_CATEGORY_2D:
|
||||
case GSK_FINE_TRANSFORM_CATEGORY_2D_DIHEDRAL:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
||||
case GSK_FINE_TRANSFORM_CATEGORY_2D_NEGATIVE_AFFINE:
|
||||
case GSK_FINE_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_x_translation (&self->matrix);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_y_translation (&self->matrix);
|
||||
*out_scale_x *= graphene_matrix_get_x_scale (&self->matrix);
|
||||
*out_scale_y *= graphene_matrix_get_y_scale (&self->matrix);
|
||||
break;
|
||||
|
||||
case GSK_FINE_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
*out_dx += *out_scale_x * graphene_matrix_get_x_translation (&self->matrix);
|
||||
*out_dy += *out_scale_y * graphene_matrix_get_y_translation (&self->matrix);
|
||||
break;
|
||||
|
||||
case GSK_FINE_TRANSFORM_CATEGORY_IDENTITY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_matrix_transform_apply_affine (GskTransform *transform,
|
||||
float *out_scale_x,
|
||||
@ -466,6 +521,7 @@ static const GskTransformClass GSK_TRANSFORM_TRANSFORM_CLASS =
|
||||
gsk_matrix_transform_finalize,
|
||||
gsk_matrix_transform_to_matrix,
|
||||
gsk_matrix_transform_apply_2d,
|
||||
gsk_matrix_transform_apply_dihedral,
|
||||
gsk_matrix_transform_apply_affine,
|
||||
gsk_matrix_transform_apply_translate,
|
||||
gsk_matrix_transform_print,
|
||||
@ -481,6 +537,9 @@ gsk_transform_matrix_with_category (GskTransform *next,
|
||||
{
|
||||
GskMatrixTransform *result = gsk_transform_alloc (&GSK_TRANSFORM_TRANSFORM_CLASS, category, next);
|
||||
|
||||
/* We can't deal with these yet - also because lots of code gets transposing wrong */
|
||||
g_assert (category != GSK_FINE_TRANSFORM_CATEGORY_2D_DIHEDRAL);
|
||||
|
||||
graphene_matrix_init_from_matrix (&result->matrix, matrix);
|
||||
|
||||
return &result->parent;
|
||||
@ -548,6 +607,25 @@ gsk_translate_transform_apply_2d (GskTransform *transform,
|
||||
*out_dy += *out_yx * self->point.x + *out_yy * self->point.y;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_translate_transform_apply_dihedral (GskTransform *transform,
|
||||
GdkDihedral *out_dihedral,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y,
|
||||
float *out_dx,
|
||||
float *out_dy)
|
||||
{
|
||||
GskTranslateTransform *self = (GskTranslateTransform *) transform;
|
||||
float xx, xy, yx, yy;
|
||||
|
||||
g_assert (self->point.z == 0.0);
|
||||
|
||||
gdk_dihedral_get_mat2 (*out_dihedral, &xx, &xy, &yx, &yy);
|
||||
|
||||
*out_dx += *out_scale_x * (xx * self->point.x + xy * self->point.y);
|
||||
*out_dy += *out_scale_y * (yx * self->point.x + yy * self->point.y);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_translate_transform_apply_affine (GskTransform *transform,
|
||||
float *out_scale_x,
|
||||
@ -635,6 +713,7 @@ static const GskTransformClass GSK_TRANSLATE_TRANSFORM_CLASS =
|
||||
gsk_translate_transform_finalize,
|
||||
gsk_translate_transform_to_matrix,
|
||||
gsk_translate_transform_apply_2d,
|
||||
gsk_translate_transform_apply_dihedral,
|
||||
gsk_translate_transform_apply_affine,
|
||||
gsk_translate_transform_apply_translate,
|
||||
gsk_translate_transform_print,
|
||||
@ -804,6 +883,23 @@ gsk_rotate_transform_apply_2d (GskTransform *transform,
|
||||
*out_yy = yy;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_rotate_transform_apply_dihedral (GskTransform *transform,
|
||||
GdkDihedral *out_dihedral,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y,
|
||||
float *out_dx,
|
||||
float *out_dy)
|
||||
{
|
||||
GskRotateTransform *self = (GskRotateTransform *) transform;
|
||||
GdkDihedral dihedral;
|
||||
|
||||
dihedral = (int) self->angle / 90;
|
||||
g_assert (dihedral >= GDK_DIHEDRAL_NORMAL && dihedral < GDK_DIHEDRAL_FLIPPED);
|
||||
|
||||
*out_dihedral = gdk_dihedral_combine (dihedral, *out_dihedral);
|
||||
}
|
||||
|
||||
static GskTransform *
|
||||
gsk_rotate_transform_apply (GskTransform *transform,
|
||||
GskTransform *apply_to)
|
||||
@ -850,6 +946,7 @@ static const GskTransformClass GSK_ROTATE_TRANSFORM_CLASS =
|
||||
gsk_rotate_transform_finalize,
|
||||
gsk_rotate_transform_to_matrix,
|
||||
gsk_rotate_transform_apply_2d,
|
||||
gsk_rotate_transform_apply_dihedral,
|
||||
NULL,
|
||||
NULL,
|
||||
gsk_rotate_transform_print,
|
||||
@ -1009,6 +1106,7 @@ static const GskTransformClass GSK_ROTATE3D_TRANSFORM_CLASS =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
gsk_rotate3d_transform_print,
|
||||
gsk_rotate3d_transform_apply,
|
||||
gsk_rotate3d_transform_invert,
|
||||
@ -1190,6 +1288,7 @@ static const GskTransformClass GSK_SKEW_TRANSFORM_CLASS =
|
||||
gsk_skew_transform_apply_2d,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
gsk_skew_transform_print,
|
||||
gsk_skew_transform_apply,
|
||||
gsk_skew_transform_invert,
|
||||
@ -1277,6 +1376,41 @@ gsk_scale_transform_apply_2d (GskTransform *transform,
|
||||
*out_yy *= self->factor_y;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_scale_transform_apply_dihedral (GskTransform *transform,
|
||||
GdkDihedral *out_dihedral,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y,
|
||||
float *out_dx,
|
||||
float *out_dy)
|
||||
{
|
||||
GskScaleTransform *self = (GskScaleTransform *) transform;
|
||||
GdkDihedral dihedral;
|
||||
float xx, xy, yx, yy;
|
||||
|
||||
g_assert (self->factor_z == 1.0);
|
||||
|
||||
gdk_dihedral_get_mat2 (*out_dihedral, &xx, &xy, &yx, &yy);
|
||||
|
||||
if (self->factor_x >= 0)
|
||||
{
|
||||
if (self->factor_y >= 0)
|
||||
dihedral = GDK_DIHEDRAL_NORMAL;
|
||||
else
|
||||
dihedral = GDK_DIHEDRAL_FLIPPED_180;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->factor_y >= 0)
|
||||
dihedral = GDK_DIHEDRAL_FLIPPED;
|
||||
else
|
||||
dihedral = GDK_DIHEDRAL_180;
|
||||
}
|
||||
*out_dihedral = gdk_dihedral_combine (dihedral, *out_dihedral);
|
||||
*out_scale_x *= fabs (xx * self->factor_x + xy * self->factor_y);
|
||||
*out_scale_y *= fabs (yx * self->factor_x + yy * self->factor_y);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_scale_transform_apply_affine (GskTransform *transform,
|
||||
float *out_scale_x,
|
||||
@ -1361,6 +1495,7 @@ static const GskTransformClass GSK_SCALE_TRANSFORM_CLASS =
|
||||
gsk_scale_transform_finalize,
|
||||
gsk_scale_transform_to_matrix,
|
||||
gsk_scale_transform_apply_2d,
|
||||
gsk_scale_transform_apply_dihedral,
|
||||
gsk_scale_transform_apply_affine,
|
||||
NULL,
|
||||
gsk_scale_transform_print,
|
||||
@ -1526,6 +1661,7 @@ static const GskTransformClass GSK_PERSPECTIVE_TRANSFORM_CLASS =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
gsk_perspective_transform_print,
|
||||
gsk_perspective_transform_apply,
|
||||
gsk_perspective_transform_invert,
|
||||
@ -1909,6 +2045,66 @@ gsk_transform_to_affine (GskTransform *self,
|
||||
out_dx, out_dy);
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gsk_transform_to_dihedral:
|
||||
* @self: a `GskTransform`
|
||||
* @out_dihedral: (out): return location for the
|
||||
* @out_scale_x: (out): return location for the scale
|
||||
* factor in the x direction
|
||||
* @out_scale_y: (out): return location for the scale
|
||||
* factor in the y direction
|
||||
* @out_dx: (out): return location for the translation
|
||||
* in the x direction
|
||||
* @out_dy: (out): return location for the translation
|
||||
* in the y direction
|
||||
*
|
||||
* Converts a `GskTransform` to 2D affine transformation factors.
|
||||
*
|
||||
* To recreate an equivalent transform from the factors returned
|
||||
* by this function, use
|
||||
*
|
||||
* gsk_transform_scale (gsk_transform_translate (NULL,
|
||||
* &GRAPHENE_POINT_T (dx, dy)),
|
||||
* sx, sy)
|
||||
*
|
||||
* @self must be a 2D affine transformation. If you are not
|
||||
* sure, use
|
||||
*
|
||||
* gsk_transform_get_category() >= %GSK_TRANSFORM_CATEGORY_2D_AFFINE
|
||||
*
|
||||
* to check.
|
||||
*/
|
||||
void
|
||||
gsk_transform_to_dihedral (GskTransform *self,
|
||||
GdkDihedral *out_dihedral,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y,
|
||||
float *out_dx,
|
||||
float *out_dy)
|
||||
{
|
||||
if (self == NULL)
|
||||
{
|
||||
*out_dihedral = GDK_DIHEDRAL_NORMAL;
|
||||
*out_scale_x = 1.0f;
|
||||
*out_scale_y = 1.0f;
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert (self->category >= GSK_FINE_TRANSFORM_CATEGORY_2D_DIHEDRAL);
|
||||
|
||||
gsk_transform_to_dihedral (self->next,
|
||||
out_dihedral,
|
||||
out_scale_x, out_scale_y,
|
||||
out_dx, out_dy);
|
||||
|
||||
self->transform_class->apply_dihedral (self,
|
||||
out_dihedral,
|
||||
out_scale_x, out_scale_y,
|
||||
out_dx, out_dy);
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_transform_to_translate:
|
||||
* @self: a `GskTransform`
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include <gtk/css/gtkcss.h>
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
|
||||
/* declares GdkDihedralTransform */
|
||||
#include "gdk/gdksubsurfaceprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskTransformClass GskTransformClass;
|
||||
@ -87,6 +90,13 @@ struct _GskTransform
|
||||
gboolean gsk_transform_parser_parse (GtkCssParser *parser,
|
||||
GskTransform **out_transform);
|
||||
|
||||
void gsk_transform_to_dihedral (GskTransform *self,
|
||||
GdkDihedral *out_dihedral,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y,
|
||||
float *out_dx,
|
||||
float *out_dy);
|
||||
|
||||
void gsk_matrix_transform_point (const graphene_matrix_t *m,
|
||||
const graphene_point_t *p,
|
||||
graphene_point_t *res);
|
||||
|
Loading…
Reference in New Issue
Block a user