diff options
author | Benjamin Otte <otte@redhat.com> | 2019-06-02 14:16:45 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2019-06-02 21:18:56 +0200 |
commit | 5a0c8805fc9d0477b00139ae63c3c696a1fc5d19 (patch) | |
tree | 7e2ab745bbb8fd68b3f233ddf764bc2e004f0f9f /gsk | |
parent | 69629ebb1a3d33376aaa3bfcf6fcd385ffa6377b (diff) | |
download | gtk+-5a0c8805fc9d0477b00139ae63c3c696a1fc5d19.tar.gz |
transform: Coalesce similar transforms
If somebody does a transform like
scale(5) scale(10) translate(1,1) translate(5,0)
store it instead as
scale(50) translate(6,1)
This way, less memory is consumed and transforms are easier to read.
In particular, this simplifies the typical transforms we do in GTK,
which are just one translation after another.
Diffstat (limited to 'gsk')
-rw-r--r-- | gsk/gsktransform.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/gsk/gsktransform.c b/gsk/gsktransform.c index 3baf8bb061..a32d62131d 100644 --- a/gsk/gsktransform.c +++ b/gsk/gsktransform.c @@ -94,6 +94,13 @@ G_DEFINE_BOXED_TYPE (GskTransform, gsk_transform, static gboolean gsk_transform_is_identity (GskTransform *self); +static inline gboolean +gsk_transform_has_class (GskTransform *self, + const GskTransformClass *transform_class) +{ + return self != NULL && self->transform_class == transform_class; +} + /*< private > * gsk_transform_alloc: * @transform_class: class structure for this self @@ -638,6 +645,17 @@ gsk_transform_translate_3d (GskTransform *next, { GskTranslateTransform *result; + if (gsk_transform_has_class (next, &GSK_TRANSLATE_TRANSFORM_CLASS)) + { + GskTranslateTransform *t = (GskTranslateTransform *) next; + GskTransform *r = gsk_transform_translate_3d (gsk_transform_ref (next->next), + &GRAPHENE_POINT3D_INIT(t->point.x + point->x, + t->point.y + point->y, + t->point.z + point->z)); + gsk_transform_unref (next); + return r; + } + result = gsk_transform_alloc (&GSK_TRANSLATE_TRANSFORM_CLASS, point->z == 0.0 ? GSK_TRANSFORM_CATEGORY_2D_TRANSLATE : GSK_TRANSFORM_CATEGORY_3D, @@ -777,9 +795,19 @@ GskTransform * gsk_transform_rotate (GskTransform *next, float angle) { - GskRotateTransform *result = gsk_transform_alloc (&GSK_ROTATE_TRANSFORM_CLASS, - GSK_TRANSFORM_CATEGORY_2D, - next); + GskRotateTransform *result; + + if (gsk_transform_has_class (next, &GSK_ROTATE_TRANSFORM_CLASS)) + { + GskTransform *r = gsk_transform_rotate (gsk_transform_ref (next->next), + ((GskRotateTransform *) next)->angle + angle); + gsk_transform_unref (next); + return r; + } + + result = gsk_transform_alloc (&GSK_ROTATE_TRANSFORM_CLASS, + GSK_TRANSFORM_CATEGORY_2D, + next); result->angle = angle; @@ -1083,6 +1111,17 @@ gsk_transform_scale_3d (GskTransform *next, { GskScaleTransform *result; + if (gsk_transform_has_class (next, &GSK_SCALE_TRANSFORM_CLASS)) + { + GskScaleTransform *scale = (GskScaleTransform *) next; + GskTransform *r = gsk_transform_scale_3d (gsk_transform_ref (next->next), + scale->factor_x * factor_x, + scale->factor_y * factor_y, + scale->factor_z * factor_z); + gsk_transform_unref (next); + return r; + } + result = gsk_transform_alloc (&GSK_SCALE_TRANSFORM_CLASS, factor_z != 1.0 ? GSK_TRANSFORM_CATEGORY_3D : GSK_TRANSFORM_CATEGORY_2D_AFFINE, @@ -1200,6 +1239,14 @@ gsk_transform_perspective (GskTransform *next, { GskPerspectiveTransform *result; + if (gsk_transform_has_class (next, &GSK_PERSPECTIVE_TRANSFORM_CLASS)) + { + GskTransform *r = gsk_transform_perspective (gsk_transform_ref (next->next), + ((GskPerspectiveTransform *) next)->depth + depth); + gsk_transform_unref (next); + return r; + } + result = gsk_transform_alloc (&GSK_PERSPECTIVE_TRANSFORM_CLASS, GSK_TRANSFORM_CATEGORY_ANY, next); |