summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2022-07-02 19:24:43 +0200
committerBenjamin Otte <otte@redhat.com>2022-07-05 07:37:47 +0200
commit9eedd3f5acd09bece2c1436b1c061277c53b5ba5 (patch)
tree638aee3be317dda782059277ed519d99aa50950c
parentd329c904b88d6a22074959aa9cf0475da7f140f1 (diff)
downloadgtk+-9eedd3f5acd09bece2c1436b1c061277c53b5ba5.tar.gz
canvas: Redo points and sizes
Instead of lots of special cases, just have 3 types: * sums * constants * variables And implement it in a new GtkCanvasVec2 struct and use it for points and sizes. Simplifies te code a lot. Requires some changes though so that now all variables are preinitialized instead of queried on demand.
-rw-r--r--demos/gtk-demo/canvas_intro.c2
-rw-r--r--demos/gtk-demo/canvas_puzzle.c2
-rw-r--r--gtk/gtkcanvas.c30
-rw-r--r--gtk/gtkcanvasbox.c91
-rw-r--r--gtk/gtkcanvasboxprivate.h17
-rw-r--r--gtk/gtkcanvasitem.c78
-rw-r--r--gtk/gtkcanvasitemprivate.h7
-rw-r--r--gtk/gtkcanvaspoint.c227
-rw-r--r--gtk/gtkcanvaspoint.h4
-rw-r--r--gtk/gtkcanvaspointprivate.h52
-rw-r--r--gtk/gtkcanvassize.c432
-rw-r--r--gtk/gtkcanvassizeprivate.h84
-rw-r--r--gtk/gtkcanvasvec2.c343
-rw-r--r--gtk/gtkcanvasvec2private.h99
-rw-r--r--gtk/meson.build1
15 files changed, 695 insertions, 774 deletions
diff --git a/demos/gtk-demo/canvas_intro.c b/demos/gtk-demo/canvas_intro.c
index 7216b7a7e7..715bb2529f 100644
--- a/demos/gtk-demo/canvas_intro.c
+++ b/demos/gtk-demo/canvas_intro.c
@@ -27,7 +27,7 @@ bind_item (GtkListItemFactory *factory,
0.0, 0.0);
gtk_canvas_point_free (point);
- point = gtk_canvas_point_new_from_box (box, 0.5, 0.5, 0, 0);
+ point = gtk_canvas_point_new_from_box (box, 0.5, 0.5);
gtk_canvas_box_free (box);
size = gtk_canvas_size_new_measure_item (ci, GTK_CANVAS_ITEM_MEASURE_MIN_FOR_MIN);
box = gtk_canvas_box_new (point, size, 0.5, 0.5);
diff --git a/demos/gtk-demo/canvas_puzzle.c b/demos/gtk-demo/canvas_puzzle.c
index 07b0d5f66d..c30d24a346 100644
--- a/demos/gtk-demo/canvas_puzzle.c
+++ b/demos/gtk-demo/canvas_puzzle.c
@@ -27,7 +27,7 @@ set_item_position (GtkCanvasItem *ci,
0.0, 0.0);
gtk_canvas_point_free (point);
- point = gtk_canvas_point_new_from_box (viewport, x, y, 0, 0);
+ point = gtk_canvas_point_new_from_box (viewport, x, y);
gtk_canvas_box_free (viewport);
size = gtk_canvas_size_new (0, 0);
box = gtk_canvas_box_new (point, size, x, y);
diff --git a/gtk/gtkcanvas.c b/gtk/gtkcanvas.c
index e7047be63f..a1aef6f566 100644
--- a/gtk/gtkcanvas.c
+++ b/gtk/gtkcanvas.c
@@ -23,7 +23,8 @@
#include "gtkcanvasbox.h"
#include "gtkcanvasitemprivate.h"
-#include "gtkcanvassizeprivate.h"
+#include "gtkcanvassize.h"
+#include "gtkcanvasvec2private.h"
#include "gtkintl.h"
#include "gtklistitemfactory.h"
#include "gtkwidgetprivate.h"
@@ -53,7 +54,7 @@ struct _GtkCanvas
GtkCanvasItems items;
GHashTable *item_lookup;
- GtkCanvasSize viewport_size;
+ GtkCanvasVec2 viewport_size;
};
enum
@@ -164,7 +165,7 @@ gtk_canvas_finalize (GObject *object)
GtkCanvas *self = GTK_CANVAS (object);
g_hash_table_unref (self->item_lookup);
- gtk_canvas_size_finish (&self->viewport_size);
+ gtk_canvas_vec2_finish (&self->viewport_size);
G_OBJECT_CLASS (gtk_canvas_parent_class)->finalize (object);
}
@@ -218,6 +219,19 @@ gtk_canvas_set_property (GObject *object,
}
static void
+gtk_canvas_validate_variables (GtkCanvas *self)
+{
+ int i;
+
+ for (i = 0; i < gtk_canvas_items_get_size (&self->items); i++)
+ {
+ GtkCanvasItem *ci = gtk_canvas_items_get (&self->items, i);
+
+ gtk_canvas_item_validate_variables (ci);
+ }
+}
+
+static void
gtk_canvas_allocate (GtkWidget *widget,
int width,
int height,
@@ -226,8 +240,9 @@ gtk_canvas_allocate (GtkWidget *widget,
GtkCanvas *self = GTK_CANVAS (widget);
gsize i;
- self->viewport_size.reference.reference->width = width;
- self->viewport_size.reference.reference->height = height;
+ gtk_canvas_validate_variables (self);
+
+ gtk_canvas_vec2_init_constant (gtk_canvas_vec2_get_variable (&self->viewport_size), width, height);
for (i = 0; i < gtk_canvas_items_get_size (&self->items); i++)
{
@@ -317,8 +332,7 @@ gtk_canvas_init (GtkCanvas *self)
{
self->item_lookup = g_hash_table_new (g_direct_hash, g_direct_equal);
- gtk_canvas_size_init_reference (&self->viewport_size,
- g_rc_box_new0 (graphene_size_t));
+ gtk_canvas_vec2_init_variable (&self->viewport_size);
}
/**
@@ -494,5 +508,5 @@ gtk_canvas_lookup_item (GtkCanvas *self,
const GtkCanvasSize *
gtk_canvas_get_viewport_size (GtkCanvas *self)
{
- return &self->viewport_size;
+ return (const GtkCanvasSize *) &self->viewport_size;
}
diff --git a/gtk/gtkcanvasbox.c b/gtk/gtkcanvasbox.c
index 48b31fdc92..52dac1f7cc 100644
--- a/gtk/gtkcanvasbox.c
+++ b/gtk/gtkcanvasbox.c
@@ -31,9 +31,6 @@
#include "gtkcanvasboxprivate.h"
-#include "gtkcanvaspointprivate.h"
-#include "gtkcanvassizeprivate.h"
-
/* {{{ Boilerplate */
G_DEFINE_BOXED_TYPE (GtkCanvasBox, gtk_canvas_box,
@@ -41,33 +38,28 @@ G_DEFINE_BOXED_TYPE (GtkCanvasBox, gtk_canvas_box,
gtk_canvas_box_free)
void
-gtk_canvas_box_init (GtkCanvasBox *self,
- const GtkCanvasPoint *point,
- const GtkCanvasSize *size,
- float origin_x,
- float origin_y)
+gtk_canvas_box_init (GtkCanvasBox *self,
+ const GtkCanvasVec2 *point,
+ const GtkCanvasVec2 *size,
+ const graphene_vec2_t *origin)
{
- gtk_canvas_point_init_copy (&self->point, point);
- gtk_canvas_size_init_copy (&self->size, size);
- self->origin_x = origin_x;
- self->origin_y = origin_y;
+ gtk_canvas_vec2_init_copy (&self->point, point);
+ gtk_canvas_vec2_init_copy (&self->size, size);
+ graphene_vec2_init_from_vec2 (&self->origin, origin);
}
void
gtk_canvas_box_init_copy (GtkCanvasBox *self,
const GtkCanvasBox *source)
{
- gtk_canvas_point_init_copy (&self->point, &source->point);
- gtk_canvas_size_init_copy (&self->size, &source->size);
- self->origin_x = source->origin_x;
- self->origin_y = source->origin_y;
+ gtk_canvas_box_init (self, &source->point, &source->size, &source->origin);
}
void
gtk_canvas_box_finish (GtkCanvasBox *self)
{
- gtk_canvas_point_finish (&self->point);
- gtk_canvas_size_finish (&self->size);
+ gtk_canvas_vec2_finish (&self->point);
+ gtk_canvas_vec2_finish (&self->size);
}
/**
@@ -84,15 +76,23 @@ GtkCanvasBox *
gtk_canvas_box_new_points (const GtkCanvasPoint *point1,
const GtkCanvasPoint *point2)
{
- GtkCanvasSize size;
+ GtkCanvasVec2 size;
GtkCanvasBox *result;
+ graphene_vec2_t minus_one;
g_return_val_if_fail (point1 != NULL, NULL);
g_return_val_if_fail (point2 != NULL, NULL);
- gtk_canvas_size_init_distance (&size, point1, point2);
- result = gtk_canvas_box_new (point1, &size, 0, 0);
- gtk_canvas_size_finish (&size);
+ graphene_vec2_init (&minus_one, -1.f, -1.f);
+ gtk_canvas_vec2_init_sum (&size,
+ graphene_vec2_one (),
+ point2,
+ &minus_one,
+ point1,
+ NULL);
+ result = g_slice_new (GtkCanvasBox);
+ gtk_canvas_box_init (result, (GtkCanvasVec2 *) point1, &size, graphene_vec2_zero ());
+ gtk_canvas_vec2_finish (&size);
return result;
}
@@ -118,13 +118,18 @@ gtk_canvas_box_new (const GtkCanvasPoint *point,
float origin_y)
{
GtkCanvasBox *self;
+ graphene_vec2_t origin;
g_return_val_if_fail (point != NULL, NULL);
g_return_val_if_fail (size != NULL, NULL);
- self = g_slice_new (GtkCanvasBox);
+ graphene_vec2_init (&origin, origin_x, origin_y);
- gtk_canvas_box_init (self, point, size, origin_x, origin_y);
+ self = g_slice_new (GtkCanvasBox);
+ gtk_canvas_box_init (self,
+ (GtkCanvasVec2 *) point,
+ (GtkCanvasVec2 *) size,
+ &origin);
return self;
}
@@ -132,9 +137,14 @@ gtk_canvas_box_new (const GtkCanvasPoint *point,
GtkCanvasBox *
gtk_canvas_box_copy (const GtkCanvasBox *self)
{
+ GtkCanvasBox *copy;
+
g_return_val_if_fail (self != NULL, NULL);
- return gtk_canvas_box_new (&self->point, &self->size, self->origin_x, self->origin_y);
+ copy = g_slice_new (GtkCanvasBox);
+ gtk_canvas_box_init_copy (copy, self);
+
+ return copy;
}
void
@@ -149,15 +159,28 @@ gboolean
gtk_canvas_box_eval (const GtkCanvasBox *self,
graphene_rect_t *rect)
{
+ graphene_vec2_t point, size, tmp;
+
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (rect != NULL, FALSE);
- if (gtk_canvas_point_eval (&self->point, &rect->origin.x, &rect->origin.y) &&
- gtk_canvas_size_eval (&self->size, &rect->size.width, &rect->size.height))
- return TRUE;
+ if (!gtk_canvas_vec2_eval (&self->point, &point) ||
+ !gtk_canvas_vec2_eval (&self->size, &size))
+ {
+ *rect = *graphene_rect_zero ();
+ return FALSE;
+ }
+
+ graphene_vec2_multiply (&self->origin, &size, &tmp);
+ graphene_vec2_subtract (&point, &tmp, &point);
+
+ graphene_rect_init (rect,
+ graphene_vec2_get_x (&point),
+ graphene_vec2_get_y (&point),
+ graphene_vec2_get_x (&size),
+ graphene_vec2_get_y (&size));
- *rect = *graphene_rect_zero ();
- return FALSE;
+ return TRUE;
}
const GtkCanvasPoint *
@@ -165,7 +188,7 @@ gtk_canvas_box_get_point (const GtkCanvasBox *self)
{
g_return_val_if_fail (self != NULL, NULL);
- return &self->point;
+ return (GtkCanvasPoint *) &self->point;
}
const GtkCanvasSize *
@@ -173,7 +196,7 @@ gtk_canvas_box_get_size (const GtkCanvasBox *self)
{
g_return_val_if_fail (self != NULL, NULL);
- return &self->size;
+ return (GtkCanvasSize *) &self->size;
}
void
@@ -184,7 +207,7 @@ gtk_canvas_box_get_origin (const GtkCanvasBox *self,
g_return_if_fail (self != NULL);
if (x)
- *x = self->origin_x;
+ *x = graphene_vec2_get_x (&self->origin);
if (y)
- *y = self->origin_y;
+ *y = graphene_vec2_get_y (&self->origin);
}
diff --git a/gtk/gtkcanvasboxprivate.h b/gtk/gtkcanvasboxprivate.h
index 82baa5fb2a..99e7e7f084 100644
--- a/gtk/gtkcanvasboxprivate.h
+++ b/gtk/gtkcanvasboxprivate.h
@@ -3,25 +3,22 @@
#include "gtkcanvasbox.h"
-#include "gtkcanvaspointprivate.h"
-#include "gtkcanvassizeprivate.h"
+#include "gtkcanvasvec2private.h"
G_BEGIN_DECLS
struct _GtkCanvasBox
{
- GtkCanvasPoint point;
- GtkCanvasSize size;
- float origin_x;
- float origin_y;
+ GtkCanvasVec2 point;
+ GtkCanvasVec2 size;
+ graphene_vec2_t origin;
};
void gtk_canvas_box_init (GtkCanvasBox *self,
- const GtkCanvasPoint *point,
- const GtkCanvasSize *size,
- float origin_x,
- float origin_y);
+ const GtkCanvasVec2 *point,
+ const GtkCanvasVec2 *size,
+ const graphene_vec2_t *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 1a56374a9b..b5def0b8ba 100644
--- a/gtk/gtkcanvasitem.c
+++ b/gtk/gtkcanvasitem.c
@@ -23,8 +23,6 @@
#include "gtkcanvas.h"
#include "gtkcanvasboxprivate.h"
-#include "gtkcanvaspointprivate.h"
-#include "gtkcanvassizeprivate.h"
#include "gtkintl.h"
#include "gtklistitemfactoryprivate.h"
#include "gtkwidget.h"
@@ -44,6 +42,8 @@ struct _GtkCanvasItem
gpointer item;
GtkWidget *widget;
GtkCanvasBox bounds;
+
+ GtkCanvasVec2 size_vecs[4];
};
enum
@@ -78,6 +78,18 @@ gtk_canvas_item_dispose (GObject *object)
}
static void
+gtk_canvas_item_finalize (GObject *object)
+{
+ GtkCanvasItem *self = GTK_CANVAS_ITEM (object);
+ int i;
+
+ for (i = 0; i < 4; i++)
+ gtk_canvas_vec2_finish (&self->size_vecs[i]);
+
+ G_OBJECT_CLASS (gtk_canvas_item_parent_class)->finalize (object);
+}
+
+static void
gtk_canvas_item_get_property (GObject *object,
guint property_id,
GValue *value,
@@ -139,6 +151,7 @@ gtk_canvas_item_class_init (GtkCanvasItemClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = gtk_canvas_item_dispose;
+ gobject_class->finalize = gtk_canvas_item_finalize;
gobject_class->get_property = gtk_canvas_item_get_property;
gobject_class->set_property = gtk_canvas_item_set_property;
@@ -188,14 +201,14 @@ gtk_canvas_item_class_init (GtkCanvasItemClass *klass)
static void
gtk_canvas_item_init (GtkCanvasItem *self)
{
- GtkCanvasPoint point;
- GtkCanvasSize size;
-
- gtk_canvas_point_init (&point, 0, 0);
- gtk_canvas_size_init_measure_item (&size, self, GTK_CANVAS_ITEM_MEASURE_NAT_FOR_NAT);
- gtk_canvas_box_init (&self->bounds, &point, &size, 0, 0);
- gtk_canvas_size_finish (&size);
- gtk_canvas_point_finish (&point);
+ int i;
+
+ for (i = 0; i < 4; i++)
+ gtk_canvas_vec2_init_variable (&self->size_vecs[i]);
+
+ gtk_canvas_vec2_init_constant (&self->bounds.point, 0, 0);
+ gtk_canvas_vec2_init_copy (&self->bounds.size, &self->size_vecs[GTK_CANVAS_ITEM_MEASURE_NAT_FOR_NAT]);
+ graphene_vec2_init (&self->bounds.origin, 0, 0);
}
GtkCanvasItem *
@@ -215,6 +228,51 @@ gtk_canvas_item_new (GtkCanvas *canvas,
return self;
}
+void
+gtk_canvas_item_validate_variables (GtkCanvasItem *self)
+{
+ int w[4], h[4], i;
+
+ if (self->widget == NULL)
+ {
+ memset (w, 0, sizeof (w));
+ memset (h, 0, sizeof (h));
+ }
+ else
+ {
+ if (gtk_widget_get_request_mode (self->widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+ {
+ gtk_widget_measure (self->widget, GTK_ORIENTATION_HORIZONTAL, -1, &w[0], &w[2], NULL, NULL);
+ w[1] = w[0];
+ gtk_widget_measure (self->widget, GTK_ORIENTATION_VERTICAL, w[0], &h[0], &h[1], NULL, NULL);
+ w[3] = w[2];
+ gtk_widget_measure (self->widget, GTK_ORIENTATION_VERTICAL, w[2], &h[2], &h[3], NULL, NULL);
+ }
+ else
+ {
+ gtk_widget_measure (self->widget, GTK_ORIENTATION_VERTICAL, -1, &h[0], &h[2], NULL, NULL);
+ h[1] = h[0];
+ gtk_widget_measure (self->widget, GTK_ORIENTATION_HORIZONTAL, h[0], &w[0], &w[1], NULL, NULL);
+ h[3] = h[2];
+ gtk_widget_measure (self->widget, GTK_ORIENTATION_HORIZONTAL, h[2], &w[2], &w[3], NULL, NULL);
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ gtk_canvas_vec2_init_constant (
+ gtk_canvas_vec2_get_variable (&self->size_vecs[i]),
+ 0, 0);
+ }
+}
+
+const GtkCanvasVec2 *
+gtk_canvas_item_get_measure_vec2 (GtkCanvasItem *self,
+ GtkCanvasItemMeasurement measure)
+{
+ return &self->size_vecs[measure];
+}
+
/**
* gtk_canvas_item_get_canvas: (attributes org.gtk.Method.get_property=canvas)
* @self: a `GtkCanvasItem`
diff --git a/gtk/gtkcanvasitemprivate.h b/gtk/gtkcanvasitemprivate.h
index f22916e925..49724204ff 100644
--- a/gtk/gtkcanvasitemprivate.h
+++ b/gtk/gtkcanvasitemprivate.h
@@ -3,11 +3,18 @@
#include "gtkcanvasitem.h"
+#include "gtkcanvassize.h"
+#include "gtkcanvasvec2private.h"
+
G_BEGIN_DECLS
GtkCanvasItem * gtk_canvas_item_new (GtkCanvas *canvas,
gpointer item);
+void gtk_canvas_item_validate_variables (GtkCanvasItem *self);
+const GtkCanvasVec2 * gtk_canvas_item_get_measure_vec2 (GtkCanvasItem *self,
+ GtkCanvasItemMeasurement measure);
+
void gtk_canvas_item_clear_canvas (GtkCanvasItem *self);
void gtk_canvas_item_setup (GtkCanvasItem *self,
diff --git a/gtk/gtkcanvaspoint.c b/gtk/gtkcanvaspoint.c
index df812b5cf4..e5536ebc7a 100644
--- a/gtk/gtkcanvaspoint.c
+++ b/gtk/gtkcanvaspoint.c
@@ -26,121 +26,24 @@
#include "config.h"
-#include "gtkcanvaspointprivate.h"
+#include "gtkcanvaspoint.h"
-#include "gtkcanvasbox.h"
-
-/* {{{ Boilerplate */
-
-struct _GtkCanvasPointClass
-{
- const char *type_name;
-
- void (* copy) (GtkCanvasPoint *self,
- const GtkCanvasPoint *source);
- void (* finish) (GtkCanvasPoint *self);
- gboolean (* eval) (const GtkCanvasPoint *self,
- float *x,
- float *y);
-};
+#include "gtkcanvasboxprivate.h"
+#include "gtkcanvasvec2private.h"
G_DEFINE_BOXED_TYPE (GtkCanvasPoint, gtk_canvas_point,
gtk_canvas_point_copy,
gtk_canvas_point_free)
-static gpointer
-gtk_canvas_point_alloc (const GtkCanvasPointClass *class)
-{
- GtkCanvasPoint *self = g_slice_new (GtkCanvasPoint);
-
- self->class = class;
-
- return self;
-}
-
-void
-gtk_canvas_point_init_copy (GtkCanvasPoint *self,
- const GtkCanvasPoint *source)
-{
- self->class = source->class;
- self->class->copy (self, source);
-}
-
-void
-gtk_canvas_point_finish (GtkCanvasPoint *self)
-{
- self->class->finish (self);
-}
-
-/* }}} */
-/* {{{ OFFSET */
-
-static void
-gtk_canvas_point_offset_copy (GtkCanvasPoint *point,
- const GtkCanvasPoint *source_point)
+struct _GtkCanvasPoint
{
- GtkCanvasPointOffset *self = &point->offset;
- const GtkCanvasPointOffset *source = &source_point->offset;
-
- *self = *source;
-
- if (source->other)
- self->other = gtk_canvas_point_copy (source->other);
-}
-
-static void
-gtk_canvas_point_offset_finish (GtkCanvasPoint *point)
-{
- GtkCanvasPointOffset *self = &point->offset;
-
- if (self->other)
- gtk_canvas_point_free (self->other);
-}
-
-static gboolean
-gtk_canvas_point_offset_eval (const GtkCanvasPoint *point,
- float *x,
- float *y)
-{
- const GtkCanvasPointOffset *self = &point->offset;
-
- if (self->other != NULL)
- {
- if (!gtk_canvas_point_eval (self->other, x, y))
- return FALSE;
-
- *x += self->dx;
- *y += self->dy;
- }
- else
- {
- *x = self->dx;
- *y = self->dy;
- }
-
- return TRUE;
-}
-
-static const GtkCanvasPointClass GTK_CANVAS_POINT_OFFSET_CLASS =
-{
- "GtkCanvasPointOffset",
- gtk_canvas_point_offset_copy,
- gtk_canvas_point_offset_finish,
- gtk_canvas_point_offset_eval,
+ GtkCanvasVec2 vec2;
};
-void
-gtk_canvas_point_init (GtkCanvasPoint *point,
- float x,
- float y)
+static GtkCanvasPoint *
+gtk_canvas_point_alloc (void)
{
- GtkCanvasPointOffset *self = &point->offset;
-
- self->class = &GTK_CANVAS_POINT_OFFSET_CLASS;
-
- self->other = NULL;
- self->dx = x;
- self->dy = y;
+ return g_slice_new (GtkCanvasPoint);
}
/**
@@ -158,68 +61,17 @@ gtk_canvas_point_new (float x,
{
GtkCanvasPoint *self;
- self = gtk_canvas_point_alloc (&GTK_CANVAS_POINT_OFFSET_CLASS);
-
- gtk_canvas_point_init (self, x, y);
+ self = gtk_canvas_point_alloc ();
+ gtk_canvas_vec2_init_constant (&self->vec2, x, y);
return self;
}
-/* }}} */
-/* {{{ BOX */
-
-static void
-gtk_canvas_point_box_copy (GtkCanvasPoint *point,
- const GtkCanvasPoint *source_point)
-{
- GtkCanvasPointBox *self = &point->box;
- const GtkCanvasPointBox *source = &source_point->box;
-
- *self = *source;
-
- self->box = gtk_canvas_box_copy (source->box);
-}
-
-static void
-gtk_canvas_point_box_finish (GtkCanvasPoint *point)
-{
- GtkCanvasPointBox *self = &point->box;
-
- gtk_canvas_box_free (self->box);
-}
-
-static gboolean
-gtk_canvas_point_box_eval (const GtkCanvasPoint *point,
- float *x,
- float *y)
-{
- const GtkCanvasPointBox *self = &point->box;
- graphene_rect_t rect;
-
- if (!gtk_canvas_box_eval (self->box, &rect))
- return FALSE;
-
- *x = rect.origin.x + self->offset_x + self->origin_x * rect.size.width;
- *y = rect.origin.y + self->offset_y + self->origin_y * rect.size.height;
-
- return TRUE;
-}
-
-static const GtkCanvasPointClass GTK_CANVAS_POINT_BOX_CLASS =
-{
- "GtkCanvasPointBox",
- gtk_canvas_point_box_copy,
- gtk_canvas_point_box_finish,
- gtk_canvas_point_box_eval,
-};
-
/**
* gtk_canvas_point_new_from_box:
* @box: a box
* @origin_x: x coordinate of box origin
* @origin_y: y coordinate of box origin
- * @offset_x: offset in x direction
- * @offset_y: offset in y direction
*
* Creates a point relative to the given box.
*
@@ -227,35 +79,31 @@ static const GtkCanvasPointClass GTK_CANVAS_POINT_BOX_CLASS =
* (0, 0) being the top left and (1, 1) being the bottom right
* corner of the box.
*
- * The offset is then added to the origin. It may be negative.
- *
* Returns: a new point
**/
GtkCanvasPoint *
gtk_canvas_point_new_from_box (const GtkCanvasBox *box,
float origin_x,
- float origin_y,
- float offset_x,
- float offset_y)
+ float origin_y)
{
- GtkCanvasPointBox *self;
-
+ GtkCanvasPoint *self;
+ graphene_vec2_t origin;
+
g_return_val_if_fail (box != NULL, NULL);
-
- self = gtk_canvas_point_alloc (&GTK_CANVAS_POINT_BOX_CLASS);
-
- self->box = gtk_canvas_box_copy (box);
- self->origin_x = origin_x;
- self->origin_y = origin_y;
- self->offset_x = offset_x;
- self->offset_y = offset_y;
-
- return (GtkCanvasPoint *) self;
+
+ graphene_vec2_init (&origin, origin_x, origin_y);
+ graphene_vec2_subtract (&origin, &box->origin, &origin);
+
+ self = gtk_canvas_point_alloc ();
+ gtk_canvas_vec2_init_sum (&self->vec2,
+ graphene_vec2_one (),
+ &box->point,
+ &origin,
+ &box->size,
+ NULL);
+ return self;
}
-/* }}} */
-/* {{{ PUBLIC API */
-
GtkCanvasPoint *
gtk_canvas_point_copy (const GtkCanvasPoint *self)
{
@@ -263,9 +111,8 @@ gtk_canvas_point_copy (const GtkCanvasPoint *self)
g_return_val_if_fail (self != NULL, NULL);
- copy = gtk_canvas_point_alloc (self->class);
-
- gtk_canvas_point_init_copy (copy, self);
+ copy = gtk_canvas_point_alloc ();
+ gtk_canvas_vec2_init_copy (&copy->vec2, &self->vec2);
return copy;
}
@@ -273,7 +120,7 @@ gtk_canvas_point_copy (const GtkCanvasPoint *self)
void
gtk_canvas_point_free (GtkCanvasPoint *self)
{
- gtk_canvas_point_finish (self);
+ gtk_canvas_vec2_finish (&self->vec2);
g_slice_free (GtkCanvasPoint, self);
}
@@ -283,15 +130,21 @@ gtk_canvas_point_eval (const GtkCanvasPoint *self,
float *x,
float *y)
{
+ graphene_vec2_t vec2;
+
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (x != NULL, FALSE);
g_return_val_if_fail (y != NULL, FALSE);
- if (self->class->eval (self, x, y))
- return TRUE;
+ if (!gtk_canvas_vec2_eval (&self->vec2, &vec2))
+ {
+ *x = 0;
+ *y = 0;
+ return FALSE;
+ }
- *x = 0;
- *y = 0;
- return FALSE;
+ *x = graphene_vec2_get_x (&vec2);
+ *y = graphene_vec2_get_y (&vec2);
+ return TRUE;
}
diff --git a/gtk/gtkcanvaspoint.h b/gtk/gtkcanvaspoint.h
index 5a35ba3423..f59db58e1a 100644
--- a/gtk/gtkcanvaspoint.h
+++ b/gtk/gtkcanvaspoint.h
@@ -50,9 +50,7 @@ GtkCanvasPoint * gtk_canvas_point_new (float
GDK_AVAILABLE_IN_ALL
GtkCanvasPoint * gtk_canvas_point_new_from_box (const GtkCanvasBox *box,
float origin_x,
- float origin_y,
- float offset_x,
- float offset_y);
+ float origin_y);
GDK_AVAILABLE_IN_ALL
GtkCanvasPoint * gtk_canvas_point_new_from_item (GtkCanvasItem *item,
float origin_x,
diff --git a/gtk/gtkcanvaspointprivate.h b/gtk/gtkcanvaspointprivate.h
deleted file mode 100644
index 1d10efa6b3..0000000000
--- a/gtk/gtkcanvaspointprivate.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef __GTK_CANVAS_POINT_PRIVATE_H__
-#define __GTK_CANVAS_POINT_PRIVATE_H__
-
-#include "gtkcanvaspoint.h"
-
-G_BEGIN_DECLS
-
-typedef struct _GtkCanvasPointClass GtkCanvasPointClass;
-typedef struct _GtkCanvasPointBox GtkCanvasPointBox;
-typedef struct _GtkCanvasPointItem GtkCanvasPointItem;
-typedef struct _GtkCanvasPointOffset GtkCanvasPointOffset;
-
-struct _GtkCanvasPointBox
-{
- const GtkCanvasPointClass *class;
-
- GtkCanvasBox *box;
- float origin_x;
- float origin_y;
- float offset_x;
- float offset_y;
-};
-
-struct _GtkCanvasPointOffset
-{
- const GtkCanvasPointClass *class;
-
- GtkCanvasPoint *other;
- float dx;
- float dy;
-};
-
-struct _GtkCanvasPoint
-{
- union {
- const GtkCanvasPointClass *class;
- GtkCanvasPointBox box;
- GtkCanvasPointOffset offset;
- };
-};
-
-
-void gtk_canvas_point_init (GtkCanvasPoint * point,
- float x,
- float y);
-void gtk_canvas_point_init_copy (GtkCanvasPoint *self,
- const GtkCanvasPoint *source);
-void gtk_canvas_point_finish (GtkCanvasPoint *self);
-
-G_END_DECLS
-
-#endif /* __GTK_CANVAS_POINT_PRIVATE_H__ */
diff --git a/gtk/gtkcanvassize.c b/gtk/gtkcanvassize.c
index 81fcba2d19..a706def6af 100644
--- a/gtk/gtkcanvassize.c
+++ b/gtk/gtkcanvassize.c
@@ -26,94 +26,28 @@
#include "config.h"
-#include "gtkcanvassizeprivate.h"
+#include "gtkcanvassize.h"
-#include "gtkcanvasbox.h"
-#include "gtkcanvasitem.h"
+#include "gtkcanvasboxprivate.h"
+#include "gtkcanvasitemprivate.h"
#include "gtkcanvaspoint.h"
-#include "gtkwidget.h"
-
-/* {{{ Boilerplate */
-
-struct _GtkCanvasSizeClass
-{
- const char *type_name;
-
- void (* copy) (GtkCanvasSize *self,
- const GtkCanvasSize *source);
- void (* finish) (GtkCanvasSize *self);
- gboolean (* eval) (const GtkCanvasSize *self,
- float *width,
- float *height);
-};
+#include "gtkcanvasvec2private.h"
G_DEFINE_BOXED_TYPE (GtkCanvasSize, gtk_canvas_size,
gtk_canvas_size_copy,
gtk_canvas_size_free)
-static gpointer
-gtk_canvas_size_alloc (const GtkCanvasSizeClass *class)
-{
- GtkCanvasSize *self = g_slice_new (GtkCanvasSize);
-
- self->class = class;
-
- return self;
-}
-
-void
-gtk_canvas_size_init_copy (GtkCanvasSize *self,
- const GtkCanvasSize *source)
-{
- self->class = source->class;
- self->class->copy (self, source);
-}
-
-void
-gtk_canvas_size_finish (GtkCanvasSize *self)
-{
- self->class->finish (self);
-}
-
-/* }}} */
-/* {{{ ABSOLUTE */
-
-static void
-gtk_canvas_size_absolute_copy (GtkCanvasSize *size,
- const GtkCanvasSize *source_size)
+struct _GtkCanvasSize
{
- GtkCanvasSizeAbsolute *self = &size->absolute;
- const GtkCanvasSizeAbsolute *source = &source_size->absolute;
-
- *self = *source;
-}
-
-static void
-gtk_canvas_size_absolute_finish (GtkCanvasSize *size)
-{
-}
+ GtkCanvasVec2 vec2;
+};
-static gboolean
-gtk_canvas_size_absolute_eval (const GtkCanvasSize *size,
- float *width,
- float *height)
+static GtkCanvasSize *
+gtk_canvas_size_alloc (void)
{
- const GtkCanvasSizeAbsolute *self = &size->absolute;
-
- *width = self->width;
- *height = self->height;
-
- return TRUE;
+ return g_slice_new (GtkCanvasSize);
}
-static const GtkCanvasSizeClass GTK_CANVAS_SIZE_ABSOLUTE_CLASS =
-{
- "GtkCanvasSizeAbsolute",
- gtk_canvas_size_absolute_copy,
- gtk_canvas_size_absolute_finish,
- gtk_canvas_size_absolute_eval,
-};
-
/**
* gtk_canvas_size_new:
* @width: width of the size
@@ -127,63 +61,14 @@ GtkCanvasSize *
gtk_canvas_size_new (float width,
float height)
{
- GtkCanvasSizeAbsolute *self;
-
- self = gtk_canvas_size_alloc (&GTK_CANVAS_SIZE_ABSOLUTE_CLASS);
- self->width = width;
- self->height = height;
-
- return (GtkCanvasSize *) self;
-}
-
-/* }}} */
-/* {{{ BOX */
-
-static void
-gtk_canvas_size_box_copy (GtkCanvasSize *size,
- const GtkCanvasSize *source_size)
-{
- GtkCanvasSizeBox *self = &size->box;
- const GtkCanvasSizeBox *source = &source_size->box;
-
- *self = *source;
-
- self->box = gtk_canvas_box_copy (source->box);
-}
-
-static void
-gtk_canvas_size_box_finish (GtkCanvasSize *size)
-{
- GtkCanvasSizeBox *self = &size->box;
-
- gtk_canvas_box_free (self->box);
-}
-
-static gboolean
-gtk_canvas_size_box_eval (const GtkCanvasSize *size,
- float *width,
- float *height)
-{
- const GtkCanvasSizeBox *self = &size->box;
- graphene_rect_t rect;
-
- if (!gtk_canvas_box_eval (self->box, &rect))
- return FALSE;
+ GtkCanvasSize *self;
- *width = rect.size.width;
- *height = rect.size.height;
+ self = gtk_canvas_size_alloc ();
+ gtk_canvas_vec2_init_constant (&self->vec2, width, height);
- return TRUE;
+ return self;
}
-static const GtkCanvasSizeClass GTK_CANVAS_SIZE_BOX_CLASS =
-{
- "GtkCanvasSizeBox",
- gtk_canvas_size_box_copy,
- gtk_canvas_size_box_finish,
- gtk_canvas_size_box_eval,
-};
-
/**
* gtk_canvas_size_new_from_box:
* @box: a box
@@ -195,76 +80,12 @@ static const GtkCanvasSizeClass GTK_CANVAS_SIZE_BOX_CLASS =
GtkCanvasSize *
gtk_canvas_size_new_from_box (const GtkCanvasBox *box)
{
- GtkCanvasSizeBox *self;
-
- g_return_val_if_fail (box != NULL, NULL);
-
- self = gtk_canvas_size_alloc (&GTK_CANVAS_SIZE_BOX_CLASS);
-
- /* FIXME: We could potentially just copy the box's size here */
- self->box = gtk_canvas_box_copy (box);
-
- return (GtkCanvasSize *) self;
-}
-
-/* }}} */
-/* {{{ DISTANCE */
-
-static void
-gtk_canvas_size_distance_copy (GtkCanvasSize *size,
- const GtkCanvasSize *source_size)
-{
- const GtkCanvasSizeDistance *source = &source_size->distance;
-
- gtk_canvas_size_init_distance (size, source->from, source->to);
-}
-
-static void
-gtk_canvas_size_distance_finish (GtkCanvasSize *size)
-{
- GtkCanvasSizeDistance *self = &size->distance;
-
- gtk_canvas_point_free (self->from);
- gtk_canvas_point_free (self->to);
-}
-
-static gboolean
-gtk_canvas_size_distance_eval (const GtkCanvasSize *size,
- float *width,
- float *height)
-{
- const GtkCanvasSizeDistance *self = &size->distance;
- float x1, y1, x2, y2;
-
- if (!gtk_canvas_point_eval (self->from, &x1, &y1) ||
- !gtk_canvas_point_eval (self->from, &x2, &y2))
- return FALSE;
-
- *width = x1 - x2;
- *height = y1 - y2;
-
- return TRUE;
-}
-
-static const GtkCanvasSizeClass GTK_CANVAS_SIZE_DISTANCE_CLASS =
-{
- "GtkCanvasSizeDistance",
- gtk_canvas_size_distance_copy,
- gtk_canvas_size_distance_finish,
- gtk_canvas_size_distance_eval,
-};
+ GtkCanvasSize *self;
-void
-gtk_canvas_size_init_distance (GtkCanvasSize *size,
- const GtkCanvasPoint *from,
- const GtkCanvasPoint *to)
-{
- GtkCanvasSizeDistance *self = &size->distance;
-
- self->class = &GTK_CANVAS_SIZE_DISTANCE_CLASS;
+ self = gtk_canvas_size_alloc ();
+ gtk_canvas_vec2_init_copy (&self->vec2, &box->size);
- self->from = gtk_canvas_point_copy (from);
- self->to = gtk_canvas_point_copy (to);
+ return self;
}
/**
@@ -273,7 +94,8 @@ gtk_canvas_size_init_distance (GtkCanvasSize *size,
* @to: point to where to compute the distance
*
* Creates a size for the given distance. Note that both width and height
- * can be negative if @to is smaller than @from in the corresponding dimension.
+ * can be negative if the coordinate of @to is smaller than @from in the
+ * corresponding dimension.
*
* Returns: a new size
**/
@@ -282,134 +104,24 @@ gtk_canvas_size_new_distance (const GtkCanvasPoint *from,
const GtkCanvasPoint *to)
{
GtkCanvasSize *self;
+ graphene_vec2_t minus_one;
g_return_val_if_fail (from != NULL, NULL);
g_return_val_if_fail (to != NULL, NULL);
- self = gtk_canvas_size_alloc (&GTK_CANVAS_SIZE_DISTANCE_CLASS);
+ graphene_vec2_init (&minus_one, -1.f, -1.f);
- gtk_canvas_size_init_distance (self, from, to);
+ self = gtk_canvas_size_alloc ();
+ gtk_canvas_vec2_init_sum (&self->vec2,
+ graphene_vec2_one (),
+ from,
+ &minus_one,
+ to,
+ NULL);
return self;
}
-/* }}} */
-/* {{{ MEASURE */
-
-static void
-gtk_canvas_size_measure_copy (GtkCanvasSize *size,
- const GtkCanvasSize *source_size)
-{
- const GtkCanvasSizeMeasure *source = &source_size->measure;
-
- gtk_canvas_size_init_measure_item (size, source->item, source->measure);
-}
-
-static void
-gtk_canvas_size_measure_finish (GtkCanvasSize *size)
-{
-}
-
-static gboolean
-gtk_canvas_size_measure_eval (const GtkCanvasSize *size,
- float *width,
- float *height)
-{
- const GtkCanvasSizeMeasure *self = &size->measure;
- GtkWidget *widget;
- int w, h;
-
- if (self->item == NULL)
- return FALSE;
-
- widget = gtk_canvas_item_get_widget (self->item);
- if (widget == NULL)
- {
- *width = 0;
- *height = 0;
- return TRUE;
- }
-
- if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
- {
- switch (self->measure)
- {
- case GTK_CANVAS_ITEM_MEASURE_MIN_FOR_MIN:
- gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1, &w, NULL, NULL, NULL);
- gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, w, &h, NULL, NULL, NULL);
- break;
- case GTK_CANVAS_ITEM_MEASURE_MIN_FOR_NAT:
- gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1, NULL, &w, NULL, NULL);
- gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, w, &h, NULL, NULL, NULL);
- break;
- case GTK_CANVAS_ITEM_MEASURE_NAT_FOR_MIN:
- gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1, &w, NULL, NULL, NULL);
- gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, w, NULL, &h, NULL, NULL);
- break;
- case GTK_CANVAS_ITEM_MEASURE_NAT_FOR_NAT:
- gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1, NULL, &w, NULL, NULL);
- gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, w, NULL, &h, NULL, NULL);
- break;
- default:
- g_assert_not_reached ();
- w = h = 0;
- break;
- }
- }
- else
- {
- switch (self->measure)
- {
- case GTK_CANVAS_ITEM_MEASURE_MIN_FOR_MIN:
- gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, -1, &h, NULL, NULL, NULL);
- gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, h, &w, NULL, NULL, NULL);
- break;
- case GTK_CANVAS_ITEM_MEASURE_MIN_FOR_NAT:
- gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, -1, NULL, &h, NULL, NULL);
- gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, h, &w, NULL, NULL, NULL);
- break;
- case GTK_CANVAS_ITEM_MEASURE_NAT_FOR_MIN:
- gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, -1, &h, NULL, NULL, NULL);
- gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, h, NULL, &w, NULL, NULL);
- break;
- case GTK_CANVAS_ITEM_MEASURE_NAT_FOR_NAT:
- gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, -1, NULL, &h, NULL, NULL);
- gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, h, NULL, &w, NULL, NULL);
- break;
- default:
- g_assert_not_reached ();
- w = h = 0;
- break;
- }
- }
-
- *width = w;
- *height = h;
-
- return TRUE;
-}
-
-static const GtkCanvasSizeClass GTK_CANVAS_SIZE_MEASURE_CLASS =
-{
- "GtkCanvasSizeMeasure",
- gtk_canvas_size_measure_copy,
- gtk_canvas_size_measure_finish,
- gtk_canvas_size_measure_eval,
-};
-
-void
-gtk_canvas_size_init_measure_item (GtkCanvasSize *size,
- GtkCanvasItem *item,
- GtkCanvasItemMeasurement measure)
-{
- GtkCanvasSizeMeasure *self = &size->measure;
-
- self->class = &GTK_CANVAS_SIZE_MEASURE_CLASS;
-
- self->item = item;
- self->measure = measure;
-}
-
/**
* gtk_canvas_size_new_measure_item:
* @item: the item
@@ -428,68 +140,13 @@ gtk_canvas_size_new_measure_item (GtkCanvasItem *item,
g_return_val_if_fail (GTK_IS_CANVAS_ITEM (item), NULL);
- self = gtk_canvas_size_alloc (&GTK_CANVAS_SIZE_MEASURE_CLASS);
-
- gtk_canvas_size_init_measure_item (self, item, measure);
+ self = gtk_canvas_size_alloc ();
+ gtk_canvas_vec2_init_copy (&self->vec2,
+ gtk_canvas_item_get_measure_vec2 (item, measure));
return self;
}
-/* }}} */
-/* {{{ REFERENCE */
-
-static void
-gtk_canvas_size_reference_copy (GtkCanvasSize *size,
- const GtkCanvasSize *source_size)
-{
- const GtkCanvasSizeReference *source = &source_size->reference;
-
- gtk_canvas_size_init_reference (size, g_rc_box_acquire (source->reference));
-}
-
-static void
-gtk_canvas_size_reference_finish (GtkCanvasSize *size)
-{
- const GtkCanvasSizeReference *self = &size->reference;
-
- g_rc_box_release (self->reference);
-}
-
-static gboolean
-gtk_canvas_size_reference_eval (const GtkCanvasSize *size,
- float *width,
- float *height)
-{
- const GtkCanvasSizeReference *self = &size->reference;
-
- *width = self->reference->width;
- *height = self->reference->height;
-
- return TRUE;
-}
-
-static const GtkCanvasSizeClass GTK_CANVAS_SIZE_REFERENCE_CLASS =
-{
- "GtkCanvasSizeReference",
- gtk_canvas_size_reference_copy,
- gtk_canvas_size_reference_finish,
- gtk_canvas_size_reference_eval,
-};
-
-void
-gtk_canvas_size_init_reference (GtkCanvasSize *size,
- graphene_size_t *reference)
-{
- GtkCanvasSizeReference *self = &size->reference;
-
- self->class = &GTK_CANVAS_SIZE_REFERENCE_CLASS;
-
- self->reference = reference;
-}
-
-/* }}} */
-/* {{{ PUBLIC API */
-
GtkCanvasSize *
gtk_canvas_size_copy (const GtkCanvasSize *self)
{
@@ -497,9 +154,8 @@ gtk_canvas_size_copy (const GtkCanvasSize *self)
g_return_val_if_fail (self != NULL, NULL);
- copy = gtk_canvas_size_alloc (self->class);
-
- gtk_canvas_size_init_copy (copy, self);
+ copy = gtk_canvas_size_alloc ();
+ gtk_canvas_vec2_init_copy (&copy->vec2, &self->vec2);
return copy;
}
@@ -507,7 +163,9 @@ gtk_canvas_size_copy (const GtkCanvasSize *self)
void
gtk_canvas_size_free (GtkCanvasSize *self)
{
- gtk_canvas_size_finish (self);
+ g_return_if_fail (self != NULL);
+
+ gtk_canvas_vec2_finish (&self->vec2);
g_slice_free (GtkCanvasSize, self);
}
@@ -517,15 +175,21 @@ gtk_canvas_size_eval (const GtkCanvasSize *self,
float *width,
float *height)
{
+ graphene_vec2_t vec2;
+
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (width != NULL, FALSE);
g_return_val_if_fail (height != NULL, FALSE);
- if (self->class->eval (self, width, height))
- return TRUE;
+ if (!gtk_canvas_vec2_eval (&self->vec2, &vec2))
+ {
+ *width = 0;
+ *height = 0;
+ return FALSE;
+ }
- *width = 0;
- *height = 0;
- return FALSE;
+ *width = graphene_vec2_get_x (&vec2);
+ *height = graphene_vec2_get_y (&vec2);
+ return TRUE;
}
diff --git a/gtk/gtkcanvassizeprivate.h b/gtk/gtkcanvassizeprivate.h
deleted file mode 100644
index fa8dd4cc6b..0000000000
--- a/gtk/gtkcanvassizeprivate.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef __GTK_CANVAS_SIZE_PRIVATE_H__
-#define __GTK_CANVAS_SIZE_PRIVATE_H__
-
-#include "gtkcanvassize.h"
-
-#include <graphene.h>
-
-G_BEGIN_DECLS
-
-typedef struct _GtkCanvasSizeClass GtkCanvasSizeClass;
-typedef struct _GtkCanvasSizeAbsolute GtkCanvasSizeAbsolute;
-typedef struct _GtkCanvasSizeBox GtkCanvasSizeBox;
-typedef struct _GtkCanvasSizeDistance GtkCanvasSizeDistance;
-typedef struct _GtkCanvasSizeMeasure GtkCanvasSizeMeasure;
-typedef struct _GtkCanvasSizeReference GtkCanvasSizeReference;
-
-struct _GtkCanvasSizeAbsolute
-{
- const GtkCanvasSizeClass *class;
-
- float width;
- float height;
-};
-
-struct _GtkCanvasSizeBox
-{
- const GtkCanvasSizeClass *class;
-
- GtkCanvasBox *box;
-};
-
-struct _GtkCanvasSizeDistance
-{
- const GtkCanvasSizeClass *class;
-
- GtkCanvasPoint *from;
- GtkCanvasPoint *to;
-};
-
-struct _GtkCanvasSizeMeasure
-{
- const GtkCanvasSizeClass *class;
-
- GtkCanvasItem *item;
- GtkCanvasItemMeasurement measure;
-};
-
-struct _GtkCanvasSizeReference
-{
- const GtkCanvasSizeClass *class;
-
- graphene_size_t *reference;
-};
-
-struct _GtkCanvasSize
-{
- union {
- const GtkCanvasSizeClass *class;
- GtkCanvasSizeAbsolute absolute;
- GtkCanvasSizeBox box;
- GtkCanvasSizeDistance distance;
- GtkCanvasSizeMeasure measure;
- GtkCanvasSizeReference reference;
- };
-};
-
-
-void gtk_canvas_size_init_distance (GtkCanvasSize *size,
- const GtkCanvasPoint *from,
- const GtkCanvasPoint *to);
-void gtk_canvas_size_init_measure_item (GtkCanvasSize *self,
- GtkCanvasItem *item,
- GtkCanvasItemMeasurement measure);
-void gtk_canvas_size_init_copy (GtkCanvasSize *self,
- const GtkCanvasSize *source);
-void gtk_canvas_size_finish (GtkCanvasSize *self);
-
-/* NB: Takes ownership of reference */
-void gtk_canvas_size_init_reference (GtkCanvasSize *size,
- graphene_size_t *reference);
-
-G_END_DECLS
-
-#endif /* __GTK_CANVAS_SIZE_PRIVATE_H__ */
diff --git a/gtk/gtkcanvasvec2.c b/gtk/gtkcanvasvec2.c
new file mode 100644
index 0000000000..dfba1b10b0
--- /dev/null
+++ b/gtk/gtkcanvasvec2.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright © 2022 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+
+/**
+ * GtkCanvasVec2:
+ *
+ * `GtkCanvasVec2` describes a vec2 in a `GtkCanvas`.
+ */
+
+#include "config.h"
+
+#include "gtkcanvasvec2private.h"
+
+/* {{{ Boilerplate */
+
+struct _GtkCanvasVec2Class
+{
+ const char *type_name;
+
+ void (* copy) (GtkCanvasVec2 *self,
+ const GtkCanvasVec2 *source);
+ void (* finish) (GtkCanvasVec2 *self);
+ gboolean (* eval) (const GtkCanvasVec2 *self,
+ graphene_vec2_t *result);
+};
+
+/* }}} */
+/* {{{ INVALID */
+
+static void
+gtk_canvas_vec2_invalid_copy (GtkCanvasVec2 *vec2,
+ const GtkCanvasVec2 *source_vec2)
+{
+ gtk_canvas_vec2_init_invalid (vec2);
+}
+
+static void
+gtk_canvas_vec2_invalid_finish (GtkCanvasVec2 *vec2)
+{
+}
+
+static gboolean
+gtk_canvas_vec2_invalid_eval (const GtkCanvasVec2 *vec2,
+ graphene_vec2_t *result)
+{
+ return FALSE;
+}
+
+static const GtkCanvasVec2Class GTK_CANVAS_VEC2_INVALID_CLASS =
+{
+ "GtkCanvasVec2Invalid",
+ gtk_canvas_vec2_invalid_copy,
+ gtk_canvas_vec2_invalid_finish,
+ gtk_canvas_vec2_invalid_eval,
+};
+
+void
+gtk_canvas_vec2_init_invalid (GtkCanvasVec2 *vec2)
+{
+ vec2->class = &GTK_CANVAS_VEC2_INVALID_CLASS;
+}
+
+/* }}} */
+/* {{{ CONSTANT */
+
+static void
+gtk_canvas_vec2_constant_copy (GtkCanvasVec2 *vec2,
+ const GtkCanvasVec2 *source_vec2)
+{
+ const GtkCanvasVec2Constant *source = &source_vec2->constant;
+
+ gtk_canvas_vec2_init_constant_from_vec2 (vec2, &source->value);
+}
+
+static void
+gtk_canvas_vec2_constant_finish (GtkCanvasVec2 *vec2)
+{
+}
+
+static gboolean
+gtk_canvas_vec2_constant_eval (const GtkCanvasVec2 *vec2,
+ graphene_vec2_t *result)
+{
+ const GtkCanvasVec2Constant *self = &vec2->constant;
+
+ graphene_vec2_init_from_vec2 (result, &self->value);
+
+ return TRUE;
+}
+
+static const GtkCanvasVec2Class GTK_CANVAS_VEC2_CONSTANT_CLASS =
+{
+ "GtkCanvasVec2Constant",
+ gtk_canvas_vec2_constant_copy,
+ gtk_canvas_vec2_constant_finish,
+ gtk_canvas_vec2_constant_eval,
+};
+
+void
+gtk_canvas_vec2_init_constant_from_vec2 (GtkCanvasVec2 *vec2,
+ const graphene_vec2_t *value)
+{
+ GtkCanvasVec2Constant *self = &vec2->constant;
+
+ self->class = &GTK_CANVAS_VEC2_CONSTANT_CLASS;
+ graphene_vec2_init_from_vec2 (&self->value, value);
+}
+
+void
+gtk_canvas_vec2_init_constant (GtkCanvasVec2 *vec2,
+ float x,
+ float y)
+{
+ graphene_vec2_t v;
+
+ graphene_vec2_init (&v, x, y);
+ gtk_canvas_vec2_init_constant_from_vec2 (vec2, &v);
+}
+
+/* }}} */
+/* {{{ SUM */
+
+static void
+gtk_canvas_vec2_sum_copy (GtkCanvasVec2 *vec2,
+ const GtkCanvasVec2 *source_vec2);
+
+static void
+gtk_canvas_vec2_sum_finish (GtkCanvasVec2 *vec2)
+{
+ GtkCanvasVec2Sum *self = &vec2->sum;
+ gsize i;
+
+ for (i = 0; i < self->n_summands; i++)
+ {
+ gtk_canvas_vec2_finish (&self->summands[i].value);
+ }
+
+ g_free (self->summands);
+}
+
+static gboolean
+gtk_canvas_vec2_sum_eval (const GtkCanvasVec2 *vec2,
+ graphene_vec2_t *result)
+{
+ const GtkCanvasVec2Sum *self = &vec2->sum;
+ gsize i;
+
+ if (!gtk_canvas_vec2_eval (&self->summands[0].value, result))
+ return FALSE;
+ graphene_vec2_multiply (&self->summands[0].scale, result, result);
+
+ for (i = 1; i < self->n_summands; i++)
+ {
+ graphene_vec2_t tmp;
+
+ if (!gtk_canvas_vec2_eval (&self->summands[i].value, &tmp))
+ return FALSE;
+ graphene_vec2_multiply (&self->summands[i].scale, &tmp, &tmp);
+ graphene_vec2_add (&tmp, result, result);
+ }
+
+ return TRUE;
+}
+
+static const GtkCanvasVec2Class GTK_CANVAS_VEC2_SUM_CLASS =
+{
+ "GtkCanvasVec2Sum",
+ gtk_canvas_vec2_sum_copy,
+ gtk_canvas_vec2_sum_finish,
+ gtk_canvas_vec2_sum_eval,
+};
+
+static void
+gtk_canvas_vec2_sum_copy (GtkCanvasVec2 *vec2,
+ const GtkCanvasVec2 *source_vec2)
+{
+ GtkCanvasVec2Sum *self = &vec2->sum;
+ const GtkCanvasVec2Sum *source = &source_vec2->sum;
+ gsize i;
+
+ self->class = &GTK_CANVAS_VEC2_SUM_CLASS;
+ self->summands = g_new (GtkCanvasVec2Summand, source->n_summands);
+ self->n_summands = source->n_summands;
+ for (i = 0; i < self->n_summands; i++)
+ {
+ graphene_vec2_init_from_vec2 (&self->summands[i].scale,
+ &source->summands[i].scale);
+ gtk_canvas_vec2_init_copy (&self->summands[i].value,
+ &source->summands[i].value);
+ }
+
+}
+
+void
+gtk_canvas_vec2_init_sum (GtkCanvasVec2 *vec2,
+ const graphene_vec2_t *scale,
+ ...)
+{
+ GtkCanvasVec2Sum *self = &vec2->sum;
+ GArray *array;
+ GtkCanvasVec2Summand summand;
+ va_list args;
+
+ g_assert (scale != NULL);
+
+ self->class = &GTK_CANVAS_VEC2_SUM_CLASS;
+
+ array = g_array_new (FALSE, FALSE, sizeof (GtkCanvasVec2Summand));
+ va_start (args, scale);
+
+ while (scale)
+ {
+ graphene_vec2_init_from_vec2 (&summand.scale, scale);
+ gtk_canvas_vec2_init_copy (&summand.value, va_arg (args, const GtkCanvasVec2 *));
+ g_array_append_val (array, summand);
+ scale = va_arg (args, const graphene_vec2_t *);
+ }
+ va_end (args);
+
+ self->n_summands = array->len;
+ self->summands = (GtkCanvasVec2Summand *) g_array_free (array, FALSE);
+}
+
+/* }}} */
+/* {{{ VARIABLE */
+
+static void
+gtk_canvas_vec2_init_variable_with_variable (GtkCanvasVec2 *vec2,
+ GtkCanvasVec2 *variable);
+
+static void
+gtk_canvas_vec2_variable_copy (GtkCanvasVec2 *vec2,
+ const GtkCanvasVec2 *source_vec2)
+{
+ const GtkCanvasVec2Variable *source = &source_vec2->variable;
+
+ gtk_canvas_vec2_init_variable_with_variable (vec2, g_rc_box_acquire (source->variable));
+}
+
+static void
+gtk_canvas_vec2_variable_finish (GtkCanvasVec2 *vec2)
+{
+ const GtkCanvasVec2Variable *self = &vec2->variable;
+
+ g_rc_box_release (self->variable);
+}
+
+static gboolean
+gtk_canvas_vec2_variable_eval (const GtkCanvasVec2 *vec2,
+ graphene_vec2_t *result)
+{
+ const GtkCanvasVec2Variable *self = &vec2->variable;
+
+ return gtk_canvas_vec2_eval (self->variable, result);
+}
+
+static const GtkCanvasVec2Class GTK_CANVAS_VEC2_VARIABLE_CLASS =
+{
+ "GtkCanvasVec2Variable",
+ gtk_canvas_vec2_variable_copy,
+ gtk_canvas_vec2_variable_finish,
+ gtk_canvas_vec2_variable_eval,
+};
+
+static void
+gtk_canvas_vec2_init_variable_with_variable (GtkCanvasVec2 *vec2,
+ GtkCanvasVec2 *variable)
+{
+ GtkCanvasVec2Variable *self = &vec2->variable;
+
+ self->class = &GTK_CANVAS_VEC2_VARIABLE_CLASS;
+
+ self->variable = variable;
+}
+
+void
+gtk_canvas_vec2_init_variable (GtkCanvasVec2 *vec2)
+{
+ GtkCanvasVec2 *variable;
+
+ variable = g_rc_box_new (GtkCanvasVec2);
+ gtk_canvas_vec2_init_invalid (variable);
+
+ gtk_canvas_vec2_init_variable_with_variable (vec2, variable);
+}
+
+GtkCanvasVec2 *
+gtk_canvas_vec2_get_variable (GtkCanvasVec2 *vec2)
+{
+ GtkCanvasVec2Variable *self = &vec2->variable;
+
+ g_return_val_if_fail (self->class == &GTK_CANVAS_VEC2_VARIABLE_CLASS, NULL);
+
+ return self->variable;
+}
+
+/* }}} */
+/* {{{ PUBLIC API */
+
+void
+gtk_canvas_vec2_init_copy (GtkCanvasVec2 *self,
+ const GtkCanvasVec2 *source)
+{
+ source->class->copy (self, source);
+}
+
+void
+gtk_canvas_vec2_finish (GtkCanvasVec2 *self)
+{
+ self->class->finish (self);
+}
+
+gboolean
+gtk_canvas_vec2_eval (const GtkCanvasVec2 *self,
+ graphene_vec2_t *result)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (result != NULL, FALSE);
+
+ if (self->class->eval (self, result))
+ return TRUE;
+
+ graphene_vec2_init_from_vec2 (result, graphene_vec2_zero ());
+ return FALSE;
+}
+
diff --git a/gtk/gtkcanvasvec2private.h b/gtk/gtkcanvasvec2private.h
new file mode 100644
index 0000000000..b8ad4875b8
--- /dev/null
+++ b/gtk/gtkcanvasvec2private.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright © 2022 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#ifndef __GTK_CANVAS_VEC2_PRIVATE_H__
+#define __GTK_CANVAS_VEC2_PRIVATE_H__
+
+#include <glib.h>
+#include <graphene.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GtkCanvasVec2 GtkCanvasVec2;
+typedef struct _GtkCanvasVec2Class GtkCanvasVec2Class;
+typedef struct _GtkCanvasVec2Constant GtkCanvasVec2Constant;
+typedef struct _GtkCanvasVec2Sum GtkCanvasVec2Sum;
+typedef struct _GtkCanvasVec2Summand GtkCanvasVec2Summand;
+typedef struct _GtkCanvasVec2Variable GtkCanvasVec2Variable;
+
+struct _GtkCanvasVec2Constant
+{
+ const GtkCanvasVec2Class *class;
+
+ graphene_vec2_t value;
+};
+
+struct _GtkCanvasVec2Sum
+{
+ const GtkCanvasVec2Class *class;
+
+ graphene_vec2_t constant;
+
+ gsize n_summands;
+ GtkCanvasVec2Summand *summands;
+};
+
+struct _GtkCanvasVec2Variable
+{
+ const GtkCanvasVec2Class *class;
+
+ /* a GtkRcBox */
+ GtkCanvasVec2 *variable;
+};
+
+struct _GtkCanvasVec2
+{
+ union {
+ const GtkCanvasVec2Class *class;
+ GtkCanvasVec2Constant constant;
+ GtkCanvasVec2Sum sum;
+ GtkCanvasVec2Variable variable;
+ };
+};
+
+struct _GtkCanvasVec2Summand
+{
+ graphene_vec2_t scale;
+ GtkCanvasVec2 value;
+};
+
+
+void gtk_canvas_vec2_init_copy (GtkCanvasVec2 *self,
+ const GtkCanvasVec2 *source);
+void gtk_canvas_vec2_finish (GtkCanvasVec2 *self);
+
+gboolean gtk_canvas_vec2_eval (const GtkCanvasVec2 *self,
+ graphene_vec2_t *result);
+
+void gtk_canvas_vec2_init_invalid (GtkCanvasVec2 *vec2);
+void gtk_canvas_vec2_init_constant (GtkCanvasVec2 *vec2,
+ float x,
+ float y);
+void gtk_canvas_vec2_init_constant_from_vec2 (GtkCanvasVec2 *vec2,
+ const graphene_vec2_t *value);
+void gtk_canvas_vec2_init_sum (GtkCanvasVec2 *vec2,
+ const graphene_vec2_t *scale,
+ ...) G_GNUC_NULL_TERMINATED;
+
+void gtk_canvas_vec2_init_variable (GtkCanvasVec2 *vec2);
+GtkCanvasVec2 * gtk_canvas_vec2_get_variable (GtkCanvasVec2 *vec2);
+
+G_END_DECLS
+
+#endif /* __GTK_CANVAS_VEC2_PRIVATE_H__ */
diff --git a/gtk/meson.build b/gtk/meson.build
index 63f01bbea8..93db1fb16c 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -32,6 +32,7 @@ gtk_private_sources = files([
'gtkbuilderprecompile.c',
'gtkbuiltinicon.c',
'gtkcellareaboxcontext.c',
+ 'gtkcanvasvec2.c',
'gtkcoloreditor.c',
'gtkcolorplane.c',
'gtkcolorpicker.c',