transform: Redo querying API

Make the API expect a tranform of the proper category instead of
doing the check ourselves and returning TRUE/FALSE.

The benefit is that the mai use case is switch (transform->category)
statements and in those we know the category and don't need to check
TRUE/FALSE.

Using the wrong matrix will now cause a g_warning().
This commit is contained in:
Benjamin Otte 2019-03-04 19:33:04 +01:00
parent 1fecbd4241
commit bd113aa85c
7 changed files with 166 additions and 209 deletions

View File

@ -809,10 +809,7 @@ render_transform_node (GskGLRenderer *self,
{
float dx, dy;
if (!gsk_transform_to_translate (node_transform, &dx, &dy))
{
g_assert_not_reached ();
}
gsk_transform_to_translate (node_transform, &dx, &dy);
ops_offset (builder, dx, dy);
gsk_gl_renderer_add_render_ops (self, child, builder);

View File

@ -2406,25 +2406,25 @@ gsk_transform_node_draw (GskRenderNode *node,
{
GskTransformNode *self = (GskTransformNode *) node;
float xx, yx, xy, yy, dx, dy;
cairo_matrix_t ctm;
if (gsk_transform_to_2d (self->transform, &xx, &yx, &xy, &yy, &dx, &dy))
{
cairo_matrix_t ctm = { xx, yx, xy, yy, dx, dy };
GSK_NOTE (CAIRO, g_message ("CTM = { .xx = %g, .yx = %g, .xy = %g, .yy = %g, .x0 = %g, .y0 = %g }",
ctm.xx, ctm.yx,
ctm.xy, ctm.yy,
ctm.x0, ctm.y0));
cairo_transform (cr, &ctm);
gsk_render_node_draw (self->child, cr);
}
else
if (gsk_transform_get_category (self->transform) < GSK_TRANSFORM_CATEGORY_2D)
{
cairo_set_source_rgb (cr, 255 / 255., 105 / 255., 180 / 255.);
cairo_rectangle (cr, node->bounds.origin.x, node->bounds.origin.y, node->bounds.size.width, node->bounds.size.height);
cairo_fill (cr);
return;
}
gsk_transform_to_2d (self->transform, &xx, &yx, &xy, &yy, &dx, &dy);
cairo_matrix_init (&ctm, xx, yx, xy, yy, dx, dy);
GSK_NOTE (CAIRO, g_message ("CTM = { .xx = %g, .yx = %g, .xy = %g, .yy = %g, .x0 = %g, .y0 = %g }",
ctm.xx, ctm.yx,
ctm.xy, ctm.yy,
ctm.x0, ctm.y0));
cairo_transform (cr, &ctm);
gsk_render_node_draw (self->child, cr);
}
#define GSK_TRANSFORM_NODE_VARIANT_TYPE "(idddddddddddddddduv)"

View File

@ -56,19 +56,19 @@ struct _GskTransformClass
void (* finalize) (GskTransform *transform);
void (* to_matrix) (GskTransform *transform,
graphene_matrix_t *out_matrix);
gboolean (* apply_2d) (GskTransform *transform,
void (* apply_2d) (GskTransform *transform,
float *out_xx,
float *out_yx,
float *out_xy,
float *out_yy,
float *out_dx,
float *out_dy);
gboolean (* apply_affine) (GskTransform *transform,
void (* apply_affine) (GskTransform *transform,
float *out_scale_x,
float *out_scale_y,
float *out_dx,
float *out_dy);
gboolean (* apply_translate) (GskTransform *transform,
void (* apply_translate) (GskTransform *transform,
float *out_dx,
float *out_dy);
void (* print) (GskTransform *transform,
@ -117,7 +117,7 @@ gsk_transform_alloc (const GskTransformClass *transform_class,
self->transform_class = transform_class;
self->ref_count = 1;
self->category = MIN (category, next->category);
self->category = next ? MIN (category, next->category) : category;
self->next = gsk_transform_is_identity (next) ? NULL : next;
return self;
@ -137,7 +137,7 @@ gsk_identity_transform_to_matrix (GskTransform *transform,
graphene_matrix_init_identity (out_matrix);
}
static gboolean
static void
gsk_identity_transform_apply_2d (GskTransform *transform,
float *out_xx,
float *out_yx,
@ -146,25 +146,22 @@ gsk_identity_transform_apply_2d (GskTransform *transform,
float *out_dx,
float *out_dy)
{
return TRUE;
}
static gboolean
static void
gsk_identity_transform_apply_affine (GskTransform *transform,
float *out_scale_x,
float *out_scale_y,
float *out_dx,
float *out_dy)
{
return TRUE;
}
static gboolean
static void
gsk_identity_transform_apply_translate (GskTransform *transform,
float *out_dx,
float *out_dy)
{
return TRUE;
}
static void
@ -267,7 +264,7 @@ gsk_matrix_transform_to_matrix (GskTransform *transform,
graphene_matrix_init_from_matrix (out_matrix, &self->matrix);
}
static gboolean
static void
gsk_matrix_transform_apply_2d (GskTransform *transform,
float *out_xx,
float *out_yx,
@ -276,10 +273,26 @@ gsk_matrix_transform_apply_2d (GskTransform *transform,
float *out_dx,
float *out_dy)
{
return FALSE;
GskMatrixTransform *self = (GskMatrixTransform *) transform;
graphene_matrix_t mat;
graphene_matrix_init_from_2d (&mat,
*out_xx, *out_yx,
*out_xy, *out_yy,
*out_dx, *out_dy);
graphene_matrix_multiply (&self->matrix, &mat, &mat);
/* not using graphene_matrix_to_2d() because it may
* fail the is_2d() check due to improper rounding */
*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 gboolean
static void
gsk_matrix_transform_apply_affine (GskTransform *transform,
float *out_scale_x,
float *out_scale_y,
@ -295,26 +308,27 @@ gsk_matrix_transform_apply_affine (GskTransform *transform,
case GSK_TRANSFORM_CATEGORY_3D:
case GSK_TRANSFORM_CATEGORY_2D:
default:
return FALSE;
g_assert_not_reached ();
break;
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
*out_dx += *out_scale_x * graphene_matrix_get_value (&self->matrix, 3, 0);
*out_dy += *out_scale_y * graphene_matrix_get_value (&self->matrix, 3, 1);
*out_scale_x *= graphene_matrix_get_value (&self->matrix, 0, 0);
*out_scale_y *= graphene_matrix_get_value (&self->matrix, 1, 1);
return TRUE;
break;
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
*out_dx += *out_scale_x * graphene_matrix_get_value (&self->matrix, 3, 0);
*out_dy += *out_scale_y * graphene_matrix_get_value (&self->matrix, 3, 1);
return TRUE;
break;
case GSK_TRANSFORM_CATEGORY_IDENTITY:
return TRUE;
break;
}
}
static gboolean
static void
gsk_matrix_transform_apply_translate (GskTransform *transform,
float *out_dx,
float *out_dy)
@ -329,17 +343,17 @@ gsk_matrix_transform_apply_translate (GskTransform *transform,
case GSK_TRANSFORM_CATEGORY_2D:
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
default:
return FALSE;
g_assert_not_reached ();
break;
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
*out_dx += graphene_matrix_get_value (&self->matrix, 3, 0);
*out_dy += graphene_matrix_get_value (&self->matrix, 3, 1);
return TRUE;
break;
case GSK_TRANSFORM_CATEGORY_IDENTITY:
return TRUE;
break;
}
return TRUE;
}
static void
@ -479,7 +493,7 @@ gsk_translate_transform_to_matrix (GskTransform *transform,
graphene_matrix_init_translate (out_matrix, &self->point);
}
static gboolean
static void
gsk_translate_transform_apply_2d (GskTransform *transform,
float *out_xx,
float *out_yx,
@ -490,16 +504,13 @@ gsk_translate_transform_apply_2d (GskTransform *transform,
{
GskTranslateTransform *self = (GskTranslateTransform *) transform;
if (self->point.z != 0.0)
return FALSE;
g_assert (self->point.z == 0.0);
*out_dx += *out_xx * self->point.x + *out_xy * self->point.y;
*out_dy += *out_yx * self->point.x + *out_yy * self->point.y;
return TRUE;
}
static gboolean
static void
gsk_translate_transform_apply_affine (GskTransform *transform,
float *out_scale_x,
float *out_scale_y,
@ -508,29 +519,23 @@ gsk_translate_transform_apply_affine (GskTransform *transform,
{
GskTranslateTransform *self = (GskTranslateTransform *) transform;
if (self->point.z != 0.0)
return FALSE;
g_assert (self->point.z == 0.0);
*out_dx += *out_scale_x * self->point.x;
*out_dy += *out_scale_y * self->point.y;
return TRUE;
}
static gboolean
static void
gsk_translate_transform_apply_translate (GskTransform *transform,
float *out_dx,
float *out_dy)
{
GskTranslateTransform *self = (GskTranslateTransform *) transform;
if (self->point.z != 0.0)
return FALSE;
g_assert (self->point.z == 0.0);
*out_dx += self->point.x;
*out_dy += self->point.y;
return TRUE;
}
static GskTransform *
@ -675,7 +680,7 @@ gsk_rotate_transform_to_matrix (GskTransform *transform,
0, 0);
}
static gboolean
static void
gsk_rotate_transform_apply_2d (GskTransform *transform,
float *out_xx,
float *out_yx,
@ -688,7 +693,7 @@ gsk_rotate_transform_apply_2d (GskTransform *transform,
float s, c, rad, xx, xy, yx, yy;
if (fmodf (self->angle, 360.0f) == 0.0)
return TRUE;
return;
rad = self->angle * G_PI / 180.0f;
s = sinf (rad);
@ -703,26 +708,6 @@ gsk_rotate_transform_apply_2d (GskTransform *transform,
*out_yx = yx;
*out_xy = xy;
*out_yy = yy;
return TRUE;
}
static gboolean
gsk_rotate_transform_apply_affine (GskTransform *transform,
float *out_scale_x,
float *out_scale_y,
float *out_dx,
float *out_dy)
{
return FALSE;
}
static gboolean
gsk_rotate_transform_apply_translate (GskTransform *transform,
float *out_dx,
float *out_dy)
{
return FALSE;
}
static GskTransform *
@ -771,8 +756,8 @@ 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_affine,
gsk_rotate_transform_apply_translate,
NULL,
NULL,
gsk_rotate_transform_print,
gsk_rotate_transform_apply,
gsk_rotate_transform_invert,
@ -827,36 +812,6 @@ gsk_rotate3d_transform_to_matrix (GskTransform *transform,
graphene_matrix_init_rotate (out_matrix, self->angle, &self->axis);
}
static gboolean
gsk_rotate3d_transform_apply_2d (GskTransform *transform,
float *out_xx,
float *out_yx,
float *out_xy,
float *out_yy,
float *out_dx,
float *out_dy)
{
return FALSE;
}
static gboolean
gsk_rotate3d_transform_apply_affine (GskTransform *transform,
float *out_scale_x,
float *out_scale_y,
float *out_dx,
float *out_dy)
{
return FALSE;
}
static gboolean
gsk_rotate3d_transform_apply_translate (GskTransform *transform,
float *out_dx,
float *out_dy)
{
return FALSE;
}
static GskTransform *
gsk_rotate3d_transform_apply (GskTransform *transform,
GskTransform *apply_to)
@ -911,9 +866,9 @@ static const GskTransformClass GSK_ROTATE3D_TRANSFORM_CLASS =
"GskRotate3dTransform",
gsk_rotate3d_transform_finalize,
gsk_rotate3d_transform_to_matrix,
gsk_rotate3d_transform_apply_2d,
gsk_rotate3d_transform_apply_affine,
gsk_rotate3d_transform_apply_translate,
NULL,
NULL,
NULL,
gsk_rotate3d_transform_print,
gsk_rotate3d_transform_apply,
gsk_rotate3d_transform_invert,
@ -979,7 +934,7 @@ gsk_scale_transform_to_matrix (GskTransform *transform,
graphene_matrix_init_scale (out_matrix, self->factor_x, self->factor_y, self->factor_z);
}
static gboolean
static void
gsk_scale_transform_apply_2d (GskTransform *transform,
float *out_xx,
float *out_yx,
@ -990,18 +945,15 @@ gsk_scale_transform_apply_2d (GskTransform *transform,
{
GskScaleTransform *self = (GskScaleTransform *) transform;
if (self->factor_z != 1.0)
return FALSE;
g_assert (self->factor_z == 1.0);
*out_xx *= self->factor_x;
*out_yx *= self->factor_x;
*out_xy *= self->factor_y;
*out_yy *= self->factor_y;
return TRUE;
}
static gboolean
static void
gsk_scale_transform_apply_affine (GskTransform *transform,
float *out_scale_x,
float *out_scale_y,
@ -1010,21 +962,10 @@ gsk_scale_transform_apply_affine (GskTransform *transform,
{
GskScaleTransform *self = (GskScaleTransform *) transform;
if (self->factor_z != 1.0)
return FALSE;
g_assert (self->factor_z == 1.0);
*out_scale_x *= self->factor_x;
*out_scale_y *= self->factor_y;
return TRUE;
}
static gboolean
gsk_scale_transform_apply_translate (GskTransform *transform,
float *out_dx,
float *out_dy)
{
return FALSE;
}
static GskTransform *
@ -1097,7 +1038,7 @@ static const GskTransformClass GSK_SCALE_TRANSFORM_CLASS =
gsk_scale_transform_to_matrix,
gsk_scale_transform_apply_2d,
gsk_scale_transform_apply_affine,
gsk_scale_transform_apply_translate,
NULL,
gsk_scale_transform_print,
gsk_scale_transform_apply,
gsk_scale_transform_invert,
@ -1284,7 +1225,7 @@ gsk_transform_to_matrix (GskTransform *self,
/**
* gsk_transform_to_2d:
* @m: a #GskTransform
* @m: a 2D #GskTransform
* @out_xx: (out): return location for the xx member
* @out_yx: (out): return location for the yx member
* @out_xy: (out): return location for the xy member
@ -1293,7 +1234,10 @@ gsk_transform_to_matrix (GskTransform *self,
* @out_dy: (out): return location for the y0 member
*
* Converts a #GskTransform to a 2D transformation
* matrix, if the given matrix is compatible.
* matrix.
* @self must be a 2D transformation. If you are not
* sure, use gsk_transform_get_category() >=
* %GSK_TRANSFORM_CATEGORY_2D to check.
*
* The returned values have the following layout:
*
@ -1310,7 +1254,7 @@ gsk_transform_to_matrix (GskTransform *self,
* Returns: %TRUE if the matrix is compatible with an 2D
* transformation matrix.
*/
gboolean
void
gsk_transform_to_2d (GskTransform *self,
float *out_xx,
float *out_yx,
@ -1319,32 +1263,38 @@ gsk_transform_to_2d (GskTransform *self,
float *out_dx,
float *out_dy)
{
if (self == NULL)
if (self == NULL ||
self->category < GSK_TRANSFORM_CATEGORY_2D)
{
if (self != NULL)
{
char *s = gsk_transform_to_string (self);
g_warning ("Given transform \"%s\" is not a 2D transform.", s);
g_free (s);
}
*out_xx = 1.0f;
*out_yx = 0.0f;
*out_xy = 0.0f;
*out_yy = 1.0f;
*out_dx = 0.0f;
*out_dy = 0.0f;
return TRUE;
return;
}
if (!gsk_transform_to_2d (self->next,
out_xx, out_yx,
out_xy, out_yy,
out_dx, out_dy))
return FALSE;
gsk_transform_to_2d (self->next,
out_xx, out_yx,
out_xy, out_yy,
out_dx, out_dy);
return self->transform_class->apply_2d (self,
out_xx, out_yx,
out_xy, out_yy,
out_dx, out_dy);
self->transform_class->apply_2d (self,
out_xx, out_yx,
out_xy, out_yy,
out_dx, out_dy);
}
/**
* gsk_transform_to_affine:
* @m: a #GskTransform
* @self: a #GskTransform
* @out_scale_x: (out): return location for the scale
* factor in the x direction
* @out_scale_y: (out): return location for the scale
@ -1355,35 +1305,41 @@ gsk_transform_to_2d (GskTransform *self,
* in the y direction
*
* Converts a #GskTransform to 2D affine transformation
* factors, if the given matrix is compatible.
*
* Returns: %TRUE if the matrix is compatible with an 2D
* affine transformation.
* factors.
* @self must be a 2D transformation. If you are not
* sure, use gsk_transform_get_category() >=
* %GSK_TRANSFORM_CATEGORY_2D_AFFINE to check.
*/
gboolean
void
gsk_transform_to_affine (GskTransform *self,
float *out_scale_x,
float *out_scale_y,
float *out_dx,
float *out_dy)
{
if (self == NULL)
if (self == NULL ||
self->category < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
{
if (self != NULL)
{
char *s = gsk_transform_to_string (self);
g_warning ("Given transform \"%s\" is not an affine 2D transform.", s);
g_free (s);
}
*out_scale_x = 1.0f;
*out_scale_y = 1.0f;
*out_dx = 0.0f;
*out_dy = 0.0f;
return TRUE;
return;
}
if (!gsk_transform_to_affine (self->next,
out_scale_x, out_scale_y,
out_dx, out_dy))
return FALSE;
gsk_transform_to_affine (self->next,
out_scale_x, out_scale_y,
out_dx, out_dy);
return self->transform_class->apply_affine (self,
out_scale_x, out_scale_y,
out_dx, out_dy);
self->transform_class->apply_affine (self,
out_scale_x, out_scale_y,
out_dx, out_dy);
}
/**
@ -1394,30 +1350,35 @@ gsk_transform_to_affine (GskTransform *self,
* @out_dy: (out): return location for the translation
* in the y direction
*
* Converts a #GskTransform to a translation operation,
* if the given matrix is compatible.
*
* Returns: %TRUE if the matrix is compatible with a
* translation transformation.
* Converts a #GskTransform to a translation operation.
* @self must be a 2D transformation. If you are not
* sure, use gsk_transform_get_category() >=
* %GSK_TRANSFORM_CATEGORY_2D_TRANSLATE to check.
*/
gboolean
void
gsk_transform_to_translate (GskTransform *self,
float *out_dx,
float *out_dy)
{
if (self == NULL)
if (self == NULL ||
self->category < GSK_TRANSFORM_CATEGORY_2D_TRANSLATE)
{
if (self != NULL)
{
char *s = gsk_transform_to_string (self);
g_warning ("Given transform \"%s\" is not a 2D translation.", s);
g_free (s);
}
*out_dx = 0.0f;
*out_dy = 0.0f;
return TRUE;
return;
}
if (!gsk_transform_to_translate (self->next,
out_dx, out_dy))
return FALSE;
gsk_transform_to_translate (self->next,
out_dx, out_dy);
return self->transform_class->apply_translate (self,
out_dx, out_dy);
self->transform_class->apply_translate (self,
out_dx, out_dy);
}
/**

View File

@ -49,23 +49,23 @@ GDK_AVAILABLE_IN_ALL
void gsk_transform_to_matrix (GskTransform *self,
graphene_matrix_t *out_matrix);
GDK_AVAILABLE_IN_ALL
gboolean gsk_transform_to_2d (GskTransform *self,
void gsk_transform_to_2d (GskTransform *self,
float *out_xx,
float *out_yx,
float *out_xy,
float *out_yy,
float *out_dx,
float *out_dy) G_GNUC_WARN_UNUSED_RESULT;
float *out_dy);
GDK_AVAILABLE_IN_ALL
gboolean gsk_transform_to_affine (GskTransform *self,
void gsk_transform_to_affine (GskTransform *self,
float *out_scale_x,
float *out_scale_y,
float *out_dx,
float *out_dy) G_GNUC_WARN_UNUSED_RESULT;
float *out_dy);
GDK_AVAILABLE_IN_ALL
gboolean gsk_transform_to_translate (GskTransform *self,
void gsk_transform_to_translate (GskTransform *self,
float *out_dx,
float *out_dy) G_GNUC_WARN_UNUSED_RESULT;
float *out_dy);
GDK_AVAILABLE_IN_ALL
GskTransformCategory gsk_transform_get_category (GskTransform *self) G_GNUC_PURE;

View File

@ -575,15 +575,15 @@ gtk_snapshot_ensure_affine (GtkSnapshot *snapshot,
float *dx,
float *dy)
{
const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
const GtkSnapshotState *state = gtk_snapshot_get_current_state (snapshot);
if (gsk_transform_to_affine (current_state->transform, scale_x, scale_y, dx, dy))
return;
gtk_snapshot_autopush_transform (snapshot);
*scale_x = *scale_y = 1;
*dx = *dy = 0;
if (gsk_transform_get_category (state->transform) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
{
gtk_snapshot_autopush_transform (snapshot);
state = gtk_snapshot_get_current_state (snapshot);
}
gsk_transform_to_affine (state->transform, scale_x, scale_y, dx, dy);
}
static void
@ -591,16 +591,15 @@ gtk_snapshot_ensure_translate (GtkSnapshot *snapshot,
float *dx,
float *dy)
{
const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
float scale_x, scale_y;
const GtkSnapshotState *state = gtk_snapshot_get_current_state (snapshot);
if (gsk_transform_to_affine (current_state->transform, &scale_x, &scale_y, dx, dy) &&
scale_x == 1.0f && scale_y == 1.0f)
return;
gtk_snapshot_autopush_transform (snapshot);
*dx = *dy = 0;
if (gsk_transform_get_category (state->transform) < GSK_TRANSFORM_CATEGORY_2D_TRANSLATE)
{
gtk_snapshot_autopush_transform (snapshot);
state = gtk_snapshot_get_current_state (snapshot);
}
gsk_transform_to_translate (state->transform, dx, dy);
}
static void
@ -608,10 +607,8 @@ gtk_snapshot_ensure_identity (GtkSnapshot *snapshot)
{
const GtkSnapshotState *state = gtk_snapshot_get_current_state (snapshot);
if (state->transform == NULL)
return;
gtk_snapshot_autopush_transform (snapshot);
if (gsk_transform_get_category (state->transform) < GSK_TRANSFORM_CATEGORY_IDENTITY)
gtk_snapshot_autopush_transform (snapshot);
}
void

View File

@ -11089,7 +11089,9 @@ gtk_widget_get_allocation (GtkWidget *widget,
gtk_css_boxes_init (&boxes, widget);
margin_rect = gtk_css_boxes_get_margin_rect (&boxes);
if (!gsk_transform_to_translate (priv->transform, &dx, &dy))
if (gsk_transform_get_category (priv->transform) >= GSK_TRANSFORM_CATEGORY_2D_TRANSLATE)
gsk_transform_to_translate (priv->transform, &dx, &dy);
else
dx = dy = 0;
allocation->x = dx + ceil (margin_rect->origin.x);

View File

@ -182,25 +182,25 @@ check_conversions (GskTransform *transform,
case GSK_TRANSFORM_CATEGORY_IDENTITY:
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
g_assert (gsk_transform_to_translate (transform,
&f[4 * 3 + 0], &f[4 * 3 + 1]));
gsk_transform_to_translate (transform,
&f[4 * 3 + 0], &f[4 * 3 + 1]);
graphene_matrix_init_from_float (&test, f);
graphene_assert_fuzzy_matrix_equal (&matrix, &test, EPSILON);
/* fallthrough */
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
g_assert (gsk_transform_to_affine (transform,
&f[4 * 0 + 0], &f[4 * 1 + 1],
&f[4 * 3 + 0], &f[4 * 3 + 1]));
gsk_transform_to_affine (transform,
&f[4 * 0 + 0], &f[4 * 1 + 1],
&f[4 * 3 + 0], &f[4 * 3 + 1]);
graphene_matrix_init_from_float (&test, f);
graphene_assert_fuzzy_matrix_equal (&matrix, &test, EPSILON);
/* fallthrough */
case GSK_TRANSFORM_CATEGORY_2D:
g_assert (gsk_transform_to_2d (transform,
&f[4 * 0 + 0], &f[4 * 0 + 1],
&f[4 * 1 + 0], &f[4 * 1 + 1],
&f[4 * 3 + 0], &f[4 * 3 + 1]));
gsk_transform_to_2d (transform,
&f[4 * 0 + 0], &f[4 * 0 + 1],
&f[4 * 1 + 0], &f[4 * 1 + 1],
&f[4 * 3 + 0], &f[4 * 3 + 1]);
graphene_matrix_init_from_float (&test, f);
graphene_assert_fuzzy_matrix_equal (&matrix, &test, EPSILON);
break;