summaryrefslogtreecommitdiff
path: root/gsk
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2019-06-02 14:16:45 +0200
committerBenjamin Otte <otte@redhat.com>2019-06-02 21:18:56 +0200
commit5a0c8805fc9d0477b00139ae63c3c696a1fc5d19 (patch)
tree7e2ab745bbb8fd68b3f233ddf764bc2e004f0f9f /gsk
parent69629ebb1a3d33376aaa3bfcf6fcd385ffa6377b (diff)
downloadgtk+-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.c53
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);