[gtk/wip/otte/canvas: 31/36] canvas: Make origin a GtkCanvasVector




commit a80b4c006f57dddd8e41da1a89c04d8d817c75b9
Author: Benjamin Otte <otte redhat com>
Date:   Mon Jul 4 09:30:02 2022 +0200

    canvas: Make origin a GtkCanvasVector
    
    That way we can use it as a variable and properly track things with it.

 gtk/gtkcanvas.c              | 29 +++++++++++++++-------
 gtk/gtkcanvasbox.c           | 48 ++++++++++++++++++-------------------
 gtk/gtkcanvasbox.h           |  4 +---
 gtk/gtkcanvasboxprivate.h    |  4 ++--
 gtk/gtkcanvasitem.c          | 18 ++++++++++----
 gtk/gtkcanvasvector.c        | 11 +++++++--
 gtk/gtkcanvasvectorimpl.c    | 57 ++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkcanvasvectorprivate.h | 13 ++++++++++
 8 files changed, 139 insertions(+), 45 deletions(-)
---
diff --git a/gtk/gtkcanvas.c b/gtk/gtkcanvas.c
index e638cff9af..57116c66f2 100644
--- a/gtk/gtkcanvas.c
+++ b/gtk/gtkcanvas.c
@@ -256,7 +256,6 @@ gtk_canvas_allocate (GtkWidget *widget,
           GtkCanvasItem *ci = gtk_canvas_items_get (&self->items, i);
           GtkWidget *child = gtk_canvas_item_get_widget (ci);
           const GtkCanvasBox *bounds;
-          float origin_x, origin_y;
           graphene_rect_t rect;
           int x, y, w, h;
 
@@ -297,15 +296,27 @@ gtk_canvas_allocate (GtkWidget *widget,
             w = -w;
           if (rect.size.height < 0)
             h = -h;
-          gtk_canvas_box_get_origin (bounds, &origin_x, &origin_y);
-          if (ABS (w) > ABS (rect.size.width))
-            x = round (rect.origin.x + origin_x * (rect.size.width - w));
-          else
-            x = round (rect.origin.x);
-          if (ABS (h) > ABS (rect.size.height))
-            y = round (rect.origin.y + origin_y * (rect.size.height - h));
+          if (ABS (w) > ABS (rect.size.width) || ABS (h) > ABS (rect.size.height))
+            {
+              graphene_vec2_t origin;
+
+              if (!gtk_canvas_vector_eval (gtk_canvas_box_get_origin (bounds), &origin))
+                graphene_vec2_init_from_vec2 (&origin, graphene_vec2_zero ());
+
+              if (ABS (w) > ABS (rect.size.width))
+                x = round (rect.origin.x + graphene_vec2_get_y (&origin) * (rect.size.width - w));
+              else
+                x = round (rect.origin.x);
+              if (ABS (h) > ABS (rect.size.height))
+                y = round (rect.origin.y + graphene_vec2_get_y (&origin) * (rect.size.height - h));
+              else
+                y = round (rect.origin.y);
+            }
           else
-            y = round (rect.origin.y);
+            {
+              x = round (rect.origin.x);
+              y = round (rect.origin.y);
+            }
 
           gtk_canvas_item_allocate (ci, &GRAPHENE_RECT_INIT (x, y, w, h));
           success = TRUE;
diff --git a/gtk/gtkcanvasbox.c b/gtk/gtkcanvasbox.c
index a5d2cb5cb8..72fe87c428 100644
--- a/gtk/gtkcanvasbox.c
+++ b/gtk/gtkcanvasbox.c
@@ -41,11 +41,11 @@ void
 gtk_canvas_box_init (GtkCanvasBox          *self,
                      const GtkCanvasVector *point,
                      const GtkCanvasVector *size,
-                     const graphene_vec2_t *origin)
+                     const GtkCanvasVector *origin)
 {
   gtk_canvas_vector_init_copy (&self->point, point);
   gtk_canvas_vector_init_copy (&self->size, size);
-  graphene_vec2_init_from_vec2 (&self->origin, origin);
+  gtk_canvas_vector_init_copy (&self->origin, origin);
 }
 
 void
@@ -60,6 +60,7 @@ gtk_canvas_box_finish (GtkCanvasBox *self)
 {
   gtk_canvas_vector_finish (&self->point);
   gtk_canvas_vector_finish (&self->size);
+  gtk_canvas_vector_finish (&self->origin);
 }
 
 void
@@ -67,7 +68,7 @@ gtk_canvas_box_init_variable (GtkCanvasBox *self)
 {
   gtk_canvas_vector_init_variable (&self->point);
   gtk_canvas_vector_init_variable (&self->size);
-  graphene_vec2_init (&self->origin, 0, 0);
+  gtk_canvas_vector_init_variable (&self->origin);
 }
 
 void
@@ -76,7 +77,7 @@ gtk_canvas_box_update_variable (GtkCanvasBox       *self,
 {
   gtk_canvas_vector_init_copy (gtk_canvas_vector_get_variable (&self->point), &other->point);
   gtk_canvas_vector_init_copy (gtk_canvas_vector_get_variable (&self->size), &other->size);
-  graphene_vec2_init_from_vec2 (&self->origin, &other->origin);
+  gtk_canvas_vector_init_copy (gtk_canvas_vector_get_variable (&self->origin), &other->origin);
 }
 
 /**
@@ -93,7 +94,7 @@ GtkCanvasBox *
 gtk_canvas_box_new_points (const GtkCanvasVector *point1,
                            const GtkCanvasVector *point2)
 {
-  GtkCanvasVector size;
+  GtkCanvasVector size, origin;
   GtkCanvasBox *result;
   graphene_vec2_t minus_one;
 
@@ -107,9 +108,11 @@ gtk_canvas_box_new_points (const GtkCanvasVector *point1,
                               &minus_one,
                               point1,
                               NULL);
+  gtk_canvas_vector_init_constant (&origin, 0, 0);
   result = g_slice_new (GtkCanvasBox);
-  gtk_canvas_box_init (result, (GtkCanvasVector *) point1, &size, graphene_vec2_zero ());
+  gtk_canvas_box_init (result, (GtkCanvasVector *) point1, &size, &origin);
   gtk_canvas_vector_finish (&size);
+  gtk_canvas_vector_finish (&origin);
 
   return result;
 }
@@ -135,18 +138,17 @@ gtk_canvas_box_new (const GtkCanvasVector *point,
                     float                  origin_y)
 {
   GtkCanvasBox *self;
-  graphene_vec2_t origin;
+  GtkCanvasVector origin;
 
   g_return_val_if_fail (point != NULL, NULL);
   g_return_val_if_fail (size != NULL, NULL);
 
-  graphene_vec2_init (&origin, origin_x, origin_y);
+  gtk_canvas_vector_init_constant (&origin, origin_x, origin_y);
 
   self = g_slice_new (GtkCanvasBox);
-  gtk_canvas_box_init (self,
-                       (GtkCanvasVector *) point,
-                       (GtkCanvasVector *) size,
-                       &origin);
+  gtk_canvas_box_init (self, point, size, &origin);
+
+  gtk_canvas_vector_finish (&origin);
 
   return self;
 }
@@ -176,20 +178,21 @@ gboolean
 gtk_canvas_box_eval (const GtkCanvasBox *self,
                      graphene_rect_t    *rect)
 {
-  graphene_vec2_t point, size, tmp;
+  graphene_vec2_t point, size, origin;
 
   g_return_val_if_fail (self != NULL, FALSE);
   g_return_val_if_fail (rect != NULL, FALSE);
 
   if (!gtk_canvas_vector_eval (&self->point, &point) ||
-      !gtk_canvas_vector_eval (&self->size, &size))
+      !gtk_canvas_vector_eval (&self->size, &size) ||
+      !gtk_canvas_vector_eval (&self->origin, &origin))
     {
       *rect = *graphene_rect_zero ();
       return FALSE;
     }
 
-  graphene_vec2_multiply (&self->origin, &size, &tmp);
-  graphene_vec2_subtract (&point, &tmp, &point);
+  graphene_vec2_multiply (&origin, &size, &origin);
+  graphene_vec2_subtract (&point, &origin, &point);
 
   *rect = GRAPHENE_RECT_INIT (graphene_vec2_get_x (&point),
                               graphene_vec2_get_y (&point),
@@ -215,15 +218,10 @@ gtk_canvas_box_get_size (const GtkCanvasBox *self)
   return &self->size;
 }
 
-void
-gtk_canvas_box_get_origin (const GtkCanvasBox *self,
-                           float              *x,
-                           float              *y)
+const GtkCanvasVector *
+gtk_canvas_box_get_origin (const GtkCanvasBox *self)
 {
-  g_return_if_fail (self != NULL);
+  g_return_val_if_fail (self != NULL, NULL);
 
-  if (x)
-    *x = graphene_vec2_get_x (&self->origin);
-  if (y)
-    *y = graphene_vec2_get_y (&self->origin);
+  return &self->origin;
 }
diff --git a/gtk/gtkcanvasbox.h b/gtk/gtkcanvasbox.h
index 34884e687d..2f08699f5a 100644
--- a/gtk/gtkcanvasbox.h
+++ b/gtk/gtkcanvasbox.h
@@ -45,9 +45,7 @@ const GtkCanvasVector * gtk_canvas_box_get_point              (const GtkCanvasBo
 GDK_AVAILABLE_IN_ALL
 const GtkCanvasVector * gtk_canvas_box_get_size               (const GtkCanvasBox       *self) G_GNUC_PURE;
 GDK_AVAILABLE_IN_ALL
-void                    gtk_canvas_box_get_origin             (const GtkCanvasBox       *self,
-                                                               float                    *x,
-                                                               float                    *y);
+const GtkCanvasVector * gtk_canvas_box_get_origin             (const GtkCanvasBox       *self) G_GNUC_PURE;
 
 GDK_AVAILABLE_IN_ALL
 gboolean                gtk_canvas_box_eval                   (const GtkCanvasBox       *self,
diff --git a/gtk/gtkcanvasboxprivate.h b/gtk/gtkcanvasboxprivate.h
index e93a9dac28..7aa13e61a3 100644
--- a/gtk/gtkcanvasboxprivate.h
+++ b/gtk/gtkcanvasboxprivate.h
@@ -11,14 +11,14 @@ struct _GtkCanvasBox
 {
   GtkCanvasVector point;
   GtkCanvasVector size;
-  graphene_vec2_t origin;
+  GtkCanvasVector origin;
 };
 
 
 void                    gtk_canvas_box_init                     (GtkCanvasBox           *self,
                                                                  const GtkCanvasVector  *point,
                                                                  const GtkCanvasVector  *size,
-                                                                 const graphene_vec2_t  *origin);
+                                                                 const GtkCanvasVector  *origin);
 void                    gtk_canvas_box_init_copy                (GtkCanvasBox           *self,
                                                                  const GtkCanvasBox     *source);
 void                    gtk_canvas_box_finish                   (GtkCanvasBox           *self);
diff --git a/gtk/gtkcanvasitem.c b/gtk/gtkcanvasitem.c
index 05ec3845fa..893f505b98 100644
--- a/gtk/gtkcanvasitem.c
+++ b/gtk/gtkcanvasitem.c
@@ -212,7 +212,7 @@ gtk_canvas_item_init (GtkCanvasItem *self)
 
   gtk_canvas_vector_init_constant (&self->bounds.point, 0, 0);
   gtk_canvas_vector_init_copy (&self->bounds.size, &self->size_vecs[GTK_CANVAS_ITEM_MEASURE_NAT_FOR_NAT]);
-  graphene_vec2_init (&self->bounds.origin, 0, 0);
+  gtk_canvas_vector_init_constant (&self->bounds.origin, 0.5, 0.5);
   gtk_canvas_box_init_variable (&self->bounds_var);
   gtk_canvas_box_update_variable (&self->bounds_var, &self->bounds);
   gtk_canvas_box_init_variable (&self->allocation_var);
@@ -276,20 +276,30 @@ gtk_canvas_item_validate_variables (GtkCanvasItem *self)
       gtk_canvas_vector_get_variable (&self->allocation_var.point));
   gtk_canvas_vector_init_invalid (
       gtk_canvas_vector_get_variable (&self->allocation_var.size));
+  gtk_canvas_vector_init_invalid (
+      gtk_canvas_vector_get_variable (&self->allocation_var.origin));
 }
 
 void
 gtk_canvas_item_allocate (GtkCanvasItem   *self,
                           graphene_rect_t *rect)
 {
+  graphene_vec2_t origin;
+
+  if (!gtk_canvas_vector_eval (&self->bounds.origin, &origin))
+    graphene_vec2_init_from_vec2 (&origin, graphene_vec2_zero ());
+
   gtk_canvas_vector_init_constant (
       gtk_canvas_vector_get_variable (&self->allocation_var.point),
-      rect->origin.x + graphene_vec2_get_x (&self->bounds.origin) * rect->size.width,
-      rect->origin.y + graphene_vec2_get_y (&self->bounds.origin) * rect->size.height);
+      rect->origin.x + graphene_vec2_get_x (&origin) * rect->size.width,
+      rect->origin.y + graphene_vec2_get_y (&origin) * rect->size.height);
   gtk_canvas_vector_init_constant (
       gtk_canvas_vector_get_variable (&self->allocation_var.size),
       rect->size.width, rect->size.height);
-  graphene_vec2_init_from_vec2 (&self->allocation_var.origin, &self->bounds.origin);
+  gtk_canvas_vector_init_constant (
+      gtk_canvas_vector_get_variable (&self->allocation_var.origin),
+      graphene_vec2_get_x (&origin),
+      graphene_vec2_get_y (&origin));
 }
 
 void
diff --git a/gtk/gtkcanvasvector.c b/gtk/gtkcanvasvector.c
index 81009fcbdb..905f6c547c 100644
--- a/gtk/gtkcanvasvector.c
+++ b/gtk/gtkcanvasvector.c
@@ -86,12 +86,14 @@ gtk_canvas_vector_new_from_box (const GtkCanvasBox *box,
                                 float               origin_y)
 {
   GtkCanvasVector *self;
-  graphene_vec2_t origin;
+  GtkCanvasVector mult;
+  graphene_vec2_t origin, minus_one;
  
   g_return_val_if_fail (box != NULL, NULL);
  
   graphene_vec2_init (&origin, origin_x, origin_y);
-  graphene_vec2_subtract (&origin, &box->origin, &origin);
+  graphene_vec2_init (&minus_one, -1, -1);
+  gtk_canvas_vector_init_multiply (&mult, &box->origin, &box->size);
  
   self = gtk_canvas_vector_alloc ();
   gtk_canvas_vector_init_sum (self,
@@ -99,7 +101,12 @@ gtk_canvas_vector_new_from_box (const GtkCanvasBox *box,
                               &box->point,
                               &origin,
                               &box->size,
+                              &minus_one,
+                              &mult,
                               NULL);
+
+  gtk_canvas_vector_finish (&mult);
+
   return self;
 }
 
diff --git a/gtk/gtkcanvasvectorimpl.c b/gtk/gtkcanvasvectorimpl.c
index 3f75156315..4eeb8c398c 100644
--- a/gtk/gtkcanvasvectorimpl.c
+++ b/gtk/gtkcanvasvectorimpl.c
@@ -243,6 +243,63 @@ gtk_canvas_vector_init_sum (GtkCanvasVector         *vector,
   self->summands = (GtkCanvasVectorSummand *) g_array_free (array, FALSE);
 }
 
+/* }}} */
+/* {{{ MULTIPLY */
+
+static void
+gtk_canvas_vector_multiply_copy (GtkCanvasVector       *vector,
+                                 const GtkCanvasVector *source_vector)
+{
+  const GtkCanvasVectorMultiply *source = &source_vector->multiply;
+
+  gtk_canvas_vector_init_multiply (vector, source->a, source->b);
+}
+
+static void
+gtk_canvas_vector_multiply_finish (GtkCanvasVector *vector)
+{
+  const GtkCanvasVectorMultiply *self = &vector->multiply;
+
+  gtk_canvas_vector_free (self->a);
+  gtk_canvas_vector_free (self->b);
+}
+
+static gboolean
+gtk_canvas_vector_multiply_eval (const GtkCanvasVector *vector,
+                                 graphene_vec2_t       *result)
+{
+  const GtkCanvasVectorMultiply *self = &vector->multiply;
+  graphene_vec2_t a, b;
+
+  if (!gtk_canvas_vector_eval (self->a, &a) ||
+      !gtk_canvas_vector_eval (self->b, &b))
+    return FALSE;
+
+  graphene_vec2_multiply (&a, &b, result);
+  return TRUE;
+}
+
+static const GtkCanvasVectorClass GTK_CANVAS_VECTOR_MULTIPLY_CLASS =
+{
+  "GtkCanvasVectorMultiply",
+  gtk_canvas_vector_multiply_copy,
+  gtk_canvas_vector_multiply_finish,
+  gtk_canvas_vector_multiply_eval,
+};
+
+void
+gtk_canvas_vector_init_multiply (GtkCanvasVector       *vector,
+                                 const GtkCanvasVector *a,
+                                 const GtkCanvasVector *b)
+{
+  GtkCanvasVectorMultiply *self = &vector->multiply;
+
+  self->class = &GTK_CANVAS_VECTOR_MULTIPLY_CLASS;
+  
+  self->a = gtk_canvas_vector_copy (a);
+  self->b = gtk_canvas_vector_copy (b);
+}
+
 /* }}} */
 /* {{{ VARIABLE */
 
diff --git a/gtk/gtkcanvasvectorprivate.h b/gtk/gtkcanvasvectorprivate.h
index f4f63d6880..596fc079ed 100644
--- a/gtk/gtkcanvasvectorprivate.h
+++ b/gtk/gtkcanvasvectorprivate.h
@@ -29,6 +29,7 @@ G_BEGIN_DECLS
 typedef struct _GtkCanvasVector GtkCanvasVector;
 typedef struct _GtkCanvasVectorClass GtkCanvasVectorClass;
 typedef struct _GtkCanvasVectorConstant GtkCanvasVectorConstant;
+typedef struct _GtkCanvasVectorMultiply GtkCanvasVectorMultiply;
 typedef struct _GtkCanvasVectorSum GtkCanvasVectorSum;
 typedef struct _GtkCanvasVectorSummand GtkCanvasVectorSummand;
 typedef struct _GtkCanvasVectorVariable GtkCanvasVectorVariable;
@@ -40,6 +41,14 @@ struct _GtkCanvasVectorConstant
   graphene_vec2_t value;
 };
 
+struct _GtkCanvasVectorMultiply
+{
+  const GtkCanvasVectorClass *class;
+
+  GtkCanvasVector *a;
+  GtkCanvasVector *b;
+};
+
 struct _GtkCanvasVectorSum
 {
   const GtkCanvasVectorClass *class;
@@ -63,6 +72,7 @@ struct _GtkCanvasVector
   union {
     const GtkCanvasVectorClass *class;
     GtkCanvasVectorConstant constant;
+    GtkCanvasVectorMultiply multiply;
     GtkCanvasVectorSum sum;
     GtkCanvasVectorVariable variable;
   };
@@ -88,6 +98,9 @@ void                    gtk_canvas_vector_init_constant_from_vector (GtkCanvasVe
 void                    gtk_canvas_vector_init_sum              (GtkCanvasVector        *vector,
                                                                  const graphene_vec2_t  *scale,
                                                                  ...) G_GNUC_NULL_TERMINATED;
+void                    gtk_canvas_vector_init_multiply         (GtkCanvasVector        *vector,
+                                                                 const GtkCanvasVector  *a,
+                                                                 const GtkCanvasVector  *b);
 
 void                    gtk_canvas_vector_init_variable         (GtkCanvasVector        *vector);
 GtkCanvasVector *       gtk_canvas_vector_get_variable          (GtkCanvasVector        *vector);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]