[dia/zbrown/graphene-rect] general: store bounding and extent boxes as graphene_rect_t




commit 491f0228b15efa764c320448dfa5cf418b5fe365
Author: Zander Brown <zbrown gnome org>
Date:   Tue Mar 23 03:15:42 2021 +0000

    general: store bounding and extent boxes as graphene_rect_t
    
    Unfortunatly with porting to graphene patches end up rather big touching
    every single object and half the UI code all at once with no real way to
    do it incrementally…
    
    Python plug-in now talks to PyGObject’s C API to return graphene rects -
    at least for now we don't need to manually wrap them
    
    bbox.py now draws the extent box as well as bounding
    
    Given the scale of this commit it probably introduces a few bugs, having
    reviewed and updated it over several months I *think* I've ironed out
    most issues - but it wouldn't surprise me if something was missed
    
    At somepoint between $LAST_WORKING and now the expected bounds of bezier
    test seem to have difted by FTP_EPSILON - use a hacky workaround for now
    
    Good news is the All Objects (with bbox drawn) rendered to png hasn't
    changed (ignoring clock of course) so it isn't obviously broken

 app/commands.c                      |   2 +-
 app/connectionpoint_ops.c           |  13 +-
 app/create_object.c                 |  45 ++--
 app/diagram.c                       |  67 +++--
 app/disp_callbacks.c                |   2 +-
 app/display.c                       |  84 ++++---
 app/filedlg.c                       |   2 +-
 app/load_save.c                     | 188 ++++++++------
 app/modify_tool.c                   |  48 ++--
 app/object_ops.c                    | 241 ++++++++++++------
 lib/arrows.c                        |  47 ++--
 lib/arrows.h                        |  82 +++---
 lib/autoroute.c                     | 232 +++++++++--------
 lib/bezier_conn.c                   |   7 +-
 lib/beziershape.c                   |  16 +-
 lib/boundingbox.c                   | 254 +++++++++++++------
 lib/boundingbox.h                   | 118 ++++-----
 lib/connection.c                    |  14 +-
 lib/dia-graphene.h                  | 118 +++++++++
 lib/dia-layer.h                     |   3 +-
 lib/diapathrenderer.c               |  46 ++--
 lib/diarenderer.c                   | 135 ++++++----
 lib/diatransformrenderer.c          |  20 +-
 lib/element.c                       |  15 +-
 lib/geometry.h                      |  29 +--
 lib/group.c                         | 123 +++++----
 lib/layer.c                         | 110 ++++++---
 lib/libdia.def                      |   2 +
 lib/object.c                        |  82 ++++--
 lib/object.h                        | 146 ++++++-----
 lib/object_defaults.c               |  52 ++--
 lib/orth_conn.c                     |  21 +-
 lib/path-math.c                     |  48 ++--
 lib/poly_conn.c                     |  20 +-
 lib/polyshape.c                     |  18 +-
 lib/renderer/diacairo-renderer.c    |   4 +-
 lib/renderer/diacairo.h             |   2 +-
 lib/standard-path.c                 | 238 +++++++++++-------
 lib/text.c                          | 114 ++++++---
 lib/text.h                          |  55 +++--
 meson.build                         |   2 +-
 objects/AADL/aadlbox.c              |  55 +++--
 objects/Database/compound.c         |  48 ++--
 objects/Database/reference.c        | 219 ++++++++--------
 objects/Database/table.c            |  18 +-
 objects/ER/relationship.c           |  26 +-
 objects/FS/flow-ortho.c             |  13 +-
 objects/FS/flow.c                   |  36 +--
 objects/FS/function.c               | 125 +++++-----
 objects/GRAFCET/action.c            |  22 +-
 objects/GRAFCET/action_text_draw.c  |  31 +--
 objects/GRAFCET/condition.c         |  25 +-
 objects/GRAFCET/step.c              |  15 +-
 objects/GRAFCET/transition.c        |  26 +-
 objects/Istar/link.c                | 132 +++++-----
 objects/Jackson/phenomenon.c        |  28 ++-
 objects/Jackson/requirement.c       |  26 +-
 objects/KAOS/metaandorrel.c         |  84 ++++---
 objects/KAOS/metabinrel.c           |  57 +++--
 objects/Misc/analog_clock.c         |  18 +-
 objects/Misc/diagram_as_object.c    |  18 +-
 objects/Misc/grid_object.c          |  45 ++--
 objects/Misc/measure.c              |  51 ++--
 objects/Misc/n_gon.c                |  12 +-
 objects/Misc/tree.c                 |  31 ++-
 objects/SADT/annotation.c           | 131 ++++++----
 objects/UML/activity.c              |  16 +-
 objects/UML/actor.c                 |  50 ++--
 objects/UML/association.c           |  95 ++++---
 objects/UML/branch.c                |  16 +-
 objects/UML/class.c                 |  62 +++--
 objects/UML/classicon.c             |  36 ++-
 objects/UML/component.c             |   2 +-
 objects/UML/component_feature.c     |  27 +-
 objects/UML/constraint.c            |  40 +--
 objects/UML/dependency.c            |  52 ++--
 objects/UML/fork.c                  |  16 +-
 objects/UML/generalization.c        |  82 +++---
 objects/UML/implements.c            |  57 +++--
 objects/UML/large_package.c         |  50 ++--
 objects/UML/message.c               |  12 +-
 objects/UML/node.c                  |  70 ++++--
 objects/UML/object.c                |  34 ++-
 objects/UML/realizes.c              |  22 +-
 objects/UML/small_package.c         |  27 +-
 objects/UML/state.c                 |  16 +-
 objects/UML/state_term.c            |  16 +-
 objects/UML/transition.c            |  39 ++-
 objects/UML/usecase.c               |  16 +-
 objects/chronogram/chronoline.c     |  56 +++--
 objects/chronogram/chronoref.c      |  41 ++-
 objects/custom/custom_object.c      |  82 ++++--
 objects/custom/shape_info.c         |  36 ++-
 objects/flowchart/ellipse.c         |  56 +++--
 objects/network/basestation.c       |  48 ++--
 objects/network/bus.c               |  32 ++-
 objects/network/radiocell.c         |  37 +--
 objects/network/wanlink.c           | 182 +++++---------
 objects/standard/arc.c              | 184 ++++++++------
 objects/standard/bezier.c           | 134 ++++++----
 objects/standard/beziergon.c        |  48 ++--
 objects/standard/image.c            |  16 +-
 objects/standard/line.c             |  69 ++++--
 objects/standard/outline.c          |   8 +-
 objects/standard/polyline.c         |  59 +++--
 objects/standard/textobj.c          | 176 +++++++------
 objects/standard/zigzagline.c       |  68 +++--
 plug-ins/layout/layout.cpp          |  20 +-
 plug-ins/metapost/render_metapost.c |   6 +-
 plug-ins/python/bbox.py             |  71 +++---
 plug-ins/python/meson.build         |  12 +-
 plug-ins/python/pydia-geometry.c    |  12 +
 plug-ins/python/pydia-object.c      |  19 +-
 plug-ins/python/python-startup.py   |   9 +-
 plug-ins/python/python.c            |   3 +
 plug-ins/shape/shape-export.c       |  28 ++-
 plug-ins/svg/render_svg.c           |  15 +-
 tests/test-boundingbox.c            |  45 ++--
 tests/test-objects.c                | 480 +++++++++++++++++-------------------
 119 files changed, 4391 insertions(+), 2671 deletions(-)
---
diff --git a/app/commands.c b/app/commands.c
index a13fb4e57..aa01126e3 100644
--- a/app/commands.c
+++ b/app/commands.c
@@ -1167,7 +1167,7 @@ view_zoom_in_callback (GtkAction *action)
     return;
   }
 
-  ddisplay_zoom_middle (ddisp, M_SQRT2);
+  ddisplay_zoom_middle (ddisp, G_SQRT2);
 }
 
 void
diff --git a/app/connectionpoint_ops.c b/app/connectionpoint_ops.c
index fa406cd39..b4810a8c4 100644
--- a/app/connectionpoint_ops.c
+++ b/app/connectionpoint_ops.c
@@ -71,22 +71,29 @@ object_draw_connectionpoints (DiaObject *obj, DDisplay *ddisp)
    * connection points - or some variation thereof ;)
    */
   if (dia_object_get_num_connections (obj) > 1) {
-    const DiaRectangle *bbox = dia_object_get_bounding_box (obj);
-    real w = ddisplay_transform_length (ddisp, bbox->right - bbox->left);
-    real h = ddisplay_transform_length (ddisp, bbox->bottom - bbox->top);
+    graphene_rect_t bbox;
+    double w;
+    double h;
     int n = dia_object_get_num_connections (obj);
 
+    dia_object_get_bounding_box (obj, &bbox);
+
+    w = ddisplay_transform_length (ddisp, graphene_rect_get_width (&bbox));
+    h = ddisplay_transform_length (ddisp, graphene_rect_get_height (&bbox));
+
     /* just comparing the sizes is still drawing more CPs than useful - try 50% */
     if (w * h < n * CONNECTIONPOINT_SIZE * CONNECTIONPOINT_SIZE * 2) {
       if (ddisp->mainpoint_magnetism) {
         return;
       }
+
       /* just draw the main point */
       for (i = 0; i < n; ++i) {
         if (obj->connections[i]->flags & CP_FLAG_ANYPLACE) {
           connectionpoint_draw (obj->connections[i], ddisp, renderer, &midpoint_color);
         }
       }
+
       return;
     }
   }
diff --git a/app/create_object.c b/app/create_object.c
index 1738d2069..6f4eb5d63 100644
--- a/app/create_object.c
+++ b/app/create_object.c
@@ -125,13 +125,16 @@ create_object_double_click(CreateObjectTool *tool, GdkEventMotion *event,
 {
 }
 
+
 static void
-create_object_button_release(CreateObjectTool *tool, GdkEventButton *event,
-                            DDisplay *ddisp)
+create_object_button_release (CreateObjectTool *tool,
+                              GdkEventButton   *event,
+                              DDisplay         *ddisp)
 {
   GList *list = NULL;
   DiaObject *obj = tool->obj;
   gboolean reset;
+  graphene_rect_t bbox;
 
   GList *parent_candidates;
 
@@ -149,9 +152,9 @@ create_object_button_release(CreateObjectTool *tool, GdkEventButton *event,
 
   }
 
+  dia_object_get_bounding_box (obj, &bbox);
   parent_candidates =
-    dia_layer_find_objects_containing_rectangle (obj->parent_layer,
-                                                 &obj->bounding_box);
+    dia_layer_find_objects_containing_rectangle (obj->parent_layer, &bbox);
 
   /* whole object must be within another object to parent it */
   for (; parent_candidates != NULL; parent_candidates = g_list_next(parent_candidates)) {
@@ -209,33 +212,40 @@ create_object_button_release(CreateObjectTool *tool, GdkEventButton *event,
   ddisplay_do_update_menu_sensitivity(ddisp);
 }
 
+
 static void
-create_object_motion(CreateObjectTool *tool, GdkEventMotion *event,
-                  DDisplay *ddisp)
+create_object_motion (CreateObjectTool *tool,
+                      GdkEventMotion   *event,
+                      DDisplay         *ddisp)
 {
   Point to;
   ConnectionPoint *connectionpoint = NULL;
-  gchar *postext;
+  char *postext;
   GtkStatusbar *statusbar;
   guint context_id;
+  graphene_rect_t bbox;
+  graphene_point_t tl, br;
 
-  if (!tool->moving)
+  if (!tool->moving) {
     return;
+  }
 
-  ddisplay_untransform_coords(ddisp, event->x, event->y, &to.x, &to.y);
+  ddisplay_untransform_coords (ddisp, event->x, event->y, &to.x, &to.y);
 
   /* make sure the new object is restricted to its parent */
-  parent_handle_move_out_check(tool->obj, &to);
+  parent_handle_move_out_check (tool->obj, &to);
 
   /* Move to ConnectionPoint if near: */
   if (tool->handle != NULL &&
       tool->handle->connect_type != HANDLE_NONCONNECTABLE) {
     connectionpoint =
-      object_find_connectpoint_display(ddisp, &to, tool->obj, TRUE);
+      object_find_connectpoint_display (ddisp, &to, tool->obj, TRUE);
 
     if (connectionpoint != NULL) {
       to = connectionpoint->pos;
-      highlight_object(connectionpoint->object, DIA_HIGHLIGHT_CONNECTIONPOINT, ddisp->diagram);
+      highlight_object (connectionpoint->object,
+                        DIA_HIGHLIGHT_CONNECTIONPOINT,
+                        ddisp->diagram);
       ddisplay_set_all_cursor_name (NULL, "crosshair");
     }
   }
@@ -256,11 +266,11 @@ create_object_motion(CreateObjectTool *tool, GdkEventMotion *event,
   statusbar = GTK_STATUSBAR (ddisp->modified_status);
   context_id = gtk_statusbar_get_context_id (statusbar, "ObjectPos");
 
-  postext = g_strdup_printf("%.3f, %.3f - %.3f, %.3f",
-                           tool->obj->bounding_box.left,
-                           tool->obj->bounding_box.top,
-                           tool->obj->bounding_box.right,
-                           tool->obj->bounding_box.bottom);
+  dia_object_get_bounding_box (tool->obj, &bbox);
+  graphene_rect_get_top_left (&bbox, &tl);
+  graphene_rect_get_bottom_right (&bbox, &br);
+
+  postext = g_strdup_printf ("%.3f, %.3f - %.3f, %.3f", tl.x, tl.y, br.x, br.y);
 
   gtk_statusbar_pop (statusbar, context_id);
   gtk_statusbar_push (statusbar, context_id, postext);
@@ -275,7 +285,6 @@ create_object_motion(CreateObjectTool *tool, GdkEventMotion *event,
 }
 
 
-
 Tool *
 create_create_object_tool(DiaObjectType *objtype, void *user_data,
                          int invert_persistence)
diff --git a/app/diagram.c b/app/diagram.c
index c9f80bf53..91884b8fb 100644
--- a/app/diagram.c
+++ b/app/diagram.c
@@ -588,24 +588,35 @@ diagram_selected_can_parent(Diagram *dia) {
   return FALSE;
 }
 
-/** Returns TRUE if an object is fully enclosed by a another object, which
- * can be a parent */
+
+/**
+ * object_within_parent:
+ * @obj: the #DiaObject
+ * @p: the (potential) parent #DiaObject
+ *
+ * Returns: %TRUE if an object is fully enclosed by a another object, which
+ *          can be a parent
+ */
 gboolean
-object_within_parent(DiaObject *obj, DiaObject *p)
+object_within_parent (DiaObject *obj, DiaObject *p)
 {
-  DiaRectangle obj_bb = obj->bounding_box;
-  if (!object_flags_set(p, DIA_OBJECT_CAN_PARENT))
+  graphene_rect_t obj_bbox, parent_bbox;
+
+  if (!object_flags_set (p, DIA_OBJECT_CAN_PARENT)) {
     return FALSE;
-  if (p == obj)
+  }
+
+  if (p == obj) {
     return FALSE;
-  if (obj_bb.left > p->bounding_box.left &&
-      obj_bb.right < p->bounding_box.right &&
-      obj_bb.top > p->bounding_box.top &&
-      obj_bb.bottom < p->bounding_box.bottom)
-    return TRUE;
-  return FALSE;
+  }
+
+  dia_object_get_bounding_box (obj, &obj_bbox);
+  dia_object_get_bounding_box (obj, &parent_bbox);
+
+  return graphene_rect_contains_rect (&parent_bbox, &obj_bbox);
 }
 
+
 /*
   This is the real implementation of the sensitivity update.
   TODO: move it to the DDisplay as it belongs to it IMHO
@@ -1041,19 +1052,21 @@ diagram_flush(Diagram *dia)
   dynobj_refresh_kick();
 }
 
+
 DiaObject *
 diagram_find_clicked_object (Diagram *dia,
                              Point   *pos,
-                             real     maxdist)
+                             double   maxdist)
 {
   return dia_layer_find_closest_object_except (dia_diagram_data_get_active_layer (DIA_DIAGRAM_DATA (dia)),
                                                pos, maxdist, NULL);
 }
 
+
 DiaObject *
 diagram_find_clicked_object_except (Diagram *dia,
                                     Point   *pos,
-                                    real     maxdist,
+                                    double   maxdist,
                                     GList   *avoid)
 {
   return dia_layer_find_closest_object_except (dia_diagram_data_get_active_layer (DIA_DIAGRAM_DATA (dia)),
@@ -1062,18 +1075,21 @@ diagram_find_clicked_object_except (Diagram *dia,
                                                avoid);
 }
 
+
 /*
  * Always returns the last handle in an object that has
  * the closest distance
  */
-real
-diagram_find_closest_handle(Diagram *dia, Handle **closest,
-                           DiaObject **object, Point *pos)
+double
+diagram_find_closest_handle (Diagram    *dia,
+                             Handle    **closest,
+                             DiaObject **object,
+                             Point      *pos)
 {
   GList *l;
   DiaObject *obj;
   Handle *handle;
-  real mindist, dist;
+  double mindist, dist;
   int i;
 
   mindist = 1000000.0; /* Realy big value... */
@@ -1101,17 +1117,18 @@ diagram_find_closest_handle(Diagram *dia, Handle **closest,
   return mindist;
 }
 
-real
+
+double
 diagram_find_closest_connectionpoint (Diagram          *dia,
                                       ConnectionPoint **closest,
                                       Point            *pos,
                                       DiaObject        *notthis)
 {
-  real dist = 100000000.0;
+  double dist = 100000000.0;
 
   DIA_FOR_LAYER_IN_DIAGRAM (DIA_DIAGRAM_DATA (dia), layer, i, {
     ConnectionPoint *this_cp;
-    real this_dist;
+    double this_dist;
     if (dia_layer_is_connectable (layer)) {
       this_dist = dia_layer_find_closest_connectionpoint (layer,
                                                           &this_cp,
@@ -1698,7 +1715,7 @@ dia_diagram_get_file (Diagram *self)
  */
 DiaGuide *
 dia_diagram_add_guide (Diagram        *dia,
-                       real            position,
+                       double          position,
                        GtkOrientation  orientation,
                        gboolean        push_undo)
 {
@@ -1750,7 +1767,7 @@ dia_diagram_pick_guide (Diagram *dia,
        list;
        list = g_list_next (list)) {
     DiaGuide *guide = list->data;
-    real position = guide->position;
+    double position = guide->position;
     gdouble dist;
 
     switch (guide->orientation) {
@@ -1811,7 +1828,7 @@ dia_diagram_pick_guide_h (Diagram *dia,
        list;
        list = g_list_next (list)) {
     DiaGuide *guide = list->data;
-    real position = guide->position;
+    double position = guide->position;
     gdouble dist;
 
     switch (guide->orientation) {
@@ -1865,7 +1882,7 @@ dia_diagram_pick_guide_v (Diagram *dia,
        list;
        list = g_list_next (list)) {
     DiaGuide *guide = list->data;
-    real position = guide->position;
+    double position = guide->position;
     gdouble dist;
 
     switch (guide->orientation) {
diff --git a/app/disp_callbacks.c b/app/disp_callbacks.c
index dd8013d1c..1250a04ec 100644
--- a/app/disp_callbacks.c
+++ b/app/disp_callbacks.c
@@ -1045,7 +1045,7 @@ ddisplay_canvas_events (GtkWidget *canvas,
           case GDK_KP_Add:
           case GDK_plus:
           case GDK_equal:
-            ddisplay_zoom_middle (ddisp, M_SQRT2);
+            ddisplay_zoom_middle (ddisp, G_SQRT2);
             break;
           case GDK_KP_Subtract:
           case GDK_minus:
diff --git a/app/display.c b/app/display.c
index e86ff18c1..3a4b258fe 100644
--- a/app/display.c
+++ b/app/display.c
@@ -48,6 +48,7 @@
 #include "filedlg.h"
 #include "dia-layer.h"
 #include "exit_dialog.h"
+#include "dia-graphene.h"
 
 
 static GdkCursor *current_cursor = NULL;
@@ -1009,11 +1010,15 @@ ddisplay_scroll_center_point (DDisplay *ddisp, Point *p)
 gboolean
 ddisplay_scroll_to_object (DDisplay *ddisp, DiaObject *obj)
 {
-  DiaRectangle r = obj->bounding_box;
-
+  graphene_rect_t bbox;
+  graphene_point_t center;
   Point p;
-  p.x = (r.left+r.right)/2;
-  p.y = (r.top+r.bottom)/2;
+
+  dia_object_get_bounding_box (obj, &bbox);
+
+  graphene_rect_get_center (&bbox, &center);
+
+  dia_graphene_to_point (&center, &p);
 
   display_set_active (ddisp);
 
@@ -1031,26 +1036,39 @@ ddisplay_scroll_to_object (DDisplay *ddisp, DiaObject *obj)
 gboolean
 ddisplay_present_object (DDisplay *ddisp, DiaObject *obj)
 {
-  const DiaRectangle *r = dia_object_get_enclosing_box (obj);
-  const DiaRectangle *v = &ddisp->visible;
+  graphene_rect_t ebox, v;
+  graphene_point_t ebox_tl, ebox_br, v_tl, v_br;
+
+  dia_object_get_enclosing_box (obj, &ebox);
+  dia_rectangle_to_graphene (&ddisp->visible, &v);
 
   display_set_active (ddisp);
-  if (!rectangle_in_rectangle (v, r)) {
+  if (!graphene_rect_contains_rect (&v, &ebox)) {
     Point delta = { 0, 0 };
 
-    if ((r->right - r->left) > (v->right - v->left)) /* object bigger than visible area */
-      delta.x = (r->left - v->left + r->right - v->right) / 2;
-    else if (r->left < v->left)
-      delta.x = r->left - v->left;
-    else if  (r->right > v->right)
-      delta.x = r->right - v->right;
+    graphene_rect_get_top_left (&ebox, &ebox_tl);
+    graphene_rect_get_bottom_right (&ebox, &ebox_br);
 
-    if ((r->bottom - r->top) > (v->bottom - v->top)) /* object bigger than visible area */
-      delta.y = (r->top - v->top + r->bottom - v->bottom) / 2;
-    else if (r->top < v->top)
-      delta.y = r->top - v->top;
-    else if  (r->bottom > v->bottom)
-      delta.y = r->bottom - v->bottom;
+    graphene_rect_get_top_left (&v, &v_tl);
+    graphene_rect_get_bottom_right (&v, &v_br);
+
+    if (graphene_rect_get_width (&ebox) > graphene_rect_get_width (&v)) {
+      /* object wider than visible area */
+      delta.x = (ebox_tl.x - v_tl.x + ebox_br.x - v_br.x) / 2;
+    } else if (ebox_tl.x < v_tl.x) {
+      delta.x = ebox_tl.x - v_tl.x;
+    } else if (ebox_br.x > v_br.x) {
+      delta.x = ebox_br.x - v_br.x;
+    }
+
+    if (graphene_rect_get_height (&ebox) > graphene_rect_get_height (&v)) {
+      /* object bigger than visible area */
+      delta.y = (ebox_tl.y - v_tl.y + ebox_br.y - v_br.y) / 2;
+    } else if (ebox_tl.y < v_tl.y) {
+      delta.y = ebox_tl.y - v_tl.y;
+    } else if (ebox_br.y > v_br.y) {
+      delta.y = ebox_br.y - v_br.y;
+    }
 
     ddisplay_scroll (ddisp, &delta);
 
@@ -1677,17 +1695,27 @@ ddisplay_show_all (DDisplay *ddisp)
   /* if there is something selected show that instead of all exisiting objects */
   if (dia->data->selected) {
     GList *list = dia->data->selected;
-    DiaRectangle extents = *dia_object_get_enclosing_box ((DiaObject*)list->data);
-    list = g_list_next(list);
+    graphene_rect_t extents;
+    graphene_point_t centre;
+
+    dia_object_get_enclosing_box (DIA_OBJECT (list->data), &extents);
+
+    list = g_list_next (list);
     while (list) {
-      DiaObject *obj = (DiaObject *)list->data;
-      rectangle_union(&extents, dia_object_get_enclosing_box (obj));
-      list = g_list_next(list);
+      graphene_rect_t ebox;
+
+      dia_object_get_enclosing_box (DIA_OBJECT (list->data), &ebox);
+      graphene_rect_union (&extents, &ebox, &extents);
+
+      list = g_list_next (list);
     }
-    magnify_x = (double)width / (extents.right - extents.left) / ddisp->zoom_factor;
-    magnify_y = (double)height / (extents.bottom - extents.top) / ddisp->zoom_factor;
-    middle.x = extents.left + (extents.right - extents.left) / 2.0;
-    middle.y = extents.top + (extents.bottom - extents.top) / 2.0;
+
+    magnify_x = (double) width / graphene_rect_get_width (&extents) / ddisp->zoom_factor;
+    magnify_y = (double) height / graphene_rect_get_height (&extents) / ddisp->zoom_factor;
+
+    graphene_rect_get_center (&extents, &centre);
+
+    dia_graphene_to_point (&centre, &middle);
   } else {
     magnify_x = (double)width /
       (dia->data->extents.right - dia->data->extents.left) / ddisp->zoom_factor;
diff --git a/app/filedlg.c b/app/filedlg.c
index 98675cd54..9a00c13ba 100644
--- a/app/filedlg.c
+++ b/app/filedlg.c
@@ -825,7 +825,7 @@ file_export_callback (GtkAction *action)
     /* export via vfs gives: Permission denied - but only if you do not
      * have write permissions ;) */
     gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (exportdlg), FALSE);
-    gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (savedlg), TRUE);
+    gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (exportdlg), TRUE);
     gtk_window_set_role (GTK_WINDOW (exportdlg), "export_diagram");
 
     g_signal_connect (G_OBJECT (exportdlg),
diff --git a/app/load_save.c b/app/load_save.c
index 0f977c848..43c04dd82 100644
--- a/app/load_save.c
+++ b/app/load_save.c
@@ -216,9 +216,11 @@ read_objects (xmlNodePtr objects,
   return list;
 }
 
+
 static void
-read_connections(GList *objects, xmlNodePtr layer_node,
-                GHashTable *objects_hash)
+read_connections (GList      *objects,
+                  xmlNodePtr  layer_node,
+                  GHashTable *objects_hash)
 {
   ObjectNode obj_node;
   GList *list;
@@ -233,114 +235,142 @@ read_connections(GList *objects, xmlNodePtr layer_node,
   list = objects;
   obj_node = layer_node->xmlChildrenNode;
   while ((list != NULL) && (obj_node != NULL)) {
-    DiaObject *obj = (DiaObject *) list->data;
+    DiaObject *obj = DIA_OBJECT (list->data);
 
     /* the obj and there node must stay in sync to properly setup connections */
-    while (obj_node && (xmlIsBlankNode(obj_node) || XML_COMMENT_NODE == obj_node->type))
+    while (obj_node && (xmlIsBlankNode (obj_node) || XML_COMMENT_NODE == obj_node->type)) {
       obj_node = obj_node->next;
+    }
+
     if (!obj_node) break;
 
-    if IS_GROUP(obj) {
-      read_connections(group_objects(obj), obj_node, objects_hash);
+    if (IS_GROUP (obj)) {
+      read_connections (group_objects (obj), obj_node, objects_hash);
     } else {
       gboolean broken = FALSE;
-      /* an invalid bounding box is a good sign for some need of corrections */
-      gboolean wants_update = obj->bounding_box.right >= obj->bounding_box.left
-                           || obj->bounding_box.top >= obj->bounding_box.bottom;
+      gboolean wants_update;
+      graphene_rect_t bbox;
+      graphene_point_t tl, br;
+
       connections = obj_node->xmlChildrenNode;
-      while ((connections!=NULL) &&
-            (xmlStrcmp(connections->name, (const xmlChar *)"connections")!=0))
-       connections = connections->next;
+
+      dia_object_get_bounding_box (obj, &bbox);
+      graphene_rect_get_top_left (&bbox, &tl);
+      graphene_rect_get_bottom_right (&bbox, &br);
+
+      /* an invalid bounding box is a good sign for some need of corrections */
+      /* TODO: What is this actually doing */
+      wants_update = (br.x >= tl.x) || (tl.y >= br.y);
+
+      while ((connections != NULL) &&
+             (xmlStrcmp (connections->name,
+                         (const xmlChar *) "connections") != 0)) {
+        connections = connections->next;
+      }
+
       if (connections != NULL) {
-       connection = connections->xmlChildrenNode;
-       while (connection != NULL) {
-         char *donestr;
-          if (xmlIsBlankNode(connection)) {
+        connection = connections->xmlChildrenNode;
+
+        while (connection != NULL) {
+          char *donestr;
+
+          if (xmlIsBlankNode (connection)) {
             connection = connection->next;
             continue;
           }
-         handlestr = (char * )xmlGetProp(connection, (const xmlChar *)"handle");
-         tostr = (char *) xmlGetProp(connection, (const xmlChar *)"to");
-         connstr = (char *) xmlGetProp(connection, (const xmlChar *)"connection");
-
-         handle = atoi(handlestr);
-         conn = strtol(connstr, &donestr, 10);
-         if (*donestr != '\0') { /* Didn't convert it all -- use string */
-           conn = -1;
-         }
 
-         to = g_hash_table_lookup(objects_hash, tostr);
-
-         if (to == NULL) {
-           message_error(_("Error loading diagram.\n"
-                           "Linked object not found in document."));
-           broken = TRUE;
-         } else if (handle < 0 || handle >= obj->num_handles) {
-           message_error(_("Error loading diagram.\n"
-                           "Connection handle %d does not exist on '%s'."),
-                           handle, to->type->name);
-           broken = TRUE;
-         } else {
-           if (conn >= 0 && conn < to->num_connections) {
-             object_connect(obj, obj->handles[handle],
-                            to->connections[conn]);
-             /* force an update on the connection, helpful with (incomplete) generated files */
-             if (wants_update) {
-#if 0
-               obj->ops->move_handle(obj, obj->handles[handle], &to->connections[conn]->pos,
-                                     to->connections[conn], HANDLE_MOVE_CONNECTED,0);
-#endif
-             }
-           } else {
-             message_error(_("Error loading diagram.\n"
-                             "Connection point %d does not exist on '%s'."),
-                           conn, to->type->name);
-             broken = TRUE;
-           }
-         }
+          handlestr = (char *) xmlGetProp (connection, (const xmlChar *) "handle");
+          tostr = (char *) xmlGetProp (connection, (const xmlChar *) "to");
+          connstr = (char *) xmlGetProp (connection, (const xmlChar *) "connection");
 
-         if (handlestr) xmlFree(handlestr);
-         if (tostr) xmlFree(tostr);
-         if (connstr) xmlFree(connstr);
+          handle = atoi (handlestr);
+          conn = strtol (connstr, &donestr, 10);
+          if (*donestr != '\0') { /* Didn't convert it all -- use string */
+            conn = -1;
+          }
 
-         connection = connection->next;
-       }
+          to = g_hash_table_lookup (objects_hash, tostr);
+
+          if (to == NULL) {
+            message_error (_("Error loading diagram.\n"
+                             "Linked object not found in document."));
+            broken = TRUE;
+          } else if (handle < 0 || handle >= obj->num_handles) {
+            message_error (_("Error loading diagram.\n"
+                             "Connection handle %d does not exist on '%s'."),
+                           handle,
+                           to->type->name);
+            broken = TRUE;
+          } else {
+            if (conn >= 0 && conn < to->num_connections) {
+              object_connect (obj, obj->handles[handle], to->connections[conn]);
+
+              /* force an update on the connection, helpful with (incomplete) generated files */
+              if (wants_update) {
+      #if 0
+                obj->ops->move_handle(obj, obj->handles[handle], &to->connections[conn]->pos,
+                    to->connections[conn], HANDLE_MOVE_CONNECTED,0);
+      #endif
+              }
+            } else {
+              message_error (_("Error loading diagram.\n"
+                             "Connection point %d does not exist on '%s'."),
+                             conn,
+                             to->type->name);
+              broken = TRUE;
+            }
+          }
+
+          dia_clear_xml_string (&handlestr);
+          dia_clear_xml_string (&tostr);
+          dia_clear_xml_string (&connstr);
+
+          connection = connection->next;
+        }
         /* Fix positions of the connection object for (de)generated files.
          * Only done for the last point connected otherwise the intermediate posisitions
          * may screw the auto-routing algorithm.
          */
         if (!broken && obj && obj->ops->set_props && wants_update) {
-         /* called for it's side-effect of update_data */
-         obj->ops->move(obj,&obj->position);
-
-         for (handle = 0; handle < obj->num_handles; ++handle) {
-           if (obj->handles[handle]->connected_to)
-             obj->ops->move_handle(obj, obj->handles[handle], &obj->handles[handle]->pos,
-                                   obj->handles[handle]->connected_to, HANDLE_MOVE_CONNECTED,0);
-         }
-       }
+          /* called for it's side-effect of update_data */
+          dia_object_move (obj, &obj->position);
+
+          for (handle = 0; handle < obj->num_handles; ++handle) {
+            if (obj->handles[handle]->connected_to) {
+              dia_object_move_handle (obj,
+                                      obj->handles[handle],
+                                      &obj->handles[handle]->pos,
+                                      obj->handles[handle]->connected_to,
+                                      HANDLE_MOVE_CONNECTED,
+                                      0);
+            }
+          }
+        }
       }
     }
 
     /* Now set up parent relationships. */
     connections = obj_node->xmlChildrenNode;
-    while ((connections!=NULL) &&
-          (xmlStrcmp(connections->name, (const xmlChar *)"childnode")!=0))
+    while ((connections != NULL) &&
+           (xmlStrcmp (connections->name, (const xmlChar *) "childnode") != 0)) {
       connections = connections->next;
+    }
+
     if (connections != NULL) {
-      tostr = (char *)xmlGetProp(connections, (const xmlChar *)"parent");
+      tostr = (char *) xmlGetProp (connections, (const xmlChar *) "parent");
       if (tostr) {
-       obj->parent = g_hash_table_lookup(objects_hash, tostr);
-       if (obj->parent == NULL) {
-         message_error(_("Can't find parent %s of %s object\n"),
-                       tostr, obj->type->name);
-       } else {
-         obj->parent->children = g_list_prepend(obj->parent->children, obj);
-       }
+        obj->parent = g_hash_table_lookup (objects_hash, tostr);
+        if (obj->parent == NULL) {
+          message_error (_("Can't find parent %s of %s object\n"),
+                         tostr,
+                         obj->type->name);
+        } else {
+          obj->parent->children = g_list_prepend (obj->parent->children, obj);
+        }
       }
     }
 
-    list = g_list_next(list);
+    list = g_list_next (list);
     obj_node = obj_node->next;
   }
 }
diff --git a/app/modify_tool.c b/app/modify_tool.c
index d0ba15b7a..9f20de160 100644
--- a/app/modify_tool.c
+++ b/app/modify_tool.c
@@ -163,11 +163,12 @@ free_modify_tool (Tool *tool)
 
 
 static DiaObject *
-click_select_object(DDisplay *ddisp, Point *clickedpoint,
-                   GdkEventButton *event)
+click_select_object (DDisplay       *ddisp,
+                     Point          *clickedpoint,
+                     GdkEventButton *event)
 {
   Diagram *diagram;
-  real click_distance;
+  double click_distance;
   DiaObject *obj;
 
   diagram = ddisp->diagram;
@@ -425,7 +426,7 @@ modify_move_already(ModifyTool *tool, DDisplay *ddisp, Point *to)
 {
   static gboolean settings_taken = FALSE;
   static int double_click_time = 250;
-  real dist;
+  double dist;
 
   if (!settings_taken) {
     /* One could argue that if the settings were updated while running,
@@ -441,17 +442,22 @@ modify_move_already(ModifyTool *tool, DDisplay *ddisp, Point *to)
     }
     settings_taken = TRUE;
   }
+
   if (tool->start_time < time_micro()-double_click_time*1000) {
     return TRUE;
   }
+
   dist = distance_point_point_manhattan(&tool->start_at, to);
+
   if (ddisp->grid.snap) {
-    real grid_x = ddisp->diagram->grid.width_x;
-    real grid_y = ddisp->diagram->grid.width_y;
+    double grid_x = ddisp->diagram->grid.width_x;
+    double grid_y = ddisp->diagram->grid.width_y;
+
     if (dist > grid_x || dist > grid_y) {
       return TRUE;
     }
   }
+
   if (ddisplay_transform_length(ddisp, dist) > MIN_PIXELS) {
     return (ddisplay_transform_length(ddisp, dist) > MIN_PIXELS);
   } else {
@@ -547,15 +553,19 @@ modify_motion (ModifyTool     *tool,
 
     /* Put current mouse position in status bar */
     {
-      gchar *postext;
+      char *postext;
       GtkStatusbar *statusbar = GTK_STATUSBAR (ddisp->modified_status);
       guint context_id = gtk_statusbar_get_context_id (statusbar, "ObjectPos");
+      graphene_rect_t bbox;
+      graphene_point_t tl, br;
+
       gtk_statusbar_pop (statusbar, context_id);
-      postext = g_strdup_printf("%.3f, %.3f - %.3f, %.3f",
-                               tool->object->bounding_box.left,
-                               tool->object->bounding_box.top,
-                               tool->object->bounding_box.right,
-                               tool->object->bounding_box.bottom);
+
+      dia_object_get_bounding_box (tool->object, &bbox);
+      graphene_rect_get_top_left (&bbox, &tl);
+      graphene_rect_get_bottom_right (&bbox, &br);
+
+      postext = g_strdup_printf ("%.3f, %.3f - %.3f, %.3f", tl.x, tl.y, br.x, br.y);
 
       gtk_statusbar_pop (statusbar, context_id);
       gtk_statusbar_push (statusbar, context_id, postext);
@@ -631,14 +641,20 @@ modify_motion (ModifyTool     *tool,
 
     /* Put current mouse position in status bar */
     {
-      gchar *postext;
+      char *postext;
       GtkStatusbar *statusbar = GTK_STATUSBAR (ddisp->modified_status);
       guint context_id = gtk_statusbar_get_context_id (statusbar, "ObjectPos");
 
       if (tool->object) { /* play safe */
-        real w = tool->object->bounding_box.right - tool->object->bounding_box.left;
-        real h = tool->object->bounding_box.bottom - tool->object->bounding_box.top;
-        postext = g_strdup_printf("%.3f, %.3f (%.3fx%.3f)", to.x, to.y, w, h);
+        graphene_rect_t bbox;
+
+        dia_object_get_bounding_box (tool->object, &bbox);
+
+        postext = g_strdup_printf ("%.3f, %.3f (%.3fx%.3f)",
+                                   to.x,
+                                   to.y,
+                                   graphene_rect_get_width (&bbox),
+                                   graphene_rect_get_height (&bbox));
       } else {
         postext = g_strdup_printf("%.3f, %.3f", to.x, to.y);
       }
diff --git a/app/object_ops.c b/app/object_ops.c
index 8826f240d..689a0d7b2 100644
--- a/app/object_ops.c
+++ b/app/object_ops.c
@@ -25,33 +25,39 @@
 #include "handle_ops.h"
 #include "message.h"
 #include "object.h"
+#include "dia-graphene.h"
+
 
 #define OBJECT_CONNECT_DISTANCE 4.5
 
 void
-object_add_updates(DiaObject *obj, Diagram *dia)
+object_add_updates (DiaObject *obj, Diagram *dia)
 {
-  int i;
+  graphene_rect_t ebox;
+  DiaRectangle rect;
+
+  dia_object_get_enclosing_box (obj, &ebox);
+  dia_graphene_to_rectangle (&ebox, &rect);
 
   /* Bounding box */
-  if (data_object_get_highlight(dia->data,obj) != DIA_HIGHLIGHT_NONE) {
-    diagram_add_update_with_border(dia, dia_object_get_enclosing_box (obj), 5);
+  if (data_object_get_highlight (dia->data,obj) != DIA_HIGHLIGHT_NONE) {
+    diagram_add_update_with_border (dia, &rect, 5);
   } else {
-    diagram_add_update(dia, dia_object_get_enclosing_box (obj));
+    diagram_add_update (dia, &rect);
   }
 
   /* Handles */
-  for (i=0;i<obj->num_handles;i++) {
-    handle_add_update(obj->handles[i], dia);
+  for (int i = 0; i < obj->num_handles; i++) {
+    handle_add_update (obj->handles[i], dia);
   }
 
   /* Connection points */
-  for (i=0;i<dia_object_get_num_connections(obj);++i) {
-    connectionpoint_add_update(obj->connections[i], dia);
+  for (int i = 0; i < dia_object_get_num_connections (obj); ++i) {
+    connectionpoint_add_update (obj->connections[i], dia);
   }
-
 }
 
+
 void
 object_add_updates_list(GList *list, Diagram *dia)
 {
@@ -146,45 +152,70 @@ object_connect_display(DDisplay *ddisp, DiaObject *obj, Handle *handle,
   }
 }
 
+
 Point
-object_list_corner(GList *list)
+object_list_corner (GList *list)
 {
   Point p = {0.0,0.0};
   DiaObject *obj;
+  graphene_rect_t bbox;
+  graphene_point_t tl;
 
-  if (list == NULL)
+  if (list == NULL) {
     return p;
+  }
+
+  obj = DIA_OBJECT (list->data);
 
-  obj = (DiaObject *)list->data;
-  p.x = obj->bounding_box.left;
-  p.y = obj->bounding_box.top;
+  dia_object_get_bounding_box (obj, &bbox);
 
-  list = g_list_next(list);
+  graphene_rect_get_top_left (&bbox, &tl);
+
+  dia_graphene_to_point (&tl, &p);
+
+  list = g_list_next (list);
 
   while (list != NULL) {
-    obj = (DiaObject *)list->data;
+    obj = DIA_OBJECT (list->data);
 
-    if (p.x > obj->bounding_box.left)
-      p.x = obj->bounding_box.left;
-    if (p.y > obj->bounding_box.top)
-      p.y = obj->bounding_box.top;
+    graphene_rect_get_top_left (&bbox, &tl);
 
-    list = g_list_next(list);
+    if (p.x > tl.x) {
+      p.x = tl.x;
+    }
+
+    if (p.y > tl.y) {
+      p.y = tl.y;
+    }
+
+    list = g_list_next (list);
   }
 
   return p;
 }
 
+
 static int
-object_list_sort_vertical(const void *o1, const void *o2)
+object_list_sort_vertical (const void *o1, const void *o2)
 {
-    DiaObject *obj1 = *(DiaObject **)o1;
-    DiaObject *obj2 = *(DiaObject **)o2;
+  DiaObject *obj1 = *(DiaObject **) o1;
+  DiaObject *obj2 = *(DiaObject **) o2;
+  graphene_rect_t bbox1, bbox2;
+  graphene_point_t tl1, tl2, br1, br2;
+
+  dia_object_get_bounding_box (obj1, &bbox1);
+  dia_object_get_bounding_box (obj2, &bbox2);
 
-    return (obj1->bounding_box.bottom+obj1->bounding_box.top)/2 -
-       (obj2->bounding_box.bottom+obj2->bounding_box.top)/2;
+  graphene_rect_get_top_left (&bbox1, &tl1);
+  graphene_rect_get_bottom_right (&bbox1, &br1);
+
+  graphene_rect_get_top_left (&bbox2, &tl2);
+  graphene_rect_get_bottom_right (&bbox2, &br2);
+
+  return ((br1.y + tl1.y) / 2) - ((br2.y + tl2.y) / 2);
 }
 
+
 /*!
  * \brief Separate list of objects into connected and not connected ones
  *
@@ -227,54 +258,70 @@ filter_connected (const GList *objects,
   }
 }
 
-/*!
- * \brief Align objects by moving them vertically
+
+/**
+ * object_list_align_v:
+ * @objects: selection of objects to be considered
+ * @dia: the #Diagram owning the objects (and holding undo information)
+ * @align: the alignment algorithm
  *
- * For each node in objects align them vertically. The connections (edges) will follow.
+ * Align objects by moving them vertically
  *
- * @param objects  selection of objects to be considered
- * @param dia      the diagram owning the objects (and holding undo information)
- * @param align    the alignment algorithm
+ * For each node in objects align them vertically. The connections (edges)
+ * will follow.
  */
 void
-object_list_align_v(GList *objects, Diagram *dia, int align)
+object_list_align_v (GList *objects, Diagram *dia, int align)
 {
   GList *list;
   Point *orig_pos;
   Point *dest_pos;
-  real y_pos = 0;
+  double y_pos = 0;
   DiaObject *obj;
   Point pos;
-  real top, bottom, freespc;
+  double top, bottom, freespc;
   int nobjs;
   int i;
   GList *unconnected = NULL;
+  graphene_rect_t bbox;
+  graphene_point_t tl, br;
 
   filter_connected (objects, 1, NULL, &unconnected);
   objects = unconnected;
   if (objects==NULL)
     return;
 
-  obj = (DiaObject *) objects->data; /*  First object */
+  obj = DIA_OBJECT (objects->data); /*  First object */
 
-  top = obj->bounding_box.top;
-  bottom = obj->bounding_box.bottom;
+  dia_object_get_bounding_box (obj, &bbox);
+
+  graphene_rect_get_top_left (&bbox, &tl);
+  graphene_rect_get_bottom_right (&bbox, &br);
+
+  top = tl.y;
+  bottom = br.y;
   freespc = bottom - top;
 
   nobjs = 1;
   list = objects->next;
   while (list != NULL) {
-    obj = (DiaObject *) list->data;
+    obj = DIA_OBJECT (list->data);
+
+    graphene_rect_get_top_left (&bbox, &tl);
+    graphene_rect_get_bottom_right (&bbox, &br);
 
-    if (obj->bounding_box.top < top)
-      top = obj->bounding_box.top;
-    if (obj->bounding_box.bottom > bottom)
-      bottom = obj->bounding_box.bottom;
+    if (tl.y < top) {
+      top = tl.y;
+    }
+
+    if (br.y > bottom) {
+      bottom = br.y;
+    }
 
-    freespc += obj->bounding_box.bottom - obj->bounding_box.top;
+    freespc += br.y - tl.y;
     nobjs++;
 
-    list = g_list_next(list);
+    list = g_list_next (list);
   }
 
   /*
@@ -335,30 +382,33 @@ object_list_align_v(GList *objects, Diagram *dia, int align)
   i = 0;
   list = objects;
   while (list != NULL) {
-    obj = (DiaObject *) list->data;
+    obj = DIA_OBJECT (list->data);
+
+    graphene_rect_get_top_left (&bbox, &tl);
+    graphene_rect_get_bottom_right (&bbox, &br);
 
     pos.x = obj->position.x;
 
     switch (align) {
       case DIA_ALIGN_TOP: /* TOP */
-        pos.y = y_pos + obj->position.y - obj->bounding_box.top;
+        pos.y = y_pos + obj->position.y - tl.y;
         break;
       case DIA_ALIGN_CENTER: /* CENTER */
-        pos.y = y_pos + obj->position.y - (obj->bounding_box.top + obj->bounding_box.bottom)/2.0;
+        pos.y = y_pos + obj->position.y - (tl.y + br.y) / 2.0;
         break;
       case DIA_ALIGN_BOTTOM: /* BOTTOM */
-        pos.y = y_pos - (obj->bounding_box.bottom - obj->position.y);
+        pos.y = y_pos - (br.y - obj->position.y);
         break;
       case DIA_ALIGN_POSITION: /* OBJECT POSITION */
         pos.y = y_pos;
         break;
       case DIA_ALIGN_EQUAL: /* EQUAL DISTANCE */
-        pos.y = y_pos + obj->position.y - obj->bounding_box.top;
-        y_pos += obj->bounding_box.bottom - obj->bounding_box.top + freespc;
+        pos.y = y_pos + obj->position.y - tl.y;
+        y_pos += br.y - tl.y + freespc;
         break;
       case DIA_ALIGN_ADJACENT: /* ADJACENT */
-        pos.y = y_pos + obj->position.y - obj->bounding_box.top;
-        y_pos += obj->bounding_box.bottom - obj->bounding_box.top;
+        pos.y = y_pos + obj->position.y - tl.y;
+        y_pos += br.y - tl.y;
         break;
       default:
         g_return_if_reached ();
@@ -381,15 +431,26 @@ object_list_align_v(GList *objects, Diagram *dia, int align)
 
 
 static int
-object_list_sort_horizontal(const void *o1, const void *o2)
+object_list_sort_horizontal (const void *o1, const void *o2)
 {
-  DiaObject *obj1 = *(DiaObject **)o1;
-  DiaObject *obj2 = *(DiaObject **)o2;
+  DiaObject *obj1 = *(DiaObject **) o1;
+  DiaObject *obj2 = *(DiaObject **) o2;
+  graphene_rect_t bbox1, bbox2;
+  graphene_point_t tl1, tl2, br1, br2;
+
+  dia_object_get_bounding_box (obj1, &bbox1);
+  dia_object_get_bounding_box (obj2, &bbox2);
+
+  graphene_rect_get_top_left (&bbox1, &tl1);
+  graphene_rect_get_bottom_right (&bbox1, &br1);
+
+  graphene_rect_get_top_left (&bbox2, &tl2);
+  graphene_rect_get_bottom_right (&bbox2, &br2);
 
-  return (obj1->bounding_box.right+obj1->bounding_box.left)/2 -
-    (obj2->bounding_box.right+obj2->bounding_box.left)/2;
+  return ((br1.x + tl1.x) / 2) - ((br2.x + tl2.x) / 2);
 }
 
+
 /*!
  * \brief Align objects by moving then horizontally
  *
@@ -405,13 +466,15 @@ object_list_align_h(GList *objects, Diagram *dia, int align)
   GList *list;
   Point *orig_pos;
   Point *dest_pos;
-  real x_pos = 0;
+  double x_pos = 0;
   DiaObject *obj;
   Point pos;
-  real left, right, freespc = 0;
+  double left, right, freespc = 0;
   int nobjs;
   int i;
   GList *unconnected = NULL;
+  graphene_rect_t bbox;
+  graphene_point_t tl, br;
 
   filter_connected (objects, 1, NULL, &unconnected);
   objects = unconnected;
@@ -420,21 +483,35 @@ object_list_align_h(GList *objects, Diagram *dia, int align)
 
   obj = (DiaObject *) objects->data; /*  First object */
 
-  left = obj->bounding_box.left;
-  right = obj->bounding_box.right;
+  dia_object_get_bounding_box (obj, &bbox);
+
+  graphene_rect_get_top_left (&bbox, &tl);
+  graphene_rect_get_bottom_right (&bbox, &br);
+
+  left = tl.x;
+  right = br.x;
+
   freespc = right - left;
 
   nobjs = 1;
   list = objects->next;
   while (list != NULL) {
-    obj = (DiaObject *) list->data;
+    obj = DIA_OBJECT (list->data);
+
+    dia_object_get_bounding_box (obj, &bbox);
+
+    graphene_rect_get_top_left (&bbox, &tl);
+    graphene_rect_get_bottom_right (&bbox, &br);
 
-    if (obj->bounding_box.left < left)
-      left = obj->bounding_box.left;
-    if (obj->bounding_box.right > right)
-      right = obj->bounding_box.right;
+    if (tl.x < left) {
+      left = tl.x;
+    }
+
+    if (br.x > right) {
+      right = br.x;
+    }
 
-    freespc += obj->bounding_box.right - obj->bounding_box.left;
+    freespc += br.x - tl.x;
     nobjs++;
 
     list = g_list_next(list);
@@ -496,28 +573,33 @@ object_list_align_h(GList *objects, Diagram *dia, int align)
   i = 0;
   list = objects;
   while (list != NULL) {
-    obj = (DiaObject *) list->data;
+    obj = DIA_OBJECT (list->data);
+
+    dia_object_get_bounding_box (obj, &bbox);
+
+    graphene_rect_get_top_left (&bbox, &tl);
+    graphene_rect_get_bottom_right (&bbox, &br);
 
     switch (align) {
       case DIA_ALIGN_LEFT:
-        pos.x = x_pos + obj->position.x - obj->bounding_box.left;
+        pos.x = x_pos + obj->position.x - tl.x;
         break;
       case DIA_ALIGN_CENTER:
-        pos.x = x_pos + obj->position.x - (obj->bounding_box.left + obj->bounding_box.right)/2.0;
+        pos.x = x_pos + obj->position.x - ((tl.x + br.x) / 2.0);
         break;
       case DIA_ALIGN_RIGHT:
-        pos.x = x_pos - (obj->bounding_box.right - obj->position.x);
+        pos.x = x_pos - (br.x - obj->position.x);
         break;
       case DIA_ALIGN_POSITION:
         pos.x = x_pos;
         break;
       case DIA_ALIGN_EQUAL:
-        pos.x = x_pos + obj->position.x - obj->bounding_box.left;
-        x_pos += obj->bounding_box.right - obj->bounding_box.left + freespc;
+        pos.x = x_pos + obj->position.x - tl.x;
+        x_pos += br.x - tl.x + freespc;
         break;
       case DIA_ALIGN_ADJACENT:
-        pos.x = x_pos + obj->position.x - obj->bounding_box.left;
-        x_pos += obj->bounding_box.right - obj->bounding_box.left;
+        pos.x = x_pos + obj->position.x - tl.x;
+        x_pos += br.x - tl.x;
         break;
       default:
         break;
@@ -538,6 +620,7 @@ object_list_align_h(GList *objects, Diagram *dia, int align)
   g_list_free (unconnected);
 }
 
+
 /*!
  * \brief Align objects at their connected points
  *
@@ -687,12 +770,12 @@ object_list_align_connected (GList *objects, Diagram *dia, int align)
  * @param step The step-width to move
  */
 void
-object_list_nudge(GList *objects, Diagram *dia, Direction dir, real step)
+object_list_nudge (GList *objects, Diagram *dia, Direction dir, double step)
 {
   Point *orig_pos;
   Point *dest_pos;
   guint nobjs, i;
-  real inc_x, inc_y;
+  double inc_x, inc_y;
   GList *list;
   DiaObject *obj;
 
diff --git a/lib/arrows.c b/lib/arrows.c
index b42589171..64eac4e5f 100644
--- a/lib/arrows.c
+++ b/lib/arrows.c
@@ -42,6 +42,8 @@
 #include "attributes.h"
 #include "widgets.h"
 #include "intl.h"
+#include "dia-graphene.h"
+
 
 /**
  * SECTION:arrows
@@ -135,13 +137,14 @@ calculate_arrow_point (const Arrow *arrow,
                        const Point *from,
                        Point       *move_arrow,
                        Point       *move_line,
-                       real         linewidth)
+                       double       linewidth)
 {
-  real add_len;
-  real angle;
+  double add_len;
+  double angle;
   Point tmp;
-  real dist;
+  double dist;
   ArrowType arrow_type = arrow->type;
+
   /* Otherwise line is drawn through arrow
    * head for some hollow arrow heads
    * */
@@ -162,6 +165,7 @@ calculate_arrow_point (const Arrow *arrow,
   /* default to non-moving arrow */
   move_arrow->x = 0.0;
   move_arrow->y = 0.0;
+
   /* First, we move the arrow head backwards.
    * This in most cases just accounts for the linewidth of the arrow.
    * In pointy arrows, this means we must look at the angle of the
@@ -197,7 +201,7 @@ calculate_arrow_point (const Arrow *arrow,
       if (arrow->width < 0.0000001) return;
       angle = atan (arrow->length/(arrow->width/2));
       if (angle < 60*2*G_PI/360.0) {
-        add_len = linewidth/cos (angle);
+        add_len = linewidth / cos (angle);
       } else {
         add_len = 0;
       }
@@ -216,7 +220,7 @@ calculate_arrow_point (const Arrow *arrow,
     case ARROW_DIMENSION_ORIGIN:
     case ARROW_BLANKED_DOT:
     case ARROW_BLANKED_BOX:
-      add_len = .5*linewidth;
+      add_len = .5 * linewidth;
 
       /* don't move arrow if it would change direction */
       if (fabs (add_len) < dist) {
@@ -341,10 +345,11 @@ calculate_arrow_point (const Arrow *arrow,
       point_sub (move_line, from);
       add_len = point_len (move_line);
       point_normalize (move_line);
-      if (add_len > 4*arrow->length)
-        point_scale (move_line, 2*arrow->length);
-      else
+      if (add_len > (4 * arrow->length)) {
+        point_scale (move_line, 2 * arrow->length);
+      } else {
         point_scale (move_line, arrow->length);
+      }
       return;
     case ARROW_SLASH_ARROW:
     case ARROW_INTEGRAL_SYMBOL:
@@ -372,6 +377,7 @@ calculate_arrow_point (const Arrow *arrow,
   }
 }
 
+
 /**
  * calculate_arrow:
  * @poly: A three-element array in which to return the three points
@@ -2316,6 +2322,7 @@ struct ArrowDesc {
   {NULL,0}
 };
 
+
 /**
  * arrow_bbox:
  * @self: the arrow
@@ -2328,11 +2335,11 @@ struct ArrowDesc {
  * the arrow bounding box is added to the given rect
  */
 void
-arrow_bbox (const Arrow  *self,
-            real          line_width,
-            const Point  *to,
-            const Point  *from,
-            DiaRectangle *rect)
+arrow_bbox (const Arrow     *self,
+            double           line_width,
+            const Point     *to,
+            const Point     *from,
+            graphene_rect_t *rect)
 {
   Point poly[6]; /* Attention: nust be the maximum used! */
   PolyBBExtras pextra;
@@ -2358,6 +2365,7 @@ arrow_bbox (const Arrow  *self,
   polyline_bbox (poly, n_points, &pextra, TRUE, rect);
 }
 
+
 /**
  * arrow_draw:
  * @renderer: A renderer instance to draw into
@@ -2457,16 +2465,17 @@ arrow_draw (DiaRenderer *renderer,
   }
   if ((type != ARROW_NONE) && (render_bounding_boxes ()) && DIA_IS_INTERACTIVE_RENDERER (renderer)) {
     Arrow arrow = {type, length, width};
-    DiaRectangle bbox = {0, };
     Point p1, p2;
     Color col = { 1.0, 0.0, 1.0, 1.0 };
+    graphene_rect_t bbox;
+    graphene_point_t tl, br;
 
     arrow_bbox (&arrow, linewidth, to, from, &bbox);
 
-    p1.x = bbox.left;
-    p1.y = bbox.top;
-    p2.x = bbox.right;
-    p2.y = bbox.bottom;
+    graphene_rect_get_top_left (&bbox, &tl);
+    dia_graphene_to_point (&tl, &p1);
+    graphene_rect_get_bottom_right (&bbox, &br);
+    dia_graphene_to_point (&br, &p2);
 
     dia_renderer_set_linewidth (renderer,0.01);
     dia_renderer_draw_rect (renderer, &p1, &p2, NULL, &col);
diff --git a/lib/arrows.h b/lib/arrows.h
index 8f6b74313..e22d88932 100644
--- a/lib/arrows.h
+++ b/lib/arrows.h
@@ -18,6 +18,8 @@
 
 #pragma once
 
+#include <graphene.h>
+
 #include "diatypes.h"
 #include "geometry.h"
 #include "color.h"
@@ -138,50 +140,50 @@ typedef enum {
  */
 struct _Arrow {
   ArrowType type;
-  real      length;
-  real      width;
+  double    length;
+  double    width;
 };
 
 #define DIA_TYPE_ARROW (dia_arrow_get_type ())
 
 
-Arrow        *dia_arrow_copy           (Arrow       *self);
-void          dia_arrow_free           (Arrow       *self);
+Arrow        *dia_arrow_copy           (Arrow           *self);
+void          dia_arrow_free           (Arrow           *self);
 GType         dia_arrow_get_type       (void);
-void          arrow_draw               (DiaRenderer *renderer,
-                                        ArrowType    type,
-                                        Point       *to,
-                                        Point       *from,
-                                        real         length,
-                                        real         width,
-                                        real         linewidth,
-                                        Color       *fg_color,
-                                        Color       *bg_color);
-void          arrow_bbox               (const Arrow *self,
-                                        real         line_width,
-                                        const Point *to,
-                                        const Point *from,
-                                        DiaRectangle *rect);
-void          calculate_arrow_point    (const Arrow *arrow,
-                                        const Point *to,
-                                        const Point *from,
-                                        Point       *move_arrow,
-                                        Point       *move_line,
-                                        real         linewidth);
-void          save_arrow               (ObjectNode   obj_node,
-                                        Arrow       *arrow,
-                                        gchar       *type_attribute,
-                                        gchar       *length_attribute,
-                                        gchar       *width_attribute,
-                                        DiaContext  *ctx);
-void          load_arrow               (ObjectNode   obj_node,
-                                        Arrow       *arrow,
-                                        gchar       *type_attribute,
-                                        gchar       *length_attribute,
-                                        gchar       *width_attribute,
-                                        DiaContext  *ctx);
-ArrowType     arrow_type_from_name     (const gchar *name);
-gint          arrow_index_from_type    (ArrowType    atype);
-ArrowType     arrow_type_from_index    (gint         index);
-const gchar  *arrow_get_name_from_type (ArrowType    type);
+void          arrow_draw               (DiaRenderer     *renderer,
+                                        ArrowType        type,
+                                        Point           *to,
+                                        Point           *from,
+                                        double           length,
+                                        double           width,
+                                        double           linewidth,
+                                        Color           *fg_color,
+                                        Color           *bg_color);
+void          arrow_bbox               (const Arrow     *self,
+                                        double           line_width,
+                                        const Point     *to,
+                                        const Point     *from,
+                                        graphene_rect_t *rect);
+void          calculate_arrow_point    (const Arrow     *arrow,
+                                        const Point     *to,
+                                        const Point     *from,
+                                        Point           *move_arrow,
+                                        Point           *move_line,
+                                        double           linewidth);
+void          save_arrow               (ObjectNode       obj_node,
+                                        Arrow           *arrow,
+                                        char            *type_attribute,
+                                        char            *length_attribute,
+                                        char            *width_attribute,
+                                        DiaContext      *ctx);
+void          load_arrow               (ObjectNode       obj_node,
+                                        Arrow           *arrow,
+                                        char            *type_attribute,
+                                        char            *length_attribute,
+                                        char            *width_attribute,
+                                        DiaContext      *ctx);
+ArrowType     arrow_type_from_name     (const char      *name);
+gint          arrow_index_from_type    (ArrowType        atype);
+ArrowType     arrow_type_from_index    (int              index);
+const char   *arrow_get_name_from_type (ArrowType        type);
 GList        *get_arrow_names          (void);
diff --git a/lib/autoroute.c b/lib/autoroute.c
index 3585f7c45..30fcdaaf1 100644
--- a/lib/autoroute.c
+++ b/lib/autoroute.c
@@ -58,23 +58,35 @@ static Point *autolayout_unnormalize_points(guint dir,
                                            Point *points,
                                            guint num_points);
 
+
 static int
-autolayout_calc_intersects (const DiaRectangle *r1, const DiaRectangle *r2,
-                           const Point *points, guint num_points)
+autolayout_calc_intersects (const graphene_rect_t *r1,
+                            const graphene_rect_t *r2,
+                            const Point           *points,
+                            guint                  num_points)
 {
   guint i, n = 0;
 
   /* ignoring the first and last line assuming a proper 'outer' algorithm */
   for (i = 1; i < num_points - 2; ++i) {
-    DiaRectangle rt = { points[i].x, points[i].y, points[i+1].x, points[i+1].y };
-    if (r1)
-      n += (rectangle_intersects (r1, &rt) ? 1 : 0);
-    if (r2)
-      n += (rectangle_intersects (r2, &rt) ? 1 : 0);
+    graphene_rect_t rt = GRAPHENE_RECT_INIT (points[i].x, points[i].y, 0, 0);
+    graphene_point_t br = GRAPHENE_POINT_INIT (points[i + 1].x, points[i + 1].y);
+
+    graphene_rect_expand (&rt, &br, &rt);
+
+    if (r1) {
+      n += (graphene_rect_intersection (r1, &rt, NULL) ? 1 : 0);
+    }
+
+    if (r2) {
+      n += (graphene_rect_intersection (r2, &rt, NULL) ? 1 : 0);
+    }
   }
 
   return n;
 }
+
+
 /*!
  * \brief Apply a good route (or none) to the given _OrthConn
  *
@@ -124,72 +136,84 @@ autoroute_layout_orthconn(OrthConn *conn,
   for (startdir = DIR_NORTH; startdir <= DIR_WEST; startdir *= 2) {
     for (enddir = DIR_NORTH; enddir <= DIR_WEST; enddir *= 2) {
       if ((fromdir & startdir) &&
-         (todir & enddir)) {
-       real this_badness;
-       Point *this_layout = NULL;
-       guint this_num_points;
-       guint normal_enddir;
-       Point startpoint, endpoint;
-       Point otherpoint;
-       startpoint = autolayout_adjust_for_gap(&frompos, startdir, startconn);
-       autolayout_adjust_for_arrow(&startpoint, startdir, conn->extra_spacing.start_trans);
-       endpoint = autolayout_adjust_for_gap(&topos, enddir, endconn);
-       autolayout_adjust_for_arrow(&endpoint, enddir, conn->extra_spacing.end_trans);
-       /*
-       printf("Startdir %d enddir %d orgstart %.2f, %.2f orgend %.2f, %.2f start %.2f, %.2f end %.2f, 
%.2f\n",
-              startdir, enddir,
-              frompos.x, frompos.y,
-              topos.x, topos.y,
-              startpoint.x, startpoint.y,
-              endpoint.x, endpoint.y);
-       */
-       normal_enddir = autolayout_normalize_points(startdir, enddir,
-                                                   startpoint, endpoint,
-                                                   &otherpoint);
-       if (normal_enddir == DIR_NORTH ) {
-         this_badness = autoroute_layout_parallel(&otherpoint,
-                                                  &this_num_points,
-                                                  &this_layout);
-       } else if (normal_enddir == DIR_SOUTH) {
-         this_badness = autoroute_layout_opposite(&otherpoint,
-                                                  &this_num_points,
-                                                  &this_layout);
-       } else {
-         this_badness = autoroute_layout_orthogonal(&otherpoint,
-                                                    normal_enddir,
-                                                    &this_num_points,
-                                                    &this_layout);
-       }
-       if (this_layout != NULL) {
-         /* this_layout is eaten by unnormalize */
-         Point *unnormalized = autolayout_unnormalize_points(startdir, startpoint,
-                                                              this_layout, this_num_points);
-
-         intersects = autolayout_calc_intersects (
-           startconn ? dia_object_get_bounding_box (startconn->object) : NULL,
-           endconn ? dia_object_get_bounding_box (endconn->object) : NULL,
-           unnormalized, this_num_points);
-
-         if (   intersects <= best_intersects
-             && this_badness-min_badness < -0.00001) {
-           /*
-           printf("Dir %d to %d badness %f < %f\n", startdir, enddir,
-                  this_badness, min_badness);
-           */
-           min_badness = this_badness;
-           g_clear_pointer (&best_layout, g_free);
-           best_layout = unnormalized;
-           best_num_points = this_num_points;
-            /* revert adjusting start and end point */
-           autolayout_adjust_for_arrow(&best_layout[0], startdir,
-                                       -conn->extra_spacing.start_trans);
-           autolayout_adjust_for_arrow(&best_layout[best_num_points-1], enddir,
-                                       -conn->extra_spacing.end_trans);
-           best_intersects = intersects;
-         } else {
-           g_clear_pointer (&unnormalized, g_free);
-         }
-       }
+          (todir & enddir)) {
+        double this_badness;
+        Point *this_layout = NULL;
+        guint this_num_points;
+        guint normal_enddir;
+        Point startpoint, endpoint;
+        Point otherpoint;
+        startpoint = autolayout_adjust_for_gap(&frompos, startdir, startconn);
+        autolayout_adjust_for_arrow(&startpoint, startdir, conn->extra_spacing.start_trans);
+        endpoint = autolayout_adjust_for_gap(&topos, enddir, endconn);
+        autolayout_adjust_for_arrow(&endpoint, enddir, conn->extra_spacing.end_trans);
+        /*
+        printf("Startdir %d enddir %d orgstart %.2f, %.2f orgend %.2f, %.2f start %.2f, %.2f end %.2f, 
%.2f\n",
+              startdir, enddir,
+              frompos.x, frompos.y,
+              topos.x, topos.y,
+              startpoint.x, startpoint.y,
+              endpoint.x, endpoint.y);
+        */
+        normal_enddir = autolayout_normalize_points(startdir, enddir,
+                      startpoint, endpoint,
+                      &otherpoint);
+        if (normal_enddir == DIR_NORTH ) {
+          this_badness = autoroute_layout_parallel(&otherpoint,
+                    &this_num_points,
+                    &this_layout);
+        } else if (normal_enddir == DIR_SOUTH) {
+          this_badness = autoroute_layout_opposite(&otherpoint,
+                    &this_num_points,
+                    &this_layout);
+        } else {
+          this_badness = autoroute_layout_orthogonal(&otherpoint,
+                      normal_enddir,
+                      &this_num_points,
+                      &this_layout);
+        }
+
+        if (this_layout != NULL) {
+          /* this_layout is eaten by unnormalize */
+          Point *unnormalized = autolayout_unnormalize_points (startdir,
+                                                               startpoint,
+                                                               this_layout,
+                                                               this_num_points);
+          graphene_rect_t startconn_bbox, endconn_bbox;
+
+          if (startconn) {
+            dia_object_get_bounding_box (startconn->object, &startconn_bbox);
+          }
+
+          if (endconn) {
+            dia_object_get_bounding_box (endconn->object, &endconn_bbox);
+          }
+
+          intersects = autolayout_calc_intersects (startconn ? &startconn_bbox : NULL,
+                                                   endconn ? &endconn_bbox : NULL,
+                                                   unnormalized,
+                                                   this_num_points);
+
+          if (   intersects <= best_intersects
+              && this_badness-min_badness < -0.00001) {
+            /*
+            printf("Dir %d to %d badness %f < %f\n", startdir, enddir,
+            this_badness, min_badness);
+            */
+            min_badness = this_badness;
+            g_clear_pointer (&best_layout, g_free);
+            best_layout = unnormalized;
+            best_num_points = this_num_points;
+                  /* revert adjusting start and end point */
+            autolayout_adjust_for_arrow(&best_layout[0], startdir,
+                                        -conn->extra_spacing.start_trans);
+            autolayout_adjust_for_arrow(&best_layout[best_num_points-1], enddir,
+                                        -conn->extra_spacing.end_trans);
+            best_intersects = intersects;
+          } else {
+            g_clear_pointer (&unnormalized, g_free);
+          }
+        }
       }
     }
   }
@@ -250,50 +274,60 @@ calculate_badness(Point *ps, guint num_points)
   return badness;
 }
 
-/*!
- * \brief Gap adjustement for points and a connection point
+
+/**
+ * autolayout_adjust_for_gap:
+ * @pos: #Point of the end of the line.
+ * @dir: Which of the four cardinal directions the line goes from pos.
+ * @cp: The connectionpoint the line is connected to.
+ *
+ * Gap adjustement for points and a connection point
  *
  * Adjust one end of an orthconn for gaps, if autogap is on for the connpoint.
- * @param pos Point of the end of the line.
- * @param dir Which of the four cardinal directions the line goes from pos.
- * @param cp The connectionpoint the line is connected to.
- * @return Where the line should end to be on the correct edge of the
- *          object, if cp has autogap on.
  *
- * \ingroup Autorouting
+ * Returns: Where the line should end to be on the correct edge of the
+ *          object, if @cp has autogap on.
  */
 static Point
-autolayout_adjust_for_gap(Point *pos, int dir, ConnectionPoint *cp)
+autolayout_adjust_for_gap (Point *pos, int dir, ConnectionPoint *cp)
 {
   DiaObject *object;
   Point dir_other;
+  graphene_rect_t bbox;
+  graphene_point_t tl, br;
   /* Do absolute gaps here, once it's defined */
 
-  if (!cp || !connpoint_is_autogap(cp)) {
+  if (!cp || !connpoint_is_autogap (cp)) {
     return *pos;
   }
 
-  object  = cp->object;
+  object = cp->object;
 
   dir_other.x = pos->x;
   dir_other.y = pos->y;
+
+  dia_object_get_bounding_box (DIA_OBJECT (object), &bbox);
+  graphene_rect_get_top_left (&bbox, &tl);
+  graphene_rect_get_bottom_right (&bbox, &br);
+
   switch (dir) {
-  case DIR_NORTH:
-    dir_other.y += 2 * (object->bounding_box.top - pos->y);
-    break;
-  case DIR_SOUTH:
-    dir_other.y += 2 * (object->bounding_box.bottom - pos->y);
-    break;
-  case DIR_EAST:
-    dir_other.x += 2 * (object->bounding_box.right - pos->x);
-    break;
-  case DIR_WEST:
-    dir_other.x += 2 * (object->bounding_box.left - pos->x);
-    break;
-  default:
-    g_warning("Impossible direction %d\n", dir);
+    case DIR_NORTH:
+      dir_other.y += 2 * (tl.y - pos->y);
+      break;
+    case DIR_SOUTH:
+      dir_other.y += 2 * (br.y - pos->y);
+      break;
+    case DIR_EAST:
+      dir_other.x += 2 * (br.x - pos->x);
+      break;
+    case DIR_WEST:
+      dir_other.x += 2 * (tl.x - pos->x);
+      break;
+    default:
+      g_warning ("Impossible direction %d\n", dir);
   }
-  return calculate_object_edge(pos, &dir_other, object);
+
+  return calculate_object_edge (pos, &dir_other, object);
 }
 
 
diff --git a/lib/bezier_conn.c b/lib/bezier_conn.c
index 001efac56..b5e2f0657 100644
--- a/lib/bezier_conn.c
+++ b/lib/bezier_conn.c
@@ -29,6 +29,7 @@
 
 #include "bezier_conn.h"
 #include "diarenderer.h"
+#include "dia-graphene.h"
 
 
 #define HANDLE_BEZMAJOR  (HANDLE_CUSTOM1)
@@ -843,12 +844,16 @@ bezierconn_update_data (BezierConn *bezier)
 void
 bezierconn_update_boundingbox (BezierConn *bezier)
 {
+  graphene_rect_t bbox;
+
   g_return_if_fail (bezier != NULL);
 
   polybezier_bbox (&bezier->bezier.points[0],
                    bezier->bezier.num_points,
                    &bezier->extra_spacing, FALSE,
-                   &bezier->object.bounding_box);
+                   &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (bezier), &bbox);
 }
 
 
diff --git a/lib/beziershape.c b/lib/beziershape.c
index 7ced5ec87..d6f095ab6 100644
--- a/lib/beziershape.c
+++ b/lib/beziershape.c
@@ -28,6 +28,7 @@
 
 #include "beziershape.h"
 #include "diarenderer.h"
+#include "dia-graphene.h"
 
 
 #define HANDLE_BEZMAJOR  (HANDLE_CUSTOM1)
@@ -838,23 +839,28 @@ beziershape_update_data (BezierShape *bezier)
   obj->connections[obj->num_connections-1]->directions = DIR_ALL;
 }
 
+
 void
 beziershape_update_boundingbox (BezierShape *bezier)
 {
   ElementBBExtras *extra;
   PolyBBExtras pextra;
+  graphene_rect_t bbox;
 
-  g_assert(bezier != NULL);
+  g_return_if_fail (bezier != NULL);
 
   extra = &bezier->extra_spacing;
   pextra.start_trans = pextra.end_trans =
     pextra.start_long = pextra.end_long = 0;
   pextra.middle_trans = extra->border_trans;
 
-  polybezier_bbox(&bezier->bezier.points[0],
-                  bezier->bezier.num_points,
-                  &pextra, TRUE,
-                  &bezier->object.bounding_box);
+  polybezier_bbox (&bezier->bezier.points[0],
+                   bezier->bezier.num_points,
+                   &pextra,
+                   TRUE,
+                   &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (bezier), &bbox);
 }
 
 
diff --git a/lib/boundingbox.c b/lib/boundingbox.c
index 8853fff69..09c964ff2 100644
--- a/lib/boundingbox.c
+++ b/lib/boundingbox.c
@@ -27,6 +27,22 @@
 
 #include "geometry.h"
 #include "boundingbox.h"
+#include "dia-graphene.h"
+
+
+static inline void _rectangle_bbox  (const DiaRectangle    *rin,
+                                     const ElementBBExtras *extra,
+                                     DiaRectangle          *rout);
+static inline void _line_bbox       (const Point           *p1,
+                                     const Point           *p2,
+                                     const LineBBExtras    *extra,
+                                     DiaRectangle          *rect);
+static inline void _polybezier_bbox (const BezPoint        *pts,
+                                     int                    numpoints,
+                                     const PolyBBExtras    *extra,
+                                     gboolean               closed,
+                                     DiaRectangle          *rect);
+
 
 /**
  * bernstein_develop:
@@ -177,13 +193,13 @@ add_arrow_rectangle (DiaRectangle *rect,
  *
  * Calculate the boundingbox for a 2D bezier curve segment.
  */
-void
-bicubicbezier2D_bbox (const Point        *p0,
-                      const Point        *p1,
-                      const Point        *p2,
-                      const Point        *p3,
-                      const PolyBBExtras *extra,
-                      DiaRectangle       *rect)
+static inline void
+_bicubicbezier2D_bbox (const Point        *p0,
+                       const Point        *p1,
+                       const Point        *p2,
+                       const Point        *p3,
+                       const PolyBBExtras *extra,
+                       DiaRectangle       *rect)
 {
   double x[4], y[4];
   Point vl, vt, p,tt;
@@ -245,6 +261,25 @@ bicubicbezier2D_bbox (const Point        *p0,
 }
 
 
+void
+bicubicbezier2D_bbox (const graphene_vec2_t *p0,
+                      const Point           *p1,
+                      const Point           *p2,
+                      const Point           *p3,
+                      const PolyBBExtras    *extra,
+                      graphene_rect_t       *rect)
+{
+  DiaRectangle out;
+  Point t0;
+
+  dia_vec2_to_point (p0, &t0);
+
+  _bicubicbezier2D_bbox (&t0, p1, p2, p3, extra, &out);
+
+  dia_rectangle_to_graphene (&out, rect);
+}
+
+
 /**
  * line_bbox:
  * @p1: One end of the line.
@@ -254,11 +289,11 @@ bicubicbezier2D_bbox (const Point        *p0,
  *
  * Calculate the bounding box for a simple line.
  */
-void
-line_bbox (const Point        *p1,
-           const Point        *p2,
-           const LineBBExtras *extra,
-           DiaRectangle       *rect)
+static inline void
+_line_bbox (const Point        *p1,
+            const Point        *p2,
+            const LineBBExtras *extra,
+            DiaRectangle       *rect)
 {
   Point vl;
 
@@ -275,6 +310,24 @@ line_bbox (const Point        *p1,
 }
 
 
+void
+line_bbox (const graphene_vec2_t *p1,
+           const graphene_vec2_t *p2,
+           const LineBBExtras    *extra,
+           graphene_rect_t       *rect)
+{
+  DiaRectangle out;
+  Point t1, t2;
+
+  dia_vec2_to_point (p1, &t1);
+  dia_vec2_to_point (p2, &t2);
+
+  _line_bbox (&t1, &t2, extra, &out);
+
+  dia_rectangle_to_graphene (&out, rect);
+}
+
+
 /**
  * ellipse_bbox:
  * @centre: The center point of the ellipse.
@@ -285,12 +338,12 @@ line_bbox (const Point        *p1,
  *
  * Calculate the bounding box of an ellipse.
  */
-void
-ellipse_bbox (const Point           *centre,
-              double                 width,
-              double                 height,
-              const ElementBBExtras *extra,
-              DiaRectangle          *rect)
+static inline void
+_ellipse_bbox (const Point          *centre,
+               double                width,
+               double                height,
+               const ElementBBExtras *extra,
+               DiaRectangle          *rect)
 {
   DiaRectangle rin;
   rin.left = centre->x - width / 2;
@@ -298,7 +351,22 @@ ellipse_bbox (const Point           *centre,
   rin.top = centre->y - height / 2;
   rin.bottom = centre->y + height / 2;
 
-  rectangle_bbox (&rin, extra, rect);
+  _rectangle_bbox (&rin, extra, rect);
+}
+
+
+void
+ellipse_bbox (const Point           *centre,
+              float                  width,
+              float                  height,
+              const ElementBBExtras *extra,
+              graphene_rect_t       *rect)
+{
+  DiaRectangle out;
+
+  _ellipse_bbox (centre, width, height, extra, &out);
+
+  dia_rectangle_to_graphene (&out, rect);
 }
 
 
@@ -354,12 +422,12 @@ free_polybezier_space (BezPoint *points)
  *
  * Calculate the boundingbox for a polyline.
  */
-void
-polyline_bbox (const Point        *pts,
-               int                 numpoints,
-               const PolyBBExtras *extra,
-               gboolean            closed,
-               DiaRectangle       *rect)
+static inline void
+_polyline_bbox (const Point        *pts,
+                int                 numpoints,
+                const PolyBBExtras *extra,
+                gboolean            closed,
+                DiaRectangle       *rect)
 {
   /* It's much easier to re-use the Bezier code... */
   int i;
@@ -376,11 +444,26 @@ polyline_bbox (const Point        *pts,
   bpts[numpoints].type = BEZ_LINE_TO;
   bpts[numpoints].p1 = pts[0];
 
-  polybezier_bbox (bpts, numpoints + (closed ? 1 : 0), extra, closed, rect);
+  _polybezier_bbox (bpts,numpoints + (closed ? 1 : 0), extra, closed, rect);
   free_polybezier_space (bpts);
 }
 
 
+void
+polyline_bbox (const Point        *pts,
+               int                 numpoints,
+               const PolyBBExtras *extra,
+               gboolean            closed,
+               graphene_rect_t    *rect)
+{
+  DiaRectangle out;
+
+  _polyline_bbox (pts, numpoints, extra, closed, &out);
+
+  dia_rectangle_to_graphene (&out, rect);
+}
+
+
 /**
  * polybezier_bbox:
  * @pts: The bezier points
@@ -391,12 +474,12 @@ polyline_bbox (const Point        *pts,
  *
  * Calculate a bounding box for a set of bezier points.
  */
-void
-polybezier_bbox (const BezPoint     *pts,
-                 int                 numpoints,
-                 const PolyBBExtras *extra,
-                 gboolean            closed,
-                 DiaRectangle       *rect)
+static inline void
+_polybezier_bbox (const BezPoint     *pts,
+                  int                 numpoints,
+                  const PolyBBExtras *extra,
+                  gboolean            closed,
+                  DiaRectangle       *rect)
 {
   Point vx, vn, vsc, vp;
   int i, prev, next;
@@ -538,60 +621,60 @@ polybezier_bbox (const BezPoint     *pts,
        it's a middle or end segment, we'll be doing different stuff. */
     if (closed) {
       if (pts[i].type == BEZ_LINE_TO) {
-        line_bbox (&vsc, &vx, &full_lextra, &rt);
+        _line_bbox (&vsc, &vx, &full_lextra, &rt);
       } else {
-        bicubicbezier2D_bbox (&vsc,
-                              &pts[i].p1,
-                              &pts[i].p2,
-                              &pts[i].p3,
-                              &bextra,
-                              &rt);
+        _bicubicbezier2D_bbox (&vsc,
+                               &pts[i].p1,
+                               &pts[i].p2,
+                               &pts[i].p3,
+                               &bextra,
+                               &rt);
       }
     } else if (start) {
       if (pts[i].type == BEZ_LINE_TO) {
         if (end) {
-          line_bbox (&vsc, &vx, &full_lextra, &rt);
+          _line_bbox (&vsc, &vx, &full_lextra, &rt);
         } else {
-          line_bbox (&vsc, &vx, &start_lextra, &rt);
+          _line_bbox (&vsc, &vx, &start_lextra, &rt);
         }
       } else { /* BEZ_MOVE_TO */
         if (end) {
-          bicubicbezier2D_bbox (&vsc,
-                                &pts[i].p1,
-                                &pts[i].p2,
-                                &pts[i].p3,
-                                &full_bextra,
-                                &rt);
+          _bicubicbezier2D_bbox (&vsc,
+                                 &pts[i].p1,
+                                 &pts[i].p2,
+                                 &pts[i].p3,
+                                 &full_bextra,
+                                 &rt);
         } else {
-          bicubicbezier2D_bbox (&vsc,
-                                &pts[i].p1,
-                                &pts[i].p2,
-                                &pts[i].p3,
-                                &start_bextra,
-                                &rt);
+          _bicubicbezier2D_bbox (&vsc,
+                                 &pts[i].p1,
+                                 &pts[i].p2,
+                                 &pts[i].p3,
+                                 &start_bextra,
+                                 &rt);
         }
       }
     } else if (end) { /* end but not start. Not closed anyway. */
       if (pts[i].type == BEZ_LINE_TO) {
-        line_bbox (&vsc, &vx, &end_lextra, &rt);
+        _line_bbox (&vsc, &vx, &end_lextra, &rt);
       } else {
-        bicubicbezier2D_bbox (&vsc,
-                              &pts[i].p1,
-                              &pts[i].p2,
-                              &pts[i].p3,
-                              &end_bextra,
-                              &rt);
+        _bicubicbezier2D_bbox (&vsc,
+                               &pts[i].p1,
+                               &pts[i].p2,
+                               &pts[i].p3,
+                               &end_bextra,
+                               &rt);
       }
     } else { /* normal case : middle segment (not closed shape). */
       if (pts[i].type == BEZ_LINE_TO) {
-        line_bbox (&vsc, &vx, &lextra, &rt);
+        _line_bbox (&vsc, &vx, &lextra, &rt);
       } else {
-        bicubicbezier2D_bbox (&vsc,
-                              &pts[i].p1,
-                              &pts[i].p2,
-                              &pts[i].p3,
-                              &bextra,
-                              &rt);
+        _bicubicbezier2D_bbox (&vsc,
+                               &pts[i].p1,
+                               &pts[i].p2,
+                               &pts[i].p3,
+                               &bextra,
+                               &rt);
       }
     }
     rectangle_union (rect, &rt);
@@ -652,6 +735,21 @@ polybezier_bbox (const BezPoint     *pts,
 }
 
 
+void
+polybezier_bbox (const BezPoint     *pts,
+                 int                 numpoints,
+                 const PolyBBExtras *extra,
+                 gboolean            closed,
+                 graphene_rect_t    *rect)
+{
+  DiaRectangle out;
+
+  _polybezier_bbox (pts, numpoints, extra, closed, &out);
+
+  dia_rectangle_to_graphene (&out, rect);
+}
+
+
 /**
  * rectangle_bbox:
  * @rin: A rectangle to find bbox for.
@@ -660,10 +758,10 @@ polybezier_bbox (const BezPoint     *pts,
  *
  * Figure out a bounding box for a rectangle (fairly simple:)
  */
-void
-rectangle_bbox (const DiaRectangle    *rin,
-                const ElementBBExtras *extra,
-                DiaRectangle          *rout)
+static inline void
+_rectangle_bbox (const DiaRectangle    *rin,
+                 const ElementBBExtras *extra,
+                 DiaRectangle          *rout)
 {
   rout->left = rin->left - extra->border_trans;
   rout->top = rin->top - extra->border_trans;
@@ -671,3 +769,17 @@ rectangle_bbox (const DiaRectangle    *rin,
   rout->bottom = rin->bottom + extra->border_trans;
 }
 
+
+void
+rectangle_bbox (const graphene_rect_t *rin,
+                const ElementBBExtras *extra,
+                graphene_rect_t       *rout)
+{
+  DiaRectangle in, out;
+
+  dia_graphene_to_rectangle (rin, &in);
+
+  _rectangle_bbox (&in, extra, &out);
+
+  dia_rectangle_to_graphene (&out, rout);
+}
diff --git a/lib/boundingbox.h b/lib/boundingbox.h
index e02a15ce5..6832485f9 100644
--- a/lib/boundingbox.h
+++ b/lib/boundingbox.h
@@ -17,28 +17,33 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#pragma once
+
 /*!
  * \defgroup ObjectBBox Bounding box
  * \brief Calculations considering line width, caps and joins
  * \ingroup ObjectParts
  */
 
-#ifndef BOUNDINGBOX_H
-#define BOUNDINGBOX_H
+#include <graphene.h>
 
 #include "diatypes.h"
 #include "geometry.h"
 
-/*!
- * \brief Polygon/Polyline bounding box extras
- * \ingroup ObjectBBox
+G_BEGIN_DECLS
+
+/**
+ * PolyBBExtras:
+ *
+ * Polygon/Polyline bounding box extras
  */
 struct _PolyBBExtras {
-  double start_long, start_trans;
-  double middle_trans;
-  double end_long, end_trans;
+  float start_long, start_trans;
+  float middle_trans;
+  float end_long, end_trans;
 };
 
+
 /*!
  * \brief Line bounding box extras
  * \ingroup ObjectBBox
@@ -56,65 +61,44 @@ struct _ElementBBExtras {
   double border_trans;
 };
 
-void bicubicbezier2D_bbox(const Point *p0,const Point *p1,
-                          const Point *p2,const Point *p3,
-                          const PolyBBExtras *extra,
-                          DiaRectangle       *rect);
-
-/*!
- * \brief Bounding box calculation for a straight line
- * The calcualtion includes line width and arrwos with the right extra
- * \ingroup ObjectBBox
- */
-void line_bbox(const Point *p1, const Point *p2,
-               const LineBBExtras *extra,
-               DiaRectangle       *rect);
-
-/*!
- * \brief Bounding box calculation for a rectangle
- * The calcualtion includes line width with the right extra
- * \ingroup ObjectBBox
- */
-void rectangle_bbox(const DiaRectangle    *rin,
-                    const ElementBBExtras *extra,
-                    DiaRectangle          *rout);
-
-/*!
- * \brief Bounding box calculation for an ellipse
- * The calcualtion includes line width with the right extra
- * \ingroup ObjectBBox
- */
-void ellipse_bbox (const Point           *centre,
-                   double                 width,
-                   double                 height,
-                   const ElementBBExtras *extra,
-                   DiaRectangle          *rect);
-/*!
- * \brief Bounding box calculation for a polyline
- * The calcualtion includes line width and arrwos with the right extra
- * \ingroup ObjectBBox
- */
-void polyline_bbox(const Point *pts, int numpoints,
-                   const PolyBBExtras *extra, gboolean closed,
-                   DiaRectangle       *rect);
-/*!
- * \brief Bounding box calculation for a bezier
- * The calcualtion includes line width and arrwos with the right extra
- * \ingroup ObjectBBox
- */
-void polybezier_bbox(const BezPoint *pts, int numpoints,
-                     const PolyBBExtras *extra, gboolean closed,
-                     DiaRectangle       *rect);
 
+void   bicubicbezier2D_bbox   (const graphene_vec2_t *p0,
+                               const Point           *p1,
+                               const Point           *p2,
+                               const Point           *p3,
+                               const PolyBBExtras    *extra,
+                               graphene_rect_t       *rect);
+void   line_bbox              (const graphene_vec2_t *p1,
+                               const graphene_vec2_t *p2,
+                               const LineBBExtras    *extra,
+                               graphene_rect_t       *rect);
+void   rectangle_bbox         (const graphene_rect_t *rin,
+                               const ElementBBExtras *extra,
+                               graphene_rect_t       *rout);
+void   ellipse_bbox           (const Point           *centre,
+                               float                  width,
+                               float                  height,
+                               const ElementBBExtras *extra,
+                               graphene_rect_t       *rect);
+void   polyline_bbox          (const Point           *pts,
+                               int                    numpoints,
+                               const PolyBBExtras    *extra,
+                               gboolean               closed,
+                               graphene_rect_t       *rect);
+void   polybezier_bbox        (const BezPoint        *pts,
+                               int                    numpoints,
+                               const PolyBBExtras    *extra,
+                               gboolean               closed,
+                               graphene_rect_t       *rect);
 /* helpers for bezier curve calculation */
-void   bernstein_develop   (const double  p[4],
-                            double       *A,
-                            double       *B,
-                            double       *C,
-                            double       *D);
-double bezier_eval         (const double  p[4],
-                            double        u);
-double bezier_eval_tangent (const double  p[4],
-                            double        u);
+void   bernstein_develop      (const double           p[4],
+                               double                *A,
+                               double                *B,
+                               double                *C,
+                               double                *D);
+double bezier_eval            (const double           p[4],
+                               double                 u);
+double bezier_eval_tangent    (const double           p[4],
+                               double                 u);
 
-#endif /* BOUNDINGBOX_H */
+G_END_DECLS
diff --git a/lib/connection.c b/lib/connection.c
index c8e71542d..20786e246 100644
--- a/lib/connection.c
+++ b/lib/connection.c
@@ -23,6 +23,7 @@
 #include <assert.h>
 
 #include "connection.h"
+#include "dia-graphene.h"
 
 
 /**
@@ -158,12 +159,17 @@ connection_update_handles (Connection *conn)
 void
 connection_update_boundingbox (Connection *conn)
 {
+  graphene_rect_t bbox;
+  graphene_vec2_t p1, p2;
+
   g_return_if_fail (conn != NULL);
 
-  line_bbox (&conn->endpoints[0],
-             &conn->endpoints[1],
-             &conn->extra_spacing,
-             &conn->object.bounding_box);
+  graphene_vec2_init (&p1, conn->endpoints[0].x, conn->endpoints[0].y);
+  graphene_vec2_init (&p2, conn->endpoints[1].x, conn->endpoints[1].y);
+
+  line_bbox (&p1, &p2, &conn->extra_spacing, &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (conn), &bbox);
 }
 
 
diff --git a/lib/dia-graphene.h b/lib/dia-graphene.h
index af2fd0a94..32c3dc3fe 100644
--- a/lib/dia-graphene.h
+++ b/lib/dia-graphene.h
@@ -26,6 +26,8 @@
 
 #include "geometry.h"
 
+G_BEGIN_DECLS
+
 static inline void
 dia_matrix_from_graphene (DiaMatrix         *matrix,
                           graphene_matrix_t *graphene)
@@ -38,6 +40,7 @@ dia_matrix_from_graphene (DiaMatrix         *matrix,
   matrix->y0 = graphene_matrix_get_y_translation (graphene);
 }
 
+
 static inline void
 dia_graphene_from_matrix (graphene_matrix_t *graphene,
                           const DiaMatrix   *matrix)
@@ -50,3 +53,118 @@ dia_graphene_from_matrix (graphene_matrix_t *graphene,
                                 matrix->x0,
                                 matrix->y0);
 }
+
+
+static inline void
+dia_graphene_to_rectangle (const graphene_rect_t *rect,
+                           DiaRectangle          *bounds)
+{
+  graphene_point_t point;
+
+  graphene_rect_get_top_left (rect, &point);
+  bounds->top = point.y;
+  bounds->left = point.x;
+
+  graphene_rect_get_bottom_right (rect, &point);
+  bounds->bottom = point.y;
+  bounds->right = point.x;
+}
+
+
+static inline void
+dia_rectangle_to_graphene (const DiaRectangle *bounds,
+                           graphene_rect_t    *rect)
+{
+  graphene_rect_init (rect,
+                      bounds->left,
+                      bounds->top,
+                      bounds->right - bounds->left,
+                      bounds->bottom - bounds->top);
+}
+
+
+static inline void
+dia_graphene_dump_rect (const graphene_rect_t *self)
+{
+  graphene_point_t point;
+
+  graphene_rect_get_top_left (self, &point);
+  g_print (" \\ %10f\n", point.y);
+  g_print (" %10f\n", point.x);
+  g_print ("   %10f X %10f\n",
+           graphene_rect_get_width (self),
+           graphene_rect_get_height (self));
+
+  graphene_rect_get_bottom_right (self, &point);
+  g_print ("                \\ %10f\n", point.x);
+  g_print ("                %10f\n", point.y);
+}
+
+
+static inline void
+dia_graphene_to_point (const graphene_point_t *src,
+                       Point                  *dest)
+{
+  dest->x = src->x;
+  dest->y = src->y;
+}
+
+
+static inline void
+dia_point_to_graphene (const Point      *src,
+                       graphene_point_t *dest)
+{
+  dest->x = src->x;
+  dest->y = src->y;
+}
+
+
+static inline void
+dia_point_to_vec2 (const Point     *src,
+                   graphene_vec2_t *dest)
+{
+  graphene_vec2_init (dest, src->x, src->y);
+}
+
+
+static inline void
+dia_vec2_to_point (const graphene_vec2_t *src,
+                   Point                 *dest)
+{
+  dest->x = graphene_vec2_get_x (src);
+  dest->y = graphene_vec2_get_y (src);
+}
+
+
+/**
+ * dia_vec2_add_scaled:
+ * @a: the first #graphene_vec2_t
+ * @b: the second #graphene_vec2_t
+ * @scale: scale to apply to @b
+ * @res: (out caller-allocates): where to store the result
+ *
+ * See graphene_vec2_add()/graphene_vec2_scale()
+ */
+static inline void
+dia_vec2_add_scaled (const graphene_vec2_t *a,
+                     const graphene_vec2_t *b,
+                     float                  scale,
+                     graphene_vec2_t       *res)
+{
+  graphene_vec2_t tmp;
+  graphene_vec2_scale (b, scale, &tmp);
+  graphene_vec2_add (a, &tmp, res);
+}
+
+
+static inline void
+dia_vec2_perpendicular (const graphene_vec2_t *src, graphene_vec2_t *res)
+{
+  float y = graphene_vec2_get_x (src);
+  float x = -graphene_vec2_get_y (src);
+
+  graphene_vec2_init (res, x, y);
+}
+
+
+G_END_DECLS
diff --git a/lib/dia-layer.h b/lib/dia-layer.h
index 7906a48dc..dcfb04b93 100644
--- a/lib/dia-layer.h
+++ b/lib/dia-layer.h
@@ -21,6 +21,7 @@
  */
 
 #include <glib.h>
+#include <graphene.h>
 
 #include "diatypes.h"
 #include "diarenderer.h"
@@ -70,7 +71,7 @@ GList       *dia_layer_find_objects_intersecting_rectangle (DiaLayer         *la
 GList       *dia_layer_find_objects_in_rectangle           (DiaLayer         *layer,
                                                             DiaRectangle     *rect);
 GList       *dia_layer_find_objects_containing_rectangle   (DiaLayer         *layer,
-                                                            DiaRectangle     *rect);
+                                                            graphene_rect_t  *rect);
 DiaObject   *dia_layer_find_closest_object                 (DiaLayer         *layer,
                                                             Point            *pos,
                                                             real              maxdist);
diff --git a/lib/diapathrenderer.c b/lib/diapathrenderer.c
index 045b16f48..4d82cf540 100644
--- a/lib/diapathrenderer.c
+++ b/lib/diapathrenderer.c
@@ -24,7 +24,7 @@
 #include "text.h" /* just for text->color */
 #include "standard-path.h" /* for text_to_path() */
 #include "boundingbox.h"
-
+#include "dia-graphene.h"
 #include "attributes.h" /* attributes_get_foreground() */
 
 typedef enum {
@@ -599,38 +599,53 @@ draw_beziergon (DiaRenderer *self,
 {
   _bezier(self, points, numpoints, fill, stroke);
 }
-/*!
- * \brief Convert the text object to a scaled path
- * \memberof _DiaPathRenderer
+
+
+/**
+ * draw_text:
+ * @self: the #DiaRenderer to draw with
+ * @text: the #Text to draw
+ *
+ * Convert the text object to a scaled path
  */
 static void
 draw_text (DiaRenderer *self,
-          Text        *text)
+           Text        *text)
 {
   DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
   GArray *path = _get_current_path (renderer, NULL, &text->color);
   int n0 = path->len;
 
   if (!text_is_empty (text) && text_to_path (text, path)) {
-    DiaRectangle bz_bb, tx_bb;
+    graphene_rect_t bz_bb, tx_bb;
     PolyBBExtras extra = { 0, };
-    real dx, dy, sx, sy;
-    guint i;
+    double dx, dy, sx, sy;
+    graphene_point_t bz_tl, tx_tl;
+
+    polybezier_bbox (&g_array_index (path, BezPoint, n0),
+                     path->len - n0,
+                     &extra,
+                     TRUE,
+                     &bz_bb);
 
-    polybezier_bbox (&g_array_index (path, BezPoint, n0), path->len - n0, &extra, TRUE, &bz_bb);
     text_calc_boundingbox (text, &tx_bb);
-    sx = (tx_bb.right - tx_bb.left) / (bz_bb.right - bz_bb.left);
-    sy = (tx_bb.bottom - tx_bb.top) / (bz_bb.bottom - bz_bb.top);
-    dx = tx_bb.left - bz_bb.left * sx;
-    dy = tx_bb.top - bz_bb.top * sy;
+    sx = graphene_rect_get_width (&tx_bb) / graphene_rect_get_width (&bz_bb);
+    sy = graphene_rect_get_height (&tx_bb) / graphene_rect_get_height (&bz_bb);
+
+    graphene_rect_get_top_left (&tx_bb, &tx_tl);
+    graphene_rect_get_top_left (&bz_bb, &bz_tl);
 
-    for (i = n0; i < path->len; ++i) {
+    dx = tx_tl.x - bz_tl.x * sx;
+    dy = tx_tl.y - bz_tl.y * sy;
+
+    for (int i = n0; i < path->len; ++i) {
       BezPoint *bp = &g_array_index (path, BezPoint, i);
 
       bp->p1.x = bp->p1.x * sx + dx;
       bp->p1.y = bp->p1.y * sy + dy;
-      if (bp->type != BEZ_CURVE_TO)
+      if (bp->type != BEZ_CURVE_TO) {
         continue;
+      }
       bp->p2.x = bp->p2.x * sx + dx;
       bp->p2.y = bp->p2.y * sy + dy;
       bp->p3.x = bp->p3.x * sx + dx;
@@ -639,6 +654,7 @@ draw_text (DiaRenderer *self,
   }
 }
 
+
 /*!
  * \brief Convert the string back to a _Text object and render that
  * \memberof _DiaPathRenderer
diff --git a/lib/diarenderer.c b/lib/diarenderer.c
index 38d85de9e..a45f9585a 100644
--- a/lib/diarenderer.c
+++ b/lib/diarenderer.c
@@ -29,6 +29,9 @@
 #include "standard-path.h" /* text_to_path */
 #include "boundingbox.h" /* PolyBBextra */
 #include "dia-layer.h"
+#include "dia-graphene.h"
+
+
 /*
  * redefinition of isnan, for portability, as explained in :
  * http://www.gnu.org/software/autoconf/manual/html_node/Function-Portability.html
@@ -256,22 +259,30 @@ draw_layer (DiaRenderer  *renderer,
             DiaRectangle *update)
 {
   GList *list = dia_layer_get_object_list (layer);
-  void (*func) (DiaRenderer*, DiaObject *, DiaMatrix *);
+  graphene_rect_t rect;
 
-  g_return_if_fail (layer != NULL);
+  g_return_if_fail (DIA_IS_LAYER (layer));
+
+  if (update) {
+    dia_rectangle_to_graphene (update, &rect);
+  }
 
-  func = DIA_RENDERER_GET_CLASS(renderer)->draw_object;
   /* Draw all objects  */
-  while (list!=NULL) {
-    DiaObject *obj = (DiaObject *) list->data;
+  while (list != NULL) {
+    DiaObject *obj = DIA_OBJECT (list->data);
+    graphene_rect_t ebox;
 
-    if (update==NULL || rectangle_intersects(update, dia_object_get_enclosing_box(obj))) {
-      (*func)(renderer, obj, NULL);
+    dia_object_get_enclosing_box (obj, &ebox);
+
+    if (update == NULL || graphene_rect_intersection (&rect, &ebox, NULL)) {
+      dia_renderer_draw_object (renderer, obj, NULL);
     }
-    list = g_list_next(list);
+
+    list = g_list_next (list);
   }
 }
 
+
 /*!
  * \brief Render the given object with optional transformation matrix
  *
@@ -644,15 +655,13 @@ draw_image (DiaRenderer *renderer,
  * \memberof _DiaRenderer
  */
 static void
-draw_text (DiaRenderer *renderer,
-          Text *text)
+draw_text (DiaRenderer *renderer, Text *text)
 {
   Point pos;
-  int i;
 
-  pos = text->position;
+  dia_text_get_position (text, &pos);
 
-  for (i=0;i<text->numlines;i++) {
+  for (int i = 0; i < text->numlines; i++) {
     TextLine *text_line = text->lines[i];
 
     dia_renderer_draw_text_line (renderer,
@@ -664,6 +673,7 @@ draw_text (DiaRenderer *renderer,
   }
 }
 
+
 /**
  * draw_rotated_text:
  * @renderer: the #DiaRenderer
@@ -691,44 +701,68 @@ draw_rotated_text (DiaRenderer *renderer,
     draw_text (renderer, text);
   } else {
     GArray *path = g_array_new (FALSE, FALSE, sizeof (BezPoint));
+
     if (!text_is_empty (text) && text_to_path (text, path)) {
       /* Scaling and transformation here */
-      DiaRectangle bz_bb, tx_bb;
       PolyBBExtras extra = { 0, };
-      real sx, sy;
+      double sx, sy;
       guint i;
-      real dx = center ? (text->position.x - center->x) : 0;
-      real dy = center ? (text->position.y - center->y) : 0;
+      double dx;
+      double dy;
       DiaMatrix m = { 1, 0, 0, 1, 0, 0 };
       DiaMatrix t = { 1, 0, 0, 1, 0, 0 };
+      graphene_rect_t bz_bb, tx_bb;
+      graphene_point_t bz_tl, bz_br, tx_tl, tx_br;
+      Point text_pos;
+
+      dia_text_get_position (text, &text_pos);
+
+      dx = center ? (text_pos.x - center->x) : 0;
+      dy = center ? (text_pos.y - center->y) : 0;
+
+      polybezier_bbox (&g_array_index (path, BezPoint, 0),
+                       path->len,
+                       &extra,
+                       TRUE,
+                       &bz_bb);
 
-      polybezier_bbox (&g_array_index (path, BezPoint, 0), path->len, &extra, TRUE, &bz_bb);
       text_calc_boundingbox (text, &tx_bb);
-      sx = (tx_bb.right - tx_bb.left) / (bz_bb.right - bz_bb.left);
-      sy = (tx_bb.bottom - tx_bb.top) / (bz_bb.bottom - bz_bb.top);
+      sx = graphene_rect_get_width (&tx_bb) / graphene_rect_get_width (&bz_bb);
+      sy = graphene_rect_get_height (&tx_bb) / graphene_rect_get_height (&bz_bb);
+
+      graphene_rect_get_top_left (&bz_bb, &bz_tl);
+      graphene_rect_get_bottom_right (&bz_bb, &bz_br);
 
       /* move center to origin */
       if (ALIGN_LEFT == text->alignment) {
-        t.x0 = -bz_bb.left;
+        t.x0 = -bz_tl.x;
       } else if (ALIGN_RIGHT == text->alignment) {
-        t.x0 = - bz_bb.right;
+        t.x0 = -bz_br.x;
       } else {
-        t.x0 = -(bz_bb.left + bz_bb.right) / 2.0;
+        t.x0 = -(bz_tl.x + bz_br.x) / 2.0;
       }
+
       t.x0 -= dx / sx;
-      t.y0 = - bz_bb.top - (text_get_ascent (text) - dy) / sy;
+      t.y0 = - bz_tl.y - (text_get_ascent (text) - dy) / sy;
+
       dia_matrix_set_angle_and_scales (&m, G_PI * angle / 180.0, sx, sx);
       dia_matrix_multiply (&m, &t, &m);
+
+      graphene_rect_get_top_left (&tx_bb, &tx_tl);
+      graphene_rect_get_bottom_right (&tx_bb, &tx_br);
+
       /* move back center from origin */
       if (ALIGN_LEFT == text->alignment) {
-        t.x0 = tx_bb.left;
+        t.x0 = tx_tl.x;
       } else if (ALIGN_RIGHT == text->alignment) {
-        t.x0 = tx_bb.right;
+        t.x0 = tx_br.x;
       } else {
-        t.x0 = (tx_bb.left + tx_bb.right) / 2.0;
+        t.x0 = (tx_tl.x + tx_br.x) / 2.0;
       }
+
       t.x0 += dx;
-      t.y0 = tx_bb.top + (text_get_ascent (text) - dy);
+      t.y0 = tx_tl.y + (text_get_ascent (text) - dy);
+
       dia_matrix_multiply (&m, &m, &t);
 
       for (i = 0; i < path->len; ++i) {
@@ -738,10 +772,10 @@ draw_rotated_text (DiaRenderer *renderer,
 
       if (dia_renderer_is_capable_of (renderer, RENDER_HOLES)) {
         dia_renderer_draw_beziergon (renderer,
-                                      &g_array_index (path, BezPoint, 0),
-                                      path->len,
-                                      &text->color,
-                                      NULL);
+                                     &g_array_index (path, BezPoint, 0),
+                                     path->len,
+                                     &text->color,
+                                     NULL);
       } else {
         dia_renderer_bezier_fill (renderer,
                                   &g_array_index (path, BezPoint, 0),
@@ -750,23 +784,39 @@ draw_rotated_text (DiaRenderer *renderer,
       }
     } else {
       Color magenta = { 1.0, 0.0, 1.0, 1.0 };
-      Point pt = center ? *center : text->position;
-      DiaMatrix m = { 1, 0, 0, 1, pt.x, pt.y };
-      DiaMatrix t = { 1, 0, 0, 1, -pt.x, -pt.y };
-      DiaRectangle tb;
+      Point pt;
+      DiaMatrix m, t;
+      graphene_rect_t tb;
+      graphene_point_t corner;
       Point poly[4];
-      int i;
+
+      if (center) {
+        pt = *center;
+      } else {
+        dia_text_get_position (text, &pt);
+      }
+
+      m = (DiaMatrix) { 1, 0, 0, 1, pt.x, pt.y };
+      t = (DiaMatrix) { 1, 0, 0, 1, -pt.x, -pt.y };
 
       text_calc_boundingbox (text, &tb);
-      poly[0].x = tb.left;  poly[0].y = tb.top;
-      poly[1].x = tb.right; poly[1].y = tb.top;
-      poly[2].x = tb.right; poly[2].y = tb.bottom;
-      poly[3].x = tb.left;  poly[3].y = tb.bottom;
+
+      graphene_rect_get_top_left (&tb, &corner);
+      dia_graphene_to_point (&corner, &poly[0]);
+
+      graphene_rect_get_top_right (&tb, &corner);
+      dia_graphene_to_point (&corner, &poly[1]);
+
+      graphene_rect_get_bottom_right (&tb, &corner);
+      dia_graphene_to_point (&corner, &poly[2]);
+
+      graphene_rect_get_bottom_left (&tb, &corner);
+      dia_graphene_to_point (&corner, &poly[3]);
 
       dia_matrix_set_angle_and_scales (&m, G_PI * angle / 180.0, 1.0, 1.0);
       dia_matrix_multiply (&m, &t, &m);
 
-      for (i = 0; i < 4; ++i) {
+      for (int i = 0; i < 4; ++i) {
         transform_point (&poly[i], &m);
       }
 
@@ -777,6 +827,7 @@ draw_rotated_text (DiaRenderer *renderer,
                                  NULL,
                                  &magenta);
     }
+
     g_array_free (path, TRUE);
   }
 }
diff --git a/lib/diatransformrenderer.c b/lib/diatransformrenderer.c
index b1b98d0bd..65351a9d7 100644
--- a/lib/diatransformrenderer.c
+++ b/lib/diatransformrenderer.c
@@ -402,16 +402,15 @@ draw_beziergon (DiaRenderer *self,
  * \memberof _DiaTransformRenderer
  */
 static void
-draw_text (DiaRenderer *self,
-          Text        *text)
+draw_text (DiaRenderer *self, Text *text)
 {
   DiaTransformRenderer *renderer = DIA_TRANSFORM_RENDERER (self);
   DiaMatrix *m = g_queue_peek_tail (renderer->matrices);
-  Point pos = text->position;
-  real angle, sx, sy;
-  int i;
+  Point pos;
+  double angle, sx, sy;
+
+  dia_text_get_position (text, &pos);
 
-  pos = text->position;
   if (m && dia_matrix_get_angle_and_scales (m, &angle, &sx, &sy)) {
     Text *tc = text_copy (text);
     transform_point (&pos, m);
@@ -423,7 +422,7 @@ draw_text (DiaRenderer *self,
                                     180.0 * angle / G_PI);
     text_destroy (tc);
   } else {
-    for (i=0;i<text->numlines;i++) {
+    for (int i = 0; i < text->numlines; i++) {
       TextLine *text_line = text->lines[i];
       Point pt;
 
@@ -442,6 +441,7 @@ draw_text (DiaRenderer *self,
   }
 }
 
+
 /*!
  * \brief Transform the text object while drawing
  *
@@ -454,10 +454,12 @@ draw_rotated_text (DiaRenderer *self, Text *text, Point *center, real angle)
 {
   DiaTransformRenderer *renderer = DIA_TRANSFORM_RENDERER (self);
   DiaMatrix *m = g_queue_peek_tail (renderer->matrices);
-  Point pos = text->position;
+  Point pos;
+
+  dia_text_get_position (text, &pos);
 
   if (m) {
-    real angle2, sx, sy;
+    double angle2, sx, sy;
     DiaMatrix m2 = { 1, 0, 0, 1, -pos.x, -pos.y };
     DiaMatrix t = { 1, 0, 0, 1, pos.x, pos.y };
 
diff --git a/lib/element.c b/lib/element.c
index e9c7f862d..6010774c1 100644
--- a/lib/element.c
+++ b/lib/element.c
@@ -35,6 +35,7 @@
 
 #include "element.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 
 #ifdef G_OS_WIN32
@@ -55,19 +56,19 @@ PropNumData width_range = { -G_MAXFLOAT, G_MAXFLOAT, 0.1};
 void
 element_update_boundingbox (Element *elem)
 {
-  DiaRectangle bb;
   Point *corner;
   ElementBBExtras *extra = &elem->extra_spacing;
+  graphene_rect_t src, bbox;
 
-  assert(elem != NULL);
+  assert (elem != NULL);
 
   corner = &elem->corner;
-  bb.left = corner->x;
-  bb.right = corner->x + elem->width;
-  bb.top = corner->y;
-  bb.bottom = corner->y + elem->height;
 
-  rectangle_bbox(&bb,extra,&elem->object.bounding_box);
+  graphene_rect_init (&src, corner->x, corner->y, elem->width, elem->height);
+
+  rectangle_bbox (&src, extra, &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (elem), &bbox);
 }
 
 
diff --git a/lib/geometry.h b/lib/geometry.h
index 11f78cf7a..cead225f3 100644
--- a/lib/geometry.h
+++ b/lib/geometry.h
@@ -17,28 +17,15 @@
  */
 
 /** \file geometry.h -- basic geometry classes and functions operationg on them */
-#ifndef GEOMETRY_H
-#define GEOMETRY_H
 
-#include <config.h>
+#pragma once
 
-#include "diatypes.h"
+#include "config.h"
 
 #include <glib.h>
 #include <math.h>
 
-/* Solaris 2.4, 2.6, probably 2.5.x, and possibly others prototype
-   finite() in ieeefp.h instead of math.h.  finite() might not be
-   available at all on some HP-UX configurations (in which case,
-   you're on your own). */
-#ifdef HAVE_IEEEFP_H
-#include <ieeefp.h>
-#endif
-#ifndef HAVE_ISINF
-#  ifndef isinf
-#    define isinf(a) (!finite(a))
-#  endif
-#endif
+#include "diatypes.h"
 
 #ifdef _MSC_VER
 /* #ifdef G_OS_WIN32  apparently _MSC_VER and mingw */
@@ -51,7 +38,6 @@
 #endif
 #ifdef G_OS_WIN32
 #  define M_PI      3.14159265358979323846
-#  define M_SQRT2      1.41421356237309504880  /* sqrt(2) */
 #  define M_SQRT1_2 0.70710678118654752440     /* 1/sqrt(2) */
 #endif
 
@@ -59,9 +45,6 @@
 #ifndef M_PI
 #define M_PI G_PI
 #endif
-#ifndef M_SQRT2
-#define M_SQRT2 G_SQRT2
-#endif
 #ifndef M_SQRT1_2
 #define M_SQRT1_2 (1.0/G_SQRT2)
 #endif
@@ -252,8 +235,9 @@ point_get_normed(Point *dst, const Point *src)
   dst->y = src->y / len;
 }
 
+
 static inline void
-point_get_perp(Point *dst, const Point *src)
+point_get_perp (Point *dst, const Point *src)
 {
   /* dst = the src vector, rotated 90deg counter clowkwise. src *must* be
      normalized before. */
@@ -261,6 +245,7 @@ point_get_perp(Point *dst, const Point *src)
   dst->x = -src->y;
 }
 
+
 static inline void
 point_copy(Point *dst, const Point *src)
 {
@@ -364,5 +349,3 @@ real dia_asin (real x);
 real dia_acos (real x);
 
 G_END_DECLS
-
-#endif /* GEOMETRY_H */
diff --git a/lib/group.c b/lib/group.c
index d19542a54..cd1d967e9 100644
--- a/lib/group.c
+++ b/lib/group.c
@@ -25,6 +25,7 @@
 #include "group.h"
 #include "properties.h"
 #include "diarenderer.h"
+#include "dia-graphene.h"
 
 
 /*!
@@ -135,42 +136,60 @@ group_select(Group *group)
   group_update_handles(group);
 }
 
+
 static void
-group_update_handles(Group *group)
+group_update_handles (Group *group)
 {
-  DiaRectangle *bb = &group->object.bounding_box;
+  graphene_rect_t bb;
+  graphene_point_t point_a, point_b;
+
+  dia_object_get_bounding_box (DIA_OBJECT (group), &bb);
 
   group->handles[0].id = HANDLE_RESIZE_NW;
-  group->handles[0].pos.x = bb->left;
-  group->handles[0].pos.y = bb->top;
+
+  graphene_rect_get_top_left (&bb, &point_a);
+  dia_graphene_to_point (&point_a, &group->handles[0].pos);
 
   group->handles[1].id = HANDLE_RESIZE_N;
-  group->handles[1].pos.x = (bb->left + bb->right) / 2.0;
-  group->handles[1].pos.y = bb->top;
+
+  graphene_rect_get_top_right (&bb, &point_b);
+  graphene_point_interpolate (&point_a, &point_b, 0.5, &point_b);
+  dia_graphene_to_point (&point_b, &group->handles[1].pos);
 
   group->handles[2].id = HANDLE_RESIZE_NE;
-  group->handles[2].pos.x = bb->right;
-  group->handles[2].pos.y = bb->top;
+
+  graphene_rect_get_top_right (&bb, &point_a);
+  dia_graphene_to_point (&point_a, &group->handles[2].pos);
 
   group->handles[3].id = HANDLE_RESIZE_W;
-  group->handles[3].pos.x = bb->left;
-  group->handles[3].pos.y = (bb->top + bb->bottom) / 2.0;
+
+  graphene_rect_get_top_left (&bb, &point_a);
+  graphene_rect_get_bottom_left (&bb, &point_b);
+  graphene_point_interpolate (&point_a, &point_b, 0.5, &point_b);
+  dia_graphene_to_point (&point_b, &group->handles[3].pos);
 
   group->handles[4].id = HANDLE_RESIZE_E;
-  group->handles[4].pos.x = bb->right;
-  group->handles[4].pos.y = (bb->top + bb->bottom) / 2.0;
+
+  graphene_rect_get_top_right (&bb, &point_a);
+  graphene_rect_get_bottom_right (&bb, &point_b);
+  graphene_point_interpolate (&point_a, &point_b, 0.5, &point_b);
+  dia_graphene_to_point (&point_b, &group->handles[4].pos);
 
   group->handles[5].id = HANDLE_RESIZE_SW;
-  group->handles[5].pos.x = bb->left;
-  group->handles[5].pos.y = bb->bottom;
+
+  graphene_rect_get_bottom_left (&bb, &point_a);
+  dia_graphene_to_point (&point_a, &group->handles[5].pos);
 
   group->handles[6].id = HANDLE_RESIZE_S;
-  group->handles[6].pos.x = (bb->left + bb->right) / 2.0;
-  group->handles[6].pos.y = bb->bottom;
+
+  graphene_rect_get_bottom_right (&bb, &point_b);
+  graphene_point_interpolate (&point_a, &point_b, 0.5, &point_b);
+  dia_graphene_to_point (&point_b, &group->handles[6].pos);
 
   group->handles[7].id = HANDLE_RESIZE_SE;
-  group->handles[7].pos.x = bb->right;
-  group->handles[7].pos.y = bb->bottom;
+
+  graphene_rect_get_bottom_right (&bb, &point_a);
+  dia_graphene_to_point (&point_a, &group->handles[7].pos);
 }
 
 /*! \brief Update connection points positions of contained objects
@@ -224,19 +243,24 @@ group_move_handle (Group            *group,
                    HandleMoveReason  reason,
                    ModifierKeys      modifiers)
 {
-  DiaObject *obj = &group->object;
-  DiaRectangle *bb = &obj->bounding_box;
+  graphene_rect_t bb;
   /* top and left handles are also changing the objects position */
-  Point top_left = { bb->left, bb->top };
+  graphene_point_t tl;
+  Point top_left;
   /* before and after width and height */
-  real w0, h0, w1, h1;
+  double w0, h0, w1, h1;
   Point fixed;
 
   assert(handle->id>=HANDLE_RESIZE_NW);
   assert(handle->id<=HANDLE_RESIZE_SE);
 
-  w0 = w1 = bb->right - bb->left;
-  h0 = h1 = bb->bottom - bb->top;
+  dia_object_get_bounding_box (DIA_OBJECT (group), &bb);
+
+  graphene_rect_get_top_left (&bb, &tl);
+  dia_graphene_to_point (&tl, &top_left);
+
+  w0 = w1 = graphene_rect_get_width (&bb);
+  h0 = h1 = graphene_rect_get_height (&bb);
 
   /* Movement and scaling only work as intended with no active rotation.
    * For rotated group we should either translate the handle positions
@@ -463,23 +487,30 @@ group_copy(Group *group)
 
 
 static void
-group_update_data(Group *group)
+group_update_data (Group *group)
 {
   GList *list;
   DiaObject *obj;
+  graphene_rect_t new_bbox;
 
   if (group->objects != NULL) {
     list = group->objects;
-    obj = (DiaObject *) list->data;
-    group->object.bounding_box = obj->bounding_box;
 
-    list = g_list_next(list);
+    obj = DIA_OBJECT (list->data);
+
+    dia_object_get_bounding_box (obj, &new_bbox);
+
+    list = g_list_next (list);
     while (list != NULL) {
-      obj = (DiaObject *) list->data;
+      graphene_rect_t bbox;
 
-      rectangle_union(&group->object.bounding_box, &obj->bounding_box);
+      obj = DIA_OBJECT (list->data);
 
-      list = g_list_next(list);
+      dia_object_get_bounding_box (obj, &bbox);
+
+      graphene_rect_union (&new_bbox, &bbox, &new_bbox);
+
+      list = g_list_next (list);
     }
 
     obj = (DiaObject *) group->objects->data;
@@ -491,36 +522,42 @@ group_update_data(Group *group)
     if (group->matrix) {
       Point p;
       DiaRectangle box;
-      DiaRectangle *bb = &group->object.bounding_box;
+      DiaRectangle bb;
       DiaMatrix *m = group->matrix;
 
+      dia_graphene_to_rectangle (&new_bbox, &bb);
+
       /* maintain obj->position */
       transform_point (&group->object.position, m);
 
       /* recalculate bounding box */
       /* need to consider all corners */
-      p.x = m->xx * bb->left + m->xy * bb->top + m->x0;
-      p.y = m->yx * bb->left + m->yy * bb->top + m->y0;
+      p.x = m->xx * bb.left + m->xy * bb.top + m->x0;
+      p.y = m->yx * bb.left + m->yy * bb.top + m->y0;
       box.left = box.right = p.x;
       box.top = box.bottom = p.y;
 
-      p.x = m->xx * bb->right + m->xy * bb->top + m->x0;
-      p.y = m->yx * bb->right + m->yy * bb->top + m->y0;
+      p.x = m->xx * bb.right + m->xy * bb.top + m->x0;
+      p.y = m->yx * bb.right + m->yy * bb.top + m->y0;
       rectangle_add_point (&box, &p);
 
-      p.x = m->xx * bb->right + m->xy * bb->bottom + m->x0;
-      p.y = m->yx * bb->right + m->yy * bb->bottom + m->y0;
+      p.x = m->xx * bb.right + m->xy * bb.bottom + m->x0;
+      p.y = m->yx * bb.right + m->yy * bb.bottom + m->y0;
       rectangle_add_point (&box, &p);
 
-      p.x  = m->xx * bb->left + m->xy * bb->bottom + m->x0;
-      p.y = m->yx * bb->left + m->yy * bb->bottom + m->y0;
+      p.x = m->xx * bb.left + m->xy * bb.bottom + m->x0;
+      p.y = m->yx * bb.left + m->yy * bb.bottom + m->y0;
       rectangle_add_point (&box, &p);
+
       /* the new one does not necessarily include the old one */
-      group->object.bounding_box = box;
+
+      dia_rectangle_to_graphene (&box, &new_bbox);
     }
 
-    group_update_connectionpoints(group);
-    group_update_handles(group);
+    dia_object_set_bounding_box (DIA_OBJECT (group), &new_bbox);
+
+    group_update_connectionpoints (group);
+    group_update_handles (group);
   }
 }
 
diff --git a/lib/layer.c b/lib/layer.c
index 7a35e2391..77c057619 100644
--- a/lib/layer.c
+++ b/lib/layer.c
@@ -24,6 +24,8 @@
 #include "diainteractiverenderer.h"
 #include "dynamic_obj.h"
 #include "dia-layer.h"
+#include "dia-graphene.h"
+
 
 static const DiaRectangle invalid_extents = { -1.0,-1.0,-1.0,-1.0 };
 
@@ -294,7 +296,16 @@ dia_layer_render (DiaLayer       *layer,
 {
   GList *list;
   DiaObject *obj;
-  DiaLayerPrivate *priv = dia_layer_get_instance_private (layer);
+  DiaLayerPrivate *priv;
+  graphene_rect_t update_rect;
+
+  g_return_if_fail (DIA_IS_LAYER (layer));
+
+  priv = dia_layer_get_instance_private (layer);
+
+  if (update) {
+    dia_rectangle_to_graphene (update, &update_rect);
+  }
 
   if (obj_renderer == NULL)
     obj_renderer = normal_render;
@@ -302,16 +313,24 @@ dia_layer_render (DiaLayer       *layer,
   /* Draw all objects: */
   list = priv->objects;
   while (list != NULL) {
-    obj = (DiaObject *) list->data;
+    graphene_rect_t bbox;
+
+    obj = DIA_OBJECT (list->data);
 
-    if (update==NULL || rectangle_intersects (update, &obj->bounding_box)) {
+    dia_object_get_bounding_box (obj, &bbox);
+
+    if (update == NULL || graphene_rect_intersection (&update_rect, &bbox, NULL)) {
       if ((render_bounding_boxes ()) && DIA_IS_INTERACTIVE_RENDERER (renderer)) {
+        graphene_point_t tl, br;
         Point p1, p2;
         Color col;
-        p1.x = obj->bounding_box.left;
-        p1.y = obj->bounding_box.top;
-        p2.x = obj->bounding_box.right;
-        p2.y = obj->bounding_box.bottom;
+
+        graphene_rect_get_top_left (&bbox, &tl);
+        graphene_rect_get_bottom_right (&bbox, &br);
+
+        dia_graphene_to_point (&tl, &p1);
+        dia_graphene_to_point (&br, &p2);
+
         col.red = 1.0;
         col.green = 0.0;
         col.blue = 1.0;
@@ -327,6 +346,7 @@ dia_layer_render (DiaLayer       *layer,
   }
 }
 
+
 /**
  * dia_layer_new:
  * @name: Name of the new layer.
@@ -614,6 +634,7 @@ dia_layer_remove_objects (DiaLayer *layer, GList *obj_list)
   }
 }
 
+
 /**
  * dia_layer_find_objects_intersecting_rectangle:
  * @layer: The layer to search in.
@@ -634,13 +655,20 @@ dia_layer_find_objects_intersecting_rectangle (DiaLayer     *layer,
   GList *selected_list;
   DiaObject *obj;
   DiaLayerPrivate *priv = dia_layer_get_instance_private (layer);
+  graphene_rect_t test_rect;
+
+  dia_rectangle_to_graphene (rect, &test_rect);
 
   selected_list = NULL;
   list = priv->objects;
   while (list != NULL) {
-    obj = (DiaObject *)list->data;
+    graphene_rect_t bbox;
+
+    obj = DIA_OBJECT (list->data);
+
+    dia_object_get_bounding_box (obj, &bbox);
 
-    if (rectangle_intersects (rect, &obj->bounding_box)) {
+    if (graphene_rect_intersection (&test_rect, &bbox, NULL)) {
       if (dia_object_is_selectable (obj)) {
         selected_list = g_list_prepend (selected_list, obj);
       }
@@ -655,6 +683,7 @@ dia_layer_find_objects_intersecting_rectangle (DiaLayer     *layer,
   return selected_list;
 }
 
+
 /**
  * dia_layer_find_objects_in_rectangle:
  * @layer: The layer to search for objects in.
@@ -674,13 +703,20 @@ dia_layer_find_objects_in_rectangle (DiaLayer *layer, DiaRectangle *rect)
   GList *selected_list;
   DiaObject *obj;
   DiaLayerPrivate *priv = dia_layer_get_instance_private (layer);
+  graphene_rect_t test_rect;
+
+  dia_rectangle_to_graphene (rect, &test_rect);
 
   selected_list = NULL;
   list = priv->objects;
   while (list != NULL) {
-    obj = (DiaObject *)list->data;
+    graphene_rect_t bbox;
+
+    obj = DIA_OBJECT (list->data);
 
-    if (rectangle_in_rectangle (rect, &obj->bounding_box)) {
+    dia_object_get_bounding_box (obj, &bbox);
+
+    if (graphene_rect_contains_rect (&test_rect, &bbox)) {
       if (dia_object_is_selectable (obj)) {
         selected_list = g_list_prepend (selected_list, obj);
       }
@@ -692,6 +728,7 @@ dia_layer_find_objects_in_rectangle (DiaLayer *layer, DiaRectangle *rect)
   return selected_list;
 }
 
+
 /**
  * dia_layer_find_objects_containing_rectangle:
  * @layer: The layer to search for objects in.
@@ -705,21 +742,26 @@ dia_layer_find_objects_in_rectangle (DiaLayer *layer, DiaRectangle *rect)
  * Since: 0.98
  */
 GList *
-dia_layer_find_objects_containing_rectangle (DiaLayer *layer, DiaRectangle *rect)
+dia_layer_find_objects_containing_rectangle (DiaLayer        *layer,
+                                             graphene_rect_t *rect)
 {
   GList *list;
   GList *selected_list;
   DiaObject *obj;
   DiaLayerPrivate *priv = dia_layer_get_instance_private (layer);
 
-  g_return_val_if_fail  (layer != NULL, NULL);
+  g_return_val_if_fail (DIA_IS_LAYER (layer), NULL);
 
   selected_list = NULL;
   list = priv->objects;
   while (list != NULL) {
-    obj = (DiaObject *) list->data;
+    graphene_rect_t bbox;
+
+    obj = DIA_OBJECT (list->data);
+
+    dia_object_get_bounding_box (obj, &bbox);
 
-    if (rectangle_in_rectangle (&obj->bounding_box, rect)) {
+    if (graphene_rect_intersection (rect, &bbox, NULL)) {
       if (dia_object_is_selectable (obj)) {
         selected_list = g_list_prepend (selected_list, obj);
       }
@@ -868,34 +910,44 @@ dia_layer_update_extents (DiaLayer *layer)
 {
   GList *l;
   DiaObject *obj;
-  DiaRectangle new_extents;
+  graphene_rect_t new_extents, old_extents;
   DiaLayerPrivate *priv = dia_layer_get_instance_private (layer);
 
   l = priv->objects;
-  if (l!=NULL) {
-    obj = (DiaObject *) l->data;
-    new_extents = obj->bounding_box;
+  if (l != NULL) {
+    obj = DIA_OBJECT (l->data);
+
+    dia_object_get_bounding_box (obj, &new_extents);
+
     l = g_list_next (l);
 
-    while (l!=NULL) {
-      const DiaRectangle *bbox;
-      obj = (DiaObject *) l->data;
-      /* don't consider empty (or broken) objects in the overall extents */
-      bbox = &obj->bounding_box;
-      if (bbox->right > bbox->left && bbox->bottom > bbox->top)
-        rectangle_union (&new_extents, &obj->bounding_box);
+    while (l != NULL) {
+      graphene_rect_t bbox;
+
+      obj = DIA_OBJECT (l->data);
+
+      dia_object_get_bounding_box (obj, &bbox);
+
+      graphene_rect_union (&new_extents, &bbox, &new_extents);
+
       l = g_list_next (l);
     }
   } else {
-    new_extents = invalid_extents;
+    dia_rectangle_to_graphene (&invalid_extents, &new_extents);
   }
 
-  if (rectangle_equals (&new_extents, &priv->extents)) return FALSE;
+  dia_rectangle_to_graphene (&priv->extents, &old_extents);
+
+  if (graphene_rect_equal (&new_extents, &old_extents)) {
+    return FALSE;
+  }
+
+  dia_graphene_to_rectangle (&new_extents, &priv->extents);
 
-  priv->extents = new_extents;
   return TRUE;
 }
 
+
 /**
  * dia_layer_replace_object_with_list:
  * @layer: the #DiaLayer
diff --git a/lib/libdia.def b/lib/libdia.def
index 9c6793cbe..518acc236 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -856,7 +856,9 @@ EXPORTS
  prop_dialog_from_widget
  find_prop_by_name
  dia_object_get_bounding_box
+ dia_object_set_bounding_box
  dia_object_get_enclosing_box
+ dia_object_set_enclosing_box
 
  calculate_object_edge
 
diff --git a/lib/object.c b/lib/object.c
index f54aa0827..e6b190a7b 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -27,6 +27,7 @@
 #include "message.h"
 #include "parent.h"
 #include "dia-layer.h"
+#include "dia-graphene.h"
 
 #include "dummy_dep.h"
 
@@ -109,7 +110,8 @@ object_copy (DiaObject *from, DiaObject *to)
 {
   to->type = from->type;
   to->position = from->position;
-  to->bounding_box = from->bounding_box;
+  to->legacy_bbox = from->legacy_bbox;
+  graphene_rect_init_from_rect (&to->bounds, &from->bounds);
 
   to->num_handles = from->num_handles;
   g_clear_pointer (&to->handles, g_free);
@@ -889,7 +891,7 @@ object_save (DiaObject *obj, ObjectNode obj_node, DiaContext *ctx)
                   &obj->position,
                   ctx);
   data_add_rectangle (new_attribute (obj_node, "obj_bb"),
-                      &obj->bounding_box,
+                      &obj->legacy_bbox,
                       ctx);
   if (obj->meta && g_hash_table_size (obj->meta) > 0) {
     data_add_dict (new_attribute (obj_node, "meta"), obj->meta, ctx);
@@ -919,13 +921,17 @@ object_load (DiaObject *obj, ObjectNode obj_node, DiaContext *ctx)
     data_point (attribute_first_data (attr), &obj->position, ctx);
   }
 
-  obj->bounding_box.left = obj->bounding_box.right = 0.0;
-  obj->bounding_box.top = obj->bounding_box.bottom = 0.0;
+  obj->legacy_bbox.left = obj->legacy_bbox.right = 0.0;
+  obj->legacy_bbox.top = obj->legacy_bbox.bottom = 0.0;
+  graphene_rect_init (&obj->bounds, 0, 0, 0, 0);
+
   attr = object_find_attribute (obj_node, "obj_bb");
   if (attr != NULL) {
-    data_rectangle (attribute_first_data (attr), &obj->bounding_box, ctx);
+    data_rectangle (attribute_first_data (attr), &obj->legacy_bbox, ctx);
   }
 
+  dia_rectangle_to_graphene (&obj->legacy_bbox, &obj->bounds);
+
   attr = object_find_attribute (obj_node, "meta");
   if (attr != NULL) {
     obj->meta = data_dict (attribute_first_data (attr), ctx);
@@ -1215,41 +1221,79 @@ object_copy_using_properties (DiaObject *obj)
   return newobj;
 }
 
+
 /**
  * dia_object_get_bounding_box:
  * @obj: The object to get the bounding box for.
+ * @bbox: (out caller-allocates): the bounding box
  *
  * Return a box that all 'real' parts of the object is bounded by.
  *  In most cases, this is the same as the enclosing box, but things like
  *  bezier controls would lie outside of this.
- *
- * Returns: A pointer to a #DiaRectangle object.  This object should *not*
- *  be freed after use, as it belongs to the object.
  */
-const DiaRectangle *
-dia_object_get_bounding_box (const DiaObject *obj)
+void
+dia_object_get_bounding_box (DiaObject *obj, graphene_rect_t *bbox)
 {
-  return &obj->bounding_box;
+  graphene_rect_init_from_rect (bbox, &obj->bounds);
 }
 
+
+/**
+ * dia_object_set_bounding_box:
+ * @obj: the #DiaObject
+ * @bbox: the new bounding box
+ */
+void
+dia_object_set_bounding_box (DiaObject *obj, graphene_rect_t *bbox)
+{
+  graphene_rect_init_from_rect (&obj->bounds, bbox);
+  dia_graphene_to_rectangle (&obj->bounds, &obj->legacy_bbox);
+}
+
+
 /**
  * dia_object_get_enclosing_box:
  * @obj: The object to get the enclosing box for.
+ * @ebox: (out caller-allocates): the enclosing box (may or may not be equal to the bounding box)
  *
  * Return a box that encloses all interactively rendered parts of the object.
  *
- * Returns: A pointer to a #DiaRectangle object.  This object should *not*
- *  be freed after use, as it belongs to the object.
+ * Stability: Stable
+ *
+ * Since: 0.98
+ */
+void
+dia_object_get_enclosing_box (DiaObject *obj, graphene_rect_t *ebox)
+{
+  if (obj->explicit_enclosing) {
+    graphene_rect_init_from_rect (ebox, &obj->enclosing);
+  } else {
+    graphene_rect_init_from_rect (ebox, &obj->bounds);
+  }
+}
+
+
+/**
+ * dia_object_set_enclosing_box:
+ * @obj: the #DiaObject
+ * @ebox: (nullable): the enclosing box, or %NULL to clear
+ *
+ * Stability: Stable
+ *
+ * Since: 0.98
  */
-const DiaRectangle *
-dia_object_get_enclosing_box (const DiaObject *obj)
+void
+dia_object_set_enclosing_box (DiaObject *obj, graphene_rect_t *ebox)
 {
-  if (!obj->enclosing_box)
-    return &obj->bounding_box;
-  else
-    return obj->enclosing_box;
+  if (ebox) {
+    obj->explicit_enclosing = TRUE;
+    graphene_rect_init_from_rect (&obj->enclosing, ebox);
+  } else {
+    obj->explicit_enclosing = FALSE;
+  }
 }
 
+
 void
 dia_object_set_meta (DiaObject *obj, const gchar *key, const gchar *value)
 {
diff --git a/lib/object.h b/lib/object.h
index dd32716a3..0487aabbd 100644
--- a/lib/object.h
+++ b/lib/object.h
@@ -191,12 +191,14 @@ typedef void (*DestroyFunc) (DiaObject* obj);
 // TODO: Actually check the cast with GType
 #define DIA_OBJECT(object) ((DiaObject *) object)
 
-typedef void (*DrawFunc) (DiaObject* obj, DiaRenderer* ddisp);
-typedef double (*DistanceFunc) (DiaObject* obj, Point* point);
-typedef void (*SelectFunc) (DiaObject*   obj,
-                           Point*    clicked_point,
-                           DiaRenderer* interactive_renderer);
-typedef DiaObject* (*CopyFunc) (DiaObject* obj);
+typedef void                   (*DrawFunc)                  (DiaObject        *obj,
+                                                             DiaRenderer      *ddisp);
+typedef double                 (*DistanceFunc)              (DiaObject        *obj,
+                                                             Point            *point);
+typedef void                   (*SelectFunc)                (DiaObject        *obj,
+                                                            Point            *clicked_point,
+                                                            DiaRenderer      *interactive_renderer);
+typedef DiaObject             *(*CopyFunc)                  (DiaObject        *obj);
 typedef DiaObjectChange       *(*MoveFunc)                  (DiaObject        *obj,
                                                              Point            *pos);
 typedef DiaObjectChange       *(*MoveHandleFunc)            (DiaObject        *obj,
@@ -330,70 +332,80 @@ struct _ObjectOps {
   void      (*unused[3])(DiaObject *obj,...);
 };
 
-// #ifdef _DIA_OBJECT_BUILD
+#ifdef _DIA_OBJECT_BUILD
 # define _DIA_OBJECT_FIELD(type,name)      type name
-// #else
-// # define _DIA_OBJECT_FIELD(type,name)      type __graphene_private_##name
-// #endif
+#else
+# define _DIA_OBJECT_FIELD(type,name)      type __graphene_private_##name
+#endif
 
-/*!
-  \brief Base class for all of Dia's objects, i.e. diagram building blocks
+/**
+ * DiaObject:
+ * @type: pointer to the registered type
+ * @position: often but not necessarily the upper left corner of the object
+ * @bounds: #graphene_rect_t containing the whole object
+ *
+ *          The area that contains all parts of the 'real' object, i.e. the
+ *          parts that would be printed, exported to pixmaps etc. This is also
+ *          used to determine the size of autofit scaling, so it should be as
+ *          large as the objects without interactive bits and preferably no
+ *          larger. Do not access this field directly, but use
+ *          dia_object_get_bounding_box() / dia_object_set_bounding_box()
+ * @legacy_bbox: replaced by @bounds but still needed for load/store :-(
+ * @num_handles: Number of #Handle(s) of this object
+ * @handles: Array of handles of this object with fixed index
+ * @num_connections: Number of #ConnectionPoint this object has
+ * @connections: Array of #ConnectionPoint - indexing fixed by meaning
+ * @ops: pointer to the vtable
+ * @parent_layer: Back-pointer to the owning layer. This may only be set by
+ *                functions internal to the layer, and accessed via
+ *                dia_object_get_parent_layer()
+ * @parent: Back-pointer to #DiaObject which is parenting this object. Can be
+ *          %NULL
+ * @children: In case this object is a parent of other object the children are
+ *            listed here
+ * @explicit_enclosing: %TRUE when @enclosing has been populated, otherwise
+ *                      proxy to @bounds
+ * @enclosing: The area that contains all parts rendered interactively, so
+ *             includes handles, bezier controllers etc. Despite historical
+ *             difference, this should not be accessed directly, but through
+ *             dia_object_get_enclosing_box().
+ *             Note that handles and connection points are not included by
+ *             this, but added by that which needs it.
+ * @meta: Metainfo of the object, should not be manipulated directly. Use
+ *        dia_object_set_meta()
+ *
+ * Base class for all of Dia's objects, i.e. diagram building blocks
+ *
+ * The base class in the #DiaObject hierarchy.
+ *
+ * All information in this structure read-only from the application point of
+ * view except when connection objects. (Then handles and connections are
+ * changed).
+ *
+ * @position is not necessarily the corner of the object, but rather
+ * some 'good' spot on it which will be natural to snap to.
+ */
+struct _DiaObject {
+  DiaObjectType    *type;
+  Point             position;
 
-  The base class in the DiaObject hierarchy.
-  All information in this structure read-only
-  from the application point of view except
-  when connection objects. (Then handles and
-  connections are changed).
+  _DIA_OBJECT_FIELD (graphene_rect_t, bounds);
+  DiaRectangle      legacy_bbox;
 
-  position is not necessarily the corner of the object, but rather
-  some 'good' spot on it which will be natural to snap to.
-*/
-struct _DiaObject {
-  DiaObjectType    *type; /*!< pointer to the registered type */
-  Point             position; /*!<  often but not necessarily the upper left corner of the object */
-  /*!
-   * \brief DiaRectangle containing the whole object
-   *
-   * The area that contains all parts of the 'real' object, i.e. the parts
-   *  that would be printed, exported to pixmaps etc.  This is also used to
-   *  determine the size of autofit scaling, so it should be as large as
-   *  the objects without interactive bits and preferably no larger.
-   *  The bounding_box will always contain this box.
-   *  Do not access this field directly, but use dia_object_get_enclosing_box().
-   *
-   * \protected Use dia_object_get_bounding_box()
-   */
-  DiaRectangle      bounding_box;
-  /*! Number of Handle(s) of this object */
   int               num_handles;
-  /*! Array of handles of this object with fixed index */
   Handle          **handles;
-  /*! Number of ConnectionPoint this object has */
   int               num_connections;
-  /*! Array of ConnectionPoint* - indexing fixed by meaning */
   ConnectionPoint **connections;
 
-  _DIA_OBJECT_FIELD (ObjectOps *, ops); /* pointer to the vtable */
-
-  DiaLayer *parent_layer; /*!< Back-pointer to the owning layer.
-                          This may only be set by functions internal to
-                          the layer, and accessed via
-                          dia_object_get_parent_layer() */
-  DiaObject *parent; /*!< Back-pointer to DiaObject which is parenting this object. Can be NULL */
-  GList *children; /*!< In case this object is a parent of other object the children are listed here */
-
-  /* The area that contains all parts rendered interactively, so includes
-   * handles, bezier controllers etc.  Despite historical difference, this
-   * should not be accessed directly, but through dia_object_get_bounding_box().
-   * Note that handles and connection points are not included by this, but
-   * added by that which needs it.
-   * Internal:  If this is set to a NULL, returns bounding_box.  That is for
-   * those objects that don't actually calculate it, but can just use the BB.
-   * Since handles and CPs are not in the BB, that will be the case for most
-   * objects.
-   */
-  DiaRectangle     *enclosing_box;
-  /*! Metainfo of the object, should not be manipulated directly. Use dia_object_set_meta() */
+  /*_DIA_OBJECT_FIELD (ObjectOps *, ops);*/
+  ObjectOps        *ops;
+
+  DiaLayer         *parent_layer;
+  DiaObject        *parent;
+  GList            *children;
+
+  _DIA_OBJECT_FIELD (gboolean, explicit_enclosing);
+  _DIA_OBJECT_FIELD (graphene_rect_t, enclosing);
   GHashTable       *meta;
 };
 
@@ -480,7 +492,7 @@ struct _DiaObjectType {
 
 #define OBJECT_COMMON_PROPERTIES_OFFSETS \
   { "obj_pos", PROP_TYPE_POINT, offsetof(DiaObject, position) }, \
-  { "obj_bb", PROP_TYPE_RECT, offsetof(DiaObject, bounding_box) }, \
+  { "obj_bb", PROP_TYPE_RECT, offsetof(DiaObject, legacy_bbox) }, \
   { "meta", PROP_TYPE_DICT, offsetof(DiaObject, meta) }
 
 
@@ -546,8 +558,14 @@ DiaObject  *dia_object_default_create (const DiaObjectType *type,
 gboolean         dia_object_defaults_save (const gchar *filename, DiaContext *ctx);
 DiaLayer        *dia_object_get_parent_layer(DiaObject *obj);
 gboolean         dia_object_is_selected (const DiaObject *obj);
-const DiaRectangle *dia_object_get_bounding_box(const DiaObject *obj);
-const DiaRectangle *dia_object_get_enclosing_box(const DiaObject *obj);
+void                   dia_object_get_bounding_box     (DiaObject               *obj,
+                                                        graphene_rect_t         *bbox);
+void                   dia_object_set_bounding_box     (DiaObject               *obj,
+                                                        graphene_rect_t         *bbox);
+void                   dia_object_get_enclosing_box    (DiaObject               *obj,
+                                                        graphene_rect_t         *ebox);
+void                   dia_object_set_enclosing_box    (DiaObject               *obj,
+                                                        graphene_rect_t         *ebox);
 DiaObject       *dia_object_get_parent_with_flags(DiaObject *obj, guint flags);
 gboolean         dia_object_is_selectable(DiaObject *obj);
 /* The below is for debugging purposes only. */
diff --git a/lib/object_defaults.c b/lib/object_defaults.c
index 7a6197e5f..ff5da4791 100644
--- a/lib/object_defaults.c
+++ b/lib/object_defaults.c
@@ -303,19 +303,21 @@ struct _MyRootInfo
   DiaContext *ctx;
 };
 
+
 static void
 _obj_store (gpointer key,
             gpointer value,
             gpointer user_data)
 {
-  gchar *name = (gchar *)key;
-  DiaObject *obj = (DiaObject *)value;
-  MyRootInfo *ri = (MyRootInfo *)user_data;
+  char *name = (char *) key;
+  DiaObject *obj = (DiaObject *) value;
+  MyRootInfo *ri = (MyRootInfo *) user_data;
   ObjectNode obj_node;
-  gchar *layer_name;
-  gchar buffer[31];
-  gchar *p;
+  char *layer_name;
+  char buffer[31];
+  char *p;
   MyLayerInfo *li;
+  graphene_rect_t bbox;
 
   /* fires if you have messed up the hash keys,
    * e.g. by using non permanent memory */
@@ -323,20 +325,21 @@ _obj_store (gpointer key,
 
   p = strstr (name, " - ");
   if (p) {
-    if (p > name)
+    if (p > name) {
       layer_name = g_strndup (name, p - name);
-    else
-      layer_name = g_strdup("NULL");
-  }
-  else
+    } else {
+      layer_name = g_strdup ("NULL");
+    }
+  } else {
     layer_name = g_strdup ("default");
+  }
 
   li = g_hash_table_lookup (ri->layer_hash, layer_name);
   if (!li) {
     li = g_new0 (MyLayerInfo, 1);
-    li->node = xmlNewChild(ri->node, ri->name_space, (const xmlChar *)"layer", NULL);
-    xmlSetProp(li->node, (const xmlChar *)"name", (xmlChar *)layer_name);
-    xmlSetProp(li->node, (const xmlChar *)"visible", (const xmlChar *)"false");
+    li->node = xmlNewChild (ri->node, ri->name_space, (const xmlChar *) "layer", NULL);
+    xmlSetProp (li->node, (const xmlChar *) "name", (xmlChar *) layer_name);
+    xmlSetProp (li->node, (const xmlChar *) "visible", (const xmlChar *) "false");
     li->pos.x = li->pos.y = 0.0;
     g_hash_table_insert (ri->layer_hash, layer_name, li);
   } else {
@@ -346,27 +349,30 @@ _obj_store (gpointer key,
   obj_node = xmlNewChild(li->node, NULL, (const xmlChar *)"object", NULL);
   xmlSetProp(obj_node, (const xmlChar *)"type", (xmlChar *) obj->type->name);
 
-  g_snprintf(buffer, 30, "%d", obj->type->version);
-  xmlSetProp(obj_node, (const xmlChar *)"version", (xmlChar *)buffer);
+  g_snprintf (buffer, 30, "%d", obj->type->version);
+  xmlSetProp (obj_node, (const xmlChar *) "version", (xmlChar *) buffer);
 
-  g_snprintf(buffer, 30, "O%d", ri->obj_nr++);
-  xmlSetProp(obj_node, (const xmlChar *)"id", (xmlChar *)buffer);
+  g_snprintf (buffer, 30, "O%d", ri->obj_nr++);
+  xmlSetProp (obj_node, (const xmlChar *) "id", (xmlChar *) buffer);
 
   /* if it looks like intdata store it as well */
-  if (   GPOINTER_TO_INT(obj->type->default_user_data) > 0
-      && GPOINTER_TO_INT(obj->type->default_user_data) < 0xFF) {
-    g_snprintf(buffer, 30, "%d", GPOINTER_TO_INT(obj->type->default_user_data));
-    xmlSetProp(obj_node, (const xmlChar *)"intdata", (xmlChar *)buffer);
+  if (   GPOINTER_TO_INT (obj->type->default_user_data) > 0
+      && GPOINTER_TO_INT (obj->type->default_user_data) < 0xFF) {
+    g_snprintf (buffer, 30, "%d", GPOINTER_TO_INT (obj->type->default_user_data));
+    xmlSetProp (obj_node, (const xmlChar *) "intdata", (xmlChar *) buffer);
   }
 
   dia_object_move (obj, &(li->pos));
   /* saving every property of the object */
   obj->type->ops->save (obj, obj_node, ri->ctx);
 
+  dia_object_get_bounding_box (obj, &bbox);
+
   /* arrange following objects below */
-  li->pos.y += (obj->bounding_box.bottom - obj->bounding_box.top + 1.0);
+  li->pos.y += (graphene_rect_get_height (&bbox) + 1.0);
 }
 
+
 /**
  * dia_object_defaults_save:
  *
diff --git a/lib/orth_conn.c b/lib/orth_conn.c
index 0be707a90..230c86749 100644
--- a/lib/orth_conn.c
+++ b/lib/orth_conn.c
@@ -30,6 +30,7 @@
 #include "handle.h"
 #include "diarenderer.h"
 #include "autoroute.h"
+#include "dia-graphene.h"
 
 
 static void place_handle_by_swapping(OrthConn *orth,
@@ -452,16 +453,24 @@ orthconn_update_data(OrthConn *orth)
   neworthconn_update_midpoints(orth);
 }
 
+
 void
-orthconn_update_boundingbox(OrthConn *orth)
+orthconn_update_boundingbox (OrthConn *orth)
 {
-  assert(orth != NULL);
-  polyline_bbox(&orth->points[0],
-                orth->numpoints,
-                &orth->extra_spacing, FALSE,
-                &orth->object.bounding_box);
+  graphene_rect_t bbox;
+
+  g_return_if_fail (orth != NULL);
+
+  polyline_bbox (&orth->points[0],
+                 orth->numpoints,
+                 &orth->extra_spacing,
+                 FALSE,
+                 &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (orth), &bbox);
 }
 
+
 int
 orthconn_can_delete_segment(OrthConn *orth, Point *clickedpoint)
 {
diff --git a/lib/path-math.c b/lib/path-math.c
index 356fd84b6..ddf47baec 100644
--- a/lib/path-math.c
+++ b/lib/path-math.c
@@ -164,8 +164,11 @@ _segment_is_lineto (const BezierSegment *bs)
 /* search precision */
 static const real EPSILON = 0.0001;
 
-/*!
- * \brief Calculate crossing points of two bezier segments
+
+/**
+ * bezier_bezier_intersection:
+ *
+ * Calculate crossing points of two bezier segments
  *
  * Beware two bezier segments can intersect more than once, but this
  * function only returns the first or no intersection. It is the
@@ -180,7 +183,8 @@ bezier_bezier_intersection (GArray              *crossing,
                             real                 asplit,
                             real                 bsplit)
 {
-  DiaRectangle abox, bbox;
+  graphene_rect_t abox, bbox;
+  graphene_vec2_t p0;
   PolyBBExtras extra = { 0, };
   gboolean small_a, small_b;
 
@@ -188,8 +192,9 @@ bezier_bezier_intersection (GArray              *crossing,
    * assume full overlap and no crossing.
    */
   if (   (_segment_has_point (a, &b->p0) && _segment_has_point (a, &b->p3))
-      || (_segment_has_point (b, &a->p0) && _segment_has_point (b, &a->p3)))
+      || (_segment_has_point (b, &a->p0) && _segment_has_point (b, &a->p3))) {
     return FALSE; /* XXX: more variants pending, partial overlap */
+  }
 
   /* With very similar segments we would create a lot of points with not
    * a very deep recursion (test with ying-yang symbol).
@@ -201,26 +206,41 @@ bezier_bezier_intersection (GArray              *crossing,
     return FALSE;
   }
 
-  bicubicbezier2D_bbox (&a->p0, &a->p1, &a->p2, &a->p3, &extra, &abox);
-  bicubicbezier2D_bbox (&b->p0, &b->p1, &b->p2, &b->p3, &extra, &bbox);
+  graphene_vec2_init (&p0, a->p0.x, a->p0.y);
+  bicubicbezier2D_bbox (&p0, &a->p1, &a->p2, &a->p3, &extra, &abox);
+  graphene_vec2_init (&p0, b->p0.x, b->p0.y);
+  bicubicbezier2D_bbox (&p0, &b->p1, &b->p2, &b->p3, &extra, &bbox);
 
-  if (!rectangle_intersects (&abox, &bbox))
+  if (!graphene_rect_intersection (&abox, &bbox, NULL)) {
     return FALSE;
-  small_a = (abox.right - abox.left) < EPSILON && (abox.bottom - abox.top) < EPSILON;
-  small_b = (bbox.right - bbox.left) < EPSILON && (bbox.bottom - bbox.top) < EPSILON;
+  }
+
+  small_a = (graphene_rect_get_width (&abox) < EPSILON) && (graphene_rect_get_height (&abox) < EPSILON);
+  small_b = (graphene_rect_get_width (&bbox) < EPSILON) && (graphene_rect_get_height (&bbox) < EPSILON);
+
   /* if the boxes are small enough we can calculate the point */
   if (small_a && small_b) {
+    graphene_point_t atl, abr, btl, bbr;
     /* intersecting and both small, should not matter which one is used */
-    Point pt = { (abox.right + abox.left + bbox.right + bbox.left) / 4,
-                (abox.bottom + abox.top + bbox.bottom + bbox.top) / 4 };
+    Point pt;
     Intersection is;
-    int i;
 
-    for (i = 0; i < crossing->len; ++i) {
+    graphene_rect_get_top_left (&abox, &atl);
+    graphene_rect_get_bottom_right (&abox, &abr);
+
+    graphene_rect_get_top_left (&bbox, &btl);
+    graphene_rect_get_bottom_right (&bbox, &bbr);
+
+    pt.x = (abr.x + atl.x + bbr.x + btl.x) / 4;
+    pt.y = (abr.y + atl.y + bbr.y + btl.y) / 4;
+
+    for (int i = 0; i < crossing->len; ++i) {
       /* if it's already included we are done */
-      if (distance_point_point (&g_array_index (crossing, Intersection, i).pt, &pt) < 1.4142*EPSILON)
+      if (distance_point_point (&g_array_index (crossing, Intersection, i).pt, &pt) < 1.4142*EPSILON) {
         return TRUE; /* although we did not add it */
+      }
     }
+
     is.split_one = asplit;
     is.split_two = bsplit;
     is.pt = pt;
diff --git a/lib/poly_conn.c b/lib/poly_conn.c
index 5f65f0155..a0a8716b2 100644
--- a/lib/poly_conn.c
+++ b/lib/poly_conn.c
@@ -26,6 +26,7 @@
 
 #include "poly_conn.h"
 #include "diarenderer.h"
+#include "dia-graphene.h"
 
 
 enum change_type {
@@ -342,17 +343,24 @@ polyconn_update_data(PolyConn *poly)
   }
 }
 
+
 void
-polyconn_update_boundingbox(PolyConn *poly)
+polyconn_update_boundingbox (PolyConn *poly)
 {
-  assert(poly != NULL);
+  graphene_rect_t bbox;
+
+  g_return_if_fail (poly != NULL);
 
-  polyline_bbox(&poly->points[0],
-                poly->numpoints,
-                &poly->extra_spacing, FALSE,
-                &poly->object.bounding_box);
+  polyline_bbox (&poly->points[0],
+                 poly->numpoints,
+                 &poly->extra_spacing,
+                 FALSE,
+                 &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (poly), &bbox);
 }
 
+
 void
 polyconn_init(PolyConn *poly, int num_points)
 {
diff --git a/lib/polyshape.c b/lib/polyshape.c
index b1a703ad7..e8e5fff82 100644
--- a/lib/polyshape.c
+++ b/lib/polyshape.c
@@ -27,6 +27,8 @@
 #include "polyshape.h"
 #include "message.h"
 #include "diarenderer.h"
+#include "dia-graphene.h"
+
 
 #define NUM_CONNECTIONS(poly) ((poly)->numpoints * 2 + 1)
 
@@ -389,11 +391,13 @@ polyshape_update_data(PolyShape *poly)
   obj->connections[obj->num_connections-1]->directions = DIR_ALL;
 }
 
+
 void
-polyshape_update_boundingbox(PolyShape *poly)
+polyshape_update_boundingbox (PolyShape *poly)
 {
   ElementBBExtras *extra;
   PolyBBExtras pextra;
+  graphene_rect_t bbox;
 
   assert(poly != NULL);
 
@@ -402,12 +406,16 @@ polyshape_update_boundingbox(PolyShape *poly)
     pextra.start_long = pextra.end_long = 0;
   pextra.middle_trans = extra->border_trans;
 
-  polyline_bbox(&poly->points[0],
-                poly->numpoints,
-                &pextra, TRUE,
-                &poly->object.bounding_box);
+  polyline_bbox (&poly->points[0],
+                 poly->numpoints,
+                 &pextra,
+                 TRUE,
+                 &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (poly), &bbox);
 }
 
+
 void
 polyshape_init(PolyShape *poly, int num_points)
 {
diff --git a/lib/renderer/diacairo-renderer.c b/lib/renderer/diacairo-renderer.c
index db852a594..5cda7dd71 100644
--- a/lib/renderer/diacairo-renderer.c
+++ b/lib/renderer/diacairo-renderer.c
@@ -1073,8 +1073,8 @@ dia_cairo_renderer_draw_rotated_image (DiaRenderer *self,
   int w = dia_image_width (image);
   int h = dia_image_height (image);
 
-  DIAG_NOTE (g_message ("draw_image %fx%f [%d(%d),%d] @%f,%f",
-                        width, height, w, rs, h, point->x, point->y));
+  DIAG_NOTE (g_message ("draw_image %fx%f [%d,%d] @%f,%f",
+                        width, height, w, h, point->x, point->y));
 
   cairo_save (renderer->cr);
   cairo_translate (renderer->cr, point->x, point->y);
diff --git a/lib/renderer/diacairo.h b/lib/renderer/diacairo.h
index 3cde4608c..d13d1a0b3 100644
--- a/lib/renderer/diacairo.h
+++ b/lib/renderer/diacairo.h
@@ -36,7 +36,7 @@
  */
 #define DIAG_STATE(cr) { \
   if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) \
-    g_warning ("%s:%d, %s\n", __FILE__, __LINE__, cairo_status_to_string (cairo_status(cr))); \
+    g_warning ("%s[%s:%d] %s", __func__, __FILE__, __LINE__, cairo_status_to_string (cairo_status(cr))); \
 }
 
 /* --- the renderer base class --- */
diff --git a/lib/standard-path.c b/lib/standard-path.c
index 747e92cee..0d3319e85 100644
--- a/lib/standard-path.c
+++ b/lib/standard-path.c
@@ -44,6 +44,7 @@
 #include "bezier-common.h"
 #include "pattern.h"
 #include "dia-object-change-list.h"
+#include "dia-graphene.h"
 
 
 #define NUM_HANDLES 8
@@ -324,53 +325,71 @@ stdpath_load(ObjectNode obj_node, int version,DiaContext *ctx)
  * \protected \memberof _StdPath
  */
 static void
-stdpath_update_handles(StdPath *stdpath)
+stdpath_update_handles (StdPath *stdpath)
 {
   DiaObject *obj = &stdpath->object;
   PolyBBExtras extra = { 0, };
-  DiaRectangle rect, *bb;
+  graphene_rect_t bbox;
+  graphene_point_t tl, br, pt;
 
   g_return_if_fail (obj->handles != NULL);
 
   /* Using the zero-line-width boundingbox for handles */
-  bb = &rect;
-  polybezier_bbox (stdpath->points, stdpath->num_points, &extra,
-                  FALSE /*(stdpath->stroke_or_fill & PDO_FILL)*/, bb);
+  polybezier_bbox (stdpath->points,
+                   stdpath->num_points,
+                   &extra,
+                   FALSE /*(stdpath->stroke_or_fill & PDO_FILL)*/,
+                   &bbox);
+
+  graphene_rect_get_top_left (&bbox, &tl);
+  graphene_rect_get_bottom_right (&bbox, &br);
 
   /* from left to right, from top to bottom */
-  obj->handles[0]->pos.x = bb->left;
-  obj->handles[0]->pos.y = bb->top;
-  obj->handles[1]->pos.x = (bb->left + bb->right) / 2.0;
-  obj->handles[1]->pos.y = bb->top;
+
+  dia_graphene_to_point (&tl, &obj->handles[0]->pos);
+
+  obj->handles[1]->pos.x = (tl.x + br.x) / 2.0;
+  obj->handles[1]->pos.y = tl.y;
+
   /* adjust handle pos for runtime shear? */
-  obj->handles[2]->pos.x = bb->right;
-  obj->handles[2]->pos.y = bb->top;
-  obj->handles[3]->pos.x = bb->left;
-  obj->handles[3]->pos.y = (bb->top + bb->bottom) / 2.0;
-  obj->handles[4]->pos.x = bb->right;
-  obj->handles[4]->pos.y = (bb->top + bb->bottom) / 2.0;
+
+  graphene_rect_get_top_right (&bbox, &pt);
+  dia_graphene_to_point (&pt, &obj->handles[2]->pos);
+
+  obj->handles[3]->pos.x = tl.x;
+  obj->handles[3]->pos.y = (tl.y + br.y) / 2.0;
+
+  obj->handles[4]->pos.x = br.x;
+  obj->handles[4]->pos.y = (tl.y + br.y) / 2.0;
+
   /* adjust handle pos for runtime perspective? */
-  obj->handles[5]->pos.x = bb->left;
-  obj->handles[5]->pos.y = bb->bottom;
-  obj->handles[6]->pos.x = (bb->left + bb->right) / 2.0;
-  obj->handles[6]->pos.y = bb->bottom;
-  obj->handles[7]->pos.x = bb->right;
-  obj->handles[7]->pos.y = bb->bottom;
+
+  graphene_rect_get_bottom_left (&bbox, &pt);
+  dia_graphene_to_point (&pt, &obj->handles[5]->pos);
+
+  obj->handles[6]->pos.x = (tl.x + br.x) / 2.0;
+  obj->handles[6]->pos.y = br.y;
+
+  dia_graphene_to_point (&br, &obj->handles[7]->pos);
 }
-/*!
- * \brief Object update function called after property change
+
+
+/**
+ * stdpath_update_data:
+ * @stdpath: the #StdPath
+ *
+ * Object update function called after property change
  *
  * Not in the object interface but very important anyway.
  * Used to recalculate the object data after a change
- * \protected \memberof _StdPath
  */
 static void
 stdpath_update_data (StdPath *stdpath)
 {
   DiaObject *obj = &stdpath->object;
-  DiaRectangle *bb = &obj->bounding_box;
   PolyBBExtras extra = { 0 };
-  real lw = stdpath->stroke_or_fill & PDO_STROKE ? stdpath->line_width : 0.0;
+  double lw = stdpath->stroke_or_fill & PDO_STROKE ? stdpath->line_width : 0.0;
+  graphene_rect_t bbox;
 
   extra.start_trans =
   extra.end_trans =
@@ -379,15 +398,23 @@ stdpath_update_data (StdPath *stdpath)
   extra.middle_trans = lw/2.0;
 
   /* recalculate the bounding box */
-  polybezier_bbox (stdpath->points, stdpath->num_points, &extra,
-                  FALSE /*(stdpath->stroke_or_fill & PDO_FILL)*/, bb);
+  polybezier_bbox (stdpath->points,
+                   stdpath->num_points,
+                   &extra,
+                   FALSE /*(stdpath->stroke_or_fill & PDO_FILL)*/,
+                   &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (stdpath), &bbox);
+
   /* adjust position from it */
   obj->position.x = stdpath->points[0].p1.x;
   obj->position.y = stdpath->points[0].p1.y;
+
   /* adjust handles */
   stdpath_update_handles (stdpath);
 }
 
+
 /*!
  * \brief Object drawing to the given renderer
  *
@@ -599,15 +626,18 @@ _path_object_transform_change_create (DiaObject *obj, DiaMatrix *matrix)
 }
 
 
-/*!
- * \brief Flip the path over the vertical or horizontal axis
+/**
+ * _path_flip_callback:
+ * @obj: the #DiaObject
+ * @clicked: the #Point clicked
+ *
+ * Flip the path over the vertical or horizontal axis
  *
  * Flip horizontal/vertical like custom objects do, except that this
  * function is modifying the underlying point data. This function is
  * available with the context menu of the 'Standard - Path' object.
- * @return Undo information
  *
- * \relates _StdPath
+ * Returns: Undo information
  */
 static DiaObjectChange *
 _path_flip_callback (DiaObject *obj, Point *clicked, gpointer data)
@@ -616,21 +646,26 @@ _path_flip_callback (DiaObject *obj, Point *clicked, gpointer data)
   StdPath *sp = (StdPath *)obj;
   DiaMatrix m = {horz ? -1 : 1, 0, 0, horz ? 1 : -1, 0, 0 };
   DiaMatrix translate = {1, 0, 0, 1, 0, 0 };
-  real cx = (sp->object.bounding_box.left + sp->object.bounding_box.right) / 2;
-  real cy = (sp->object.bounding_box.top + sp->object.bounding_box.bottom) / 2;
+  graphene_rect_t bbox;
+  graphene_point_t center;
+
+  dia_object_get_bounding_box (obj, &bbox);
+
+  graphene_rect_get_center (&bbox, &center);
 
   /* flip around center */
-  translate.x0 = cx;
-  translate.y0 = cy;
+  translate.x0 = center.x;
+  translate.y0 = center.y;
   dia_matrix_multiply (&m, &m, &translate);
-  translate.x0 = -cx;
-  translate.y0 = -cy;
+  translate.x0 = -center.x;
+  translate.y0 = -center.y;
   dia_matrix_multiply (&m, &translate, &m);
 
   _path_transform (sp, &m);
   return _path_object_transform_change_create (obj, &m);
 }
 
+
 /*!
  * \brief Rotate path towards clicked point
  *
@@ -645,24 +680,28 @@ static DiaObjectChange *
 _path_rotate_callback (DiaObject *obj, Point *clicked, gpointer data)
 {
   StdPath *sp = (StdPath *)obj;
-  real cx = (sp->object.bounding_box.left + sp->object.bounding_box.right) / 2;
-  real cy = (sp->object.bounding_box.top + sp->object.bounding_box.bottom) / 2;
   DiaMatrix m = {1, 0, 0, 1, 0, 0 };
   DiaMatrix translate = {1, 0, 0, 1, 0, 0 };
   Point d;
+  graphene_rect_t bbox;
+  graphene_point_t center;
+
+  dia_object_get_bounding_box (obj, &bbox);
 
-  d.x = clicked->x - cx;
-  d.y = clicked->y - cy;
+  graphene_rect_get_center (&bbox, &center);
+
+  d.x = clicked->x - center.x;
+  d.y = clicked->y - center.y;
   point_normalize (&d);
   /* to make the top, center handle clicked no rotation we subtract -PI/2 */
   dia_matrix_set_angle_and_scales (&m, atan2 (d.y, d.x) + M_PI/2.0, 1.0, 1.0);
 
   /* rotate around center */
-  translate.x0 = cx;
-  translate.y0 = cy;
+  translate.x0 = center.x;
+  translate.y0 = center.y;
   dia_matrix_multiply (&m, &m, &translate);
-  translate.x0 = -cx;
-  translate.y0 = -cy;
+  translate.x0 = -center.x;
+  translate.y0 = -center.y;
   dia_matrix_multiply (&m, &translate, &m);
 
   _path_transform (sp, &m);
@@ -709,27 +748,31 @@ _path_shear_callback (DiaObject *obj, Point *clicked, gpointer data)
   StdPath *sp = (StdPath *)obj;
   DiaMatrix m = {1, 0, 0, 1, 0, 0 };
   DiaMatrix translate = {1, 0, 0, 1, 0, 0 };
-  real cx = (sp->object.bounding_box.left + sp->object.bounding_box.right) / 2;
-  real cy = (sp->object.bounding_box.top + sp->object.bounding_box.bottom) / 2;
   const Handle *handle = _path_closest_corner_handle (sp, clicked);
-  real dx, dy;
+  double dx, dy;
+  graphene_rect_t bbox;
+  graphene_point_t center;
 
   g_return_val_if_fail (handle != NULL, NULL);
 
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_get_center (&bbox, &center);
+
   /* goal is to shear the point at corner handle close to the clicked point */
-  dx = (clicked->x - handle->pos.x) * (handle->pos.y > cy ? 1 : -1);
+  dx = (clicked->x - handle->pos.x) * (handle->pos.y > center.y ? 1 : -1);
   dy = clicked->y - handle->pos.y;
   /* normalize shear with handle distance from center, only shear one axis */
-  if (fabs(dx) > fabs(dy))
-    m.xy = dx / fabs(handle->pos.x - cx);
-  else
-    m.yx = dy / fabs(handle->pos.y - cy);
+  if (fabs (dx) > fabs (dy)) {
+    m.xy = dx / fabs (handle->pos.x - center.x);
+  } else {
+    m.yx = dy / fabs (handle->pos.y - center.y);
+  }
   /* XXX: shear around center */
-  translate.x0 = cx;
-  translate.y0 = cy;
+  translate.x0 = center.x;
+  translate.y0 = center.y;
   dia_matrix_multiply (&m, &m, &translate);
-  translate.x0 = -cx;
-  translate.y0 = -cy;
+  translate.x0 = -center.x;
+  translate.y0 = -center.y;
   dia_matrix_multiply (&m, &translate, &m);
 
   _path_transform (sp, &m);
@@ -1143,13 +1186,16 @@ text_to_path (const Text *text, GArray *points)
   if (!PANGO_IS_CAIRO_FONT_MAP (pango_context_get_font_map (dia_font_get_context())))
     return FALSE;
 
-  layout = pango_layout_new(dia_font_get_context());
+  layout = pango_layout_new (dia_font_get_context());
   pango_layout_set_font_description (layout, dia_font_get_description (text->font));
   pango_layout_set_indent (layout, 0);
   pango_layout_set_justify (layout, FALSE);
   pango_layout_set_alignment (layout,
-                             text->alignment == ALIGN_LEFT ? PANGO_ALIGN_LEFT :
-                             text->alignment == ALIGN_RIGHT ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_CENTER);
+                              text->alignment == ALIGN_LEFT ?
+                                PANGO_ALIGN_LEFT :
+                                  text->alignment == ALIGN_RIGHT ?
+                                    PANGO_ALIGN_RIGHT :
+                                    PANGO_ALIGN_CENTER);
 
   str = text_get_string_copy (text);
   pango_layout_set_text (layout, str, -1);
@@ -1158,43 +1204,43 @@ text_to_path (const Text *text, GArray *points)
   pango_layout_get_extents (layout, &ink_rect, NULL);
   /* any surface should do - this one is always available */
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                       ink_rect.width / PANGO_SCALE, ink_rect.height / PANGO_SCALE);
+                                        ink_rect.width / PANGO_SCALE,
+                                        ink_rect.height / PANGO_SCALE);
   cr = cairo_create (surface);
   cairo_surface_destroy (surface);
 
   pango_cairo_layout_path (cr, layout);
 
   /* convert the path */
-  if (cairo_status (cr) == CAIRO_STATUS_SUCCESS)
-  {
+  if (cairo_status (cr) == CAIRO_STATUS_SUCCESS) {
     cairo_path_t *path;
-    int i;
 
     path = cairo_copy_path (cr);
 
-    for (i=0; i < path->num_data; i += path->data[i].header.length) {
+    for (int i = 0; i < path->num_data; i += path->data[i].header.length) {
       cairo_path_data_t *data = &path->data[i];
       BezPoint bp;
 
       switch (data->header.type) {
-      case CAIRO_PATH_MOVE_TO :
-       bp.type = BEZ_MOVE_TO;
-       bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y;
-       break;
-      case CAIRO_PATH_LINE_TO :
-        bp.type = BEZ_LINE_TO;
-       bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y;
-       break;
-      case CAIRO_PATH_CURVE_TO :
-        bp.type = BEZ_CURVE_TO;
-       bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y;
-       bp.p2.x = data[2].point.x; bp.p2.y = data[2].point.y;
-       bp.p3.x = data[3].point.x; bp.p3.y = data[3].point.y;
-       break;
-      case CAIRO_PATH_CLOSE_PATH :
-        /* can't do anything */
-      default :
-        continue;
+        case CAIRO_PATH_MOVE_TO:
+          bp.type = BEZ_MOVE_TO;
+          bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y;
+          break;
+        case CAIRO_PATH_LINE_TO:
+          bp.type = BEZ_LINE_TO;
+          bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y;
+          break;
+        case CAIRO_PATH_CURVE_TO:
+          bp.type = BEZ_CURVE_TO;
+          bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y;
+          bp.p2.x = data[2].point.x; bp.p2.y = data[2].point.y;
+          bp.p3.x = data[3].point.x; bp.p3.y = data[3].point.y;
+          break;
+        case CAIRO_PATH_CLOSE_PATH:
+          /* can't do anything */
+        default:
+          /* TODO: Warn unhandled? */
+          continue;
       }
       g_array_append_val (points, bp);
     }
@@ -1210,35 +1256,41 @@ text_to_path (const Text *text, GArray *points)
   return ret;
 }
 
+
 DiaObject *
 create_standard_path_from_text (const Text *text)
 {
   DiaObject *obj = NULL;
   GArray *points = g_array_new (FALSE, FALSE, sizeof(BezPoint));
 
-  if (text_to_path (text, points))
+  if (text_to_path (text, points)) {
     obj = create_standard_path (points->len, &g_array_index (points, BezPoint, 0));
+  }
 
   g_array_free (points, TRUE);
 
   if (obj) {
-    StdPath *path = (StdPath *)obj;
-    DiaRectangle text_box;
-    const DiaRectangle *pbb = &path->object.bounding_box;
-    real sx, sy;
+    StdPath *path = (StdPath *) obj;
+    double sx, sy;
     Point pos;
+    graphene_rect_t text_box, bbox;
+    graphene_point_t pt;
+
+    dia_object_get_bounding_box (DIA_OBJECT (path), &bbox);
 
     path->stroke_or_fill = PDO_FILL;
     path->fill_color = text->color;
 
     /* scale to fit the original size */
-    text_calc_boundingbox ((Text *)text, &text_box);
-    pos.x = text_box.left; pos.y = text_box.top;
-    sx = (text_box.right - text_box.left) / (pbb->right - pbb->left);
-    sy = (text_box.bottom - text_box.top) / (pbb->bottom - pbb->top);
+    text_calc_boundingbox ((Text *) text, &text_box);
+
+    graphene_rect_get_top_left (&text_box, &pt);
+    sx = graphene_rect_get_width (&text_box) / graphene_rect_get_width (&bbox);
+    sy = graphene_rect_get_height (&text_box) / graphene_rect_get_height (&bbox);
     _stdpath_scale (path, sx, sy, NULL);
 
     /* also adjust top left corner - calling update, too */
+    dia_graphene_to_point (&pt, &pos);
     stdpath_move (path, &pos);
   }
 
diff --git a/lib/text.c b/lib/text.c
index f0c894a42..955f0b233 100644
--- a/lib/text.c
+++ b/lib/text.c
@@ -34,6 +34,7 @@
 #include "attributes.h"
 #include "object.h"
 #include "dia-object-change-list.h"
+#include "dia-graphene.h"
 
 
 static int text_key_event (Focus            *focus,
@@ -267,9 +268,9 @@ calc_width (Text *text)
 
 
 static void
-calc_ascent_descent(Text *text)
+calc_ascent_descent (Text *text)
 {
-  double sig_a = 0.0,sig_d = 0.0;
+  double sig_a = 0.0, sig_d = 0.0;
 
   for (int i = 0; i < text->numlines; i++) {
     sig_a += text_line_get_ascent (text->lines[i]);
@@ -376,12 +377,12 @@ new_text (const char *string,
 {
   Text *text;
 
-  text = g_new(Text, 1);
+  text = g_new0 (Text, 1);
 
-  text->font = g_object_ref (font);
+  g_set_object (&text->font, font);
   text->height = height;
 
-  text->position = *pos;
+  dia_point_to_graphene (pos, &text->position);
   text->color = *color;
   text->alignment = align;
 
@@ -430,13 +431,13 @@ text_copy (Text *text)
   Text *copy;
   int i;
 
-  copy = g_new(Text, 1);
+  copy = g_new0 (Text, 1);
   copy->numlines = text->numlines;
-  copy->lines = g_new(TextLine *, text->numlines);
+  copy->lines = g_new0 (TextLine *, text->numlines);
 
-  copy->font = dia_font_copy(text->font);
+  copy->font = dia_font_copy (text->font);
   copy->height = text->height;
-  copy->position = text->position;
+  graphene_point_init_from_point (&copy->position, &text->position);
   copy->color = text->color;
   copy->alignment = text->alignment;
 
@@ -507,10 +508,32 @@ text_set_font (Text *text, DiaFont *font)
 }
 
 
+/**
+ * dia_text_get_position:
+ * @text: the #Text
+ * @pos: (out caller-allocates): the position of @text
+ *
+ * Stability: Stable
+ *
+ * Since: 0.98
+ */
+void
+dia_text_get_position (Text *text, Point *pos)
+{
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (pos != NULL);
+
+  dia_graphene_to_point (&text->position, pos);
+}
+
+
 void
 text_set_position (Text *text, Point *pos)
 {
-  text->position = *pos;
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (pos != NULL);
+
+  dia_point_to_graphene (pos, &text->position);
 }
 
 
@@ -529,8 +552,10 @@ text_set_alignment (Text *text, Alignment align)
 
 
 void
-text_calc_boundingbox (Text *text, DiaRectangle *box)
+text_calc_boundingbox (Text *text, graphene_rect_t *box)
 {
+  double x = 0, y = 0, box_width = 0, box_height = 0;
+
   calc_width (text);
   calc_ascent_descent (text);
 
@@ -539,46 +564,50 @@ text_calc_boundingbox (Text *text, DiaRectangle *box)
                updated */
   }
 
-  box->left = text->position.x;
+  x = text->position.x;
 
   switch (text->alignment) {
     case ALIGN_LEFT:
       break;
     case ALIGN_CENTER:
-      box->left -= text->max_width / 2.0;
+      x -= text->max_width / 2.0;
       break;
     case ALIGN_RIGHT:
-      box->left -= text->max_width;
+      x -= text->max_width;
       break;
     default:
       g_return_if_reached ();
   }
 
-  box->right = box->left + text->max_width;
+  box_width = text->max_width;
 
-  box->top = text->position.y - text->ascent;
+  y = text->position.y - text->ascent;
 #if 0
   box->bottom = box->top + text->height*text->numlines + text->descent;
 #else
   /* why should we add one descent? isn't ascent+descent~=height? */
-  box->bottom = box->top + (text->ascent+text->descent+text->height*(text->numlines-1));
+  box_height = (text->ascent + text->descent + text->height * (text->numlines - 1));
 #endif
+
   if (text->focus.has_focus) {
     double height = text->ascent + text->descent;
+
     if (text->cursor_pos == 0) {
       /* Half the cursor width */
-      box->left -= height/(CURSOR_HEIGHT_RATIO*2);
+      x -= height / (CURSOR_HEIGHT_RATIO * 2);
     } else {
       /* Half the cursor width. Assume that
          if it isn't at position zero, it might be
          at the last position possible. */
-      box->right += height/(CURSOR_HEIGHT_RATIO*2);
+      box_width += height / (CURSOR_HEIGHT_RATIO * 2);
     }
 
     /* Account for the size of the cursor top and bottom */
-    box->top -= height/(CURSOR_HEIGHT_RATIO*2);
-    box->bottom += height/CURSOR_HEIGHT_RATIO;
+    y -= height / (CURSOR_HEIGHT_RATIO * 2);
+    box_height += height / CURSOR_HEIGHT_RATIO;
   }
+
+  graphene_rect_init (box, x, y, box_width, box_height);
 }
 
 
@@ -1225,22 +1254,33 @@ data_add_text (AttributeNode attr, Text *text, DiaContext *ctx)
   DataNode composite;
   char *str;
 
-  composite = data_add_composite(attr, "text", ctx);
+  composite = data_add_composite (attr, "text", ctx);
 
-  str = text_get_string_copy(text);
-  data_add_string(composite_add_attribute(composite, "string"),
-                 str, ctx);
+  str = text_get_string_copy (text);
+  data_add_string (composite_add_attribute (composite, "string"),
+                   str, ctx);
   g_clear_pointer (&str, g_free);
-  data_add_font(composite_add_attribute(composite, "font"),
-               text->font, ctx);
-  data_add_real(composite_add_attribute(composite, "height"),
-               text->height, ctx);
-  data_add_point(composite_add_attribute(composite, "pos"),
-                &text->position, ctx);
-  data_add_color(composite_add_attribute(composite, "color"),
-                &text->color, ctx);
-  data_add_enum(composite_add_attribute(composite, "alignment"),
-               text->alignment, ctx);
+
+  data_add_font (composite_add_attribute (composite, "font"),
+                 text->font,
+                 ctx);
+  data_add_real (composite_add_attribute (composite, "height"),
+                 text->height,
+                 ctx);
+
+  {
+    Point pos;
+
+    dia_text_get_position (text, &pos);
+    data_add_point (composite_add_attribute (composite, "pos"), &pos, ctx);
+  }
+
+  data_add_color (composite_add_attribute (composite, "color"),
+                  &text->color,
+                  ctx);
+  data_add_enum (composite_add_attribute (composite, "alignment"),
+                 text->alignment,
+                 ctx);
 }
 
 
@@ -1306,7 +1346,7 @@ text_get_attributes (Text *text, TextAttributes *attr)
   attr->font = g_object_ref (text->font);
   g_clear_object (&old_font);
   attr->height = text->height;
-  attr->position = text->position;
+  dia_graphene_to_point (&text->position, &attr->position);
   attr->color = text->color;
   attr->alignment = text->alignment;
 }
@@ -1319,7 +1359,7 @@ text_set_attributes (Text *text, TextAttributes *attr)
     text_set_font (text, attr->font);
   }
   text_set_height (text, attr->height);
-  text->position = attr->position;
+  dia_point_to_graphene (&attr->position, &text->position);
   text->color = attr->color;
   text->alignment = attr->alignment;
 }
diff --git a/lib/text.h b/lib/text.h
index e328d6a8c..6c63f5a18 100644
--- a/lib/text.h
+++ b/lib/text.h
@@ -25,6 +25,8 @@ typedef enum {
 } TextEditState;
 
 #include <glib.h>
+#include <graphene.h>
+
 #include "diatypes.h"
 #include "textattr.h"
 #include "focus.h"
@@ -61,7 +63,7 @@ struct _Text {
   /* Attributes: */
   DiaFont *font;
   double height;
-  Point position;
+  graphene_point_t position;
   Color color;
   Alignment alignment;
 
@@ -81,30 +83,33 @@ struct _Text {
 /*! \brief Text object creation \memberof _Text */
 Text *new_text(const char *string, DiaFont *font, double height,
               Point *pos, Color *color, Alignment align);
-Text   *new_text_default      (Point      *pos,
-                               Color      *color,
-                               Alignment   align);
-void    text_destroy          (Text       *text);
-Text   *text_copy             (Text       *text);
-char   *text_get_line         (const Text *text,
-                               int         line);
-char   *text_get_string_copy  (const Text *text);
-void    text_set_string       (Text       *text,
-                               const char *string);
-void    text_set_height       (Text       *text,
-                               double      height);
-double  text_get_height       (const Text *text);
-void    text_set_font         (Text       *text,
-                               DiaFont    *font);
-void    text_set_position     (Text       *text,
-                               Point      *pos);
-void    text_set_color        (Text       *text,
-                               Color      *col);
-void    text_set_alignment    (Text       *text,
-                               Alignment   align);
-double  text_distance_from    (Text       *text,
-                               Point      *point);
-void text_calc_boundingbox(Text *text, DiaRectangle *box);
+Text   *new_text_default      (Point           *pos,
+                               Color           *color,
+                               Alignment        align);
+void    text_destroy          (Text            *text);
+Text   *text_copy             (Text            *text);
+char   *text_get_line         (const Text      *text,
+                               int              line);
+char   *text_get_string_copy  (const Text      *text);
+void    text_set_string       (Text            *text,
+                               const char      *string);
+void    text_set_height       (Text            *text,
+                               double           height);
+double  text_get_height       (const Text      *text);
+void    text_set_font         (Text            *text,
+                               DiaFont         *font);
+void    dia_text_get_position (Text            *text,
+                               Point           *pos);
+void    text_set_position     (Text            *text,
+                               Point           *pos);
+void    text_set_color        (Text            *text,
+                               Color           *col);
+void    text_set_alignment    (Text            *text,
+                               Alignment        align);
+double  text_distance_from    (Text            *text,
+                               Point           *point);
+void    text_calc_boundingbox (Text            *text,
+                               graphene_rect_t *box);
 void text_draw(Text *text, DiaRenderer *renderer);
 void text_set_cursor(Text *text, Point *clicked_point,
                     DiaRenderer *interactive_renderer);
diff --git a/meson.build b/meson.build
index 94a97bcf2..70ad1396e 100644
--- a/meson.build
+++ b/meson.build
@@ -15,7 +15,7 @@ libxml_dep  = dependency('libxml-2.0', version: '>= 2.9.4')
 gmodule_dep = dependency('gmodule-2.0')
 libzlib_dep = dependency('zlib')
 libcairo_dep = dependency('cairo')
-graphene_dep = dependency('graphene-1.0')
+graphene_dep = dependency('graphene-1.0', version: '>= 1.10')
 
 # Not required since not all platforms ship a separate libm.
 libm_dep = cc.find_library('m', required: false)
diff --git a/objects/AADL/aadlbox.c b/objects/AADL/aadlbox.c
index 059687cd4..2071117dc 100644
--- a/objects/AADL/aadlbox.c
+++ b/objects/AADL/aadlbox.c
@@ -35,6 +35,8 @@
 
 #include "aadl.h"
 #include "edit_port_declaration.h"
+#include "dia-graphene.h"
+
 
 #define PORT_HANDLE_AADLBOX (HANDLE_CUSTOM9)
 
@@ -703,13 +705,20 @@ aadlbox_delete_connection_callback (DiaObject *obj,
  **          "CLASSIC FUNCTIONS"              **
  ***********************************************/
 
-real
-aadlbox_distance_from(Aadlbox *aadlbox, Point *point)
+
+double
+aadlbox_distance_from (Aadlbox *aadlbox, Point *point)
 {
-  DiaObject *obj = &aadlbox->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (aadlbox), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 void
 aadlbox_select(Aadlbox *aadlbox, Point *clicked_point,
                    DiaRenderer *interactive_renderer)
@@ -843,41 +852,45 @@ aadlbox_update_text_position(Aadlbox *aadlbox)
   text_set_position(aadlbox->name, &p);
 }
 
+
 static void
-aadlbox_update_data(Aadlbox *aadlbox)
+aadlbox_update_data (Aadlbox *aadlbox)
 {
   Element *elem = &aadlbox->element;
   DiaObject *obj = &aadlbox->element.object;
   Point min_size;
   int i;
-  real tmp;
+  double tmp;
+  graphene_rect_t bbox;
 
-  aadlbox->specific->min_size(aadlbox, &min_size);
+  aadlbox->specific->min_size (aadlbox, &min_size);
 
-  elem->width = MAX(elem->width, min_size.x);
-  elem->height = MAX(elem->height, min_size.y);
+  elem->width = MAX (elem->width, min_size.x);
+  elem->height = MAX (elem->height, min_size.y);
 
-  element_update_boundingbox(elem);
+  element_update_boundingbox (elem);
 
   /* extend bounding box because of ports */
   /* FIXME: This cause the box to be selectionned when clicking out of it !! */
-  obj->bounding_box.top -= AADL_PORT_MAX_OUT + 0.1;
-  obj->bounding_box.right += AADL_PORT_MAX_OUT + 0.1;
-  obj->bounding_box.bottom += AADL_PORT_MAX_OUT + 0.1;
-  obj->bounding_box.left -= AADL_PORT_MAX_OUT + 0.1;
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_inset (&bbox,
+                       -(AADL_PORT_MAX_OUT + 0.1),
+                       -(AADL_PORT_MAX_OUT + 0.1));
+  dia_object_set_bounding_box (obj, &bbox);
 
   obj->position = elem->corner;
 
-  aadlbox_update_text_position(aadlbox);
+  aadlbox_update_text_position (aadlbox);
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 
-  aadlbox_update_ports(aadlbox);
+  aadlbox_update_ports (aadlbox);
 
-  for (i=0;i<aadlbox->num_connections;i++)
-      aadlbox->specific->project_point_on_nearest_border(aadlbox,
-                                              &aadlbox->connections[i]->pos,
-                                              &tmp);
+  for (i = 0; i < aadlbox->num_connections; i++) {
+    aadlbox->specific->project_point_on_nearest_border (aadlbox,
+                                                        &aadlbox->connections[i]->pos,
+                                                        &tmp);
+  }
 }
 
 
diff --git a/objects/Database/compound.c b/objects/Database/compound.c
index ef3cbda71..2fc34468b 100644
--- a/objects/Database/compound.c
+++ b/objects/Database/compound.c
@@ -32,7 +32,7 @@
 #include "attributes.h"
 #include "geometry.h"
 #include "propinternals.h"
-
+#include "dia-graphene.h"
 #include "debug.h"
 #include "database.h"
 
@@ -835,31 +835,41 @@ compound_apply_props (Compound * comp, GPtrArray * props, gboolean is_default)
 
 
 /**
+ * compound_update_object:
+ * @comp: the #Compound
+ *
  * Determine the bounding box of the compound object and store it in the
  * object. Also update the object's position to the upper left corner of
  * the bounding box.
  */
-static void compound_update_object (Compound * comp)
+static void
+compound_update_object (Compound *comp)
 {
-  DiaRectangle * bb;
-  Handle * h;
-  gint i;
-  gint num_handles = comp->object.num_handles;
+  graphene_rect_t bb;
+  Handle *h;
+  int i;
+  int num_handles = comp->object.num_handles;
+  graphene_point_t tl;
 
   h = &comp->handles[0];
-  bb = &comp->object.bounding_box;
-  bb->right = bb->left = h->pos.x;
-  bb->top = bb->bottom = h->pos.y;
-  for (i = 1; i < num_handles; i++)
-    {
-      h = &comp->handles[i];
-      bb->left = MIN (h->pos.x, bb->left);
-      bb->right = MAX(h->pos.x, bb->right);
-      bb->top = MIN(h->pos.y, bb->top);
-      bb->bottom = MAX(h->pos.y, bb->bottom);
-    }
-  comp->object.position.x = bb->left;
-  comp->object.position.y = bb->top;
+
+  graphene_rect_init (&bb, h->pos.x, h->pos.y, 0, 0);
+
+  for (i = 1; i < num_handles; i++) {
+    graphene_point_t pt;
+
+    h = &comp->handles[i];
+
+    dia_point_to_graphene (&h->pos, &pt);
+    graphene_rect_expand (&bb, &pt, &bb);
+  }
+
+  graphene_rect_get_top_left (&bb, &tl);
+
+  comp->object.position.x = tl.x;
+  comp->object.position.y = tl.y;
+
+  dia_object_set_bounding_box (DIA_OBJECT (comp), &bb);
 
 #if DEBUG_DRAW_MP_DIRECTION
   /* make the bounding box a bit larger because drawing the direction of
diff --git a/objects/Database/reference.c b/objects/Database/reference.c
index 7a15e80d7..b1422b9c3 100644
--- a/objects/Database/reference.c
+++ b/objects/Database/reference.c
@@ -28,6 +28,7 @@
 #include "attributes.h"
 #include "properties.h"
 #include "diarenderer.h"
+#include "dia-graphene.h"
 #include "pixmaps/reference.xpm"
 
 /* ------------------------------------------------------------------------ */
@@ -52,20 +53,26 @@ static void reference_update_data (TableReference *);
 static DiaObject * reference_load (ObjectNode obj_node, int version,DiaContext *ctx);
 static void update_desc_data (Point *, Alignment *,
                               Point *, Point *, Orientation, real, real);
-static void get_desc_bbox (DiaRectangle *, gchar *, real, Point *, Alignment,
-                           DiaFont *, real);
+static void             get_desc_bbox            (graphene_rect_t  *,
+                                                  char             *,
+                                                  double            ,
+                                                  Point            *,
+                                                  Alignment         ,
+                                                  DiaFont          *,
+                                                  double);
 static DiaObjectChange *reference_add_segment_cb (DiaObject        *,
                                                   Point            *,
                                                   gpointer);
 static DiaObjectChange *reference_del_segment_cb (DiaObject        *,
                                                   Point            *,
                                                   gpointer);
-static DiaMenu * reference_object_menu(TableReference *, Point *);
+static DiaMenu         *reference_object_menu    (TableReference   *,
+                                                  Point            *);
+
 
 /* ------------------------------------------------------------------------ */
 
-static ObjectTypeOps reference_type_ops =
-{
+static ObjectTypeOps reference_type_ops = {
   (CreateFunc) reference_create,
   (LoadFunc)   reference_load,
   (SaveFunc)   object_save_using_properties,
@@ -73,8 +80,8 @@ static ObjectTypeOps reference_type_ops =
   (ApplyDefaultsFunc) NULL
 };
 
-DiaObjectType reference_type =
-{
+
+DiaObjectType reference_type = {
   "Database - Reference", /* name */
   0,                   /* version */
   reference_xpm,        /* pixmap */
@@ -83,6 +90,7 @@ DiaObjectType reference_type =
   NULL       /* default_user_data */
 };
 
+
 static ObjectOps reference_ops = {
   (DestroyFunc)         reference_destroy,
   (DrawFunc)            reference_draw,
@@ -274,19 +282,20 @@ reference_distance_from (TableReference *ref, Point *point)
   DiaRectangle rect;
   OrthConn *orth;
   double dist;
+  graphene_rect_t bbox;
 
   orth = &ref->orth;
   dist = orthconn_distance_from (orth, point, ref->line_width);
 
   if (IS_NOT_EMPTY (ref->start_point_desc)) {
-    get_desc_bbox (&rect,
+    get_desc_bbox (&bbox,
                    ref->start_point_desc,
                    ref->sp_desc_width,
                    &ref->sp_desc_pos,
                    ref->sp_desc_text_align,
                    ref->normal_font,
                    ref->normal_font_height);
-
+    dia_graphene_to_rectangle (&bbox, &rect);
     dist = MIN (distance_rectangle_point (&rect, point), dist);
 
     if (dist < 0.000001) {
@@ -295,13 +304,14 @@ reference_distance_from (TableReference *ref, Point *point)
   }
 
   if (IS_NOT_EMPTY (ref->start_point_desc)) {
-    get_desc_bbox (&rect,
+    get_desc_bbox (&bbox,
                    ref->end_point_desc,
                    ref->ep_desc_width,
                    &ref->ep_desc_pos,
                    ref->ep_desc_text_align,
                    ref->normal_font,
                    ref->normal_font_height);
+    dia_graphene_to_rectangle (&bbox, &rect);
     dist = MIN (distance_rectangle_point (&rect, point), dist);
   }
 
@@ -377,12 +387,13 @@ reference_set_props (TableReference *ref, GPtrArray *props)
   reference_update_data (ref);
 }
 
+
 static void
 reference_update_data (TableReference * ref)
 {
-  OrthConn * orth = &ref->orth;
-  DiaRectangle rect;
+  OrthConn *orth = &ref->orth;
   PolyBBExtras *extra = &orth->extra_spacing;
+  graphene_rect_t bbox, rect;
 
   orthconn_update_data (orth);
 
@@ -392,81 +403,88 @@ reference_update_data (TableReference * ref)
     extra->middle_trans =
     extra->end_trans =
     extra->end_long = ref->line_width/2.0;
+
   orthconn_update_boundingbox (orth);
 
+  dia_object_get_bounding_box (DIA_OBJECT (ref), &bbox);
+
   /* compute the position of the start point description */
-  if (IS_NOT_EMPTY(ref->start_point_desc))
-    {
-      gint p_index = 0;
-      Point * pos = &orth->points[p_index];
-      Point * next_pos = &orth->points[p_index+1];
-      Orientation orient = orth->orientation[p_index];
-
-      /* if pos and next_pos are the same take the next point following
-         next_pos */
-      if (pos->x == next_pos->x && pos->y == next_pos->y)
-        {
-          next_pos = &orth->points[p_index+2];
-          orient = (pos->y == next_pos->y) ? HORIZONTAL : VERTICAL;
-        }
-
-      ref->sp_desc_width = dia_font_string_width (ref->start_point_desc,
-                                                  ref->normal_font,
-                                                  ref->normal_font_height);
-
-      update_desc_data (&ref->sp_desc_pos, &ref->sp_desc_text_align,
-                        pos, next_pos, orient, ref->line_width,
-                        ref->normal_font_height);
-
-      get_desc_bbox (&rect, ref->start_point_desc, ref->sp_desc_width,
-                     &ref->sp_desc_pos, ref->sp_desc_text_align,
-                     ref->normal_font, ref->normal_font_height);
-      rectangle_union (&orth->object.bounding_box, &rect);
-    }
-  else
-    {
-      ref->sp_desc_width = 0.0;
+  if (IS_NOT_EMPTY (ref->start_point_desc)) {
+    int p_index = 0;
+    Point *pos = &orth->points[p_index];
+    Point *next_pos = &orth->points[p_index+1];
+    Orientation orient = orth->orientation[p_index];
+
+    /* if pos and next_pos are the same take the next point following
+        next_pos */
+    if (pos->x == next_pos->x && pos->y == next_pos->y) {
+      next_pos = &orth->points[p_index+2];
+      orient = (pos->y == next_pos->y) ? HORIZONTAL : VERTICAL;
     }
 
+    ref->sp_desc_width = dia_font_string_width (ref->start_point_desc,
+                                                ref->normal_font,
+                                                ref->normal_font_height);
+
+    update_desc_data (&ref->sp_desc_pos, &ref->sp_desc_text_align,
+                      pos, next_pos, orient, ref->line_width,
+                      ref->normal_font_height);
+
+    get_desc_bbox (&rect,
+                   ref->start_point_desc,
+                   ref->sp_desc_width,
+                   &ref->sp_desc_pos,
+                   ref->sp_desc_text_align,
+                   ref->normal_font,
+                   ref->normal_font_height);
+    graphene_rect_union (&bbox, &rect, &bbox);
+  } else {
+    ref->sp_desc_width = 0.0;
+  }
+
   /* compute the position of the start point description */
-  if (IS_NOT_EMPTY(ref->end_point_desc))
-    {
-      gint p_index = orth->numpoints - 1;
-      Point * pos = &orth->points[p_index];
-      Point * next_pos = &orth->points[p_index-1];
-      Orientation orient = orth->orientation[orth->numorient-1];
-
-      /* if pos and next_pos are the same take the next point before
-         next_pos */
-      if (pos->x == next_pos->x && pos->y == next_pos->y)
-        {
-          next_pos = &orth->points[p_index-2];
-          orient = (pos->y == next_pos->y) ? HORIZONTAL : VERTICAL;
-        }
-
-      ref->ep_desc_width = dia_font_string_width (ref->end_point_desc,
-                                                  ref->normal_font,
-                                                  ref->normal_font_height);
-
-      update_desc_data (&ref->ep_desc_pos, &ref->ep_desc_text_align,
-                        pos, next_pos, orient, ref->line_width,
-                        ref->normal_font_height);
-
-      get_desc_bbox (&rect, ref->end_point_desc, ref->ep_desc_width,
-                     &ref->ep_desc_pos, ref->ep_desc_text_align,
-                     ref->normal_font, ref->normal_font_height);
-      rectangle_union (&orth->object.bounding_box, &rect);
-    }
-  else
-    {
-      ref->ep_desc_width = 0.0;
+  if (IS_NOT_EMPTY (ref->end_point_desc)) {
+    int p_index = orth->numpoints - 1;
+    Point * pos = &orth->points[p_index];
+    Point * next_pos = &orth->points[p_index-1];
+    Orientation orient = orth->orientation[orth->numorient-1];
+
+    /* if pos and next_pos are the same take the next point before
+        next_pos */
+    if (pos->x == next_pos->x && pos->y == next_pos->y) {
+      next_pos = &orth->points[p_index-2];
+      orient = (pos->y == next_pos->y) ? HORIZONTAL : VERTICAL;
     }
+
+    ref->ep_desc_width = dia_font_string_width (ref->end_point_desc,
+                                                ref->normal_font,
+                                                ref->normal_font_height);
+
+    update_desc_data (&ref->ep_desc_pos, &ref->ep_desc_text_align,
+                      pos, next_pos, orient, ref->line_width,
+                      ref->normal_font_height);
+
+    get_desc_bbox (&rect,
+                   ref->end_point_desc,
+                   ref->ep_desc_width,
+                   &ref->ep_desc_pos,
+                   ref->ep_desc_text_align,
+                   ref->normal_font,
+                   ref->normal_font_height);
+    graphene_rect_union (&bbox, &rect, &bbox);
+  } else {
+    ref->ep_desc_width = 0.0;
+  }
+
   /* finally the end arrow */
   arrow_bbox (&ref->end_arrow, ref->line_width,
               &orth->points[orth->numpoints - 1], &orth->points[orth->numpoints - 2], &rect);
-  rectangle_union (&orth->object.bounding_box, &rect);
+  graphene_rect_union (&bbox, &rect, &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (ref), &bbox);
 }
 
+
 static void
 update_desc_data (Point * desc_pos, Alignment * desc_align,
                   Point * end_point, Point * nearest_point,
@@ -505,34 +523,37 @@ update_desc_data (Point * desc_pos, Alignment * desc_align,
   }
 }
 
+
 static void
-get_desc_bbox (DiaRectangle * r, gchar * string, real string_width,
-               Point * pos, Alignment align,
-               DiaFont * font, real font_height)
+get_desc_bbox (graphene_rect_t *r,
+               char            *string,
+               double           string_width,
+               Point           *pos,
+               Alignment        align,
+               DiaFont         *font,
+               double           font_height)
 {
-  real width;
-
-  g_assert (r != NULL);
-  g_assert (string != NULL);
-  g_assert (pos != NULL);
-
-  width = string_width;
+  double width;
+  double x;
+  double y;
+
+  g_return_if_fail (r != NULL);
+  g_return_if_fail (string != NULL);
+  g_return_if_fail (pos != NULL);
+  g_return_if_fail (align == ALIGN_LEFT || align == ALIGN_RIGHT);
+
+  if (align == ALIGN_LEFT) {
+    x = pos->x;
+    width = string_width;
+  } else {
+    x = -pos->x;
+    width = -string_width;
+  }
 
-  g_assert (align == ALIGN_LEFT || align == ALIGN_RIGHT);
-  if (align == ALIGN_LEFT)
-    {
-      r->left = pos->x;
-      r->right = r->left + width;
-    }
-  else
-    {
-      r->right = pos->x;
-      r->left = r->right - width;
-    }
+  y = pos->y - dia_font_ascent (string, font, font_height);
 
-  r->top = pos->y;
-  r->top -= dia_font_ascent (string, font, font_height);
-  r->bottom = r->top + font_height;
+  graphene_rect_init (r, x, y, width, font_height);
+  graphene_rect_normalize (r);
 }
 
 
diff --git a/objects/Database/table.c b/objects/Database/table.c
index 90cc66c89..58eea409a 100644
--- a/objects/Database/table.c
+++ b/objects/Database/table.c
@@ -37,6 +37,7 @@
 #include "diarenderer.h"
 #include "element.h"
 #include "attributes.h"
+#include "dia-graphene.h"
 #include "pixmaps/table.xpm"
 
 #define TABLE_UNDERLINE_WIDTH 0.05
@@ -812,17 +813,20 @@ table_draw_attributesbox (Table         *table,
   return Yoffset;
 }
 
-static real
-table_distance_from (Table * table, Point *point)
+
+static double
+table_distance_from (Table *table, Point *point)
 {
-  const DiaRectangle * rect;
-  DiaObject * obj;
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
 
-  obj = &table->element.object;
-  rect = dia_object_get_bounding_box (obj);
-  return distance_rectangle_point (rect, point);
+  dia_object_get_bounding_box (DIA_OBJECT (table), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 table_select (Table * table, Point * clicked_point,
                 DiaRenderer * interactive_renderer)
diff --git a/objects/ER/relationship.c b/objects/ER/relationship.c
index 2066324eb..f18a4d76f 100644
--- a/objects/ER/relationship.c
+++ b/objects/ER/relationship.c
@@ -341,12 +341,13 @@ relationship_draw (Relationship *relationship, DiaRenderer *renderer)
 
 
 static void
-relationship_update_data(Relationship *relationship)
+relationship_update_data (Relationship *relationship)
 {
   Element *elem = &relationship->element;
   DiaObject *obj = &elem->object;
   ElementBBExtras *extra = &elem->extra_spacing;
-  DiaRectangle *bbox = &obj->bounding_box;
+  graphene_rect_t bbox;
+  graphene_point_t tl, br;
 
   relationship->name_width = dia_font_string_width (relationship->name,
                                                     relationship->font,
@@ -430,17 +431,28 @@ relationship_update_data(Relationship *relationship)
                                     relationship->font,
                                     relationship->font_height);
 
+  dia_object_get_bounding_box (DIA_OBJECT (relationship), &bbox);
+
+  graphene_rect_get_top_left (&bbox, &tl);
+  graphene_rect_get_bottom_right (&bbox, &br);
+
   /* fix boundingrelationship for line_width: */
   if (relationship->rotate) {
-    bbox->top -= relationship->font_height + 0.2 + CARDINALITY_DISTANCE;
-    bbox->bottom += relationship->font_height + 0.2 + CARDINALITY_DISTANCE;
-    bbox->right += (bbox->left + bbox->right) / 2.0 + CARDINALITY_DISTANCE
+    tl.y -= relationship->font_height + 0.2 + CARDINALITY_DISTANCE;
+    br.y += relationship->font_height + 0.2 + CARDINALITY_DISTANCE;
+    br.x += (tl.x + br.x) / 2.0 + CARDINALITY_DISTANCE
                    + MAX (relationship->right_card_width,
                           relationship->left_card_width);
   } else {
-    bbox->left -= CARDINALITY_DISTANCE + relationship->left_card_width;
-    bbox->right += CARDINALITY_DISTANCE + relationship->right_card_width;
+    tl.x -= CARDINALITY_DISTANCE + relationship->left_card_width;
+    br.x += CARDINALITY_DISTANCE + relationship->right_card_width;
   }
+
+  graphene_rect_expand (&bbox, &tl, &bbox);
+  graphene_rect_expand (&bbox, &br, &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (relationship), &bbox);
+
   obj->position = elem->corner;
 
   element_update_handles (elem);
diff --git a/objects/FS/flow-ortho.c b/objects/FS/flow-ortho.c
index b6a1ae1cd..28ddb9089 100644
--- a/objects/FS/flow-ortho.c
+++ b/objects/FS/flow-ortho.c
@@ -541,8 +541,8 @@ orthflow_update_data (Orthflow *orthflow)
 {
   OrthConn *orth = &orthflow->orth ;
   DiaObject *obj = &orth->object;
-  DiaRectangle rect;
-  Color* color = &orthflow_color_signal;
+  Color *color = &orthflow_color_signal;
+  graphene_rect_t bbox, rect;
 
   switch (orthflow->type) {
     case ORTHFLOW_ENERGY:
@@ -569,8 +569,11 @@ orthflow_update_data (Orthflow *orthflow)
   orthconn_update_boundingbox (orth);
 
   /* Add boundingbox for text: */
-  text_calc_boundingbox (orthflow->text, &rect) ;
-  rectangle_union (&obj->bounding_box, &rect);
+  text_calc_boundingbox (orthflow->text, &rect);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &rect, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
 
@@ -633,7 +636,7 @@ orthflow_load(ObjectNode obj_node, int version, DiaContext *ctx)
     extra->middle_trans = ORTHFLOW_WIDTH/2.0;
   extra->end_long =
     extra->end_trans = ORTHFLOW_WIDTH/2 + ORTHFLOW_ARROWLEN;
-  orthflow->textpos = orthflow->text->position;
+  dia_text_get_position (orthflow->text, &orthflow->textpos);
 
   orthflow_update_data(orthflow);
 
diff --git a/objects/FS/flow.c b/objects/FS/flow.c
index ab239dbbf..b56aefc37 100644
--- a/objects/FS/flow.c
+++ b/objects/FS/flow.c
@@ -336,17 +336,18 @@ flow_draw (Flow *flow, DiaRenderer *renderer)
     case FLOW_SIGNAL:
       dia_renderer_set_linestyle (renderer, LINESTYLE_DASHED, FLOW_DASHLEN);
       render_color = &flow_color_signal ;
-      break ;
+      break;
     case FLOW_MATERIAL:
       dia_renderer_set_linewidth (renderer, FLOW_MATERIAL_WIDTH);
       dia_renderer_set_linestyle (renderer, LINESTYLE_SOLID, 0.0);
       render_color = &flow_color_material;
-      break ;
+      break;
     case FLOW_ENERGY:
       render_color = &flow_color_energy;
       dia_renderer_set_linestyle (renderer, LINESTYLE_SOLID, 0.0);
       break;
     default:
+      g_critical ("Flow type: %i", flow->type);
       g_return_if_reached ();
   }
 
@@ -469,16 +470,16 @@ flow_copy(Flow *flow)
 
 
 static void
-flow_update_data(Flow *flow)
+flow_update_data (Flow *flow)
 {
   Connection *conn = &flow->connection;
   DiaObject *obj = &conn->object;
-  DiaRectangle rect;
-  Color* color = NULL;
+  Color *color = NULL;
+  graphene_rect_t bbox, rect;
 
-  if (connpoint_is_autogap(flow->connection.endpoint_handles[0].connected_to) ||
-      connpoint_is_autogap(flow->connection.endpoint_handles[1].connected_to)) {
-    connection_adjust_for_autogap(conn);
+  if (connpoint_is_autogap (flow->connection.endpoint_handles[0].connected_to) ||
+      connpoint_is_autogap (flow->connection.endpoint_handles[1].connected_to)) {
+    connection_adjust_for_autogap (conn);
   }
   obj->position = conn->endpoints[0];
 
@@ -497,17 +498,20 @@ flow_update_data(Flow *flow)
   }
   text_set_color (flow->text, color);
 
-  flow->text->position = flow->textpos;
+  text_set_position (flow->text, &flow->textpos);
   flow->text_handle.pos = flow->textpos;
 
-  connection_update_handles(conn);
+  connection_update_handles (conn);
 
   /* Boundingbox: */
-  connection_update_boundingbox(conn);
+  connection_update_boundingbox (conn);
 
   /* Add boundingbox for text: */
-  text_calc_boundingbox(flow->text, &rect) ;
-  rectangle_union(&obj->bounding_box, &rect);
+  text_calc_boundingbox (flow->text, &rect);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &rect, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
 
@@ -563,7 +567,7 @@ flow_load(ObjectNode obj_node, int version, DiaContext *ctx)
   flow->text_handle.type = HANDLE_MINOR_CONTROL;
   flow->text_handle.connect_type = HANDLE_NONCONNECTABLE;
   flow->text_handle.connected_to = NULL;
-  flow->text_handle.pos = flow->text->position;
+  dia_text_get_position (flow->text, &flow->text_handle.pos);
   obj->handles[2] = &flow->text_handle;
 
   extra->start_long =
@@ -571,8 +575,8 @@ flow_load(ObjectNode obj_node, int version, DiaContext *ctx)
     extra->start_trans = FLOW_WIDTH/2.0;
   extra->end_trans = MAX(FLOW_WIDTH, FLOW_ARROWLEN) / 2.0;
 
-  flow->textpos = flow->text->position;
-  flow_update_data(flow);
+  dia_text_get_position (flow->text, &flow->textpos);
+  flow_update_data (flow);
 
   return &flow->connection.object;
 }
diff --git a/objects/FS/function.c b/objects/FS/function.c
index 8bfddefa3..dc0e38650 100644
--- a/objects/FS/function.c
+++ b/objects/FS/function.c
@@ -20,7 +20,6 @@
 
 #include <config.h>
 
-#include <assert.h>
 #include <math.h>
 #include <string.h>
 #include <stdio.h>
@@ -33,11 +32,10 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
-
+#include "dia-graphene.h"
 #include "pixmaps/function.xpm"
 
 typedef struct _Function Function;
-typedef struct _FunctionChange FunctionChange;
 
 #define NUM_CONNECTIONS 9
 
@@ -117,21 +115,22 @@ function_get_props(Function * function, GPtrArray *props);
 static void
 function_set_props(Function * function, GPtrArray *props);
 
-static ObjectTypeOps function_type_ops =
-{
+
+static ObjectTypeOps function_type_ops = {
   (CreateFunc) function_create,
   (LoadFunc)   function_load,
   (SaveFunc)   function_save
 };
 
-DiaObjectType function_type =
-{
+
+DiaObjectType function_type = {
   "FS - Function",  /* name */
   0,             /* version */
   function_xpm,   /* pixmap */
   &function_type_ops /* ops */
 };
 
+
 static ObjectOps function_ops = {
   (DestroyFunc)         function_destroy,
   (DrawFunc)            function_draw,
@@ -150,6 +149,7 @@ static ObjectOps function_ops = {
   (ApplyPropertiesListFunc) object_apply_props,
 };
 
+
 static PropDescription function_props[] = {
   ELEMENT_COMMON_PROPERTIES,
   { "wish function", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE,
@@ -276,11 +276,15 @@ function_create_change (Function *fcn, enum FuncChangeType change_type)
 
 
 static double
-function_distance_from(Function *pkg, Point *point)
+function_distance_from (Function *pkg, Point *point)
 {
-  DiaObject *obj = &pkg->element.object;
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
 
-  return distance_rectangle_point (&obj->bounding_box, point);
+  dia_object_get_bounding_box (DIA_OBJECT (pkg), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
 
@@ -302,11 +306,11 @@ function_move_handle (Function         *pkg,
                       HandleMoveReason  reason,
                       ModifierKeys      modifiers)
 {
-  assert(pkg!=NULL);
-  assert(handle!=NULL);
-  assert(to!=NULL);
+  g_return_val_if_fail (pkg != NULL, NULL);
+  g_return_val_if_fail (handle != NULL, NULL);
+  g_return_val_if_fail (to != NULL, NULL);
 
-  assert(handle->id < 8);
+  g_return_val_if_fail (handle->id < 8, NULL);
 
   return NULL;
 }
@@ -326,13 +330,13 @@ static void
 function_draw (Function *pkg, DiaRenderer *renderer)
 {
   Element *elem;
-  real x, y, w, h;
+  double x, y, w, h;
   Point p1, p2;
-  real font_height ;
+  double font_height ;
 
-  assert(pkg != NULL);
-  assert(pkg->text != NULL);
-  assert(renderer != NULL);
+  g_return_if_fail (pkg != NULL);
+  g_return_if_fail (pkg->text != NULL);
+  g_return_if_fail (renderer != NULL);
 
   elem = &pkg->element;
 
@@ -378,21 +382,22 @@ function_draw (Function *pkg, DiaRenderer *renderer)
   text_draw (pkg->text, renderer);
 }
 
+
 static void
-function_update_data(Function *pkg)
+function_update_data (Function *pkg)
 {
   Element *elem = &pkg->element;
   DiaObject *obj = &elem->object;
   Point p1;
-  real h, w = 0, font_height;
+  double h, w = 0, font_height;
 
-  text_calc_boundingbox(pkg->text, NULL) ;
+  text_calc_boundingbox (pkg->text, NULL) ;
   font_height = pkg->text->height ;
   pkg->element.extra_spacing.border_trans = (font_height / FUNCTION_BORDERWIDTH_SCALE) / 2.0;
-  h = elem->corner.y + font_height/FUNCTION_MARGIN_Y;
+  h = elem->corner.y + (font_height / FUNCTION_MARGIN_Y);
 
   if (pkg->is_user) {
-    h += 2*font_height/FUNCTION_MARGIN_SCALE;
+    h += (2 * font_height) / FUNCTION_MARGIN_SCALE;
   }
 
   w = MAX(w, pkg->text->max_width);
@@ -415,42 +420,42 @@ function_update_data(Function *pkg)
   elem->height = h - elem->corner.y;
 
   /* Update connections: */
-  connpoint_update(&pkg->connections[0],
-                  elem->corner.x,
-                  elem->corner.y,
-                  DIR_NORTHWEST);
-  connpoint_update(&pkg->connections[1],
-                  elem->corner.x + elem->width / 2.0,
-                  elem->corner.y,
-                  DIR_NORTH);
-  connpoint_update(&pkg->connections[2],
-                  elem->corner.x + elem->width,
-                  elem->corner.y,
-                  DIR_NORTHEAST);
-  connpoint_update(&pkg->connections[3],
-                  elem->corner.x,
-                  elem->corner.y + elem->height / 2.0,
-                  DIR_WEST);
-  connpoint_update(&pkg->connections[4],
-                  elem->corner.x + elem->width,
-                  elem->corner.y + elem->height / 2.0,
-                  DIR_EAST);
-  connpoint_update(&pkg->connections[5],
-                  elem->corner.x,
-                  elem->corner.y + elem->height,
-                  DIR_SOUTHWEST);
-  connpoint_update(&pkg->connections[6],
-                  elem->corner.x + elem->width / 2.0,
-                  elem->corner.y + elem->height,
-                  DIR_SOUTH);
-  connpoint_update(&pkg->connections[7],
-                  elem->corner.x + elem->width,
-                  elem->corner.y + elem->height,
-                  DIR_SOUTHEAST);
-  connpoint_update(&pkg->connections[8],
-                  elem->corner.x + elem->width / 2.0,
-                  elem->corner.y + elem->height / 2.0,
-                  DIR_SOUTHEAST);
+  connpoint_update (&pkg->connections[0],
+                    elem->corner.x,
+                    elem->corner.y,
+                    DIR_NORTHWEST);
+  connpoint_update (&pkg->connections[1],
+                    elem->corner.x + elem->width / 2.0,
+                    elem->corner.y,
+                    DIR_NORTH);
+  connpoint_update (&pkg->connections[2],
+                    elem->corner.x + elem->width,
+                    elem->corner.y,
+                    DIR_NORTHEAST);
+  connpoint_update (&pkg->connections[3],
+                    elem->corner.x,
+                    elem->corner.y + elem->height / 2.0,
+                    DIR_WEST);
+  connpoint_update (&pkg->connections[4],
+                    elem->corner.x + elem->width,
+                    elem->corner.y + elem->height / 2.0,
+                    DIR_EAST);
+  connpoint_update (&pkg->connections[5],
+                    elem->corner.x,
+                    elem->corner.y + elem->height,
+                    DIR_SOUTHWEST);
+  connpoint_update (&pkg->connections[6],
+                    elem->corner.x + elem->width / 2.0,
+                    elem->corner.y + elem->height,
+                    DIR_SOUTH);
+  connpoint_update (&pkg->connections[7],
+                    elem->corner.x + elem->width,
+                    elem->corner.y + elem->height,
+                    DIR_SOUTHEAST);
+  connpoint_update (&pkg->connections[8],
+                    elem->corner.x + elem->width / 2.0,
+                    elem->corner.y + elem->height / 2.0,
+                    CP_FLAGS_MAIN);
 
   element_update_boundingbox(elem);
 
diff --git a/objects/GRAFCET/action.c b/objects/GRAFCET/action.c
index 6f074ad64..0643ca7f9 100644
--- a/objects/GRAFCET/action.c
+++ b/objects/GRAFCET/action.c
@@ -35,7 +35,7 @@
 #include "geometry.h"
 #include "text.h"
 #include "connpoint_line.h"
-
+#include "dia-graphene.h"
 #include "grafcet.h"
 #include "action_text_draw.h"
 
@@ -236,8 +236,9 @@ action_move(Action *action, Point *to)
   return NULL;
 }
 
+
 static void
-action_update_data(Action *action)
+action_update_data (Action *action)
 {
   Point p1,p2;
   real x,x1;
@@ -246,6 +247,7 @@ action_update_data(Action *action)
   real chunksize;
   Connection *conn = &action->connection;
   DiaObject *obj = &conn->object;
+  graphene_rect_t bbox, tmp;
 
   obj->position = conn->endpoints[0];
   connection_update_boundingbox(conn);
@@ -260,9 +262,9 @@ action_update_data(Action *action)
   if (action->macro_call) {
     action->labelstart.x += 2.0 * action->space_width;
   }
-  text_set_position(action->text,&action->labelstart);
+  text_set_position (action->text,&action->labelstart);
 
-  action_text_calc_boundingbox(action->text,&action->labelbb);
+  action_text_calc_boundingbox (action->text,&action->labelbb);
 
   if (action->macro_call) {
     action->labelbb.right += 2.0 * action->space_width;
@@ -282,10 +284,10 @@ action_update_data(Action *action)
   p1.x = conn->endpoints[1].x;
   p1.y = conn->endpoints[1].y - .5 * ACTION_HEIGHT;
   p2.y = p1.y + ACTION_HEIGHT;
-  connpointline_adjust_count(action->cps,2+(2 * action->text->numlines), &p1);
+  connpointline_adjust_count (action->cps,2+(2 * action->text->numlines), &p1);
 
   for (i=0; i<action->text->numlines; i++) {
-    chunksize = text_get_line_width(action->text, i);
+    chunksize = text_get_line_width (action->text, i);
     x1 = x + 1.0;
     if (x1 >= right) {
       x1 = right - ACTION_LINE_WIDTH;
@@ -312,7 +314,13 @@ action_update_data(Action *action)
   action->labelbb.bottom += ACTION_LINE_WIDTH/2;
   action->labelbb.right += ACTION_LINE_WIDTH/2;
 
-  rectangle_union(&obj->bounding_box,&action->labelbb);
+  dia_object_get_bounding_box (obj, &bbox);
+  dia_rectangle_to_graphene (&action->labelbb, &tmp);
+
+  graphene_rect_union (&bbox, &tmp, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
+
   connection_update_handles(conn);
 }
 
diff --git a/objects/GRAFCET/action_text_draw.c b/objects/GRAFCET/action_text_draw.c
index 71e4afb47..8c97c005f 100644
--- a/objects/GRAFCET/action_text_draw.c
+++ b/objects/GRAFCET/action_text_draw.c
@@ -40,17 +40,16 @@ void
 action_text_draw (Text *text, DiaRenderer *renderer)
 {
   Point pos;
-  int i;
-  real space_width;
+  double space_width;
 
   dia_renderer_set_font (renderer, text->font, text->height);
 
-  pos = text->position;
+  dia_text_get_position (text, &pos);
 
   space_width = action_text_spacewidth (text);
 
   /* TODO: Use the TextLine object when available for faster rendering. */
-  for (i=0;i<text->numlines;i++) {
+  for (int i = 0; i < text->numlines; i++) {
     dia_renderer_draw_string (renderer,
                               text_get_line (text, i),
                               &pos,
@@ -61,9 +60,9 @@ action_text_draw (Text *text, DiaRenderer *renderer)
   }
 
   if (DIA_IS_INTERACTIVE_RENDERER (renderer) && (text->focus.has_focus)) {
-    real curs_x, curs_y;
-    real str_width_first;
-    real str_width_whole;
+    double curs_x, curs_y;
+    double str_width_first;
+    double str_width_whole;
     Point p1, p2;
 
 
@@ -74,11 +73,11 @@ action_text_draw (Text *text, DiaRenderer *renderer)
                                                    text_get_line (text, text->cursor_row),
                                                    text_get_line_strlen (text, text->cursor_row));
 
-    curs_x = text->position.x + str_width_first;
-    for (i = 0; i < text->cursor_row; i++) {
+    curs_x = pos.x + str_width_first;
+    for (int i = 0; i < text->cursor_row; i++) {
       curs_x += text_get_line_width (text, i) + 2 * space_width;
     }
-    curs_y = text->position.y - text->ascent;
+    curs_y = pos.y - text->ascent;
 
     switch (text->alignment) {
       case ALIGN_LEFT:
@@ -108,10 +107,12 @@ action_text_draw (Text *text, DiaRenderer *renderer)
 void
 action_text_calc_boundingbox (Text *text, DiaRectangle *box)
 {
-  real width;
-  int i;
+  double width;
+  Point pos;
+
+  dia_text_get_position (text, &pos);
 
-  box->left = text->position.x;
+  box->left = pos.x;
   switch (text->alignment) {
     case ALIGN_LEFT:
       break;
@@ -126,7 +127,7 @@ action_text_calc_boundingbox (Text *text, DiaRectangle *box)
   }
 
   width = 0;
-  for (i = 0; i < text->numlines; i++) {
+  for (int i = 0; i < text->numlines; i++) {
     width += text_get_line_width (text, i);
   }
 
@@ -134,7 +135,7 @@ action_text_calc_boundingbox (Text *text, DiaRectangle *box)
 
   box->right = box->left + width;
 
-  box->top = text->position.y - text->ascent;
+  box->top = pos.y - text->ascent;
 
   box->bottom = box->top + text->height;
 }
diff --git a/objects/GRAFCET/condition.c b/objects/GRAFCET/condition.c
index d001041ec..a0a87484a 100644
--- a/objects/GRAFCET/condition.c
+++ b/objects/GRAFCET/condition.c
@@ -34,7 +34,7 @@
 #include "properties.h"
 #include "geometry.h"
 #include "text.h"
-
+#include "dia-graphene.h"
 #include "grafcet.h"
 #include "boolequation.h"
 
@@ -319,25 +319,34 @@ condition_move (Condition *condition, Point *to)
   return NULL;
 }
 
+
 static void
-condition_update_data(Condition *condition)
+condition_update_data (Condition *condition)
 {
   Connection *conn = &condition->connection;
   DiaObject *obj = &conn->object;
+  graphene_rect_t bbox, tmp;
 
   obj->position = conn->endpoints[0];
-  connection_update_boundingbox(conn);
+  connection_update_boundingbox (conn);
 
   /* compute the label's width and bounding box */
   condition->cond->pos.x = conn->endpoints[0].x +
-    (.5 * dia_font_string_width("a", condition->cond->font,
-                           condition->cond->fontheight));
+    (.5 * dia_font_string_width ("a",
+                                 condition->cond->font,
+                                 condition->cond->fontheight));
   condition->cond->pos.y = conn->endpoints[0].y + condition->cond->fontheight;
 
-  boolequation_calc_boundingbox(condition->cond, &condition->labelbb);
-  rectangle_union(&obj->bounding_box,&condition->labelbb);
+  boolequation_calc_boundingbox (condition->cond, &condition->labelbb);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  dia_rectangle_to_graphene (&condition->labelbb, &tmp);
+
+  graphene_rect_union (&bbox, &tmp, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 
-  connection_update_handles(conn);
+  connection_update_handles (conn);
 }
 
 
diff --git a/objects/GRAFCET/step.c b/objects/GRAFCET/step.c
index 756c99295..2720484ab 100644
--- a/objects/GRAFCET/step.c
+++ b/objects/GRAFCET/step.c
@@ -34,7 +34,7 @@
 #include "diarenderer.h"
 #include "attributes.h"
 #include "properties.h"
-
+#include "dia-graphene.h"
 #include "grafcet.h"
 
 #include "pixmaps/etape.xpm"
@@ -454,7 +454,9 @@ step_update_data (Step *step)
   Element *elem = &step->element;
   DiaObject *obj = &elem->object;
   ElementBBExtras *extra = &elem->extra_spacing;
-  Point *p,ulc;
+  Point *p, ulc;
+  graphene_rect_t bbox;
+  graphene_point_t pt;
 
   ulc = elem->corner;
   ulc.x += ((STEP_DECLAREDWIDTH - STEP_WIDTH) / 2.0); /* we cheat a little */
@@ -545,8 +547,13 @@ step_update_data (Step *step)
   }
 
   element_update_boundingbox (elem);
-  rectangle_add_point (&obj->bounding_box, &step->north.pos);
-  rectangle_add_point (&obj->bounding_box, &step->south.pos);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  dia_point_to_graphene (&step->north.pos, &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+  dia_point_to_graphene (&step->south.pos, &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 
   obj->position = elem->corner;
 
diff --git a/objects/GRAFCET/transition.c b/objects/GRAFCET/transition.c
index 3303636c9..82fb2da71 100644
--- a/objects/GRAFCET/transition.c
+++ b/objects/GRAFCET/transition.c
@@ -34,7 +34,7 @@
 #include "properties.h"
 #include "geometry.h"
 #include "text.h"
-
+#include "dia-graphene.h"
 #include "grafcet.h"
 #include "boolequation.h"
 
@@ -264,13 +264,25 @@ transition_update_data (Transition *transition)
 
   element_update_boundingbox (elem);
 
-  rectangle_add_point (&obj->bounding_box,&transition->north.pos);
-  rectangle_add_point (&obj->bounding_box,&transition->south.pos);
+  {
+    graphene_rect_t bbox, rect;
+    graphene_point_t pt;
+
+    dia_object_get_bounding_box (obj, &bbox);
+
+    dia_point_to_graphene (&transition->north.pos, &pt);
+    graphene_rect_expand (&bbox, &pt, &bbox);
+    dia_point_to_graphene (&transition->south.pos, &pt);
+    graphene_rect_expand (&bbox, &pt, &bbox);
 
-  /* compute the rcept's width and bounding box, then merge. */
-  boolequation_calc_boundingbox (transition->receptivity,
-                                 &transition->rceptbb);
-  rectangle_union (&obj->bounding_box, &transition->rceptbb);
+    /* compute the rcept's width and bounding box, then merge. */
+    boolequation_calc_boundingbox (transition->receptivity,
+                                   &transition->rceptbb);
+    dia_rectangle_to_graphene (&transition->rceptbb, &rect);
+    graphene_rect_union (&bbox, &rect, &bbox);
+
+    dia_object_set_bounding_box (obj, &bbox);
+  }
 
   element_update_handles (elem);
 }
diff --git a/objects/Istar/link.c b/objects/Istar/link.c
index 36fbc0ea8..79f21f3f7 100644
--- a/objects/Istar/link.c
+++ b/objects/Istar/link.c
@@ -37,6 +37,7 @@
 #include "arrows.h"
 #include "properties.h"
 #include "dia_image.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/link.xpm"  /* generic "unspecified" link */
 
@@ -195,12 +196,13 @@ link_set_props(Link *link, GPtrArray *props)
 }
 
 
-static real
-link_distance_from(Link *link, Point *point)
+static double
+link_distance_from (Link *link, Point *point)
 {
-  return distance_bez_line_point(link->line, 3, LINK_WIDTH, point);
+  return distance_bez_line_point (link->line, 3, LINK_WIDTH, point);
 }
 
+
 static void
 link_select(Link *link, Point *clicked_point,
            DiaRenderer *interactive_renderer)
@@ -259,24 +261,25 @@ link_move(Link *link, Point *to)
   return NULL;
 }
 
+
 static Point
-bezier_line_eval(BezPoint *line,int p,real u)
+bezier_line_eval (BezPoint *line, int p, float u)
 {
-  real bx[4],by[4];
+  double bx[4], by[4];
   Point res;
 
-  bx[0]=line[p-1].p3.x;
-  bx[1]=line[p].p1.x;
-  bx[2]=line[p].p2.x;
-  bx[3]=line[p].p3.x;
+  bx[0] = line[p-1].p3.x;
+  bx[1] = line[p].p1.x;
+  bx[2] = line[p].p2.x;
+  bx[3] = line[p].p3.x;
 
-  by[0]=line[p-1].p3.y;
-  by[1]=line[p].p1.y;
-  by[2]=line[p].p2.y;
-  by[3]=line[p].p3.y;
+  by[0] = line[p-1].p3.y;
+  by[1] = line[p].p1.y;
+  by[2] = line[p].p2.y;
+  by[3] = line[p].p3.y;
 
-  res.x=bezier_eval(bx,u);
-  res.y=bezier_eval(by,u);
+  res.x = bezier_eval (bx, u);
+  res.y = bezier_eval (by, u);
 
   return res;
 }
@@ -321,28 +324,31 @@ compute_annot(Point* p1, Point* p2, Point* pm, double f, double d)
   return res;
 }
 
+
 /* compute bezier for Dependency */
-static void compute_dependency(BezPoint *line, BezPoint *bpl) {
+static void
+compute_dependency (BezPoint *line, BezPoint *bpl)
+{
   Point ref;
-  double dx,dy,dxp,dyp,k;
-  real bx[4],by[4];
+  double dx, dy, dxp, dyp, k;
+  double bx[4], by[4];
 
   /* computing anchor point and tangent */
-  bx[0]=line[1].p3.x;
-  bx[1]=line[2].p1.x;
-  bx[2]=line[2].p2.x;
-  bx[3]=line[2].p3.x;
-
-  by[0]=line[1].p3.y;
-  by[1]=line[2].p1.y;
-  by[2]=line[2].p2.y;
-  by[3]=line[2].p3.y;
-
-  ref.x=bezier_eval(bx,0.25);
-  ref.y=bezier_eval(by,0.25);
-  dx=bezier_eval_tangent(bx,0.25);
-  dy=bezier_eval_tangent(by,0.25);
-  k=sqrt(dx*dx+dy*dy);
+  bx[0] = line[1].p3.x;
+  bx[1] = line[2].p1.x;
+  bx[2] = line[2].p2.x;
+  bx[3] = line[2].p3.x;
+
+  by[0] = line[1].p3.y;
+  by[1] = line[2].p1.y;
+  by[2] = line[2].p2.y;
+  by[3] = line[2].p3.y;
+
+  ref.x = bezier_eval (bx, 0.25);
+  ref.y = bezier_eval (by, 0.25);
+  dx = bezier_eval_tangent (bx, 0.25);
+  dy = bezier_eval_tangent (by, 0.25);
+  k = sqrt (dx * dx + dy * dy);
 
   /* normalizing */
   if (k!=0) {
@@ -603,13 +609,15 @@ link_destroy(Link *link)
   connection_destroy(&link->connection);
 }
 
+
 static void
-link_update_data(Link *link)
+link_update_data (Link *link)
 {
   Connection *conn = &link->connection;
   DiaObject *obj = &conn->object;
-  DiaRectangle rect;
-  Point p1,p2,p3,p4,pa;
+  Point p1, p2, p3, p4, pa;
+  graphene_rect_t bbox, rect;
+  graphene_point_t pt;
 
 /* Too complex to easily decide */
 /*
@@ -622,44 +630,52 @@ link_update_data(Link *link)
 
   link->pm_handle.pos = link->pm;
 
-  connection_update_handles(conn);
-  connection_update_boundingbox(conn);
+  connection_update_handles (conn);
+  connection_update_boundingbox (conn);
 
   /* endpoint */
   p1 = conn->endpoints[0];
   p2 = conn->endpoints[1];
 
   /* bezier */
-  compute_line(&p1,&p2,&link->pm,link->line);
+  compute_line (&p1, &p2, &link->pm, link->line);
 
   /* connection point */
-  link->connector.pos.x=p1.x;
-  link->connector.pos.y=p1.y;
+  link->connector.pos.x = p1.x;
+  link->connector.pos.y = p1.y;
+
+  dia_object_get_bounding_box (obj, &bbox);
 
   /* Update boundingbox for mid-point (TBD is this necessary ?) */
-  rectangle_add_point(&obj->bounding_box, &link->pm);
+  dia_point_to_graphene (&link->pm, &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
 
   /* Add boundingbox for annotation text (over-estimated) : */
-  pa=compute_annot(&p1,&p2,&link->pm,0.75,0.75);
-  rect.left = pa.x-0.3;
-  rect.right = rect.left+0.6;
-  rect.top = pa.y - LINK_FONTHEIGHT;
-  rect.bottom = rect.top + 2*LINK_FONTHEIGHT;
-  rectangle_union(&obj->bounding_box, &rect);
+  pa = compute_annot (&p1, &p2, &link->pm, 0.75, 0.75);
+
+  graphene_rect_init (&rect,
+                      pa.x - 0.3,
+                      pa.y - LINK_FONTHEIGHT,
+                      0.6,
+                      2 * LINK_FONTHEIGHT);
+  graphene_rect_union (&bbox, &rect, &bbox);
 
   /* Add boundingbox for dependency decoration (with some overestimation toi be safe) */
-  pa=bezier_line_eval(link->line,2,0.25);
-  p3.x=pa.x-LINK_DEP_WIDTH*1.5;
-  p3.y=pa.y-LINK_DEP_HEIGHT*1.5;
-  p4.x=p3.x+LINK_DEP_WIDTH*3;
-  p4.y=p3.y+LINK_DEP_HEIGHT*3;
-  rect.left=p3.x;
-  rect.right=p4.x;
-  rect.top=p3.y;
-  rect.bottom=p4.y;
-  rectangle_union(&obj->bounding_box, &rect);
+  pa = bezier_line_eval (link->line, 2, 0.25);
+  p3.x = pa.x - LINK_DEP_WIDTH * 1.5;
+  p3.y = pa.y - LINK_DEP_HEIGHT * 1.5;
+  p4.x = p3.x + LINK_DEP_WIDTH * 3;
+  p4.y = p3.y + LINK_DEP_HEIGHT * 3;
+
+  graphene_rect_init (&rect, p3.x, p3.y, 0, 0);
+  dia_point_to_graphene (&p4, &pt);
+  graphene_rect_expand (&rect, &pt, &rect);
+  graphene_rect_union (&bbox, &rect, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
+
 static DiaObject *
 link_load(ObjectNode obj_node, int version,DiaContext *ctx)
 {
diff --git a/objects/Jackson/phenomenon.c b/objects/Jackson/phenomenon.c
index 0bf609d0a..92e242635 100644
--- a/objects/Jackson/phenomenon.c
+++ b/objects/Jackson/phenomenon.c
@@ -41,7 +41,7 @@
 #include "handle.h"
 #include "arrows.h"
 #include "properties.h"
-
+#include "dia-graphene.h"
 #include "pixmaps/shared_phen.xpm"
 
 typedef struct _Message Message;
@@ -375,34 +375,42 @@ message_destroy(Message *message)
   g_clear_pointer (&message->text, g_free);
 }
 
+
 static void
-message_update_data(Message *message)
+message_update_data (Message *message)
 {
   Connection *conn = &message->connection;
   DiaObject *obj = &conn->object;
   DiaRectangle rect;
+  graphene_rect_t bbox, tmp;
 
-  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
-      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
-    connection_adjust_for_autogap(conn);
+  if (connpoint_is_autogap (conn->endpoint_handles[0].connected_to) ||
+      connpoint_is_autogap (conn->endpoint_handles[1].connected_to)) {
+    connection_adjust_for_autogap (conn);
   }
   obj->position = conn->endpoints[0];
 
   message->text_handle.pos = message->text_pos;
 
-  connection_update_handles(conn);
-  connection_update_boundingbox(conn);
+  connection_update_handles (conn);
+  connection_update_boundingbox (conn);
 
   message->text_width =
-    dia_font_string_width(message->text, message_font, MESSAGE_FONTHEIGHT);
+    dia_font_string_width (message->text, message_font, MESSAGE_FONTHEIGHT);
 
   /* Add boundingbox for text: */
   rect.left = message->text_pos.x-message->text_width/2;
   rect.right = rect.left + message->text_width;
   rect.top = message->text_pos.y -
-      dia_font_ascent(message->text, message_font, MESSAGE_FONTHEIGHT);
+      dia_font_ascent (message->text, message_font, MESSAGE_FONTHEIGHT);
   rect.bottom = rect.top + MESSAGE_FONTHEIGHT;
-  rectangle_union(&obj->bounding_box, &rect);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  dia_rectangle_to_graphene (&rect, &tmp);
+
+  graphene_rect_union (&bbox, &tmp, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
 
diff --git a/objects/Jackson/requirement.c b/objects/Jackson/requirement.c
index 0d975b6d7..98df0a62f 100644
--- a/objects/Jackson/requirement.c
+++ b/objects/Jackson/requirement.c
@@ -38,7 +38,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
-
+#include "dia-graphene.h"
 #include "pixmaps/requirement.xpm"
 
 typedef struct _Requirement Requirement;
@@ -248,15 +248,15 @@ req_draw (Requirement *req, DiaRenderer *renderer)
 
 
 static void
-req_update_data(Requirement *req)
+req_update_data (Requirement *req)
 {
-  real w, h, ratio;
+  double w, h, ratio;
   Point c, half, r,p;
-
   Element *elem = &req->element;
   DiaObject *obj = &elem->object;
+  graphene_rect_t bbox, rect;
 
-  text_calc_boundingbox(req->text, NULL);
+  text_calc_boundingbox (req->text, NULL);
   w = req->text->max_width;
   h = req->text->height*req->text->numlines;
 
@@ -314,23 +314,23 @@ req_update_data(Requirement *req)
   p = req->element.corner;
   p.x += req->element.width/2.0;
   p.y += (req->element.height - h)/2.0 + req->text->ascent;
-  text_set_position(req->text, &p);
+  text_set_position (req->text, &p);
 
-  element_update_boundingbox(elem);
+  element_update_boundingbox (elem);
 
   obj->position = elem->corner;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 
   /* Boundingbox calculation including the line width */
-  {
-    DiaRectangle bbox;
+  ellipse_bbox (&c, elem->width, elem->height, &elem->extra_spacing, &rect);
 
-    ellipse_bbox (&c, elem->width, elem->height, &elem->extra_spacing, &bbox);
-    rectangle_union(&obj->bounding_box, &bbox);
-  }
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &rect, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
+
 /** creation here */
 static DiaObject *
 req_create(Point *startpoint,
diff --git a/objects/KAOS/metaandorrel.c b/objects/KAOS/metaandorrel.c
index af518d44c..627b0d70b 100644
--- a/objects/KAOS/metaandorrel.c
+++ b/objects/KAOS/metaandorrel.c
@@ -43,7 +43,7 @@
 #include "arrows.h"
 #include "properties.h"
 #include "dia_image.h"
-
+#include "dia-graphene.h"
 #include "pixmaps/contributes.xpm"
 
 typedef struct _Maor Maor;
@@ -577,27 +577,29 @@ maor_destroy(Maor *maor)
   g_clear_pointer (&maor->text, g_free);
 }
 
+
 static void
-maor_update_data(Maor *maor)
+maor_update_data (Maor *maor)
 {
   Connection *conn = &maor->connection;
   DiaObject *obj = &conn->object;
-  DiaRectangle rect;
-  Point p1,p2,p3,p4;
+  graphene_rect_t bbox, rect;
+  graphene_point_t pt;
+  Point p1, p2, p3, p4;
 
-  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
-      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
-    connection_adjust_for_autogap(conn);
+  if (connpoint_is_autogap (conn->endpoint_handles[0].connected_to) ||
+      connpoint_is_autogap (conn->endpoint_handles[1].connected_to)) {
+    connection_adjust_for_autogap (conn);
   }
   obj->position = conn->endpoints[0];
 
   maor->text_handle.pos = maor->text_pos;
 
-  connection_update_handles(conn);
-  connection_update_boundingbox(conn);
+  connection_update_handles (conn);
+  connection_update_boundingbox (conn);
 
   maor->text_width =
-    dia_font_string_width(maor->text, maor_font, MAOR_FONTHEIGHT);
+    dia_font_string_width (maor->text, maor_font, MAOR_FONTHEIGHT);
 
   /* endpoint */
   p1 = conn->endpoints[0];
@@ -607,39 +609,49 @@ maor_update_data(Maor *maor)
   maor->connector.pos.x=p1.x;
   maor->connector.pos.y=p1.y+MAOR_ICON_HEIGHT/2;
 
+  dia_object_get_bounding_box (obj, &bbox);
+
   /* Add boundingbox for mid image: */
-  p3.x=(p1.x+p2.x)/2.0-MAOR_ICON_WIDTH/2;
-  p3.y=(p1.y+p2.y)/2.0-MAOR_ICON_HEIGHT/2;
-  p4.x=p3.x+MAOR_ICON_WIDTH;
-  p4.y=p3.y+MAOR_ICON_HEIGHT;
-  rect.left=p3.x;
-  rect.right=p4.x;
-  rect.top=p3.y;
-  rect.bottom=p4.y;
-  rectangle_union(&obj->bounding_box, &rect);
+  p3.x = (p1.x + p2.x) / 2.0 - MAOR_ICON_WIDTH / 2;
+  p3.y = (p1.y + p2.y) / 2.0 - MAOR_ICON_HEIGHT / 2;
+  p4.x = p3.x + MAOR_ICON_WIDTH;
+  p4.y = p3.y + MAOR_ICON_HEIGHT;
+
+  graphene_rect_init (&rect, p3.x, p3.y, 0, 0);
+  dia_point_to_graphene (&p4, &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+  graphene_rect_union (&bbox, &rect, &bbox);
 
   /* Add boundingbox for end image: */
-  p3.x=p1.x-MAOR_REF_WIDTH*1.1/2;    /* 1.1 factor to be safe (fix for or) */
-  p3.y=p1.y-MAOR_REF_HEIGHT*1.1/2;
-  p4.x=p3.x+MAOR_REF_WIDTH*1.1;
-  p4.y=p3.y+MAOR_REF_HEIGHT*1.1;
-  rect.left=p3.x;
-  rect.right=p4.x;
-  rect.top=p3.y;
-  rect.bottom=p4.y;
-  rectangle_union(&obj->bounding_box, &rect);
+  p3.x = p1.x - MAOR_REF_WIDTH * 1.1 / 2; /* 1.1 factor to be safe (fix for or) */
+  p3.y = p1.y - MAOR_REF_HEIGHT * 1.1 / 2;
+  p4.x = p3.x + MAOR_REF_WIDTH * 1.1;
+  p4.y = p3.y + MAOR_REF_HEIGHT * 1.1;
+
+  graphene_rect_init (&rect, p3.x, p3.y, 0, 0);
+  dia_point_to_graphene (&p4, &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+  graphene_rect_union (&bbox, &rect, &bbox);
 
   /* Add boundingbox for text: */
-  rect.left = maor->text_pos.x-maor->text_width/2;
-  rect.right = rect.left + maor->text_width;
-  rect.top = maor->text_pos.y - dia_font_ascent(maor->text, maor_font, MAOR_FONTHEIGHT);
-  rect.bottom = rect.top + MAOR_FONTHEIGHT;
-  rectangle_union(&obj->bounding_box, &rect);
+  graphene_rect_init (&rect,
+                      maor->text_pos.x - maor->text_width / 2,
+                      maor->text_pos.y - dia_font_ascent (maor->text,
+                                                          maor_font,
+                                                          MAOR_FONTHEIGHT),
+                      maor->text_width,
+                      MAOR_FONTHEIGHT);
+  graphene_rect_union (&bbox, &rect, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
+
 static DiaObject *
-maor_load(ObjectNode obj_node, int version,DiaContext *ctx)
+maor_load (ObjectNode obj_node, int version, DiaContext *ctx)
 {
-  return object_load_using_properties(&kaos_maor_type,
-                                      obj_node,version,ctx);
+  return object_load_using_properties (&kaos_maor_type,
+                                       obj_node,
+                                       version,
+                                       ctx);
 }
diff --git a/objects/KAOS/metabinrel.c b/objects/KAOS/metabinrel.c
index d491555dd..3f04943cf 100644
--- a/objects/KAOS/metabinrel.c
+++ b/objects/KAOS/metabinrel.c
@@ -43,7 +43,7 @@
 #include "arrows.h"
 #include "properties.h"
 #include "dia_image.h"
-
+#include "dia-graphene.h"
 #include "pixmaps/contributes.xpm"
 
 typedef struct _Mbr Mbr;
@@ -545,12 +545,14 @@ mbr_destroy(Mbr *mbr)
   connection_destroy(&mbr->connection);
 }
 
+
 static void
-mbr_update_data(Mbr *mbr)
+mbr_update_data (Mbr *mbr)
 {
   Connection *conn = &mbr->connection;
   DiaObject *obj = &conn->object;
-  DiaRectangle rect;
+  graphene_rect_t bbox, rect;
+  graphene_point_t pt;
   Point p1,p2;
   Point p3,p4;
   char *text;
@@ -566,42 +568,49 @@ mbr_update_data(Mbr *mbr)
 
   mbr->pm_handle.pos = mbr->pm;
 
-  connection_update_handles(conn);
-  connection_update_boundingbox(conn);
+  connection_update_handles (conn);
+  connection_update_boundingbox (conn);
 
   /* text width */
-  text=compute_text(mbr);
-  mbr->text_width = dia_font_string_width(text, mbr_font, MBR_DECFONTHEIGHT);
-  mbr->text_ascent = dia_font_ascent(text, mbr_font, MBR_DECFONTHEIGHT);
+  text = compute_text (mbr);
+  mbr->text_width = dia_font_string_width (text, mbr_font, MBR_DECFONTHEIGHT);
+  mbr->text_ascent = dia_font_ascent (text, mbr_font, MBR_DECFONTHEIGHT);
 
   /* endpoint */
   p1 = conn->endpoints[0];
   p2 = conn->endpoints[1];
 
- /* bezier */
-  compute_line(&p1,&p2,&mbr->pm,mbr->line);
+  /* bezier */
+  compute_line (&p1, &p2, &mbr->pm, mbr->line);
+
+  dia_object_get_bounding_box (obj, &bbox);
 
   /* Add boundingbox for mid decoration (slightly overestimated) : */
-  p3.x=mbr->pm.x-MBR_DEC_SIZE;
-  p3.y=mbr->pm.y-MBR_DEC_SIZE;
-  p4.x=p3.x+MBR_DEC_SIZE*2;
-  p4.y=p3.y+MBR_DEC_SIZE*2;
-  rect.left=p3.x;
-  rect.right=p4.x;
-  rect.top=p3.y;
-  rect.bottom=p4.y;
-  rectangle_union(&obj->bounding_box, &rect);
+  p3.x = mbr->pm.x - MBR_DEC_SIZE;
+  p3.y = mbr->pm.y - MBR_DEC_SIZE;
+  p4.x = p3.x + MBR_DEC_SIZE * 2;
+  p4.y = p3.y + MBR_DEC_SIZE * 2;
+
+  graphene_rect_init (&rect, p3.x, p3.y, 0, 0);
+  dia_point_to_graphene (&p4, &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+
+  graphene_rect_union (&bbox, &rect, &bbox);
 
   /* Add boundingbox for text: */
-  rect.left = mbr->pm.x-mbr->text_width/2;
-  rect.right = rect.left + mbr->text_width;
-  rect.top = mbr->pm.y - mbr->text_ascent;
-  rect.bottom = rect.top + MBR_DECFONTHEIGHT;
-  rectangle_union(&obj->bounding_box, &rect);
+  graphene_rect_init (&rect,
+                      mbr->pm.x - mbr->text_width / 2,
+                      mbr->pm.y - mbr->text_ascent,
+                      mbr->text_width,
+                      MBR_DECFONTHEIGHT);
+  graphene_rect_union (&bbox, &rect, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 
   g_clear_pointer (&text, g_free);   /* free auxilliary text */
 }
 
+
 static DiaObject *
 mbr_load(ObjectNode obj_node, int version,DiaContext *ctx)
 {
diff --git a/objects/Misc/analog_clock.c b/objects/Misc/analog_clock.c
index f5f218a07..09c90118e 100644
--- a/objects/Misc/analog_clock.c
+++ b/objects/Misc/analog_clock.c
@@ -36,9 +36,10 @@
 #include "color.h"
 #include "properties.h"
 #include "dynamic_obj.h"
-
+#include "dia-graphene.h"
 #include "pixmaps/analog_clock.xpm"
 
+
 typedef struct _Chronoline {
   Element element;
 
@@ -187,13 +188,20 @@ analog_clock_set_props(Analog_Clock *analog_clock, GPtrArray *props)
   analog_clock_update_data(analog_clock);
 }
 
-static real
-analog_clock_distance_from(Analog_Clock *analog_clock, Point *point)
+
+static double
+analog_clock_distance_from (Analog_Clock *analog_clock, Point *point)
 {
-  DiaObject *obj = &analog_clock->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (analog_clock), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 analog_clock_select(Analog_Clock *analog_clock, Point *clicked_point,
                    DiaRenderer *interactive_renderer)
diff --git a/objects/Misc/diagram_as_object.c b/objects/Misc/diagram_as_object.c
index 92580a09f..392d6cb92 100644
--- a/objects/Misc/diagram_as_object.c
+++ b/objects/Misc/diagram_as_object.c
@@ -42,6 +42,7 @@
 
 #include "filter.h"
 #include "dia_image.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/diagram_as_element.xpm"
 
@@ -139,12 +140,21 @@ _dae_set_props(DiagramAsElement *dae, GPtrArray *props)
   object_set_props_from_offsets(&dae->element.object, _dae_offsets, props);
   _dae_update_data(dae);
 }
-static real
-_dae_distance_from(DiagramAsElement *dae, Point *point)
+
+
+static double
+_dae_distance_from (DiagramAsElement *dae, Point *point)
 {
-  DiaObject *obj = &dae->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (dae), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
+
+
 static void
 _dae_select(DiagramAsElement *dae, Point *clicked_point, DiaRenderer *interactive_renderer)
 {
diff --git a/objects/Misc/grid_object.c b/objects/Misc/grid_object.c
index 2ee926058..b8f94cee2 100644
--- a/objects/Misc/grid_object.c
+++ b/objects/Misc/grid_object.c
@@ -36,6 +36,7 @@
 #include "attributes.h"
 #include "color.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/grid_object.xpm"
 
@@ -186,13 +187,20 @@ grid_object_set_props(Grid_Object *grid_object, GPtrArray *props)
   grid_object_update_data(grid_object);
 }
 
-static real
-grid_object_distance_from(Grid_Object *grid_object, Point *point)
+
+static double
+grid_object_distance_from (Grid_Object *grid_object, Point *point)
 {
-  DiaObject *obj = &grid_object->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (grid_object), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 grid_object_select(Grid_Object *grid_object, Point *clicked_point,
                    DiaRenderer *interactive_renderer)
@@ -231,38 +239,41 @@ inline static int grid_cell (int i, int j, int rows, int cols)
   return j * cols + i;
 }
 
+
 static void
-grid_object_update_data(Grid_Object *grid_object)
+grid_object_update_data (Grid_Object *grid_object)
 {
   Element *elem = &grid_object->element;
   DiaObject *obj = &elem->object;
   ElementBBExtras *extra = &elem->extra_spacing;
 
-  real inset = (grid_object->border_line_width - grid_object->gridline_width)/2.0;
-  real cell_width = (elem->width - 2.0 * inset) / grid_object->grid_cols;
-  real cell_height = (elem->height - 2.0 * inset) / grid_object->grid_rows;
+  double inset = (grid_object->border_line_width - grid_object->gridline_width) / 2.0;
+  double cell_width = (elem->width - 2.0 * inset) / grid_object->grid_cols;
+  double cell_height = (elem->height - 2.0 * inset) / grid_object->grid_rows;
   int i, j;
   double left, top;
 
   extra->border_trans = grid_object->border_line_width / 2.0;
-  element_update_boundingbox(elem);
-  element_update_handles(elem);
-  element_update_connections_rectangle(elem, grid_object->base_cps);
+  element_update_boundingbox (elem);
+  element_update_handles (elem);
+  element_update_connections_rectangle (elem, grid_object->base_cps);
 
   obj->position = elem->corner;
   left = obj->position.x;
   top = obj->position.y;
-  for (i = 0; i < grid_object->grid_cols; ++i)
-    for (j = 0; j < grid_object->grid_rows; ++j)
-    {
-      int cell = grid_cell(i, j, grid_object->grid_rows, grid_object->grid_cols);
+
+  for (i = 0; i < grid_object->grid_cols; ++i) {
+    for (j = 0; j < grid_object->grid_rows; ++j) {
+      int cell = grid_cell (i, j, grid_object->grid_rows, grid_object->grid_cols);
       grid_object->cells[cell].pos.x =
-                       left + inset + i*cell_width + cell_width/2.0;
+                left + inset + (i * cell_width) + (cell_width / 2.0);
       grid_object->cells[cell].pos.y =
-                       top + inset + j*cell_height + cell_height/2.0;
+                top + inset + (j * cell_height) + (cell_height / 2.0);
     }
+  }
 }
 
+
 static void
 grid_object_draw_gridlines (Grid_Object *grid_object,
                             DiaRenderer *renderer,
diff --git a/objects/Misc/measure.c b/objects/Misc/measure.c
index 1357cc324..937ba312c 100644
--- a/objects/Misc/measure.c
+++ b/objects/Misc/measure.c
@@ -204,22 +204,31 @@ static PropOffset measure_offsets[] = {
   { "line_colour", PROP_TYPE_COLOUR, offsetof(Measure, line_color) },
   { NULL, 0, 0 }
 };
+
 #define MEASURE_ARROW(measure) { ARROW_FILLED_TRIANGLE, measure->font_height, measure->font_height/2 }
-/*! Not in the object interface but very important anyway. Used to recalculate the object data after a 
change  */
+
+
+/**
+ * measure_update_data:
+ *
+ * Not in the object interface but very important anyway. Used to recalculate
+ * the object data after a change
+ */
 static void
 measure_update_data (Measure *measure)
 {
   Connection *conn = &measure->connection;
   DiaObject *obj = &measure->connection.object;
-  real value;
+  double value;
   Point *ends = measure->connection.endpoints;
   LineBBExtras *extra = &conn->extra_spacing;
-  DiaRectangle bbox;
-  Arrow arrow = MEASURE_ARROW(measure);
-  real ascent, width, theta;
+  Arrow arrow = MEASURE_ARROW (measure);
+  double ascent, width, theta;
+  graphene_rect_t bbox, rect;
+  graphene_vec2_t v1, v2;
 
   g_return_if_fail (obj->handles != NULL);
-  connection_update_handles(conn);
+  connection_update_handles (conn);
 
   extra->start_trans =
   extra->end_trans   =
@@ -245,21 +254,31 @@ measure_update_data (Measure *measure)
     measure->text_pos.y = (ends[0].y + ends[1].y) / 2 - cos(theta) * measure->font_height/2;
   }
 
-  line_bbox (&ends[0], &ends[0], &conn->extra_spacing,&conn->object.bounding_box);
-  arrow_bbox (&arrow, measure->line_width, &ends[0], &ends[1], &bbox);
-  rectangle_union(&obj->bounding_box, &bbox);
-  arrow_bbox (&arrow, measure->line_width, &ends[1], &ends[0], &bbox);
-  rectangle_union(&obj->bounding_box, &bbox);
+  graphene_vec2_init (&v1, ends[0].x, ends[0].y);
+  graphene_vec2_init (&v2, ends[0].x, ends[0].y);
 
-  bbox.left = measure->text_pos.x;
-  bbox.top = measure->text_pos.y - ascent;
-  bbox.bottom = bbox.top + measure->font_height;
-  bbox.right = bbox.left + width;
-  rectangle_union(&obj->bounding_box, &bbox);
+  line_bbox (&v1, &v2, &conn->extra_spacing, &bbox);
+
+  arrow_bbox (&arrow, measure->line_width, &ends[0], &ends[1], &rect);
+  graphene_rect_union (&bbox, &rect, &bbox);
+
+  arrow_bbox (&arrow, measure->line_width, &ends[1], &ends[0], &rect);
+  graphene_rect_union (&bbox, &rect, &bbox);
+
+  graphene_rect_init (&rect,
+                      measure->text_pos.x,
+                      measure->text_pos.y - ascent,
+                      width,
+                      measure->font_height);
+
+  graphene_rect_union (&bbox, &rect, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 
   obj->position = conn->endpoints[0];
 }
 
+
 static void
 measure_draw (Measure *measure, DiaRenderer *renderer)
 {
diff --git a/objects/Misc/n_gon.c b/objects/Misc/n_gon.c
index 93d579f37..8699dfa6e 100644
--- a/objects/Misc/n_gon.c
+++ b/objects/Misc/n_gon.c
@@ -476,17 +476,23 @@ _ngon_update_data (Ngon *ng)
       }
     }
   }
+
   /* update bounding box */
   {
     PolyBBExtras extra;
+    graphene_rect_t bbox;
+
     extra.start_trans = extra.end_trans = 0;
     extra.middle_trans = ng->line_width / 2.0;
     extra.start_long = extra.end_long = 0;
+
     polyline_bbox (&g_array_index (ng->points, Point, 0),
-                  ng->points->len,
-                  &extra, TRUE,
-                  &elem->object.bounding_box);
+                   ng->points->len,
+                   &extra, TRUE,
+                   &bbox);
+    dia_object_set_bounding_box (DIA_OBJECT (elem), &bbox);
   }
+
   elem->object.position = ng->center;
   ng->center_handle.pos = ng->center;
   ng->connections[NUM_CONNECTIONS-1].pos = ng->center;
diff --git a/objects/Misc/tree.c b/objects/Misc/tree.c
index d09d956f2..62e8d43c6 100644
--- a/objects/Misc/tree.c
+++ b/objects/Misc/tree.c
@@ -29,6 +29,7 @@
 #include "attributes.h"
 #include "properties.h"
 #include "diamenu.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/tree.xpm"
 
@@ -446,15 +447,17 @@ tree_copy(Tree *tree)
 
 
 static void
-tree_update_data(Tree *tree)
+tree_update_data (Tree *tree)
 {
   Connection *conn = &tree->connection;
   DiaObject *obj = &conn->object;
   int i;
   Point u, v, vhat;
   Point *endpoints;
-  real ulen;
-  real min_par, max_par;
+  double ulen;
+  double min_par, max_par;
+  graphene_rect_t bbox;
+  graphene_point_t pt;
 
 /*
  * This seems to break stuff wildly.
@@ -498,16 +501,26 @@ tree_update_data(Tree *tree)
   point_scale(&tree->real_ends[1], max_par);
   point_add(&tree->real_ends[1], &endpoints[0]);
 
-  connection_update_boundingbox(conn);
-  rectangle_add_point(&obj->bounding_box, &tree->real_ends[0]);
-  rectangle_add_point(&obj->bounding_box, &tree->real_ends[1]);
-  for (i=0;i<tree->num_handles;i++) {
-    rectangle_add_point(&obj->bounding_box, &tree->handles[i]->pos);
+  connection_update_boundingbox (conn);
+
+  dia_object_get_bounding_box (obj, &bbox);
+
+  dia_point_to_graphene (&tree->real_ends[0], &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+  dia_point_to_graphene (&tree->real_ends[1], &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+
+  for (i = 0; i < tree->num_handles; i++) {
+    dia_point_to_graphene (&tree->handles[i]->pos, &pt);
+    graphene_rect_expand (&bbox, &pt, &bbox);
   }
 
-  connection_update_handles(conn);
+  dia_object_set_bounding_box (obj, &bbox);
+
+  connection_update_handles (conn);
 }
 
+
 static void
 tree_add_handle(Tree *tree, Point *p, Handle *handle)
 {
diff --git a/objects/SADT/annotation.c b/objects/SADT/annotation.c
index b8d676917..8091ea9cd 100644
--- a/objects/SADT/annotation.c
+++ b/objects/SADT/annotation.c
@@ -36,6 +36,7 @@
 #include "arrows.h"
 #include "properties.h"
 #include "text.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/annotation.xpm"
 
@@ -186,19 +187,27 @@ annotation_set_props(Annotation *annotation, GPtrArray *props)
   annotation_update_data(annotation);
 }
 
-static real
-annotation_distance_from(Annotation *annotation, Point *point)
+
+static double
+annotation_distance_from (Annotation *annotation, Point *point)
 {
   Point *endpoints;
-  DiaRectangle bbox;
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
   endpoints = &annotation->connection.endpoints[0];
 
-  text_calc_boundingbox(annotation->text,&bbox);
-  return MIN(distance_line_point(&endpoints[0], &endpoints[1],
-                                ANNOTATION_LINE_WIDTH, point),
-            distance_rectangle_point(&bbox,point));
+  text_calc_boundingbox (annotation->text, &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return MIN (distance_line_point (&endpoints[0],
+                                   &endpoints[1],
+                                   ANNOTATION_LINE_WIDTH,
+                                   point),
+              distance_rectangle_point (&tmp, point));
 }
 
+
 static void
 annotation_select(Annotation *annotation, Point *clicked_point,
            DiaRenderer *interactive_renderer)
@@ -209,10 +218,14 @@ annotation_select(Annotation *annotation, Point *clicked_point,
   connection_update_handles(&annotation->connection);
 }
 
-static DiaObjectChange*
-annotation_move_handle(Annotation *annotation, Handle *handle,
-                      Point *to, ConnectionPoint *cp,
-                      HandleMoveReason reason, ModifierKeys modifiers)
+
+static DiaObjectChange *
+annotation_move_handle (Annotation       *annotation,
+                        Handle           *handle,
+                        Point            *to,
+                        ConnectionPoint  *cp,
+                        HandleMoveReason  reason,
+                        ModifierKeys      modifiers)
 {
   Point p1, p2;
   Point *endpoints;
@@ -223,38 +236,48 @@ annotation_move_handle(Annotation *annotation, Handle *handle,
   g_assert(to!=NULL);
 
   if (handle->id == HANDLE_MOVE_TEXT) {
-    annotation->text->position = *to;
-  } else  {
+    text_set_position (annotation->text, to);
+  } else {
     endpoints = &(conn->endpoints[0]);
+
     if (handle->id == HANDLE_MOVE_STARTPOINT) {
+      Point text_pos;
+
       p1 = endpoints[0];
-      connection_move_handle(conn, handle->id, to, cp, reason, modifiers);
-      connection_adjust_for_autogap(conn);
+      connection_move_handle (conn, handle->id, to, cp, reason, modifiers);
+      connection_adjust_for_autogap (conn);
+
       p2 = endpoints[0];
-      point_sub(&p2, &p1);
-      point_add(&annotation->text->position, &p2);
-      point_add(&p2,&(endpoints[1]));
-      connection_move_handle(conn, HANDLE_MOVE_ENDPOINT, &p2, NULL, reason, 0);
+      point_sub (&p2, &p1);
+      dia_text_get_position (annotation->text, &text_pos);
+      point_add (&text_pos, &p2);
+      point_add (&p2, &(endpoints[1]));
+      connection_move_handle (conn, HANDLE_MOVE_ENDPOINT, &p2, NULL, reason, 0);
     } else {
+      Point text_pos;
+
       p1 = endpoints[1];
-      connection_move_handle(conn, handle->id, to, cp, reason, modifiers);
-      connection_adjust_for_autogap(conn);
+      connection_move_handle (conn, handle->id, to, cp, reason, modifiers);
+      connection_adjust_for_autogap (conn);
+
       p2 = endpoints[1];
-      point_sub(&p2, &p1);
-      point_add(&annotation->text->position, &p2);
+      point_sub (&p2, &p1);
+      dia_text_get_position (annotation->text, &text_pos);
+      point_add (&text_pos, &p2);
     }
   }
-  annotation_update_data(annotation);
+  annotation_update_data (annotation);
 
   return NULL;
 }
 
+
 static DiaObjectChange*
-annotation_move(Annotation *annotation, Point *to)
+annotation_move (Annotation *annotation, Point *to)
 {
   Point start_to_end;
   Point *endpoints = &annotation->connection.endpoints[0];
-  Point delta;
+  Point delta, text_pos;
 
   delta = *to;
   point_sub(&delta, &endpoints[0]);
@@ -265,13 +288,16 @@ annotation_move(Annotation *annotation, Point *to)
   endpoints[1] = endpoints[0] = *to;
   point_add(&endpoints[1], &start_to_end);
 
-  point_add(&annotation->text->position, &delta);
+  dia_text_get_position (annotation->text, &text_pos);
+  point_add (&text_pos, &delta);
+  text_set_position (annotation->text, &text_pos);
 
-  annotation_update_data(annotation);
+  annotation_update_data (annotation);
 
   return NULL;
 }
 
+
 static void
 annotation_draw (Annotation *annotation, DiaRenderer *renderer)
 {
@@ -319,11 +345,12 @@ annotation_draw (Annotation *annotation, DiaRenderer *renderer)
   text_draw (annotation->text,renderer);
 }
 
+
 static DiaObject *
-annotation_create(Point *startpoint,
-                 void *user_data,
-                 Handle **handle1,
-                 Handle **handle2)
+annotation_create (Point   *startpoint,
+                   void    *user_data,
+                   Handle **handle1,
+                   Handle **handle2)
 {
   Annotation *annotation;
   Connection *conn;
@@ -331,9 +358,10 @@ annotation_create(Point *startpoint,
   DiaObject *obj;
   Point offs;
   Point defaultlen = { 1.0, 1.0 };
-  DiaFont* font;
+  DiaFont *font;
+  Point text_pos;
 
-  annotation = g_malloc0(sizeof(Annotation));
+  annotation = g_new0 (Annotation, 1);
 
   conn = &annotation->connection;
   conn->endpoints[0] = *startpoint;
@@ -359,11 +387,15 @@ annotation_create(Point *startpoint,
   g_clear_object (&font);
 
   offs.x = .3 * ANNOTATION_FONTHEIGHT;
-  if (conn->endpoints[1].y < conn->endpoints[0].y)
+  if (conn->endpoints[1].y < conn->endpoints[0].y) {
     offs.y = 1.3 * ANNOTATION_FONTHEIGHT;
-  else
+  } else {
     offs.y = -.3 * ANNOTATION_FONTHEIGHT;
-  point_add(&annotation->text->position,&offs);
+  }
+
+  dia_text_get_position (annotation->text, &text_pos);
+  point_add (&text_pos, &offs);
+  text_set_position (annotation->text, &text_pos);
 
   annotation->text_handle.id = HANDLE_MOVE_TEXT;
   annotation->text_handle.type = HANDLE_MINOR_CONTROL;
@@ -391,28 +423,33 @@ annotation_destroy(Annotation *annotation)
   text_destroy(annotation->text);
 }
 
+
 static void
-annotation_update_data(Annotation *annotation)
+annotation_update_data (Annotation *annotation)
 {
   Connection *conn = &annotation->connection;
   DiaObject *obj = &conn->object;
-  DiaRectangle textrect;
+  graphene_rect_t bbox, textrect;
 
-  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
-      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
-    connection_adjust_for_autogap(conn);
+  if (connpoint_is_autogap (conn->endpoint_handles[0].connected_to) ||
+      connpoint_is_autogap (conn->endpoint_handles[1].connected_to)) {
+    connection_adjust_for_autogap (conn);
   }
   obj->position = conn->endpoints[0];
 
-  annotation->text_handle.pos = annotation->text->position;
+  dia_text_get_position (annotation->text, &annotation->text_handle.pos);
 
-  connection_update_handles(conn);
+  connection_update_handles (conn);
 
-  connection_update_boundingbox(conn);
-  text_calc_boundingbox(annotation->text,&textrect);
-  rectangle_union(&obj->bounding_box, &textrect);
+  connection_update_boundingbox (conn);
+  text_calc_boundingbox (annotation->text, &textrect);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &textrect, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
+
 static DiaObject *
 annotation_load(ObjectNode obj_node, int version,DiaContext *ctx)
 {
diff --git a/objects/UML/activity.c b/objects/UML/activity.c
index b131316df..e0d49a65a 100644
--- a/objects/UML/activity.c
+++ b/objects/UML/activity.c
@@ -32,6 +32,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/activity.xpm"
 
@@ -164,13 +165,20 @@ state_set_props(State *state, GPtrArray *props)
   state_update_data(state);
 }
 
-static real
-state_distance_from(State *state, Point *point)
+
+static double
+state_distance_from (State *state, Point *point)
 {
-  DiaObject *obj = &state->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (state), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 state_select(State *state, Point *clicked_point,
               DiaRenderer *interactive_renderer)
diff --git a/objects/UML/actor.c b/objects/UML/actor.c
index 630a2fe17..98336c395 100644
--- a/objects/UML/actor.c
+++ b/objects/UML/actor.c
@@ -28,6 +28,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/actor.xpm"
 
@@ -162,13 +163,20 @@ actor_set_props(Actor *actor, GPtrArray *props)
   actor_update_data(actor);
 }
 
-static real
-actor_distance_from(Actor *actor, Point *point)
+
+static double
+actor_distance_from (Actor *actor, Point *point)
 {
-  DiaObject *obj = &actor->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (actor), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 actor_select(Actor *actor, Point *clicked_point,
               DiaRenderer *interactive_renderer)
@@ -286,46 +294,54 @@ actor_draw(Actor *actor, DiaRenderer *renderer)
   text_draw (actor->text, renderer);
 }
 
+
 static void
-actor_update_data(Actor *actor)
+actor_update_data (Actor *actor)
 {
   Element *elem = &actor->element;
   DiaObject *obj = &elem->object;
-  DiaRectangle text_box;
   Point p;
-  real actor_height;
+  double actor_height;
+  graphene_rect_t bbox, text_box;
 
-  text_calc_boundingbox(actor->text, &text_box);
+  text_calc_boundingbox (actor->text, &text_box);
 
   /* minimum size */
-  if (elem->width < ACTOR_WIDTH + ACTOR_MARGIN_X)
+  if (elem->width < ACTOR_WIDTH + ACTOR_MARGIN_X) {
     elem->width = ACTOR_WIDTH + ACTOR_MARGIN_X;
-  if (elem->height < ACTOR_HEIGHT + actor->text->height)
+  }
+
+  if (elem->height < ACTOR_HEIGHT + actor->text->height) {
     elem->height = ACTOR_HEIGHT + actor->text->height;
+  }
+
   actor_height = elem->height - actor->text->height;
 
   /* Update connections: */
-  element_update_connections_rectangle(elem, actor->connections);
+  element_update_connections_rectangle (elem, actor->connections);
 
-  element_update_boundingbox(elem);
+  element_update_boundingbox (elem);
 
   p = elem->corner;
   p.x += elem->width/2;
-  p.y +=  actor_height + actor->text->ascent;
-  text_set_position(actor->text, &p);
+  p.y += actor_height + actor->text->ascent;
+  text_set_position (actor->text, &p);
   /* may have moved */
-  text_calc_boundingbox(actor->text, &text_box);
+  text_calc_boundingbox (actor->text, &text_box);
 
   /* Add bounding box for text: */
-  rectangle_union(&obj->bounding_box, &text_box);
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &text_box, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 
   obj->position = elem->corner;
   obj->position.x += elem->width/2.0;
   obj->position.y += elem->height / 2.0;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 }
 
+
 static DiaObject *
 actor_create(Point *startpoint,
               void *user_data,
diff --git a/objects/UML/association.c b/objects/UML/association.c
index 9cd5bdd02..c41996bcb 100644
--- a/objects/UML/association.c
+++ b/objects/UML/association.c
@@ -63,6 +63,7 @@
 #include "uml.h"
 #include "properties.h"
 #include "dia-state-object-change.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/association.xpm"
 
@@ -611,40 +612,46 @@ association_set_state(Association *assoc, AssociationState *state)
   association_update_data(assoc);
 }
 
+
 static void
-association_update_data_end(Association *assoc, int endnum)
+association_update_data_end (Association *assoc, int endnum)
 {
   OrthConn *orth = &assoc->orth;
   DiaObject *obj = &orth->object;
   Point *points  = orth->points;
-  DiaRectangle rect;
   AssociationEnd *end;
   Orientation dir;
   int n = orth->numpoints - 1, fp, sp;
   Point dir_poly[3];
+  graphene_rect_t bbox, rect;
 
   /* Find the first and second points depending on which end: */
   if (endnum) {
-      fp = n;
-      sp = n-1;
-      dir = assoc->orth.orientation[n-1];
+    fp = n;
+    sp = n - 1;
+    dir = assoc->orth.orientation[n - 1];
   } else {
-      fp = 0;
-      sp = 1;
-      dir = assoc->orth.orientation[0];
+    fp = 0;
+    sp = 1;
+    dir = assoc->orth.orientation[0];
   }
 
   /* If the points are the same, find a better candidate: */
   if (points[fp].x == points[sp].x && points[fp].y == points[sp].y) {
-      sp += (endnum ? -1 : 1);
-      if (sp < 0)
-         sp = 0;
-      if (sp > n)
-         sp = n;
-      if (points[fp].y != points[sp].y)
-         dir = VERTICAL;
-      else
-         dir = HORIZONTAL;
+    sp += (endnum ? -1 : 1);
+    if (sp < 0) {
+      sp = 0;
+    }
+
+    if (sp > n) {
+      sp = n;
+    }
+
+    if (points[fp].y != points[sp].y) {
+      dir = VERTICAL;
+    } else {
+      dir = HORIZONTAL;
+    }
   }
 
   /* Update the text-points of the ends: */
@@ -682,24 +689,33 @@ association_update_data_end(Association *assoc, int endnum)
     default:
       g_return_if_reached ();
   }
+
+  dia_object_get_bounding_box (obj, &bbox);
+
   /* Add the text recangle to the bounding box: */
-  rect.left = end->text_pos.x
-      - (end->text_align == ALIGN_LEFT ? 0 : end->text_width);
-  rect.right = rect.left + end->text_width;
-  rect.top = end->text_pos.y - end->role_ascent;
-  rect.bottom = rect.top + 2*assoc->font_height;
+  graphene_rect_init (&rect,
+                      end->text_pos.x - (end->text_align == ALIGN_LEFT ? 0 : end->text_width),
+                      end->text_pos.y - end->role_ascent,
+                      end->text_width,
+                      2 * assoc->font_height);
 
-  rectangle_union(&obj->bounding_box, &rect);
+  graphene_rect_union (&bbox, &rect, &bbox);
 
   if (assoc_get_direction_poly (assoc, dir_poly)) {
-    int i;
-    for (i = 0; i < 3; ++i)
-      rectangle_add_point (&obj->bounding_box, &dir_poly[i]);
+    for (int i = 0; i < 3; ++i) {
+      graphene_point_t poly_pt;
+
+      dia_point_to_graphene (&dir_poly[i], &poly_pt);
+      graphene_rect_expand (&bbox, &poly_pt, &bbox);
+    }
   }
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
+
 static void
-association_update_data(Association *assoc)
+association_update_data (Association *assoc)
 {
         /* FIXME: The ascent and descent computation logic here is
            fundamentally slow. */
@@ -709,7 +725,7 @@ association_update_data(Association *assoc)
   PolyBBExtras *extra = &orth->extra_spacing;
   int num_segm, i;
   Point *points;
-  DiaRectangle rect;
+  graphene_rect_t bbox, rect;
   Orientation dir;
 
   orthconn_update_data(orth);
@@ -776,17 +792,22 @@ association_update_data(Association *assoc)
   }
 
   /* Add the text recangle to the bounding box: */
-  rect.left = assoc->text_pos.x;
-  if (assoc->text_align == ALIGN_CENTER)
-    rect.left -= assoc->text_width/2.0;
-  rect.right = rect.left + assoc->text_width;
-  rect.top = assoc->text_pos.y - assoc->ascent;
-  rect.bottom = rect.top + assoc->font_height;
+  graphene_rect_init (&rect,
+                      assoc->text_pos.x,
+                      assoc->text_pos.y - assoc->ascent,
+                      assoc->text_width,
+                      assoc->font_height);
+
+  if (assoc->text_align == ALIGN_CENTER) {
+    graphene_rect_offset (&rect, -(assoc->text_width / 2.0), 0);
+  }
 
-  rectangle_union(&obj->bounding_box, &rect);
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &rect, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 
-  association_update_data_end(assoc, 0);
-  association_update_data_end(assoc, 1);
+  association_update_data_end (assoc, 0);
+  association_update_data_end (assoc, 1);
 }
 
 
diff --git a/objects/UML/branch.c b/objects/UML/branch.c
index 4cf140781..90c4f4e21 100644
--- a/objects/UML/branch.c
+++ b/objects/UML/branch.c
@@ -32,6 +32,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "uml.h"
 
@@ -149,13 +150,20 @@ branch_set_props(Branch *branch, GPtrArray *props)
   branch_update_data(branch);
 }
 
-static real
-branch_distance_from(Branch *branch, Point *point)
+
+static double
+branch_distance_from (Branch *branch, Point *point)
 {
-  DiaObject *obj = &branch->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (branch), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 branch_select(Branch *branch, Point *clicked_point, DiaRenderer *interactive_renderer)
 {
diff --git a/objects/UML/class.c b/objects/UML/class.c
index b71d737cc..c05d62534 100644
--- a/objects/UML/class.c
+++ b/objects/UML/class.c
@@ -36,6 +36,7 @@
 #include "diamenu.h"
 #include "class.h"
 #include "dia-state-object-change.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/umlclass.xpm"
 
@@ -522,13 +523,20 @@ umlclass_set_props(UMLClass *umlclass, GPtrArray *props)
 #endif
 }
 
-static real
-umlclass_distance_from(UMLClass *umlclass, Point *point)
+
+static double
+umlclass_distance_from (UMLClass *umlclass, Point *point)
 {
-  DiaObject *obj = &umlclass->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (umlclass), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 umlclass_select(UMLClass *umlclass, Point *clicked_point,
               DiaRenderer *interactive_renderer)
@@ -1259,17 +1267,18 @@ umlclass_draw (UMLClass *umlclass, DiaRenderer *renderer)
   }
 }
 
+
 void
-umlclass_update_data(UMLClass *umlclass)
+umlclass_update_data (UMLClass *umlclass)
 {
   Element *elem = &umlclass->element;
   DiaObject *obj = &elem->object;
-  real x,y;
+  double x,y;
   GList *list;
   int i;
   int pointswide;
   int lowerleftcorner;
-  real pointspacing;
+  double pointspacing;
 
   x = elem->corner.x;
   y = elem->corner.y;
@@ -1378,42 +1387,59 @@ umlclass_update_data(UMLClass *umlclass)
     op->right_connection->directions = DIR_EAST;
 
     if (op->needs_wrapping) { /* Wrapped */
-      int lines = g_list_length(op->wrappos);
+      int lines = g_list_length (op->wrappos);
       y += umlclass->font_height * lines;
     } else {
       y += umlclass->font_height;
     }
+
     if (umlclass->visible_comments && op->comment != NULL && op->comment[0] != '\0') {
       int NumberOfLines = 0;
       char *CommentString = 0;
 
-      CommentString =
-        uml_create_documentation_tag(op->comment, umlclass->comment_tagging, umlclass->comment_line_length, 
&NumberOfLines);
+      CommentString = uml_create_documentation_tag (op->comment,
+                                                    umlclass->comment_tagging,
+                                                    umlclass->comment_line_length,
+                                                    &NumberOfLines);
       g_clear_pointer (&CommentString, g_free);
-      y += umlclass->comment_font_height*NumberOfLines + umlclass->comment_font_height/2;
+      y += (umlclass->comment_font_height * NumberOfLines) + (umlclass->comment_font_height / 2);
     }
-    list = g_list_next(list);
+
+    list = g_list_next (list);
   }
 
-  element_update_boundingbox(elem);
+  element_update_boundingbox (elem);
 
   if (umlclass->template) {
+    graphene_rect_t bbox;
+    graphene_point_t pt;
+
     /* fix boundingumlclass for templates: */
-    obj->bounding_box.top -= (umlclass->templates_height  - UMLCLASS_TEMPLATE_OVERLAY_Y) ;
-    obj->bounding_box.right += (umlclass->templates_width - UMLCLASS_TEMPLATE_OVERLAY_X);
-    obj->bounding_box.left  -= (elem->width < UMLCLASS_TEMPLATE_OVERLAY_X) ?
-                               (UMLCLASS_TEMPLATE_OVERLAY_X - elem->width) : 0;
+    dia_object_get_bounding_box (DIA_OBJECT (umlclass), &bbox);
+
+    graphene_rect_get_top_right (&bbox, &pt);
+    pt.y -= (umlclass->templates_height - UMLCLASS_TEMPLATE_OVERLAY_Y);
+    pt.x += (umlclass->templates_width - UMLCLASS_TEMPLATE_OVERLAY_X);
+    graphene_rect_expand (&bbox, &pt, &bbox);
+
+    graphene_rect_get_top_left (&bbox, &pt);
+    pt.x -= (elem->width < UMLCLASS_TEMPLATE_OVERLAY_X) ?
+                (UMLCLASS_TEMPLATE_OVERLAY_X - elem->width) : 0;
+    graphene_rect_expand (&bbox, &pt, &bbox);
+
+    dia_object_set_bounding_box (DIA_OBJECT (umlclass), &bbox);
   }
 
   obj->position = elem->corner;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 
 #ifdef DEBUG
   umlclass_sanity_check(umlclass, "After updating data");
 #endif
 }
 
+
 /**
  * Calculate the dimensions of the class icons namebox for a given object of UMLClass.
  * The height is stored in the class structure. When calculating the
diff --git a/objects/UML/classicon.c b/objects/UML/classicon.c
index b2a8b4b4e..70e691158 100644
--- a/objects/UML/classicon.c
+++ b/objects/UML/classicon.c
@@ -30,6 +30,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "uml.h"
 
@@ -189,13 +190,20 @@ classicon_set_props(Classicon *classicon, GPtrArray *props)
   classicon_update_data(classicon);
 }
 
-static real
-classicon_distance_from(Classicon *cicon, Point *point)
+
+static double
+classicon_distance_from (Classicon *cicon, Point *point)
 {
-  DiaObject *obj = &cicon->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (cicon), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 classicon_select(Classicon *cicon, Point *clicked_point,
                 DiaRenderer *interactive_renderer)
@@ -236,13 +244,13 @@ classicon_move(Classicon *cicon, Point *to)
   return NULL;
 }
 
+
 static void
 classicon_draw (Classicon *icon, DiaRenderer *renderer)
 {
   Element *elem;
-  real r, x, y, w;
+  double r, x, y, w;
   Point center, p1, p2;
-  int i;
 
   assert(icon != NULL);
   assert(renderer != NULL);
@@ -254,11 +262,11 @@ classicon_draw (Classicon *icon, DiaRenderer *renderer)
   w = elem->width;
 
   r = CLASSICON_RADIOUS;
-  center.x = x + elem->width/2;
+  center.x = x + elem->width / 2;
   center.y = y + r + CLASSICON_ARROW;
 
   if (icon->stereotype==CLASSICON_BOUNDARY) {
-    center.x += r/2.0;
+    center.x += r / 2.0;
   }
 
   dia_renderer_set_fillstyle (renderer, FILLSTYLE_SOLID);
@@ -317,13 +325,16 @@ classicon_draw (Classicon *icon, DiaRenderer *renderer)
   text_draw (icon->text, renderer);
 
   if (icon->is_object) {
+    Point text_pos;
+
     dia_renderer_set_linewidth (renderer, 0.01);
-    if (icon->stereotype==CLASSICON_BOUNDARY) {
+    if (icon->stereotype == CLASSICON_BOUNDARY) {
       x += r/2.0;
     }
-    p1.y = p2.y = icon->text->position.y + text_get_descent (icon->text);
-    for (i=0; i<icon->text->numlines; i++) {
-      p1.x = x + (w - text_get_line_width (icon->text, i))/2;
+    dia_text_get_position (icon->text, &text_pos);
+    p1.y = p2.y = text_pos.y + text_get_descent (icon->text);
+    for (int i = 0; i < icon->text->numlines; i++) {
+      p1.x = x + (w - text_get_line_width (icon->text, i)) / 2;
       p2.x = p1.x + text_get_line_width (icon->text, i);
       dia_renderer_draw_line (renderer,
                               &p1, &p2,
@@ -333,6 +344,7 @@ classicon_draw (Classicon *icon, DiaRenderer *renderer)
   }
 }
 
+
 static void
 classicon_update_data(Classicon *cicon)
 {
diff --git a/objects/UML/component.c b/objects/UML/component.c
index dde444d0c..9251f17e2 100644
--- a/objects/UML/component.c
+++ b/objects/UML/component.c
@@ -270,7 +270,7 @@ component_draw (Component *cmp, DiaRenderer *renderer)
 
   if (cmp->st_stereotype != NULL &&
       cmp->st_stereotype[0] != '\0') {
-    p1 = cmp->text->position;
+    dia_text_get_position (cmp->text, &p1);
     p1.y -= cmp->text->height;
     dia_renderer_set_font (renderer, cmp->text->font, cmp->text->height);
     dia_renderer_draw_string (renderer,
diff --git a/objects/UML/component_feature.c b/objects/UML/component_feature.c
index 40778fb85..90c1601a7 100644
--- a/objects/UML/component_feature.c
+++ b/objects/UML/component_feature.c
@@ -38,6 +38,7 @@
 #include "properties.h"
 #include "text.h"
 #include "arrows.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/facet.xpm"
 
@@ -311,13 +312,15 @@ compfeat_move (Compfeat *compfeat, Point *to)
 {
   DiaObjectChange *change;
   Point delta = *to;
+  Point text_pos;
 
   delta = *to;
-  point_sub(&delta, &compfeat->orth.points[0]);
+  point_sub (&delta, &compfeat->orth.points[0]);
 
   /* I don't understand this, but the text position is wrong directly
      after compfeat_create()! */
-  point_add(&delta, &compfeat->text->position);
+  dia_text_get_position (compfeat->text, &text_pos);
+  point_add (&delta, &text_pos);
   text_set_position(compfeat->text, &delta);
   change = orthconn_move(&compfeat->orth, to);
   compfeat_update_data(compfeat);
@@ -444,15 +447,16 @@ compfeat_destroy(Compfeat *compfeat)
   orthconn_destroy(&compfeat->orth);
 }
 
+
 static void
-compfeat_update_data(Compfeat *compfeat)
+compfeat_update_data (Compfeat *compfeat)
 {
   OrthConn *orth = &compfeat->orth;
   PolyBBExtras *extra = &orth->extra_spacing;
   int n;
   DiaObject *obj = &orth->object;
-  DiaRectangle rect;
   Point *points;
+  graphene_rect_t bbox, rect;
 
   points = &orth->points[0];
   n = orth->numpoints;
@@ -463,9 +467,10 @@ compfeat_update_data(Compfeat *compfeat)
       || compfeat->role == COMPPROP_EVENTSOURCE)
     compfeat->cp.pos = points[n - 1];
 
-  compfeat->text_pos = compfeat->text_handle.pos = compfeat->text->position;
+  dia_text_get_position (compfeat->text, &compfeat->text_pos);
+  dia_text_get_position (compfeat->text, &compfeat->text_handle.pos);
 
-  orthconn_update_data(orth);
+  orthconn_update_data (orth);
 
   /* Boundingbox: */
   extra->start_long =
@@ -473,11 +478,15 @@ compfeat_update_data(Compfeat *compfeat)
     extra->end_long = compfeat->line_width + COMPPROP_DIAMETER;
   extra->end_trans = compfeat->line_width + COMPPROP_DIAMETER;
 
-  orthconn_update_boundingbox(orth);
-  text_calc_boundingbox(compfeat->text, &rect);
-  rectangle_union(&obj->bounding_box, &rect);
+  orthconn_update_boundingbox (orth);
+  text_calc_boundingbox (compfeat->text, &rect);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &rect, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
+
 static DiaObject *
 compfeat_load(ObjectNode obj_node, int version,DiaContext *ctx)
 {
diff --git a/objects/UML/constraint.c b/objects/UML/constraint.c
index b39b2cd82..5320fbdb3 100644
--- a/objects/UML/constraint.c
+++ b/objects/UML/constraint.c
@@ -31,6 +31,7 @@
 #include "properties.h"
 #include "stereotype.h"
 #include "attributes.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/constraint.xpm"
 
@@ -342,36 +343,38 @@ constraint_destroy (Constraint *constraint)
   g_clear_pointer (&constraint->text, g_free);
 }
 
+
 static void
-constraint_update_data(Constraint *constraint)
+constraint_update_data (Constraint *constraint)
 {
   Connection *conn = &constraint->connection;
   DiaObject *obj = &conn->object;
   DiaRectangle rect;
   LineBBExtras *extra;
+  graphene_rect_t bbox, tmp;
 
   if ((constraint->text) && (constraint->text[0] == '{')) {
     /* we might have a string loaded from an older dia. Clean it up. */
     g_clear_pointer (&constraint->brtext, g_free);
     constraint->brtext = constraint->text;
-    constraint->text = bracketted_to_string(constraint->text,"{","}");
+    constraint->text = bracketted_to_string (constraint->text, "{", "}");
   } else if (!constraint->brtext) {
-    constraint->brtext = string_to_bracketted(constraint->text, "{", "}");
+    constraint->brtext = string_to_bracketted (constraint->text, "{", "}");
   }
 
-  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
-      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
-    connection_adjust_for_autogap(conn);
+  if (connpoint_is_autogap (conn->endpoint_handles[0].connected_to) ||
+      connpoint_is_autogap (conn->endpoint_handles[1].connected_to)) {
+    connection_adjust_for_autogap (conn);
   }
   obj->position = conn->endpoints[0];
 
-  constraint->text_width = dia_font_string_width(constraint->brtext,
-                                                 constraint->font,
-                                                 constraint->font_height);
+  constraint->text_width = dia_font_string_width (constraint->brtext,
+                                                  constraint->font,
+                                                  constraint->font_height);
 
   constraint->text_handle.pos = constraint->text_pos;
 
-  connection_update_handles(conn);
+  connection_update_handles (conn);
 
   /* Boundingbox: */
   extra = &conn->extra_spacing;
@@ -379,18 +382,25 @@ constraint_update_data(Constraint *constraint)
   extra->start_long =
     extra->start_trans =
     extra->end_long = constraint->line_width/2.0;
-  extra->end_trans = MAX(constraint->line_width,CONSTRAINT_ARROWLEN)/2.0;
+  extra->end_trans = MAX (constraint->line_width, CONSTRAINT_ARROWLEN)/2.0;
 
-  connection_update_boundingbox(conn);
+  connection_update_boundingbox (conn);
 
   /* Add boundingbox for text: */
   rect.left = constraint->text_pos.x;
   rect.right = rect.left + constraint->text_width;
   rect.top = constraint->text_pos.y -
-      dia_font_ascent(constraint->brtext,
-                      constraint->font, constraint->font_height);
+      dia_font_ascent (constraint->brtext,
+                       constraint->font,
+                       constraint->font_height);
   rect.bottom = rect.top + constraint->font_height;
-  rectangle_union(&obj->bounding_box, &rect);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  dia_rectangle_to_graphene (&rect, &tmp);
+
+  graphene_rect_union (&bbox, &tmp, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
 
diff --git a/objects/UML/dependency.c b/objects/UML/dependency.c
index a1869f792..25ed57837 100644
--- a/objects/UML/dependency.c
+++ b/objects/UML/dependency.c
@@ -30,6 +30,7 @@
 #include "arrows.h"
 
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "stereotype.h"
 #include "uml.h"
@@ -283,8 +284,9 @@ dependency_draw (Dependency *dep, DiaRenderer *renderer)
   }
 }
 
+
 static void
-dependency_update_data(Dependency *dep)
+dependency_update_data (Dependency *dep)
 {
   OrthConn *orth = &dep->orth;
   DiaObject *obj = &orth->object;
@@ -292,22 +294,27 @@ dependency_update_data(Dependency *dep)
   int num_segm, i;
   Point *points;
   DiaRectangle rect;
+  graphene_rect_t bbox, tmp;
 
-  orthconn_update_data(orth);
+  orthconn_update_data (orth);
 
-  dep->stereotype = remove_stereotype_from_string(dep->stereotype);
+  dep->stereotype = remove_stereotype_from_string (dep->stereotype);
   if (!dep->st_stereotype) {
-    dep->st_stereotype =  string_to_stereotype(dep->stereotype);
+    dep->st_stereotype = string_to_stereotype (dep->stereotype);
   }
 
   dep->text_width = 0.0;
-  if (dep->name)
-    dep->text_width = dia_font_string_width(dep->name, dep->font,
-                                       dep->font_height);
-  if (dep->stereotype)
-    dep->text_width = MAX(dep->text_width,
-                         dia_font_string_width(dep->stereotype, dep->font,
-                                           dep->font_height));
+  if (dep->name) {
+    dep->text_width = dia_font_string_width (dep->name,
+                                             dep->font,
+                                             dep->font_height);
+  }
+  if (dep->stereotype) {
+    dep->text_width = MAX (dep->text_width,
+                           dia_font_string_width (dep->stereotype,
+                                                  dep->font,
+                                                  dep->font_height));
+  }
 
   extra->start_trans =
     extra->start_long =
@@ -318,7 +325,7 @@ dependency_update_data(Dependency *dep)
                        (dep->line_width + DEPENDENCY_ARROWLEN)/2.0:
                        dep->line_width/2.0);
 
-  orthconn_update_boundingbox(orth);
+  orthconn_update_boundingbox (orth);
 
   /* Calc text pos: */
   num_segm = dep->orth.numpoints - 1;
@@ -356,17 +363,24 @@ dependency_update_data(Dependency *dep)
 
   /* Add the text recangle to the bounding box: */
   rect.left = dep->text_pos.x;
-  if (dep->text_align == ALIGN_CENTER)
-    rect.left -= dep->text_width/2.0;
+  if (dep->text_align == ALIGN_CENTER) {
+    rect.left -= dep->text_width / 2.0;
+  }
   rect.right = rect.left + dep->text_width;
   rect.top = dep->text_pos.y;
-  if (dep->name)
-    rect.top -= dia_font_ascent(dep->name,
-                               dep->font,
-                               dep->font_height);
+  if (dep->name) {
+    rect.top -= dia_font_ascent (dep->name,
+                                 dep->font,
+                                 dep->font_height);
+  }
   rect.bottom = rect.top + 2*dep->font_height;
 
-  rectangle_union(&obj->bounding_box, &rect);
+  dia_object_get_bounding_box (obj, &bbox);
+  dia_rectangle_to_graphene (&rect, &tmp);
+
+  graphene_rect_union (&bbox, &tmp, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
 
diff --git a/objects/UML/fork.c b/objects/UML/fork.c
index 901edf3a6..5f68a31a3 100644
--- a/objects/UML/fork.c
+++ b/objects/UML/fork.c
@@ -32,6 +32,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "uml.h"
 
@@ -146,13 +147,20 @@ fork_set_props(Fork *branch, GPtrArray *props)
   fork_update_data(branch);
 }
 
-static real
-fork_distance_from(Fork *branch, Point *point)
+
+static double
+fork_distance_from (Fork *branch, Point *point)
 {
-  DiaObject *obj = &branch->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (branch), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 fork_select(Fork *branch, Point *clicked_point, DiaRenderer *interactive_renderer)
 {
diff --git a/objects/UML/generalization.c b/objects/UML/generalization.c
index f96deb22f..75e587397 100644
--- a/objects/UML/generalization.c
+++ b/objects/UML/generalization.c
@@ -30,6 +30,7 @@
 #include "arrows.h"
 #include "properties.h"
 #include "stereotype.h"
+#include "dia-graphene.h"
 
 #include "uml.h"
 
@@ -42,13 +43,13 @@ struct _Generalization {
 
   Point text_pos;
   Alignment text_align;
-  real text_width;
+  double    text_width;
 
   DiaFont *font;
-  real     font_height;
+  double   font_height;
   Color    text_color;
 
-  real     line_width;
+  double   line_width;
   Color    line_color;
 
   char *name;
@@ -279,23 +280,24 @@ generalization_draw (Generalization *genlz, DiaRenderer *renderer)
   }
 }
 
+
 static void
-generalization_update_data(Generalization *genlz)
+generalization_update_data (Generalization *genlz)
 {
   OrthConn *orth = &genlz->orth;
   DiaObject *obj = &orth->object;
   int num_segm, i;
   Point *points;
-  DiaRectangle rect;
   PolyBBExtras *extra;
-  real descent;
-  real ascent;
+  double descent;
+  double ascent;
+  graphene_rect_t bbox, rect;
 
-  orthconn_update_data(orth);
+  orthconn_update_data (orth);
 
-  genlz->stereotype = remove_stereotype_from_string(genlz->stereotype);
+  genlz->stereotype = remove_stereotype_from_string (genlz->stereotype);
   if (!genlz->st_stereotype) {
-    genlz->st_stereotype =  string_to_stereotype(genlz->stereotype);
+    genlz->st_stereotype = string_to_stereotype (genlz->stereotype);
   }
 
   genlz->text_width = 0.0;
@@ -303,24 +305,30 @@ generalization_update_data(Generalization *genlz)
   ascent = 0.0;
 
   if (genlz->name) {
-    genlz->text_width = dia_font_string_width(genlz->name, genlz->font,
-                                              genlz->font_height);
-    descent = dia_font_descent(genlz->name,
-                               genlz->font,genlz->font_height);
-    ascent = dia_font_ascent(genlz->name,
-                             genlz->font,genlz->font_height);
+    genlz->text_width = dia_font_string_width (genlz->name,
+                                               genlz->font,
+                                               genlz->font_height);
+    descent = dia_font_descent (genlz->name,
+                                genlz->font,
+                                genlz->font_height);
+    ascent = dia_font_ascent (genlz->name,
+                              genlz->font,
+                              genlz->font_height);
   }
+
   if (genlz->stereotype) {
-    genlz->text_width = MAX(genlz->text_width,
-                            dia_font_string_width(genlz->stereotype,
-                                                  genlz->font,
-                                                  genlz->font_height));
+    genlz->text_width = MAX (genlz->text_width,
+                             dia_font_string_width (genlz->stereotype,
+                                                    genlz->font,
+                                                    genlz->font_height));
     if (!genlz->name) {
-      descent = dia_font_descent(genlz->stereotype,
-                                genlz->font,genlz->font_height);
+      descent = dia_font_descent (genlz->stereotype,
+                                  genlz->font,
+                                  genlz->font_height);
     }
-    ascent = dia_font_ascent(genlz->stereotype,
-                             genlz->font,genlz->font_height);
+    ascent = dia_font_ascent (genlz->stereotype,
+                              genlz->font,
+                              genlz->font_height);
   }
 
   extra = &orth->extra_spacing;
@@ -331,7 +339,7 @@ generalization_update_data(Generalization *genlz)
     extra->end_trans =
     extra->end_long = genlz->line_width/2.0;
 
-  orthconn_update_boundingbox(orth);
+  orthconn_update_boundingbox (orth);
 
   /* Calc text pos: */
   num_segm = genlz->orth.numpoints - 1;
@@ -339,8 +347,9 @@ generalization_update_data(Generalization *genlz)
   i = num_segm / 2;
 
   if ((num_segm % 2) == 0) { /* If no middle segment, use horizontal */
-    if (genlz->orth.orientation[i]==VERTICAL)
+    if (genlz->orth.orientation[i] == VERTICAL) {
       i--;
+    }
   }
 
   switch (genlz->orth.orientation[i]) {
@@ -359,14 +368,19 @@ generalization_update_data(Generalization *genlz)
   }
 
   /* Add the text recangle to the bounding box: */
-  rect.left = genlz->text_pos.x;
-  if (genlz->text_align == ALIGN_CENTER)
-    rect.left -= genlz->text_width/2.0;
-  rect.right = rect.left + genlz->text_width;
-  rect.top = genlz->text_pos.y - ascent;
-  rect.bottom = rect.top + 2*genlz->font_height;
-
-  rectangle_union(&obj->bounding_box, &rect);
+  graphene_rect_init (&rect,
+                      genlz->text_pos.x,
+                      genlz->text_pos.y - ascent,
+                      genlz->text_width,
+                      2 * genlz->font_height);
+
+  if (genlz->text_align == ALIGN_CENTER) {
+    graphene_rect_offset (&rect, -(genlz->text_width / 2.0), 0);
+  }
+
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &rect, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
 
diff --git a/objects/UML/implements.c b/objects/UML/implements.c
index 980d69ca8..97a5887aa 100644
--- a/objects/UML/implements.c
+++ b/objects/UML/implements.c
@@ -29,6 +29,7 @@
 #include "handle.h"
 #include "properties.h"
 #include "attributes.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/implements.xpm"
 
@@ -359,26 +360,29 @@ implements_destroy (Implements *implements)
   g_clear_pointer (&implements->text, g_free);
 }
 
+
 static void
-implements_update_data(Implements *implements)
+implements_update_data (Implements *implements)
 {
   Connection *conn = &implements->connection;
   DiaObject *obj = &conn->object;
   LineBBExtras *extra = &conn->extra_spacing;
   Point delta;
   Point point;
-  real len;
+  double len;
   DiaRectangle rect;
+  graphene_rect_t bbox, tmp;
 
   implements->text_width = 0.0;
-  if (implements->text)
-    implements->text_width = dia_font_string_width(implements->text,
-                                                   implements->font,
-                                                   implements->font_height);
-
-  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
-      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
-    connection_adjust_for_autogap(conn);
+  if (implements->text) {
+    implements->text_width = dia_font_string_width (implements->text,
+                                                    implements->font,
+                                                    implements->font_height);
+  }
+
+  if (connpoint_is_autogap (conn->endpoint_handles[0].connected_to) ||
+      connpoint_is_autogap (conn->endpoint_handles[1].connected_to)) {
+    connection_adjust_for_autogap (conn);
   }
   obj->position = conn->endpoints[0];
 
@@ -386,21 +390,21 @@ implements_update_data(Implements *implements)
 
   /* circle handle/center pos: */
   delta = conn->endpoints[0];
-  point_sub(&delta, &conn->endpoints[1]);
-  len = sqrt(point_dot(&delta, &delta));
+  point_sub (&delta, &conn->endpoints[1]);
+  len = sqrt (point_dot (&delta, &delta));
   delta.x /= len; delta.y /= len;
 
   point = delta;
-  point_scale(&point, implements->circle_diameter);
-  point_add(&point, &conn->endpoints[1]);
+  point_scale (&point, implements->circle_diameter);
+  point_add (&point, &conn->endpoints[1]);
   implements->circle_handle.pos = point;
 
   point = delta;
-  point_scale(&point, implements->circle_diameter/2.0);
-  point_add(&point, &conn->endpoints[1]);
+  point_scale (&point, implements->circle_diameter/2.0);
+  point_add (&point, &conn->endpoints[1]);
   implements->circle_center = point;
 
-  connection_update_handles(conn);
+  connection_update_handles (conn);
 
   /* Boundingbox: */
   extra->start_long =
@@ -408,18 +412,25 @@ implements_update_data(Implements *implements)
     extra->end_long = implements->line_width/2.0;
   extra->end_trans = (implements->line_width + implements->circle_diameter)/2.0;
 
-  connection_update_boundingbox(conn);
+  connection_update_boundingbox (conn);
 
   /* Add boundingbox for text: */
   rect.left = implements->text_pos.x;
   rect.right = rect.left + implements->text_width;
   rect.top = implements->text_pos.y;
-  if (implements->text)
-    rect.top -= dia_font_ascent(implements->text,
-                               implements->font,
-                               implements->font_height);
+  if (implements->text) {
+    rect.top -= dia_font_ascent (implements->text,
+                                 implements->font,
+                                 implements->font_height);
+  }
   rect.bottom = rect.top + implements->font_height;
-  rectangle_union(&obj->bounding_box, &rect);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  dia_rectangle_to_graphene (&rect, &tmp);
+
+  graphene_rect_union (&bbox, &tmp, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
 static DiaObject *
diff --git a/objects/UML/large_package.c b/objects/UML/large_package.c
index 77430af9f..db83d4cad 100644
--- a/objects/UML/large_package.c
+++ b/objects/UML/large_package.c
@@ -304,48 +304,66 @@ largepackage_draw (LargePackage *pkg, DiaRenderer *renderer)
   }
 }
 
+
 static void
-largepackage_update_data(LargePackage *pkg)
+largepackage_update_data (LargePackage *pkg)
 {
   Element *elem = &pkg->element;
   DiaObject *obj = &elem->object;
+  graphene_rect_t bbox;
+  graphene_point_t pt;
 
-  pkg->stereotype = remove_stereotype_from_string(pkg->stereotype);
+  pkg->stereotype = remove_stereotype_from_string (pkg->stereotype);
   if (!pkg->st_stereotype) {
-    pkg->st_stereotype = string_to_stereotype(pkg->stereotype);
+    pkg->st_stereotype = string_to_stereotype (pkg->stereotype);
   }
 
   pkg->topheight = pkg->font_height + 0.1*2;
 
   pkg->topwidth = 2.0;
-  if (pkg->name != NULL)
-    pkg->topwidth = MAX(pkg->topwidth,
-                        dia_font_string_width(pkg->name, pkg->font,
-                                          pkg->font_height)+2*0.1);
+  if (pkg->name != NULL) {
+    pkg->topwidth = MAX (pkg->topwidth,
+                         dia_font_string_width (pkg->name,
+                                                pkg->font,
+                                                pkg->font_height) + 2 * 0.1);
+  }
+
   if (pkg->st_stereotype != NULL && pkg->st_stereotype[0] != '\0') {
-    pkg->topwidth = MAX(pkg->topwidth,
-                        dia_font_string_width(pkg->st_stereotype, pkg->font,
-                                              pkg->font_height)+2*0.1);
+    pkg->topwidth = MAX (pkg->topwidth,
+                         dia_font_string_width (pkg->st_stereotype,
+                                                pkg->font,
+                                                pkg->font_height) + 2 * 0.1);
     pkg->topheight += pkg->font_height;
   }
 
-  if (elem->width < (pkg->topwidth + 0.2))
+  if (elem->width < (pkg->topwidth + 0.2)) {
     elem->width = pkg->topwidth + 0.2;
-  if (elem->height < 1.0)
+  }
+
+  if (elem->height < 1.0) {
     elem->height = 1.0;
+  }
 
   /* Update connections: */
-  element_update_connections_rectangle(elem, pkg->connections);
+  element_update_connections_rectangle (elem, pkg->connections);
+
+  element_update_boundingbox (elem);
 
-  element_update_boundingbox(elem);
   /* fix boundingbox for top rectangle: */
-  obj->bounding_box.top -= pkg->topheight;
+  dia_object_get_bounding_box (DIA_OBJECT (elem), &bbox);
+
+  graphene_rect_get_top_left (&bbox, &pt);
+  pt.y -= pkg->topheight;
+  graphene_rect_expand (&bbox, &pt, &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (elem), &bbox);
 
   obj->position = elem->corner;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 }
 
+
 static DiaObject *
 largepackage_create(Point *startpoint,
                    void *user_data,
diff --git a/objects/UML/message.c b/objects/UML/message.c
index ff306cfd8..ff62d550b 100644
--- a/objects/UML/message.c
+++ b/objects/UML/message.c
@@ -33,6 +33,7 @@
 #include "arrows.h"
 #include "properties.h"
 #include "attributes.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/message.xpm"
 
@@ -432,11 +433,12 @@ message_destroy (Message *message)
 
 
 static void
-message_update_data(Message *message)
+message_update_data (Message *message)
 {
   Connection *conn = &message->connection;
   DiaObject *obj = &conn->object;
   DiaRectangle rect;
+  graphene_rect_t bbox, tmp;
 
   if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
       connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
@@ -458,7 +460,13 @@ message_update_data(Message *message)
   rect.top = message->text_pos.y -
       dia_font_ascent(message->text, message->font, message->font_height);
   rect.bottom = rect.top + message->font_height;
-  rectangle_union(&obj->bounding_box, &rect);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  dia_rectangle_to_graphene (&rect, &tmp);
+
+  graphene_rect_union (&bbox, &tmp, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
 
diff --git a/objects/UML/node.c b/objects/UML/node.c
index 8e9643c7b..d24ff8ae0 100644
--- a/objects/UML/node.c
+++ b/objects/UML/node.c
@@ -32,6 +32,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "uml.h"
 
@@ -173,13 +174,19 @@ node_set_props(Node *node, GPtrArray *props)
 }
 
 
-static real
-node_distance_from(Node *node, Point *point)
+static double
+node_distance_from (Node *node, Point *point)
 {
-  DiaObject *obj = &node->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (node), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 node_select(Node *node, Point *clicked_point,
                    DiaRenderer *interactive_renderer)
@@ -223,13 +230,14 @@ node_move(Node *node, Point *to)
   return NULL;
 }
 
+
 static void
 node_draw (Node *node, DiaRenderer *renderer)
 {
   Element *elem;
-  real x, y, w, h;
+  double x, y, w, h;
   Point points[7];
-  int i;
+  Point text_pos;
 
   assert(node != NULL);
   assert(renderer != NULL);
@@ -274,48 +282,68 @@ node_draw (Node *node, DiaRenderer *renderer)
 
   /* Draw underlines (!) */
   dia_renderer_set_linewidth (renderer, NODE_LINEWIDTH);
-  points[0].x = node->name->position.x;
-  points[0].y = points[1].y = node->name->position.y + node->name->descent;
-  for (i = 0; i < node->name->numlines; i++) {
+
+  dia_text_get_position (node->name, &text_pos);
+  points[0].x = text_pos.x;
+  points[0].y = points[1].y = text_pos.y + node->name->descent;
+
+  for (int i = 0; i < node->name->numlines; i++) {
     points[1].x = points[0].x + text_get_line_width (node->name, i);
     dia_renderer_draw_line (renderer, points, points + 1, &node->name->color);
     points[0].y = points[1].y += node->name->height;
   }
 }
 
+
 static void
-node_update_data(Node *node)
+node_update_data (Node *node)
 {
   Element *elem = &node->element;
   DiaObject *obj = &node->element.object;
   Point p1;
-  real h;
+  double h;
+  graphene_rect_t bbox;
+  graphene_point_t pt;
 
-  text_calc_boundingbox(node->name, NULL);
+  text_calc_boundingbox (node->name, NULL);
 
   h = elem->corner.y + NODE_TEXT_MARGIN;
 
   p1.x = elem->corner.x + NODE_TEXT_MARGIN;
   p1.y = h + node->name->ascent;  /* position of text */
-  text_set_position(node->name, &p1);
+  text_set_position (node->name, &p1);
 
-  elem->width = MAX(elem->width, node->name->max_width + 2*NODE_TEXT_MARGIN);
-  elem->height = MAX(elem->height, node->name->height * node->name->numlines + 2*NODE_TEXT_MARGIN);
+  elem->width = MAX (elem->width,
+                     node->name->max_width + (2 * NODE_TEXT_MARGIN));
+  elem->height = MAX (elem->height,
+                      node->name->height * node->name->numlines + (2 * NODE_TEXT_MARGIN));
 
   /* Update connections: */
-  element_update_connections_rectangle(elem, node->connections);
+  element_update_connections_rectangle (elem, node->connections);
+
+  element_update_boundingbox (elem);
 
-  element_update_boundingbox(elem);
   /* fix boundingbox for depth: */
-  obj->bounding_box.top -= NODE_DEPTH;
-  obj->bounding_box.right += NODE_DEPTH;
+  dia_object_get_bounding_box (DIA_OBJECT (node), &bbox);
+
+  graphene_rect_get_top_right (&bbox, &pt);
+  pt.y -= NODE_DEPTH;
+  pt.x += NODE_DEPTH;
+  graphene_rect_expand (&bbox, &pt, &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (node), &bbox);
 
   obj->position = elem->corner;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 }
 
-static DiaObject *node_create(Point *startpoint, void *user_data, Handle **handle1, Handle **handle2)
+
+static DiaObject *
+node_create (Point   *startpoint,
+             void    *user_data,
+             Handle **handle1,
+             Handle **handle2)
 {
   Node *node;
   Element *elem;
diff --git a/objects/UML/object.c b/objects/UML/object.c
index 82037388e..b93932db7 100644
--- a/objects/UML/object.c
+++ b/objects/UML/object.c
@@ -30,6 +30,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "uml.h"
 #include "stereotype.h"
@@ -230,13 +231,20 @@ objet_set_props(Objet *objet, GPtrArray *props)
   objet_update_data(objet);
 }
 
-static real
-objet_distance_from(Objet *ob, Point *point)
+
+static double
+objet_distance_from (Objet *ob, Point *point)
 {
-  DiaObject *obj = &ob->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (ob), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 objet_select(Objet *ob, Point *clicked_point,
               DiaRenderer *interactive_renderer)
@@ -275,9 +283,8 @@ static void
 objet_draw (Objet *ob, DiaRenderer *renderer)
 {
   Element *elem;
-  real bw, x, y, w, h;
-  Point p1, p2;
-  int i;
+  double bw, x, y, w, h;
+  Point p1, p2, text_pos;
 
   assert(ob != NULL);
   assert(renderer != NULL);
@@ -341,14 +348,15 @@ objet_draw (Objet *ob, DiaRenderer *renderer)
   }
 
   /* Is there a better way to underline? */
-  p1.x = x + (w - text_get_max_width (ob->text))/2;
-  p1.y = ob->text->position.y + text_get_descent (ob->text);
+  p1.x = x + (w - text_get_max_width (ob->text)) / 2;
+  dia_text_get_position (ob->text, &text_pos);
+  p1.y = text_pos.y + text_get_descent (ob->text);
   p2.x = p1.x + text_get_max_width (ob->text);
   p2.y = p1.y;
 
   dia_renderer_set_linewidth (renderer, ob->line_width/2);
 
-  for (i=0; i<ob->text->numlines; i++) {
+  for (int i = 0; i < ob->text->numlines; i++) {
     p1.x = x + (w - text_get_line_width (ob->text, i))/2;
     p2.x = p1.x + text_get_line_width (ob->text, i);
     dia_renderer_draw_line (renderer,
@@ -359,8 +367,12 @@ objet_draw (Objet *ob, DiaRenderer *renderer)
   }
 
   if (ob->show_attributes) {
+    Point attr_pos;
+
+    dia_text_get_position (ob->attributes, &attr_pos);
+
     p1.x = x; p2.x = x + w;
-    p1.y = p2.y = ob->attributes->position.y - ob->attributes->ascent - OBJET_MARGIN_Y (ob);
+    p1.y = p2.y = attr_pos.y - ob->attributes->ascent - OBJET_MARGIN_Y (ob);
 
     dia_renderer_set_linewidth (renderer, bw);
     dia_renderer_draw_line (renderer,
diff --git a/objects/UML/realizes.c b/objects/UML/realizes.c
index 585075d9e..d46e71e55 100644
--- a/objects/UML/realizes.c
+++ b/objects/UML/realizes.c
@@ -31,6 +31,7 @@
 #include "properties.h"
 #include "stereotype.h"
 #include "uml.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/realizes.xpm"
 
@@ -278,8 +279,9 @@ realizes_draw (Realizes *realize, DiaRenderer *renderer)
   }
 }
 
+
 static void
-realizes_update_data(Realizes *realize)
+realizes_update_data (Realizes *realize)
 {
   OrthConn *orth = &realize->orth;
   DiaObject *obj = &orth->object;
@@ -287,8 +289,10 @@ realizes_update_data(Realizes *realize)
   Point *points;
   DiaRectangle rect;
   PolyBBExtras *extra;
+  graphene_rect_t bbox;
+  graphene_rect_t tmp;
 
-  orthconn_update_data(orth);
+  orthconn_update_data (orth);
 
   realize->text_width = 0.0;
 
@@ -353,11 +357,19 @@ realizes_update_data(Realizes *realize)
     rect.left -= realize->text_width/2.0;
   rect.right = rect.left + realize->text_width;
   rect.top = realize->text_pos.y;
-  if (realize->name)
-    rect.top -= dia_font_ascent(realize->name,realize->font, realize->font_height);
+  if (realize->name) {
+    rect.top -= dia_font_ascent (realize->name,
+                                 realize->font,
+                                 realize->font_height);
+  }
   rect.bottom = rect.top + 2*realize->font_height;
 
-  rectangle_union(&obj->bounding_box, &rect);
+  dia_object_get_bounding_box (obj, &bbox);
+  dia_rectangle_to_graphene (&rect, &tmp);
+
+  graphene_rect_union (&bbox, &tmp, &bbox);
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
 
 
diff --git a/objects/UML/small_package.c b/objects/UML/small_package.c
index 5d8df3856..5a8aef06f 100644
--- a/objects/UML/small_package.c
+++ b/objects/UML/small_package.c
@@ -276,8 +276,10 @@ smallpackage_draw (SmallPackage *pkg, DiaRenderer *renderer)
   if ((pkg->st_stereotype != NULL) && (pkg->st_stereotype[0] != '\0')) {
     dia_renderer_set_font (renderer, pkg->text->font, pkg->text->height);
 
-    p1 = pkg->text->position;
+    dia_text_get_position (pkg->text, &p1);
+
     p1.y -= pkg->text->height;
+
     dia_renderer_draw_string (renderer,
                               pkg->st_stereotype,
                               &p1,
@@ -286,13 +288,16 @@ smallpackage_draw (SmallPackage *pkg, DiaRenderer *renderer)
   }
 }
 
+
 static void
-smallpackage_update_data(SmallPackage *pkg)
+smallpackage_update_data (SmallPackage *pkg)
 {
   Element *elem = &pkg->element;
   DiaObject *obj = &elem->object;
   Point p;
   DiaFont *font;
+  graphene_rect_t bbox;
+  graphene_point_t pt;
 
   pkg->stereotype = remove_stereotype_from_string(pkg->stereotype);
   if (!pkg->st_stereotype) {
@@ -319,20 +324,28 @@ smallpackage_update_data(SmallPackage *pkg)
     p.y += pkg->text->height;
   }
 
-  pkg->text->position = p;
+  text_set_position (pkg->text, &p);
 
   /* Update connections: */
-  element_update_connections_rectangle(elem, pkg->connections);
+  element_update_connections_rectangle (elem, pkg->connections);
+
+  element_update_boundingbox (elem);
 
-  element_update_boundingbox(elem);
   /* fix boundingbox for top rectangle: */
-  obj->bounding_box.top -= SMALLPACKAGE_TOPHEIGHT;
+  dia_object_get_bounding_box (DIA_OBJECT (elem), &bbox);
+
+  graphene_rect_get_top_left (&bbox, &pt);
+  pt.y -= SMALLPACKAGE_TOPHEIGHT;
+  graphene_rect_expand (&bbox, &pt, &bbox);
+
+  dia_object_set_bounding_box (DIA_OBJECT (elem), &bbox);
 
   obj->position = elem->corner;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 }
 
+
 static DiaObject *
 smallpackage_create(Point *startpoint,
                    void *user_data,
diff --git a/objects/UML/state.c b/objects/UML/state.c
index cc7b45d4a..f9936e709 100644
--- a/objects/UML/state.c
+++ b/objects/UML/state.c
@@ -30,6 +30,7 @@
 #include "text.h"
 #include "properties.h"
 #include "message.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/state.xpm"
 
@@ -205,13 +206,20 @@ state_set_props(State *state, GPtrArray *props)
   state_update_data(state);
 }
 
-static real
-state_distance_from(State *state, Point *point)
+
+static double
+state_distance_from (State *state, Point *point)
 {
-  DiaObject *obj = &state->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (state), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 state_select(State *state, Point *clicked_point,
               DiaRenderer *interactive_renderer)
diff --git a/objects/UML/state_term.c b/objects/UML/state_term.c
index 12b20b399..c2ca842b2 100644
--- a/objects/UML/state_term.c
+++ b/objects/UML/state_term.c
@@ -32,6 +32,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/state_term.xpm"
 
@@ -154,13 +155,20 @@ state_set_props(State *state, GPtrArray *props)
   state_update_data(state);
 }
 
-static real
-state_distance_from(State *state, Point *point)
+
+static double
+state_distance_from (State *state, Point *point)
 {
-  DiaObject *obj = &state->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (state), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 state_select(State *state, Point *clicked_point,
               DiaRenderer *interactive_renderer)
diff --git a/objects/UML/transition.c b/objects/UML/transition.c
index 0c2133d1b..8874265a1 100644
--- a/objects/UML/transition.c
+++ b/objects/UML/transition.c
@@ -558,21 +558,25 @@ transition_del_segment_cb (DiaObject *obj,
 
 
 static void
-expand_bbox_for_text (DiaRectangle *bbox,
-                      Point        *text_pos,
-                      char         *text)
+expand_bbox_for_text (graphene_rect_t *bbox,
+                      Point           *text_pos,
+                      char            *text)
 {
-  DiaRectangle text_box;
+  graphene_rect_t text_box;
   double text_width;
 
-  text_width = dia_font_string_width (text, transition_font,
+  text_width = dia_font_string_width (text,
+                                      transition_font,
                                       TRANSITION_FONTHEIGHT);
-  text_box.left = text_pos->x - text_width/2;
-  text_box.right = text_box.left + text_width;
-  text_box.top = text_pos->y - dia_font_ascent (text, transition_font,
-                                                TRANSITION_FONTHEIGHT);
-  text_box.bottom = text_box.top + TRANSITION_FONTHEIGHT;
-  rectangle_union (bbox, &text_box);
+
+  graphene_rect_init (&text_box,
+                      text_pos->x - (text_width / 2),
+                      text_pos->y - dia_font_ascent (text,
+                                                     transition_font,
+                                                     TRANSITION_FONTHEIGHT),
+                      text_width,
+                      TRANSITION_FONTHEIGHT);
+  graphene_rect_union (bbox, &text_box, bbox);
 }
 
 
@@ -581,6 +585,7 @@ uml_transition_update_data (Transition *transition)
 {
   char *temp_text;
   Point *points;
+  graphene_rect_t bbox;
 
   /* Setup helpful pointers as shortcuts */
   OrthConn *orth = &transition->orth;
@@ -604,14 +609,22 @@ uml_transition_update_data (Transition *transition)
 
   /* Update the bounding box to match the new connection data */
   orthconn_update_boundingbox (orth);
+
+  dia_object_get_bounding_box (obj, &bbox);
+
   /* Update the bounding box to match the new trigger text size and position */
   temp_text = create_event_action_text (transition);
-  expand_bbox_for_text (&obj->bounding_box, &transition->trigger_text_pos,
+  expand_bbox_for_text (&bbox,
+                        &transition->trigger_text_pos,
                         temp_text);
   g_clear_pointer (&temp_text, g_free);
+
   /* Update the bounding box to match the new guard text size and position */
   temp_text = g_strdup_printf ("[%s]", transition->guard_text ? transition->guard_text : "");
-  expand_bbox_for_text (&obj->bounding_box, &transition->guard_text_pos,
+  expand_bbox_for_text (&bbox,
+                        &transition->guard_text_pos,
                         temp_text);
   g_clear_pointer (&temp_text, g_free);
+
+  dia_object_set_bounding_box (obj, &bbox);
 }
diff --git a/objects/UML/usecase.c b/objects/UML/usecase.c
index 1146ccbd4..24ad79c46 100644
--- a/objects/UML/usecase.c
+++ b/objects/UML/usecase.c
@@ -29,6 +29,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/case.xpm"
 
@@ -177,13 +178,20 @@ usecase_set_props(Usecase *usecase, GPtrArray *props)
   usecase_update_data(usecase);
 }
 
-static real
-usecase_distance_from(Usecase *usecase, Point *point)
+
+static double
+usecase_distance_from (Usecase *usecase, Point *point)
 {
-  DiaObject *obj = &usecase->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (usecase), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 usecase_select(Usecase *usecase, Point *clicked_point,
               DiaRenderer *interactive_renderer)
diff --git a/objects/chronogram/chronoline.c b/objects/chronogram/chronoline.c
index c33fb9d0e..f6a97b054 100644
--- a/objects/chronogram/chronoline.c
+++ b/objects/chronogram/chronoline.c
@@ -42,6 +42,7 @@
 
 #include "chronogram.h"
 #include "chronoline_event.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/chronoline.xpm"
 
@@ -243,13 +244,20 @@ chronoline_set_props(Chronoline *chronoline, GPtrArray *props)
   chronoline_update_data(chronoline);
 }
 
-static real
-chronoline_distance_from(Chronoline *chronoline, Point *point)
+
+static double
+chronoline_distance_from (Chronoline *chronoline, Point *point)
 {
-  DiaObject *obj = &chronoline->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (chronoline), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 chronoline_select(Chronoline *chronoline, Point *clicked_point,
           DiaRenderer *interactive_renderer)
@@ -515,26 +523,29 @@ inline static void grayify(Color *col,Color *src)
   col->alpha = .5 * (src->alpha + color_white.alpha);
 }
 
+
 static void
-chronoline_update_data(Chronoline *chronoline)
+chronoline_update_data (Chronoline *chronoline)
 {
   Element *elem = &chronoline->element;
   DiaObject *obj = &elem->object;
-  real time_span;
+  double time_span;
   Point ur_corner;
   int shouldbe,i;
-  real realheight;
+  double realheight;
   CLEventList *lst;
   CLEvent *evt;
   GSList *conn_elem;
   ElementBBExtras *extra = &elem->extra_spacing;
+  graphene_rect_t bbox;
+  graphene_point_t pt1, pt2;
 
-  grayify(&chronoline->datagray,&chronoline->data_color);
-  grayify(&chronoline->gray,&chronoline->color);
+  grayify (&chronoline->datagray, &chronoline->data_color);
+  grayify (&chronoline->gray, &chronoline->color);
 
-  chronoline->labelwidth = dia_font_string_width(chronoline->name,
-                                                 chronoline->font,
-                                                 chronoline->font_size);
+  chronoline->labelwidth = dia_font_string_width (chronoline->name,
+                                                  chronoline->font,
+                                                  chronoline->font_size);
 
   chronoline->y_up = elem->corner.y;
   chronoline->y_down = elem->corner.y + elem->height;
@@ -551,19 +562,26 @@ chronoline_update_data(Chronoline *chronoline)
   }
 
   extra->border_trans = chronoline->main_lwidth / 2;
-  element_update_boundingbox(elem);
+  element_update_boundingbox (elem);
+
+  dia_object_get_bounding_box (obj, &bbox);
 
   /* fix boundingbox for special extras: */
-  realheight = obj->bounding_box.bottom - obj->bounding_box.top;
-  realheight = MAX(realheight,chronoline->font_size);
+  realheight = graphene_rect_get_height (&bbox);
+  realheight = MAX (realheight, chronoline->font_size);
+
+  graphene_rect_get_bottom_left (&bbox, &pt1);
+  graphene_rect_get_top_left (&bbox, &pt2);
+
+  pt1.x -= chronoline->labelwidth;
+  pt1.y = pt2.y + realheight + chronoline->main_lwidth;
+  graphene_rect_expand (&bbox, &pt1, &bbox);
 
-  obj->bounding_box.left -= chronoline->labelwidth;
-  obj->bounding_box.bottom = obj->bounding_box.top + realheight +
-    chronoline->main_lwidth;
+  dia_object_set_bounding_box (obj, &bbox);
 
   obj->position = elem->corner;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 
   /* Update connections: */
   ur_corner.x = elem->corner.x + elem->width;
diff --git a/objects/chronogram/chronoref.c b/objects/chronogram/chronoref.c
index e8d2bb6d8..1be3280bc 100644
--- a/objects/chronogram/chronoref.c
+++ b/objects/chronogram/chronoref.c
@@ -39,6 +39,7 @@
 #include "connpoint_line.h"
 #include "color.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "chronogram.h"
 #include "pixmaps/chronoref.xpm"
@@ -222,13 +223,20 @@ chronoref_set_props(Chronoref *chronoref, GPtrArray *props)
   chronoref_update_data(chronoref);
 }
 
-static real
-chronoref_distance_from(Chronoref *chronoref, Point *point)
+
+static double
+chronoref_distance_from (Chronoref *chronoref, Point *point)
 {
-  DiaObject *obj = &chronoref->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (chronoref), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 chronoref_select(Chronoref *chronoref, Point *clicked_point,
           DiaRenderer *interactive_renderer)
@@ -334,18 +342,21 @@ chronoref_draw(Chronoref *chronoref, DiaRenderer *renderer)
   dia_renderer_draw_line (renderer,&p1,&p2,&chronoref->color);
 }
 
+
 static void
-chronoref_update_data(Chronoref *chronoref)
+chronoref_update_data (Chronoref *chronoref)
 {
   Element *elem = &chronoref->element;
   DiaObject *obj = &elem->object;
-  real time_span,t;
+  double time_span,t;
   Point p1,p2;
   Point ur_corner;
   int shouldbe,i;
-  real labelwidth;
+  double labelwidth;
   char biglabel[10];
   ElementBBExtras *extra = &elem->extra_spacing;
+  graphene_rect_t bbox;
+  graphene_point_t pt;
 
   chronoref->majgrad_height = elem->height;
   chronoref->mingrad_height = elem->height / 3.0;
@@ -392,17 +403,20 @@ chronoref_update_data(Chronoref *chronoref)
   chronoref->majgrad = (chronoref->time_step * elem->width) / time_span;
   chronoref->mingrad = (chronoref->time_lstep * elem->width) / time_span;
 
-  extra->border_trans = chronoref->main_lwidth/2;
-  element_update_boundingbox(elem);
+  extra->border_trans = chronoref->main_lwidth / 2;
+  element_update_boundingbox (elem);
 
   /* fix boundingbox for special extras: */
-  obj->bounding_box.left -= (chronoref->font_size + labelwidth)/2;
-  obj->bounding_box.bottom += chronoref->font_size;
-  obj->bounding_box.right += (chronoref->font_size + labelwidth)/2;
+  dia_object_get_bounding_box (DIA_OBJECT (chronoref), &bbox);
+  graphene_rect_inset (&bbox, -((chronoref->font_size + labelwidth) / 2), 0);
+  graphene_rect_get_bottom_left (&bbox, &pt);
+  pt.y += chronoref->font_size;
+  graphene_rect_expand (&bbox, &pt, &bbox);
+  dia_object_set_bounding_box (DIA_OBJECT (chronoref), &bbox);
 
   obj->position = elem->corner;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 
   /* Update connections: */
   ur_corner.x = elem->corner.x + elem->width;
@@ -423,6 +437,7 @@ chronoref_update_data(Chronoref *chronoref)
   connpointline_putonaline(chronoref->scale,&p1,&p2, DIR_SOUTH);
 }
 
+
 static DiaObject *
 chronoref_create(Point *startpoint,
           void *user_data,
diff --git a/objects/custom/custom_object.c b/objects/custom/custom_object.c
index 327bac550..b2a2aedc5 100644
--- a/objects/custom/custom_object.c
+++ b/objects/custom/custom_object.c
@@ -46,6 +46,7 @@
 #include "dia_image.h"
 #include "custom_object.h"
 #include "prefs.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/custom.xpm"
 
@@ -529,17 +530,22 @@ transform_size(Custom *custom, real w1, real h1, real *w2, real *h2)
   }
 }
 
+
 static void
-transform_coord(Custom *custom, const Point *p1, Point *out)
+transform_coord (Custom *custom, const Point *p1, Point *out)
 {
   if (custom->current_subshape != NULL) {
-    transform_subshape_coord(custom, custom->current_subshape, p1, out);
+    transform_subshape_coord (custom, custom->current_subshape, p1, out);
   } else {
     out->x = p1->x * custom->xscale + custom->xoffs;
     out->y = p1->y * custom->yscale + custom->yoffs;
+    if (isnan (out->x) || isnan (out->y)) {
+      G_BREAKPOINT ();
+    }
   }
 }
 
+
 static void
 transform_rect(Custom *custom, const DiaRectangle *r1, DiaRectangle *out)
 {
@@ -1284,8 +1290,9 @@ assert_boundaries(Custom *custom)
   if (custom->flip_v) custom->yscale = -custom->yscale;
 }
 
+
 static void
-custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
+custom_update_data (Custom *custom, AnchorShape horiz, AnchorShape vert)
 {
   Element *elem = &custom->element;
   ShapeInfo *info = custom->info;
@@ -1481,6 +1488,7 @@ custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
      */
     real lwfactor = el->any.s.line_width == custom->border_width
                   ? 1.0 : custom->border_width;
+    graphene_rect_t tmp_rect, bbox;
 
     switch(el->type) {
     case GE_SUBSHAPE :
@@ -1489,14 +1497,20 @@ custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
       break;
     case GE_LINE: {
       LineBBExtras extra;
-      Point p1,p2;
+      Point p1, p2;
+      graphene_vec2_t v1, v2;
+
       extra.start_trans = extra.end_trans = el->line.s.line_width * lwfactor;
       extra.start_long = extra.end_long = 0;
 
       transform_coord(custom, &el->line.p1, &p1);
       transform_coord(custom, &el->line.p2, &p2);
 
-      line_bbox(&p1,&p2,&extra,&rect);
+      dia_point_to_vec2 (&p1, &v1);
+      dia_point_to_vec2 (&p2, &v2);
+
+      line_bbox (&v1, &v2, &extra, &tmp_rect);
+      dia_graphene_to_rectangle (&tmp_rect, &rect);
       break;
     }
     case GE_POLYGON:
@@ -1512,8 +1526,12 @@ custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
         transform_coord(custom, &el->polyline.points[i],
                         &g_array_index(arr, Point, i));
 
-      polyline_bbox(&g_array_index(arr,Point,0),el->polyline.npoints,
-                    &extra,el->type==GE_POLYGON,&rect);
+      polyline_bbox (&g_array_index (arr, Point, 0),
+                     el->polyline.npoints,
+                     &extra,
+                     el->type == GE_POLYGON,
+                     &tmp_rect);
+      dia_graphene_to_rectangle (&tmp_rect, &rect);
       break;
     }
     case GE_SHAPE:
@@ -1541,8 +1559,12 @@ custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
         }
       }
 
-      polybezier_bbox(&g_array_index(barr,BezPoint,0),el->path.npoints,
-                      &extra,el->type==GE_SHAPE,&rect);
+      polybezier_bbox (&g_array_index (barr, BezPoint, 0),
+                       el->path.npoints,
+                       &extra,
+                       el->type==GE_SHAPE,
+                       &tmp_rect);
+      dia_graphene_to_rectangle (&tmp_rect, &rect);
       break;
     }
     case GE_ELLIPSE: {
@@ -1551,10 +1573,12 @@ custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
       extra.border_trans = el->ellipse.s.line_width * lwfactor;
       transform_coord(custom, &el->ellipse.center, &centre);
 
-      ellipse_bbox(&centre,
-                   el->ellipse.width * fabs(custom->xscale),
-                   el->ellipse.height * fabs(custom->yscale),
-                   &extra,&rect);
+      ellipse_bbox (&centre,
+                    el->ellipse.width * fabs (custom->xscale),
+                    el->ellipse.height * fabs (custom->yscale),
+                    &extra,
+                    &tmp_rect);
+      dia_graphene_to_rectangle (&tmp_rect, &rect);
       break;
     }
     case GE_RECT: {
@@ -1567,7 +1591,13 @@ custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
       transform_rect(custom, &rin, &trin);
 
       extra.border_trans = el->rect.s.line_width * lwfactor;
-      rectangle_bbox(&trin,&extra,&rect);
+      {
+        graphene_rect_t tmp_in, tmp_out;
+
+        dia_rectangle_to_graphene (&trin, &tmp_in);
+        rectangle_bbox (&tmp_in, &extra, &tmp_out);
+        dia_graphene_to_rectangle (&tmp_out, &rect);
+      }
       break;
     }
     case GE_IMAGE: {
@@ -1584,7 +1614,8 @@ custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
     case GE_TEXT:
       text_set_height (el->text.object, custom_transform_length (custom, el->text.s.font_height));
       custom_reposition_text(custom, &el->text);
-      text_calc_boundingbox(el->text.object,&rect);
+      text_calc_boundingbox (el->text.object, &tmp_rect);
+      dia_graphene_to_rectangle (&tmp_rect, &rect);
       /* padding only to be applied on the users text box */
       /* but we need to restore the original position of the 'constant' object */
       text_set_position(el->text.object, &el->text.anchor);
@@ -1593,18 +1624,23 @@ custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
       g_assert_not_reached();
       continue;
     }
-    rectangle_union(&obj->bounding_box,&rect);
+
+    dia_object_get_bounding_box (obj, &bbox);
+    dia_rectangle_to_graphene (&rect, &tmp_rect);
+    graphene_rect_union (&bbox, &tmp_rect, &bbox);
+    dia_object_set_bounding_box (obj, &bbox);
   }
 
   /* extend bounding box to include text bounds ... */
   if (info->has_text) {
-    DiaRectangle tb;
-    text_calc_boundingbox(custom->text, &tb);
-    tb.left -= custom->padding;
-    tb.top -= custom->padding;
-    tb.right += custom->padding;
-    tb.bottom += custom->padding;
-    rectangle_union(&obj->bounding_box, &tb);
+    graphene_rect_t tb, bbox;
+
+    text_calc_boundingbox (custom->text, &tb);
+    graphene_rect_inset (&tb, -custom->padding, -custom->padding);
+
+    dia_object_get_bounding_box (obj, &bbox);
+    graphene_rect_union (&bbox, &tb, &bbox);
+    dia_object_set_bounding_box (obj, &bbox);
   }
 
   obj->position = elem->corner;
diff --git a/objects/custom/shape_info.c b/objects/custom/shape_info.c
index 5549e39ec..40946e9c0 100644
--- a/objects/custom/shape_info.c
+++ b/objects/custom/shape_info.c
@@ -42,7 +42,7 @@
 #include "intl.h"
 #include "prefs.h"
 #include "boundingbox.h"
-
+#include "dia-graphene.h"
 #include "units.h"
 
 #define FONT_HEIGHT_DEFAULT 1
@@ -131,7 +131,12 @@ shape_info_realise(ShapeInfo* info)
                                    &color_black,
                                    el->text.s.alignment);
       }
-      text_calc_boundingbox(el->text.object, &el->text.text_bounds);
+
+      {
+        graphene_rect_t bounds;
+        text_calc_boundingbox (el->text.object, &bounds);
+        dia_graphene_to_rectangle (&bounds, &el->text.text_bounds);
+      }
     }
   }
 }
@@ -605,6 +610,7 @@ update_bounds (ShapeInfo *info)
 {
   GList *tmp;
   Point pt;
+
   for (tmp = info->display_list; tmp; tmp = tmp->next) {
     GraphicElement *el = tmp->data;
     int i;
@@ -649,10 +655,15 @@ update_bounds (ShapeInfo *info)
 #if 1
         {
           DiaRectangle bbox;
+          graphene_rect_t poly_bbox;
           PolyBBExtras extra = { 0, };
 
-          polybezier_bbox (&el->path.points[0],el->path.npoints,
-                           &extra,el->type == GE_SHAPE,&bbox);
+          polybezier_bbox (&el->path.points[0],
+                           el->path.npoints,
+                           &extra,
+                           el->type == GE_SHAPE,
+                           &poly_bbox);
+          dia_graphene_to_rectangle (&poly_bbox, &bbox);
           rectangle_union (&info->shape_bounds, &bbox);
         }
 #else
@@ -744,6 +755,7 @@ load_shape_info (const gchar *filename, ShapeInfo *preload)
   else
     info = g_new0(ShapeInfo, 1);
   info->loaded = TRUE;
+
   info->shape_bounds.top = DBL_MAX;
   info->shape_bounds.left = DBL_MAX;
   info->shape_bounds.bottom = -DBL_MAX;
@@ -829,23 +841,23 @@ load_shape_info (const gchar *filename, ShapeInfo *preload)
 
       str = xmlGetProp(node, (const xmlChar *)"x1");
       if (str) {
-       info->text_bounds.left = g_ascii_strtod((gchar *) str, NULL);
-       xmlFree(str);
+        info->text_bounds.left = g_ascii_strtod((gchar *) str, NULL);
+        xmlFree(str);
       }
       str = xmlGetProp(node, (const xmlChar *)"y1");
       if (str) {
-       info->text_bounds.top = g_ascii_strtod((gchar *) str, NULL);
-       xmlFree(str);
+        info->text_bounds.top = g_ascii_strtod((gchar *) str, NULL);
+        xmlFree(str);
       }
       str = xmlGetProp(node, (const xmlChar *)"x2");
       if (str) {
-       info->text_bounds.right = g_ascii_strtod((gchar *) str, NULL);
-       xmlFree(str);
+        info->text_bounds.right = g_ascii_strtod((gchar *) str, NULL);
+        xmlFree(str);
       }
       str = xmlGetProp(node, (const xmlChar *)"y2");
       if (str) {
-       info->text_bounds.bottom = g_ascii_strtod((gchar *) str, NULL);
-       xmlFree(str);
+        info->text_bounds.bottom = g_ascii_strtod((gchar *) str, NULL);
+        xmlFree(str);
       }
       info->resize_with_text = TRUE;
       str = xmlGetProp(node, (const xmlChar *)"resize");
diff --git a/objects/flowchart/ellipse.c b/objects/flowchart/ellipse.c
index 6c6134a2a..279e3030e 100644
--- a/objects/flowchart/ellipse.c
+++ b/objects/flowchart/ellipse.c
@@ -395,17 +395,16 @@ ellipse_draw (Ellipse *ellipse, DiaRenderer *renderer)
 
 
 static void
-ellipse_update_data(Ellipse *ellipse, AnchorShape horiz, AnchorShape vert)
+ellipse_update_data (Ellipse *ellipse, AnchorShape horiz, AnchorShape vert)
 {
   Element *elem = &ellipse->element;
   ElementBBExtras *extra = &elem->extra_spacing;
   DiaObject *obj = &elem->object;
   Point center, bottom_right;
   Point p, c;
-  real dw, dh;
-  real width, height;
-  real radius1, radius2;
-  int i;
+  double dw, dh;
+  double width, height;
+  double radius1, radius2;
 
   /* save starting points */
   center = bottom_right = elem->corner;
@@ -414,27 +413,28 @@ ellipse_update_data(Ellipse *ellipse, AnchorShape horiz, AnchorShape vert)
   center.y += elem->height/2;
   bottom_right.y += elem->height;
 
-  text_calc_boundingbox(ellipse->text, NULL);
+  text_calc_boundingbox (ellipse->text, NULL);
   width = ellipse->text->max_width + 2 * ellipse->padding;
-  height = ellipse->text->height * ellipse->text->numlines +
-    2 * ellipse->padding;
+  height = (ellipse->text->height * ellipse->text->numlines) +
+                (2 * ellipse->padding);
 
   /* stop ellipse from getting infinite width/height */
-  if (elem->width / elem->height > 4)
+  if (elem->width / elem->height > 4) {
     elem->width = elem->height * 4;
-  else if (elem->height / elem->width > 4)
+  } else if (elem->height / elem->width > 4) {
     elem->height = elem->width * 4;
+  }
 
   c.x = elem->corner.x + elem->width / 2;
   c.y = elem->corner.y + elem->height / 2;
   p.x = c.x - width  / 2;
   p.y = c.y - height / 2;
-  radius1 = ellipse_radius(ellipse, p.x, p.y) - ellipse->border_width/2;
-  radius2 = distance_point_point(&c, &p);
+  radius1 = ellipse_radius (ellipse, p.x, p.y) - (ellipse->border_width / 2);
+  radius2 = distance_point_point (&c, &p);
 
   if (   (radius1 < radius2 && ellipse->text_fitting == TEXTFIT_WHEN_NEEDED)
       /* stop infinite resizing with 5% tolerance obsvered with _test_movement */
-      || (fabs(1.0 - radius2 / radius1) > 0.05 && ellipse->text_fitting == TEXTFIT_ALWAYS)) {
+      || (fabs (1.0 - radius2 / radius1) > 0.05 && ellipse->text_fitting == TEXTFIT_ALWAYS)) {
     /* increase size of the ellipse while keeping its aspect ratio */
     elem->width  *= radius2 / radius1;
     elem->height *= radius2 / radius1;
@@ -469,6 +469,7 @@ ellipse_update_data(Ellipse *ellipse, AnchorShape horiz, AnchorShape vert)
   p.x += elem->width / 2.0;
   p.y += elem->height / 2.0 - ellipse->text->height*ellipse->text->numlines/2 +
     ellipse->text->ascent;
+
   switch (ellipse->text->alignment) {
     case ALIGN_LEFT:
       p.x -= (elem->width - 2*(ellipse->padding + ellipse->border_width))/2;
@@ -488,27 +489,30 @@ ellipse_update_data(Ellipse *ellipse, AnchorShape horiz, AnchorShape vert)
   c.y = elem->corner.y + elem->height / 2;
   dw = elem->width  / 2.0;
   dh = elem->height / 2.0;
-  for (i = 0; i < NUM_CONNECTIONS-1; i++) {
-    real theta = M_PI / 8.0 * i;
-    real costheta = cos(theta);
-    real sintheta = sin(theta);
-    connpoint_update(&ellipse->connections[i],
-                     c.x + dw * costheta,
-                     c.y - dh * sintheta,
-                     (costheta > .5?DIR_EAST:(costheta < -.5?DIR_WEST:0))|
-                     (sintheta > .5?DIR_NORTH:(sintheta < -.5?DIR_SOUTH:0)));
+
+  for (int i = 0; i < NUM_CONNECTIONS - 1; i++) {
+    double theta = G_PI / 8.0 * i;
+    double costheta = cos (theta);
+    double sintheta = sin (theta);
+
+    connpoint_update (&ellipse->connections[i],
+                      c.x + dw * costheta,
+                      c.y - dh * sintheta,
+                      (costheta > .5 ? DIR_EAST : (costheta < -.5 ? DIR_WEST : 0)) |
+                      (sintheta > .5 ? DIR_NORTH : (sintheta < -.5 ? DIR_SOUTH : 0)));
   }
-  connpoint_update(&ellipse->connections[16],
-                  c.x, c.y, DIR_ALL);
+
+  connpoint_update (&ellipse->connections[16], c.x, c.y, DIR_ALL);
 
   extra->border_trans = ellipse->border_width / 2.0;
-  element_update_boundingbox(elem);
+  element_update_boundingbox (elem);
 
   obj->position = elem->corner;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 }
 
+
 static DiaObject *
 ellipse_create(Point *startpoint,
           void *user_data,
diff --git a/objects/network/basestation.c b/objects/network/basestation.c
index d6ec77aa5..219f42702 100644
--- a/objects/network/basestation.c
+++ b/objects/network/basestation.c
@@ -32,6 +32,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/basestation.xpm"
 
@@ -173,13 +174,20 @@ basestation_set_props(Basestation *basestation, GPtrArray *props)
   basestation_update_data(basestation);
 }
 
-static real
-basestation_distance_from(Basestation *basestation, Point *point)
+
+static double
+basestation_distance_from (Basestation *basestation, Point *point)
 {
-  DiaObject *obj = &basestation->element.object;
-  return distance_rectangle_point(&obj->bounding_box, point);
+  graphene_rect_t bbox;
+  DiaRectangle tmp;
+
+  dia_object_get_bounding_box (DIA_OBJECT (basestation), &bbox);
+  dia_graphene_to_rectangle (&bbox, &tmp);
+
+  return distance_rectangle_point (&tmp, point);
 }
 
+
 static void
 basestation_select(Basestation *basestation, Point *clicked_point,
                    DiaRenderer *interactive_renderer)
@@ -332,44 +340,48 @@ basestation_draw (Basestation *basestation, DiaRenderer *renderer)
   text_draw (basestation->text, renderer);
 }
 
+
 static void
-basestation_update_data(Basestation *basestation)
+basestation_update_data (Basestation *basestation)
 {
   Element *elem = &basestation->element;
   DiaObject *obj = &elem->object;
-  DiaRectangle text_box;
   Point p;
+  graphene_rect_t bbox, text_box;
 
   elem->width = BASESTATION_WIDTH;
   elem->height = BASESTATION_HEIGHT+basestation->text->height;
 
   p = elem->corner;
-  p.x += elem->width/2;
+  p.x += elem->width / 2;
   p.y += elem->height + basestation->text->ascent;
-  text_set_position(basestation->text, &p);
+  text_set_position (basestation->text, &p);
 
-  text_calc_boundingbox(basestation->text, &text_box);
+  text_calc_boundingbox (basestation->text, &text_box);
 
   /* Update connections: */
   element_update_connections_rectangle (elem, basestation->connections);
 
-  element_update_boundingbox(elem);
+  element_update_boundingbox (elem);
 
   /* Add bounding box for text: */
-  rectangle_union(&obj->bounding_box, &text_box);
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &text_box, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
 
   obj->position = elem->corner;
-  obj->position.x += elem->width/2.0;
-  obj->position.y += elem->height/2.0;
+  obj->position.x += elem->width / 2.0;
+  obj->position.y += elem->height / 2.0;
 
-  element_update_handles(elem);
+  element_update_handles (elem);
 }
 
+
 static DiaObject *
-basestation_create(Point *startpoint,
-                   void *user_data,
-                   Handle **handle1,
-                   Handle **handle2)
+basestation_create (Point   *startpoint,
+                    void    *user_data,
+                    Handle **handle1,
+                    Handle **handle2)
 {
   Basestation *basestation;
   Element *elem;
diff --git a/objects/network/bus.c b/objects/network/bus.c
index 6ba087bca..a70d2e8f7 100644
--- a/objects/network/bus.c
+++ b/objects/network/bus.c
@@ -29,6 +29,7 @@
 #include "attributes.h"
 #include "diamenu.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "pixmaps/bus.xpm"
 
@@ -446,15 +447,18 @@ bus_copy(Bus *bus)
 
 
 static void
-bus_update_data(Bus *bus)
+bus_update_data (Bus *bus)
 {
   Connection *conn = &bus->connection;
   DiaObject *obj = &conn->object;
   int i;
   Point u, v, vhat;
   Point *endpoints;
-  real ulen;
-  real min_par, max_par;
+  double ulen;
+  double min_par, max_par;
+  graphene_rect_t bbox;
+  graphene_point_t pt;
+
 
 /*
  * This seems to break stuff wildly.
@@ -498,16 +502,26 @@ bus_update_data(Bus *bus)
   point_scale(&bus->real_ends[1], max_par);
   point_add(&bus->real_ends[1], &endpoints[0]);
 
-  connection_update_boundingbox(conn);
-  rectangle_add_point(&obj->bounding_box, &bus->real_ends[0]);
-  rectangle_add_point(&obj->bounding_box, &bus->real_ends[1]);
-  for (i=0;i<bus->num_handles;i++) {
-    rectangle_add_point(&obj->bounding_box, &bus->handles[i]->pos);
+  connection_update_boundingbox (conn);
+
+  dia_object_get_bounding_box (obj, &bbox);
+
+  dia_point_to_graphene (&bus->real_ends[0], &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+  dia_point_to_graphene (&bus->real_ends[1], &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+
+  for (i = 0; i < bus->num_handles; i++) {
+    dia_point_to_graphene (&bus->handles[i]->pos, &pt);
+    graphene_rect_expand (&bbox, &pt, &bbox);
   }
 
-  connection_update_handles(conn);
+  dia_object_set_bounding_box (obj, &bbox);
+
+  connection_update_handles (conn);
 }
 
+
 static void
 bus_add_handle(Bus *bus, Point *p, Handle *handle)
 {
diff --git a/objects/network/radiocell.c b/objects/network/radiocell.c
index 8519da12d..be17035fd 100644
--- a/objects/network/radiocell.c
+++ b/objects/network/radiocell.c
@@ -32,6 +32,7 @@
 #include "attributes.h"
 #include "text.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "network.h"
 
@@ -269,48 +270,54 @@ radiocell_draw (RadioCell *radiocell, DiaRenderer *renderer)
   text_draw (radiocell->text, renderer);
 }
 
+
 static void
-radiocell_update_data(RadioCell *radiocell)
+radiocell_update_data (RadioCell *radiocell)
 {
   PolyShape *poly = &radiocell->poly;
   DiaObject *obj = &poly->object;
   ElementBBExtras *extra = &poly->extra_spacing;
-  DiaRectangle text_box;
   Point textpos;
-  int i;
   /* not exactly a regular hexagon, but this fits better in the grid */
   Point points[] = { {  1., 0. }, {  .5,  .75 }, { -.5,  .75 },
-                    { -1., 0. }, { -.5, -.75 }, {  .5, -.75 } };
+                     { -1., 0. }, { -.5, -.75 }, {  .5, -.75 } };
+  graphene_rect_t bbox, text_box;
 
   radiocell->center.x = (poly->points[0].x + poly->points[3].x) / 2.;
   radiocell->center.y = poly->points[0].y;
 
-  for (i = 0; i < 6; i++) {
+  for (int i = 0; i < 6; i++) {
     poly->points[i] = radiocell->center;
     poly->points[i].x += radiocell->radius * points[i].x;
     poly->points[i].y += radiocell->radius * points[i].y;
   }
 
   /* Add bounding box for text: */
-  text_calc_boundingbox(radiocell->text, NULL);
+  text_calc_boundingbox (radiocell->text, NULL);
   textpos.x = (poly->points[0].x + poly->points[3].x) / 2.;
   textpos.y = poly->points[0].y -
     (radiocell->text->height * (radiocell->text->numlines - 1) +
      radiocell->text->descent) / 2.;
-  text_set_position(radiocell->text, &textpos);
-  text_calc_boundingbox(radiocell->text, &text_box);
-  polyshape_update_data(poly);
+
+  text_set_position (radiocell->text, &textpos);
+  text_calc_boundingbox (radiocell->text, &text_box);
+  polyshape_update_data (poly);
   extra->border_trans = radiocell->line_width / 2.0;
-  polyshape_update_boundingbox(poly);
-  rectangle_union(&obj->bounding_box, &text_box);
+  polyshape_update_boundingbox (poly);
+
+  dia_object_get_bounding_box (obj, &bbox);
+  graphene_rect_union (&bbox, &text_box, &bbox);
+  dia_object_set_bounding_box (obj, &bbox);
+
   obj->position = poly->points[0];
 }
 
+
 static DiaObject *
-radiocell_create(Point *startpoint,
-                void *user_data,
-                Handle **handle1,
-                Handle **handle2)
+radiocell_create (Point   *startpoint,
+                  void    *user_data,
+                  Handle **handle1,
+                  Handle **handle2)
 {
   RadioCell *radiocell;
   PolyShape *poly;
diff --git a/objects/network/wanlink.c b/objects/network/wanlink.c
index db788708a..618752070 100644
--- a/objects/network/wanlink.c
+++ b/objects/network/wanlink.c
@@ -31,10 +31,7 @@
 #include "attributes.h"
 #include "properties.h"
 #include "network.h"
-
-#ifndef M_PI_2
-#define M_PI_2 1.57079632679489661923
-#endif
+#include "dia-graphene.h"
 
 #include "pixmaps/wanlink.xpm"
 
@@ -47,7 +44,7 @@ typedef struct _WanLink {
     Color line_color;
     Color fill_color;
 
-    real width;
+    float width;
     Point poly[WANLINK_POLY_LEN];
 } WanLink;
 
@@ -57,7 +54,7 @@ static DiaObject *wanlink_create(Point *startpoint,
                              Handle **handle2);
 static void wanlink_destroy(WanLink *wanlink);
 static void wanlink_draw (WanLink *wanlink, DiaRenderer *renderer);
-static real wanlink_distance_from(WanLink *wanlink, Point *point);
+static float wanlink_distance_from(WanLink *wanlink, Point *point);
 static void wanlink_select(WanLink *wanlink, Point *clicked_point,
                         DiaRenderer *interactive_renderer);
 static DiaObject *wanlink_copy(WanLink *wanlink);
@@ -104,15 +101,15 @@ static ObjectOps wanlink_ops =
 
 };
 
-DiaObjectType wanlink_type =
-{
-  "Network - WAN Link",   /* name */
-  1,                     /* version */
-  (const char **) wanlink_xpm, /* pixmap */
 
-  &wanlink_type_ops      /* ops */
+DiaObjectType wanlink_type = {
+  "Network - WAN Link",        /* name */
+  1,                           /* version */
+  (const char **) wanlink_xpm, /* pixmap */
+  &wanlink_type_ops            /* ops */
 };
 
+
 static PropDescription wanlink_props[] = {
   CONNECTION_COMMON_PROPERTIES,
   { "width", PROP_TYPE_REAL, PROP_FLAG_VISIBLE,
@@ -232,7 +229,7 @@ wanlink_draw (WanLink *wanlink, DiaRenderer *renderer)
                              &wanlink->line_color);
 }
 
-static real
+static float
 wanlink_distance_from(WanLink *wanlink, Point *point)
 {
   return distance_polygon_point (wanlink->poly, WANLINK_POLY_LEN, wanlink->width, point);
@@ -355,109 +352,59 @@ wanlink_load(ObjectNode obj_node, int version,DiaContext *ctx)
     return obj;
 }
 
-typedef real  Vector[3];
-typedef Vector  Matrix[3];
-
-static void
-_transform_point (Matrix m, Point *src, Point *dest)
-{
-  real xx, yy, ww;
-
-  xx = m[0][0] * src->x + m[0][1] * src->y + m[0][2];
-  yy = m[1][0] * src->x + m[1][1] * src->y + m[1][2];
-  ww = m[2][0] * src->x + m[2][1] * src->y + m[2][2];
-
-  if (!ww)
-    ww = 1.0;
-
-  dest->x = xx / ww;
-  dest->y = yy / ww;
-}
-static void
-_identity_matrix (Matrix m)
-{
-  int i, j;
-
-  for (i = 0; i < 3; i++)
-    for (j = 0; j < 3; j++)
-      m[i][j] = (i == j) ? 1 : 0;
 
-}
 static void
-_mult_matrix (Matrix m1, Matrix m2)
-{
-  Matrix result;
-  int i, j, k;
-
-  for (i = 0; i < 3; i++)
-    for (j = 0; j < 3; j++)
-      {
-       result [i][j] = 0.0;
-       for (k = 0; k < 3; k++)
-         result [i][j] += m1 [i][k] * m2[k][j];
-      }
-
-  /*  copy the result into matrix 2  */
-  for (i = 0; i < 3; i++)
-    for (j = 0; j < 3; j++)
-      m2 [i][j] = result [i][j];
-}
-static void
-_rotate_matrix (Matrix m, real theta)
-{
-  Matrix rotate;
-  real cos_theta, sin_theta;
-
-  cos_theta = cos (theta);
-  sin_theta = sin (theta);
-
-  _identity_matrix (rotate);
-  rotate[0][0] = cos_theta;
-  rotate[0][1] = -sin_theta;
-  rotate[1][0] = sin_theta;
-  rotate[1][1] = cos_theta;
-  _mult_matrix (rotate, m);
-}
-
-static void
-wanlink_update_data(WanLink *wanlink)
+wanlink_update_data (WanLink *wanlink)
 {
   Connection *conn = &wanlink->connection;
   DiaObject *obj = (DiaObject *) wanlink;
-  Point v, vhat;
-  Point *endpoints;
-  real width, width_2;
-  real len, angle;
+  //Point v, vhat;
+  graphene_vec2_t v, vhat;
+  graphene_vec2_t endpoints[2];
+  float width, width_2;
+  float len, angle;
   Point origin;
   int i;
-  Matrix m;
-
+  graphene_matrix_t m;
+  graphene_rect_t bbox;
+  graphene_point_t pt;
+  float tmp[GRAPHENE_VEC2_LEN];
 
   width = wanlink->width;
   width_2 = width / 2.0;
 
-  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
-      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
-    connection_adjust_for_autogap(conn);
+  if (connpoint_is_autogap (conn->endpoint_handles[0].connected_to) ||
+      connpoint_is_autogap (conn->endpoint_handles[1].connected_to)) {
+    connection_adjust_for_autogap (conn);
   }
-  endpoints = &conn->endpoints[0];
-  obj->position = endpoints[0];
 
-  v = endpoints[1];
-  point_sub(&v, &endpoints[0]);
-  if ((fabs(v.x) == 0.0) && (fabs(v.y)==0.0)) {
-    v.x += 0.01;
+  for (int j = 0; j < 2; j++) {
+    dia_point_to_vec2 (&conn->endpoints[j], &endpoints[j]);
   }
-  vhat = v;
-  point_normalize(&vhat);
 
-  connection_update_boundingbox(conn);
+  dia_vec2_to_point (&endpoints[0], &obj->position);
+
+  graphene_vec2_init_from_vec2 (&v, &endpoints[1]);
+  graphene_vec2_subtract (&v, &endpoints[0], &v);
+
+  graphene_vec2_to_float (&v, tmp);
+
+  if ((tmp[0] == 0.0) && (tmp[1] == 0.0)) {
+    graphene_vec2_init (&v, tmp[0] + 0.01, tmp[1]);
+  }
+
+  graphene_vec2_init_from_vec2 (&vhat, &v);
+  graphene_vec2_normalize (&vhat, &vhat);
+
+  connection_update_boundingbox (conn);
 
   /** compute the polygon **/
   origin = wanlink->connection.endpoints [0];
-  len = point_len (&v);
+  len = graphene_vec2_length (&v);
+
+  graphene_vec2_to_float (&vhat, tmp);
 
-  angle = atan2 (vhat.y, vhat.x) - M_PI_2;
+  angle = atan2 (tmp[1], tmp[0]) - G_PI_2;
 
     /* The case of the wanlink */
   wanlink->poly[0].x = (width * 0.50) - width_2;
@@ -474,28 +421,33 @@ wanlink_update_data(WanLink *wanlink)
   wanlink->poly[5].y = (len * 0.55);
 
   /* rotate */
-  _identity_matrix (m);
-  _rotate_matrix (m, angle);
-
-  obj->bounding_box.top = origin.y;
-  obj->bounding_box.left = origin.x;
-  obj->bounding_box.bottom = conn->endpoints[1].y;
-  obj->bounding_box.right = conn->endpoints[1].x;
-  for (i = 0; i <  WANLINK_POLY_LEN; i++)
-  {
-      Point new_pt;
-
-      _transform_point (m, &wanlink->poly[i],
-                       &new_pt);
-      point_add (&new_pt, &origin);
-      wanlink->poly[i] = new_pt;
+  graphene_matrix_init_identity (&m);
+  graphene_matrix_rotate_z (&m, DIA_DEGREES (angle));
+
+  graphene_rect_init (&bbox, origin.x, origin.y, 0, 0);
+  dia_point_to_graphene (&conn->endpoints[1], &pt);
+  graphene_rect_expand (&bbox, &pt, &bbox);
+
+  for (i = 0; i < WANLINK_POLY_LEN; i++) {
+    graphene_point_t tpt;
+    Point dpt;
+    graphene_point_t new_pt;
+
+    dia_point_to_graphene (&wanlink->poly[i], &tpt);
+    graphene_matrix_transform_point (&m, &tpt, &new_pt);
+    dia_graphene_to_point (&new_pt, &dpt);
+    point_add (&dpt, &origin);
+    wanlink->poly[i] = dpt;
   }
+
   /* calculate bounding box */
   {
-    PolyBBExtras bbex = {0, 0, wanlink->width/2, 0, 0 };
-    polyline_bbox (&wanlink->poly[0], WANLINK_POLY_LEN, &bbex, TRUE, &obj->bounding_box);
+    PolyBBExtras bbex = { 0, 0, wanlink->width / 2, 0, 0 };
+
+    polyline_bbox (&wanlink->poly[0], WANLINK_POLY_LEN, &bbex, TRUE, &bbox);
   }
 
+  dia_object_set_bounding_box (obj, &bbox);
 
-  connection_update_handles(conn);
+  connection_update_handles (conn);
 }
diff --git a/objects/standard/arc.c b/objects/standard/arc.c
index 425fc8358..c87acaabd 100644
--- a/objects/standard/arc.c
+++ b/objects/standard/arc.c
@@ -33,6 +33,8 @@
 #include "attributes.h"
 #include "arrows.h"
 #include "properties.h"
+#include "dia-graphene.h"
+
 
 #define DEFAULT_WIDTH 0.25
 
@@ -688,21 +690,21 @@ _arc_setup_handles(Arc *arc)
   arc->center_handle.connected_to = NULL;
 }
 
+
 static DiaObject *
-arc_create(Point *startpoint,
-          void *user_data,
-          Handle **handle1,
-          Handle **handle2)
+arc_create (Point   *startpoint,
+            void    *user_data,
+            Handle **handle1,
+            Handle **handle2)
 {
   Arc *arc;
   Connection *conn;
   DiaObject *obj;
   Point defaultlen = { 1.0, 1.0 };
 
-  arc = g_malloc0(sizeof(Arc));
-  arc->connection.object.enclosing_box = g_new0 (DiaRectangle, 1);
+  arc = g_new0 (Arc, 1);
 
-  arc->line_width =  attributes_get_default_linewidth();
+  arc->line_width = attributes_get_default_linewidth();
   arc->curve_distance = 1.0;
   arc->arc_color = attributes_get_foreground();
   attributes_get_default_line_style(&arc->line_style, &arc->dashlength);
@@ -731,15 +733,16 @@ arc_create(Point *startpoint,
   return &arc->connection.object;
 }
 
+
 static void
-arc_destroy(Arc *arc)
+arc_destroy (Arc *arc)
 {
-  g_clear_pointer (&arc->connection.object.enclosing_box, g_free);
-  connection_destroy(&arc->connection);
+  connection_destroy (&arc->connection);
 }
 
+
 static DiaObject *
-arc_copy(Arc *arc)
+arc_copy (Arc *arc)
 {
   Arc *newarc;
   Connection *conn, *newconn;
@@ -747,8 +750,8 @@ arc_copy(Arc *arc)
 
   conn = &arc->connection;
 
-  newarc = g_malloc0(sizeof(Arc));
-  newarc->connection.object.enclosing_box = g_new0 (DiaRectangle, 1);
+  newarc = g_new0 (Arc, 1);
+
   newconn = &newarc->connection;
   newobj = &newconn->object;
 
@@ -793,17 +796,19 @@ is_right_hand (const Point *a, const Point *b, const Point *c)
   return point_cross(&dot1, &dot2) > 0;
 }
 
+
 static void
-arc_update_data(Arc *arc)
+arc_update_data (Arc *arc)
 {
   Connection *conn = &arc->connection;
-  LineBBExtras *extra =&conn->extra_spacing;
+  LineBBExtras *extra = &conn->extra_spacing;
   DiaObject *obj = &conn->object;
   Point *endpoints;
-  real x1,y1,x2,y2,xc,yc;
-  real lensq, alpha, radius;
-  real angle1, angle2;
+  double x1, y1, x2, y2, xc, yc;
+  double lensq, alpha, radius;
+  double angle1, angle2;
   gboolean righthand;
+  graphene_rect_t bbox;
 
   endpoints = &arc->connection.endpoints[0];
   x1 = endpoints[0].x;
@@ -811,19 +816,21 @@ arc_update_data(Arc *arc)
   x2 = endpoints[1].x;
   y2 = endpoints[1].y;
 
-  lensq = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
-  if (fabs(arc->curve_distance) > 0.01)
-    radius = lensq/(8*arc->curve_distance) + arc->curve_distance/2.0;
-  else
+  lensq = ((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1));
+  if (fabs (arc->curve_distance) > 0.01) {
+    radius = (lensq / (8 * arc->curve_distance)) + (arc->curve_distance / 2.0);
+  } else {
     radius = 0.0; /* not really but used for bbox calculation below */
+  }
 
-  if (lensq == 0.0 || arc_is_line (arc))
+  if (lensq == 0.0 || arc_is_line (arc)) {
     alpha = 1.0; /* arbitrary, but /not/ 1/0  */
-  else
-    alpha = (radius - arc->curve_distance) / sqrt(lensq);
+  } else {
+    alpha = (radius - arc->curve_distance) / sqrt (lensq);
+  }
 
-  xc = (x1 + x2) / 2.0 + (y2 - y1)*alpha;
-  yc = (y1 + y2) / 2.0 + (x1 - x2)*alpha;
+  xc = (x1 + x2) / 2.0 + ((y2 - y1) * alpha);
+  yc = (y1 + y2) / 2.0 + ((x1 - x2) * alpha);
 
   angle1 = -atan2(y1-yc, x1-xc)*180.0/M_PI;
   if (angle1<0)
@@ -835,8 +842,8 @@ arc_update_data(Arc *arc)
   /* swap: draw_arc is not always counter-clockwise, but our member variables
    * stay counter-clockwise to keep all the internal calculations simple
    */
-  if (radius<0.0) {
-    real tmp;
+  if (radius < 0.0) {
+    double tmp;
     tmp = angle1;
     angle1 = angle2;
     angle2 = tmp;
@@ -855,91 +862,128 @@ arc_update_data(Arc *arc)
   extra->end_long    = (arc->line_width / 2.0);
 
   /* updates midpoint */
-  arc_update_handles(arc);
+  arc_update_handles (arc);
   /* startpoint, midpoint, endpoint */
   righthand = is_right_hand (&endpoints[0], &arc->middle_handle.pos, &endpoints[1]);
   /* there should be no need to calculate the direction once more */
   if (!(   (righthand && arc->curve_distance <= 0.0)
-        || (!righthand && arc->curve_distance >= 0.0)))
+        || (!righthand && arc->curve_distance >= 0.0))) {
     g_warning ("Standard - Arc: check invariant!");
-  connection_update_boundingbox(conn);
+  }
+  connection_update_boundingbox (conn);
+
+  dia_object_get_bounding_box (obj, &bbox);
 
   /* fix boundingbox for arc's special shape XXX find a more elegant way: */
-  if (in_angle(0, arc->angle1, arc->angle2)) {
+  if (in_angle (0, arc->angle1, arc->angle2)) {
     /* rigth side, y does not matter if included */
-    Point pt = { arc->center.x + arc->radius + (arc->line_width / 2.0), y1 };
-    rectangle_add_point (&obj->bounding_box, &pt);
+    graphene_point_t pt =
+      GRAPHENE_POINT_INIT (arc->center.x + arc->radius + (arc->line_width / 2.0), y1);
+
+    graphene_rect_expand (&bbox, &pt, &bbox);
   }
-  if (in_angle(90, arc->angle1, arc->angle2)) {
+
+  if (in_angle (90, arc->angle1, arc->angle2)) {
     /* top side, x does not matter if included */
-    Point pt = {x1, arc->center.y - arc->radius - (arc->line_width / 2.0) };
-    rectangle_add_point (&obj->bounding_box, &pt);
+    graphene_point_t pt =
+      GRAPHENE_POINT_INIT (x1, arc->center.y - arc->radius - (arc->line_width / 2.0));
+
+    graphene_rect_expand (&bbox, &pt, &bbox);
   }
-  if (in_angle(180, arc->angle1, arc->angle2)) {
+
+  if (in_angle (180, arc->angle1, arc->angle2)) {
     /* left side, y does not matter if included */
-    Point pt = { arc->center.x - arc->radius - (arc->line_width / 2.0), y1 };
-    rectangle_add_point (&obj->bounding_box, &pt);
+    graphene_point_t pt =
+      GRAPHENE_POINT_INIT (arc->center.x - arc->radius - (arc->line_width / 2.0), y1);
+
+    graphene_rect_expand (&bbox, &pt, &bbox);
   }
-  if (in_angle(270, arc->angle1, arc->angle2)) {
+
+  if (in_angle (270, arc->angle1, arc->angle2)) {
     /* bootom side, x does not matter if included */
-    Point pt = { x1, arc->center.y + arc->radius + (arc->line_width / 2.0) };
-    rectangle_add_point (&obj->bounding_box, &pt);
+    graphene_point_t pt =
+      GRAPHENE_POINT_INIT (x1, arc->center.y + arc->radius + (arc->line_width / 2.0));
+
+    graphene_rect_expand (&bbox, &pt, &bbox);
   }
+
   if (arc->start_arrow.type != ARROW_NONE) {
     /* a good from-point would be the chord of arrow length, but draw_arc_with_arrows
      * currently uses the tangent For big arcs the difference is not huge and the
      * minimum size of small arcs should be limited by the arror length.
      */
-    DiaRectangle bbox = {0,};
-    real tmp;
+    double tmp;
     Point move_arrow, move_line;
     Point to = arc->connection.endpoints[0];
     Point from = to;
+    graphene_rect_t rect;
+
     point_sub (&from, &arc->center);
+
     tmp = from.x;
-    if (righthand)
+    if (righthand) {
       from.x = -from.y, from.y = tmp;
-    else
+    } else {
       from.x = from.y, from.y = -tmp;
+    }
+
     point_add (&from, &to);
 
-    calculate_arrow_point(&arc->start_arrow, &to, &from,
-                          &move_arrow, &move_line, arc->line_width);
+    calculate_arrow_point (&arc->start_arrow, &to, &from,
+                           &move_arrow, &move_line, arc->line_width);
+
     /* move them */
-    point_sub(&to, &move_arrow);
-    point_sub(&from, &move_line);
-    arrow_bbox(&arc->start_arrow, arc->line_width, &to, &from, &bbox);
-    rectangle_union(&obj->bounding_box, &bbox);
+    point_sub (&to, &move_arrow);
+    point_sub (&from, &move_line);
+    arrow_bbox (&arc->start_arrow, arc->line_width, &to, &from, &rect);
+
+    graphene_rect_union (&bbox, &rect, &bbox);
   }
+
   if (arc->end_arrow.type != ARROW_NONE) {
-    DiaRectangle bbox = {0,};
-    real tmp;
+    double tmp;
     Point move_arrow, move_line;
     Point to = arc->connection.endpoints[1];
     Point from = to;
+    graphene_rect_t rect;
+
     point_sub (&from, &arc->center);
+
     tmp = from.x;
-    if (righthand)
+    if (righthand) {
       from.x = from.y, from.y = -tmp;
-    else
+    } else {
       from.x = -from.y, from.y = tmp;
+    }
+
     point_add (&from, &to);
-    calculate_arrow_point(&arc->end_arrow, &to, &from,
-                          &move_arrow, &move_line, arc->line_width);
+
+    calculate_arrow_point (&arc->end_arrow, &to, &from,
+                           &move_arrow, &move_line, arc->line_width);
+
     /* move them */
-    point_sub(&to, &move_arrow);
-    point_sub(&from, &move_line);
-    arrow_bbox(&arc->end_arrow, arc->line_width, &to, &from, &bbox);
-    rectangle_union(&obj->bounding_box, &bbox);
+    point_sub (&to, &move_arrow);
+    point_sub (&from, &move_line);
+    arrow_bbox (&arc->end_arrow, arc->line_width, &to, &from, &rect);
+
+    graphene_rect_union (&bbox, &rect, &bbox);
   }
+
+  dia_object_set_bounding_box (obj, &bbox);
+
   /* if selected put the centerpoint in the box, too. */
-  g_assert (obj->enclosing_box != NULL);
-  *obj->enclosing_box = obj->bounding_box;
-  rectangle_add_point(obj->enclosing_box, &arc->center);
+  {
+    graphene_point_t c;
+
+    dia_point_to_graphene (&arc->center, &c);
+    graphene_rect_expand (&bbox, &c, &bbox);
+    dia_object_set_enclosing_box (obj, &bbox);
+  }
 
   obj->position = conn->endpoints[0];
 }
 
+
 static void
 arc_save(Arc *arc, ObjectNode obj_node, DiaContext *ctx)
 {
@@ -981,16 +1025,16 @@ arc_save(Arc *arc, ObjectNode obj_node, DiaContext *ctx)
   }
 }
 
+
 static DiaObject *
-arc_load(ObjectNode obj_node, int version,DiaContext *ctx)
+arc_load (ObjectNode obj_node, int version, DiaContext *ctx)
 {
   Arc *arc;
   Connection *conn;
   DiaObject *obj;
   AttributeNode attr;
 
-  arc = g_malloc0(sizeof(Arc));
-  arc->connection.object.enclosing_box = g_new0 (DiaRectangle, 1);
+  arc = g_new0 (Arc, 1);
 
   conn = &arc->connection;
   obj = &conn->object;
diff --git a/objects/standard/bezier.c b/objects/standard/bezier.c
index 94913ab03..fbb703bb0 100644
--- a/objects/standard/bezier.c
+++ b/objects/standard/bezier.c
@@ -34,6 +34,8 @@
 #include "diamenu.h"
 #include "properties.h"
 #include "create.h"
+#include "dia-graphene.h"
+
 
 #define DEFAULT_WIDTH 0.15
 
@@ -450,8 +452,8 @@ bezierline_create(Point *startpoint,
   DiaObject *obj;
   Point defaultlen = { .3, .3 };
 
-  bezierline = g_new0(Bezierline, 1);
-  bezierline->bez.object.enclosing_box = g_new0 (DiaRectangle, 1);
+  bezierline = g_new0 (Bezierline, 1);
+
   bez = &bezierline->bez;
   obj = &bez->object;
 
@@ -492,13 +494,14 @@ bezierline_create(Point *startpoint,
   return &bezierline->bez.object;
 }
 
+
 static void
-bezierline_destroy(Bezierline *bezierline)
+bezierline_destroy (Bezierline *bezierline)
 {
-  g_clear_pointer (&bezierline->bez.object.enclosing_box, g_free);
-  bezierconn_destroy(&bezierline->bez);
+  bezierconn_destroy (&bezierline->bez);
 }
 
+
 static DiaObject *
 bezierline_copy(Bezierline *bezierline)
 {
@@ -507,8 +510,8 @@ bezierline_copy(Bezierline *bezierline)
 
   bez = &bezierline->bez;
 
-  newbezierline = g_new0(Bezierline, 1);
-  newbezierline->bez.object.enclosing_box = g_new0 (DiaRectangle, 1);
+  newbezierline = g_new0 (Bezierline, 1);
+
   newbez = &newbezierline->bez;
 
   bezierconn_copy(bez, newbez);
@@ -529,13 +532,13 @@ bezierline_copy(Bezierline *bezierline)
 
 
 static void
-bezierline_update_data(Bezierline *bezierline)
+bezierline_update_data (Bezierline *bezierline)
 {
   BezierConn *bez = &bezierline->bez;
   DiaObject *obj = &bez->object;
   PolyBBExtras *extra = &bez->extra_spacing;
 
-  bezierconn_update_data(bez);
+  bezierconn_update_data (bez);
 
   extra->start_trans = extra->start_long =
   extra->middle_trans =
@@ -543,61 +546,109 @@ bezierline_update_data(Bezierline *bezierline)
 
   obj->position = bez->bezier.points[0].p1;
 
-  if (connpoint_is_autogap(bez->object.handles[0]->connected_to) ||
-      connpoint_is_autogap(bez->object.handles[3*(bez->bezier.num_points-1)]->connected_to) ||
+  if (connpoint_is_autogap (bez->object.handles[0]->connected_to) ||
+      connpoint_is_autogap (bez->object.handles[3*(bez->bezier.num_points-1)]->connected_to) ||
       bezierline->absolute_start_gap || bezierline->absolute_end_gap ||
       bezierline->start_arrow.type != ARROW_NONE || bezierline->end_arrow.type != ARROW_NONE) {
     Point gap_points[4];
-    DiaRectangle bbox_union = {bez->bezier.points[0].p1.x, bez->bezier.points[0].p1.y,
-                           bez->bezier.points[0].p1.x, bez->bezier.points[0].p1.y};
-    compute_gap_points(bezierline, gap_points);
-    exchange_bez_gap_points(bez,gap_points);
+    graphene_rect_t arrows_bbox, bbox;
+
+    compute_gap_points (bezierline, gap_points);
+    exchange_bez_gap_points (bez, gap_points);
+
+    graphene_rect_init (&arrows_bbox,
+                        bez->bezier.points[0].p1.x,
+                        bez->bezier.points[0].p1.y,
+                        0,
+                        0);
+
     /* further modifying the points data, accounts for corrcet arrow and bezier bounding box */
     if (bezierline->start_arrow.type != ARROW_NONE) {
-      DiaRectangle bbox;
+      graphene_rect_t bbox_arrow;
       Point move_arrow, move_line;
       Point to = bez->bezier.points[0].p1, from = bez->bezier.points[1].p1;
 
-      calculate_arrow_point(&bezierline->start_arrow, &to, &from, &move_arrow, &move_line, 
bezierline->line_width);
-      point_sub(&to, &move_arrow);
-      point_sub(&bez->bezier.points[0].p1, &move_line);
-      arrow_bbox (&bezierline->start_arrow, bezierline->line_width, &to, &from, &bbox);
-      rectangle_union (&bbox_union, &bbox);
+      calculate_arrow_point (&bezierline->start_arrow,
+                             &to,
+                             &from,
+                             &move_arrow,
+                             &move_line,
+                             bezierline->line_width);
+
+      point_sub (&to, &move_arrow);
+      point_sub (&bez->bezier.points[0].p1, &move_line);
+
+      arrow_bbox (&bezierline->start_arrow,
+                  bezierline->line_width,
+                  &to,
+                  &from,
+                  &bbox_arrow);
+
+      graphene_rect_union (&arrows_bbox, &bbox_arrow, &arrows_bbox);
     }
+
     if (bezierline->end_arrow.type != ARROW_NONE) {
-      DiaRectangle bbox;
+      graphene_rect_t bbox_arrow;
       Point move_arrow, move_line;
       int num_points = bez->bezier.num_points;
       Point to = bez->bezier.points[num_points-1].p3, from = bez->bezier.points[num_points-1].p2;
 
-      calculate_arrow_point(&bezierline->end_arrow, &to, &from, &move_arrow, &move_line, 
bezierline->line_width);
-      point_sub(&to, &move_arrow);
-      point_sub(&bez->bezier.points[num_points-1].p3, &move_line);
-      arrow_bbox (&bezierline->end_arrow, bezierline->line_width, &to, &from, &bbox);
-      rectangle_union (&bbox_union, &bbox);
+      calculate_arrow_point (&bezierline->end_arrow,
+                             &to,
+                             &from,
+                             &move_arrow,
+                             &move_line,
+                             bezierline->line_width);
+
+      point_sub (&to, &move_arrow);
+      point_sub (&bez->bezier.points[num_points-1].p3, &move_line);
+
+      arrow_bbox (&bezierline->end_arrow,
+                  bezierline->line_width,
+                  &to,
+                  &from,
+                  &bbox_arrow);
+
+      graphene_rect_union (&arrows_bbox, &bbox_arrow, &arrows_bbox);
     }
-    bezierconn_update_boundingbox(bez);
-    rectangle_union (&obj->bounding_box, &bbox_union);
-    exchange_bez_gap_points(bez,gap_points);
+
+    bezierconn_update_boundingbox (bez);
+    dia_object_get_bounding_box (DIA_OBJECT (bez), &bbox);
+    graphene_rect_union (&bbox, &arrows_bbox, &bbox);
+    dia_object_set_bounding_box (obj, &bbox);
+
+    exchange_bez_gap_points (bez, gap_points);
   } else {
-    bezierconn_update_boundingbox(bez);
+    bezierconn_update_boundingbox (bez);
   }
-    /* add control points to the bounding box, needed to make them visible when showing all
-      * and to remove traces from them */
+
+  /* add control points to the bounding box, needed to make them visible when
+   * showing all and to remove traces from them
+   */
   {
-    int i, num_points = bez->bezier.num_points;
-    g_assert (obj->enclosing_box != NULL);
-    *obj->enclosing_box = obj->bounding_box;
+    int num_points = bez->bezier.num_points;
+    graphene_rect_t ebox;
+    graphene_point_t pt;
+
+    dia_object_get_bounding_box (obj, &ebox);
+
     /* starting with the second point, the first one is MOVE_TO */
-    for (i = 1; i < num_points; ++i) {
-      if (bez->bezier.points[i].type != BEZ_CURVE_TO)
+    for (int i = 1; i < num_points; ++i) {
+      if (bez->bezier.points[i].type != BEZ_CURVE_TO) {
         continue;
-      rectangle_add_point(obj->enclosing_box, &bez->bezier.points[i].p1);
-      rectangle_add_point(obj->enclosing_box, &bez->bezier.points[i].p2);
+      }
+
+      dia_point_to_graphene (&bez->bezier.points[i].p1, &pt);
+      graphene_rect_expand (&ebox, &pt, &ebox);
+      dia_point_to_graphene (&bez->bezier.points[i].p2, &pt);
+      graphene_rect_expand (&ebox, &pt, &ebox);
     }
+
+    dia_object_set_enclosing_box (obj, &ebox);
   }
 }
 
+
 static void
 bezierline_save(Bezierline *bezierline, ObjectNode obj_node,
                DiaContext *ctx)
@@ -663,8 +714,7 @@ bezierline_load(ObjectNode obj_node, int version, DiaContext *ctx)
   DiaObject *obj;
   AttributeNode attr;
 
-  bezierline = g_new0(Bezierline, 1);
-  bezierline->bez.object.enclosing_box = g_new0 (DiaRectangle, 1);
+  bezierline = g_new0 (Bezierline, 1);
 
   bez = &bezierline->bez;
   obj = &bez->object;
diff --git a/objects/standard/beziergon.c b/objects/standard/beziergon.c
index 9715f3705..e643bbd69 100644
--- a/objects/standard/beziergon.c
+++ b/objects/standard/beziergon.c
@@ -35,6 +35,8 @@
 #include "properties.h"
 #include "create.h"
 #include "pattern.h"
+#include "dia-graphene.h"
+
 
 #define DEFAULT_WIDTH 0.15
 
@@ -270,8 +272,8 @@ beziergon_create(Point *startpoint,
   Point defaultx = { 1.0, 0.0 };
   Point defaulty = { 0.0, 1.0 };
 
-  beziergon = g_new0(Beziergon, 1);
-  beziergon->bezier.object.enclosing_box = g_new0 (DiaRectangle, 1);
+  beziergon = g_new0 (Beziergon, 1);
+
   bez = &beziergon->bezier;
   obj = &bez->object;
 
@@ -319,10 +321,9 @@ beziergon_create(Point *startpoint,
 
 
 static void
-beziergon_destroy(Beziergon *beziergon)
+beziergon_destroy (Beziergon *beziergon)
 {
   g_clear_object (&beziergon->pattern);
-  g_clear_pointer (&beziergon->bezier.object.enclosing_box, g_free);
   beziershape_destroy (&beziergon->bezier);
 }
 
@@ -335,8 +336,8 @@ beziergon_copy(Beziergon *beziergon)
 
   bezier = &beziergon->bezier;
 
-  newbeziergon = g_malloc0(sizeof(Beziergon));
-  newbeziergon->bezier.object.enclosing_box = g_new0 (DiaRectangle, 1);
+  newbeziergon = g_new0 (Beziergon, 1);
+
   newbezier = &newbeziergon->bezier;
 
   beziershape_copy(bezier, newbezier);
@@ -355,32 +356,44 @@ beziergon_copy(Beziergon *beziergon)
 }
 
 static void
-beziergon_update_data(Beziergon *beziergon)
+beziergon_update_data (Beziergon *beziergon)
 {
   BezierShape *bez = &beziergon->bezier;
   DiaObject *obj = &bez->object;
   ElementBBExtras *extra = &bez->extra_spacing;
+  graphene_rect_t enclose;
 
-  beziershape_update_data(bez);
+  beziershape_update_data (bez);
 
   extra->border_trans = beziergon->line_width / 2.0;
-  beziershape_update_boundingbox(bez);
+  beziershape_update_boundingbox (bez);
+
+  dia_object_get_bounding_box (obj, &enclose);
 
   /* update the enclosing box using the control points */
   {
-    int i, num_points = bez->bezier.num_points;
-    g_assert (obj->enclosing_box != NULL);
-    *obj->enclosing_box = obj->bounding_box;
-    for (i = 0; i < num_points; ++i) {
-      if (bez->bezier.points[i].type != BEZ_CURVE_TO)
+    int num_points = bez->bezier.num_points;
+
+    for (int i = 0; i < num_points; ++i) {
+      graphene_point_t pt;
+
+      if (bez->bezier.points[i].type != BEZ_CURVE_TO) {
         continue;
-      rectangle_add_point(obj->enclosing_box, &bez->bezier.points[i].p1);
-      rectangle_add_point(obj->enclosing_box, &bez->bezier.points[i].p2);
+      }
+
+      dia_point_to_graphene (&bez->bezier.points[i].p1, &pt);
+      graphene_rect_expand (&enclose, &pt, &enclose);
+      dia_point_to_graphene (&bez->bezier.points[i].p2, &pt);
+      graphene_rect_expand (&enclose, &pt, &enclose);
     }
   }
+
+  dia_object_set_enclosing_box (obj, &enclose);
+
   obj->position = bez->bezier.points[0].p1;
 }
 
+
 static void
 beziergon_save(Beziergon *beziergon, ObjectNode obj_node,
               DiaContext *ctx)
@@ -428,8 +441,7 @@ beziergon_load(ObjectNode obj_node, int version, DiaContext *ctx)
   DiaObject *obj;
   AttributeNode attr;
 
-  beziergon = g_malloc0(sizeof(Beziergon));
-  beziergon->bezier.object.enclosing_box = g_new0 (DiaRectangle, 1);
+  beziergon = g_new0 (Beziergon, 1);
 
   bez = &beziergon->bezier;
   obj = &bez->object;
diff --git a/objects/standard/image.c b/objects/standard/image.c
index c8727fb32..77e4faba7 100644
--- a/objects/standard/image.c
+++ b/objects/standard/image.c
@@ -560,23 +560,27 @@ image_update_data (Image *image)
   element_update_connections_rectangle (elem, image->connections);
 
   if (image->angle != 0) {
-    real cx = elem->corner.x + elem->width / 2.0;
-    real cy = elem->corner.y + elem->height / 2.0;
+    double cx = elem->corner.x + elem->width / 2.0;
+    double cy = elem->corner.y + elem->height / 2.0;
     DiaMatrix m = { 1.0, 0.0, 0.0, 1.0, cx, cy };
     DiaMatrix t = { 1.0, 0.0, 0.0, 1.0, -cx, -cy };
-    int i;
     PolyBBExtras extraa = { 0, };
     Point poly[4];
-
+    graphene_rect_t bbox;
 
     dia_matrix_set_angle_and_scales (&m, G_PI*image->angle/180, 1.0, 1.0);
     dia_matrix_multiply (&m, &t, &m);
-    for (i = 0; i < 8; ++i)
+
+    for (int i = 0; i < 8; ++i) {
       transform_point (&image->connections[i].pos, &m);
+    }
 
     element_get_poly (elem, image->angle, poly);
     extraa.middle_trans = (image->draw_border ? image->border_width : 0.0);
-    polyline_bbox (poly, 4, &extraa, TRUE, &elem->object.bounding_box);
+
+    polyline_bbox (poly, 4, &extraa, TRUE, &bbox);
+
+    dia_object_set_bounding_box (DIA_OBJECT (image), &bbox);
   } else {
     /* the image border is drawn completely outside of the image, so no /2.0 on border width */
     extra->border_trans = (image->draw_border ? image->border_width : 0.0);
diff --git a/objects/standard/line.c b/objects/standard/line.c
index 9ed28996c..abfb463ac 100644
--- a/objects/standard/line.c
+++ b/objects/standard/line.c
@@ -33,6 +33,8 @@
 #include "connpoint_line.h"
 #include "properties.h"
 #include "create.h"
+#include "dia-graphene.h"
+
 
 #define DEFAULT_WIDTH 0.25
 
@@ -574,8 +576,9 @@ line_copy(Line *line)
   return &newline->connection.object;
 }
 
+
 static void
-line_update_data(Line *line)
+line_update_data (Line *line)
 {
   Connection *conn = &line->connection;
   DiaObject *obj = &conn->object;
@@ -587,58 +590,78 @@ line_update_data(Line *line)
   extra->start_long  =
   extra->end_long    = (line->line_width / 2.0);
 
-  if (connpoint_is_autogap(line->connection.endpoint_handles[0].connected_to) ||
-      connpoint_is_autogap(line->connection.endpoint_handles[1].connected_to)) {
-    connection_adjust_for_autogap(conn);
+  if (connpoint_is_autogap (line->connection.endpoint_handles[0].connected_to) ||
+      connpoint_is_autogap (line->connection.endpoint_handles[1].connected_to)) {
+    connection_adjust_for_autogap (conn);
   }
+
   if (line->absolute_start_gap || line->absolute_end_gap ) {
     Point gap_endpoints[2];
+    graphene_rect_t bbox;
+    graphene_vec2_t p1, p2;
+
+    line_adjust_for_absolute_gap (line, gap_endpoints);
+
+    graphene_vec2_init (&p1, gap_endpoints[0].x, gap_endpoints[0].y);
+    graphene_vec2_init (&p2, gap_endpoints[1].x, gap_endpoints[1].y);
+
+    line_bbox (&p1, &p2, &conn->extra_spacing, &bbox);
+
+    dia_object_set_bounding_box (DIA_OBJECT (line), &bbox);
 
-    line_adjust_for_absolute_gap(line, gap_endpoints);
-    line_bbox(&gap_endpoints[0],&gap_endpoints[1],
-             &conn->extra_spacing,&conn->object.bounding_box);
     start = gap_endpoints[0];
     end = gap_endpoints[1];
   } else {
-    connection_update_boundingbox(conn);
+    connection_update_boundingbox (conn);
     start = conn->endpoints[0];
     end = conn->endpoints[1];
   }
+
   if (line->start_arrow.type != ARROW_NONE) {
-    DiaRectangle bbox;
     Point move_arrow, move_line;
     Point to = start;
     Point from = end;
-    calculate_arrow_point(&line->start_arrow, &to, &from,
-                          &move_arrow, &move_line, line->line_width);
+    graphene_rect_t bbox, rect;
+
+    calculate_arrow_point (&line->start_arrow, &to, &from,
+                           &move_arrow, &move_line, line->line_width);
     /* move them */
-    point_sub(&to, &move_arrow);
-    point_sub(&from, &move_line);
+    point_sub (&to, &move_arrow);
+    point_sub (&from, &move_line);
+
+    arrow_bbox (&line->start_arrow, line->line_width, &to, &from, &rect);
 
-    arrow_bbox (&line->start_arrow, line->line_width, &to, &from, &bbox);
-    rectangle_union (&obj->bounding_box, &bbox);
+    dia_object_get_bounding_box (obj, &bbox);
+    graphene_rect_union (&bbox, &rect, &bbox);
+    dia_object_set_bounding_box (obj, &bbox);
   }
+
   if (line->end_arrow.type != ARROW_NONE) {
-    DiaRectangle bbox;
     Point move_arrow, move_line;
     Point to = end;
     Point from = start;
-    calculate_arrow_point(&line->end_arrow, &to, &from,
-                          &move_arrow, &move_line, line->line_width);
+    graphene_rect_t bbox, rect;
+
+    calculate_arrow_point (&line->end_arrow, &to, &from,
+                           &move_arrow, &move_line, line->line_width);
+
     /* move them */
     point_sub(&to, &move_arrow);
     point_sub(&from, &move_line);
 
-    arrow_bbox (&line->end_arrow, line->line_width, &to, &from, &bbox);
-    rectangle_union (&obj->bounding_box, &bbox);
+    arrow_bbox (&line->end_arrow, line->line_width, &to, &from, &rect);
+
+    dia_object_get_bounding_box (obj, &bbox);
+    graphene_rect_union (&bbox, &rect, &bbox);
+    dia_object_set_bounding_box (obj, &bbox);
   }
 
   obj->position = conn->endpoints[0];
 
-  connpointline_update(line->cpl);
-  connpointline_putonaline(line->cpl, &start, &end, DIR_ALL);
+  connpointline_update (line->cpl);
+  connpointline_putonaline (line->cpl, &start, &end, DIR_ALL);
 
-  connection_update_handles(conn);
+  connection_update_handles (conn);
 }
 
 
diff --git a/objects/standard/outline.c b/objects/standard/outline.c
index 41108d495..1a1343a46 100644
--- a/objects/standard/outline.c
+++ b/objects/standard/outline.c
@@ -300,11 +300,17 @@ outline_update_data (Outline *outline)
   outline->ink_rect[2].y = y + extents.width * outline->mat.yx + extents.height * outline->mat.yy;
   outline->ink_rect[3].x = x + extents.height * outline->mat.xy;
   outline->ink_rect[3].y = y + extents.height * outline->mat.yy;
+
+  
   /* x_advance? */
   /* calculate bounding box */
   {
     PolyBBExtras bbex = {0, 0, outline->line_width/2, 0, 0 };
-    polyline_bbox (&outline->ink_rect[0], 4, &bbex, TRUE, &obj->bounding_box);
+    graphene_rect_t bbox;
+
+    polyline_bbox (&outline->ink_rect[0], 4, &bbex, TRUE, &bbox);
+
+    dia_object_set_bounding_box (DIA_OBJECT (outline), &bbox);
   }
 
   outline_update_handles (outline),
diff --git a/objects/standard/polyline.c b/objects/standard/polyline.c
index 0f15467e7..7f4f34255 100644
--- a/objects/standard/polyline.c
+++ b/objects/standard/polyline.c
@@ -29,6 +29,7 @@
 #include "attributes.h"
 #include "diamenu.h"
 #include "properties.h"
+#include "dia-graphene.h"
 
 #include "create.h"
 
@@ -409,15 +410,17 @@ polyline_copy(Polyline *polyline)
   return &newpolyline->poly.object;
 }
 
+
 static void
-polyline_update_data(Polyline *polyline)
+polyline_update_data (Polyline *polyline)
 {
   PolyConn *poly = &polyline->poly;
   DiaObject *obj = &poly->object;
   PolyBBExtras *extra = &poly->extra_spacing;
   Point gap_endpoints[2];
+  graphene_rect_t bbox;
 
-  polyconn_update_data(&polyline->poly);
+  polyconn_update_data (&polyline->poly);
 
   extra->start_trans =  (polyline->line_width / 2.0);
   extra->end_trans =     (polyline->line_width / 2.0);
@@ -425,46 +428,62 @@ polyline_update_data(Polyline *polyline)
   extra->start_long = (polyline->line_width / 2.0);
   extra->end_long   = (polyline->line_width / 2.0);
 
-  polyline_calculate_gap_endpoints(polyline, gap_endpoints);
-  polyline_exchange_gap_points(polyline, gap_endpoints);
+  polyline_calculate_gap_endpoints (polyline, gap_endpoints);
+  polyline_exchange_gap_points (polyline, gap_endpoints);
+
+  polyconn_update_boundingbox (poly);
 
-  polyconn_update_boundingbox(poly);
+  dia_object_get_bounding_box (DIA_OBJECT (polyline), &bbox);
 
   if (polyline->start_arrow.type != ARROW_NONE) {
-    DiaRectangle bbox;
     Point move_arrow, move_line;
     Point to = gap_endpoints[0];
     Point from = poly->points[1];
-    calculate_arrow_point(&polyline->start_arrow, &to, &from,
-                          &move_arrow, &move_line, polyline->line_width);
+    graphene_rect_t bbox_arrow;
+
+    calculate_arrow_point (&polyline->start_arrow, &to, &from,
+                           &move_arrow, &move_line, polyline->line_width);
+
     /* move them */
-    point_sub(&to, &move_arrow);
-    point_sub(&from, &move_line);
+    point_sub (&to, &move_arrow);
+    point_sub (&from, &move_line);
 
-    arrow_bbox (&polyline->start_arrow, polyline->line_width, &to, &from, &bbox);
-    rectangle_union (&obj->bounding_box, &bbox);
+    arrow_bbox (&polyline->start_arrow,
+                polyline->line_width,
+                &to,
+                &from,
+                &bbox_arrow);
+
+    graphene_rect_union (&bbox, &bbox_arrow, &bbox);
   }
+
   if (polyline->end_arrow.type != ARROW_NONE) {
-    DiaRectangle bbox;
     int n = polyline->poly.numpoints;
     Point move_arrow, move_line;
     Point to = gap_endpoints[1];
     Point from = poly->points[n-2];
-    calculate_arrow_point(&polyline->end_arrow, &to, &from,
-                          &move_arrow, &move_line, polyline->line_width);
+    graphene_rect_t bbox_arrow;
+
+    calculate_arrow_point (&polyline->end_arrow, &to, &from,
+                           &move_arrow, &move_line, polyline->line_width);
+
     /* move them */
-    point_sub(&to, &move_arrow);
-    point_sub(&from, &move_line);
+    point_sub (&to, &move_arrow);
+    point_sub (&from, &move_line);
+
+    arrow_bbox (&polyline->end_arrow, polyline->line_width, &to, &from, &bbox_arrow);
 
-    arrow_bbox (&polyline->end_arrow, polyline->line_width, &to, &from, &bbox);
-    rectangle_union (&obj->bounding_box, &bbox);
+    graphene_rect_union (&bbox, &bbox_arrow, &bbox);
   }
 
-  polyline_exchange_gap_points(polyline, gap_endpoints);
+  dia_object_set_bounding_box (DIA_OBJECT (polyline), &bbox);
+
+  polyline_exchange_gap_points (polyline, gap_endpoints);
 
   obj->position = poly->points[0];
 }
 
+
 static void
 polyline_save(Polyline *polyline, ObjectNode obj_node,
              DiaContext *ctx)
diff --git a/objects/standard/textobj.c b/objects/standard/textobj.c
index e2b2e850c..2fb6beef3 100644
--- a/objects/standard/textobj.c
+++ b/objects/standard/textobj.c
@@ -34,6 +34,8 @@
 #include "create.h"
 #include "message.h" /* just dia_log_message */
 #include "dia-object-change-list.h"
+#include "dia-graphene.h"
+
 
 #define HANDLE_TEXT HANDLE_CUSTOM1
 
@@ -206,24 +208,24 @@ textobj_set_props(Textobj *textobj, GPtrArray *props)
   textobj_update_data(textobj);
 }
 
+
 static void
 _textobj_get_poly (const Textobj *textobj, Point poly[4])
 {
-  Point ul, lr;
+  graphene_point_t ul, lr;
   Point pt = textobj->text_handle.pos;
-  DiaRectangle box;
+  graphene_rect_t box;
   DiaMatrix m = { 1, 0, 0, 1, pt.x, pt.y };
   DiaMatrix t = { 1, 0, 0, 1, -pt.x, -pt.y };
-  int i;
 
   dia_matrix_set_angle_and_scales (&m, G_PI * textobj->text_angle / 180.0, 1.0, 1.0);
   dia_matrix_multiply (&m, &t, &m);
 
   text_calc_boundingbox (textobj->text, &box);
-  ul.x = box.left - textobj->margin;
-  ul.y = box.top - textobj->margin;
-  lr.x = box.right + textobj->margin;
-  lr.y = box.bottom + textobj->margin;
+  graphene_rect_inset (&box, -textobj->margin, -textobj->margin);
+
+  graphene_rect_get_top_left (&box, &ul);
+  graphene_rect_get_bottom_right (&box, &lr);
 
   poly[0].x = ul.x;
   poly[0].y = ul.y;
@@ -234,24 +236,36 @@ _textobj_get_poly (const Textobj *textobj, Point poly[4])
   poly[3].x = ul.x;
   poly[3].y = lr.y;
 
-  for (i = 0; i < 4; ++i)
+  for (int i = 0; i < 4; ++i) {
     transform_point (&poly[i], &m);
+  }
 }
 
-static real
-textobj_distance_from(Textobj *textobj, Point *point)
+
+static double
+textobj_distance_from (Textobj *textobj, Point *point)
 {
   if (textobj->text_angle != 0) {
     Point poly[4];
 
     _textobj_get_poly (textobj, poly);
-    return distance_polygon_point(poly, 4, 0.0, point);
+    return distance_polygon_point (poly, 4, 0.0, point);
+  }
+
+  if (textobj->show_background) {
+    graphene_rect_t bbox;
+    DiaRectangle tmp;
+
+    dia_object_get_bounding_box (DIA_OBJECT (textobj), &bbox);
+    dia_graphene_to_rectangle (&bbox, &tmp);
+
+    return distance_rectangle_point (&tmp, point);
   }
-  if (textobj->show_background)
-    return distance_rectangle_point(&textobj->object.bounding_box, point);
-  return text_distance_from(textobj->text, point);
+
+  return text_distance_from (textobj->text, point);
 }
 
+
 static void
 textobj_select(Textobj *textobj, Point *clicked_point,
               DiaRenderer *interactive_renderer)
@@ -293,19 +307,26 @@ textobj_move (Textobj *textobj, Point *to)
 
 
 static void
-textobj_draw(Textobj *textobj, DiaRenderer *renderer)
+textobj_draw (Textobj *textobj, DiaRenderer *renderer)
 {
-  assert(textobj != NULL);
-  assert(renderer != NULL);
+  g_return_if_fail (textobj != NULL);
+  g_return_if_fail (renderer != NULL);
 
   if (textobj->show_background) {
-    DiaRectangle box;
+    graphene_rect_t box;
     Point ul, lr;
+    graphene_point_t tl, br;
+
     text_calc_boundingbox (textobj->text, &box);
-    ul.x = box.left - textobj->margin;
-    ul.y = box.top - textobj->margin;
-    lr.x = box.right + textobj->margin;
-    lr.y = box.bottom + textobj->margin;
+
+    graphene_rect_inset (&box, -textobj->margin, -textobj->margin);
+
+    graphene_rect_get_top_left (&box, &tl);
+    dia_graphene_to_point (&tl, &ul);
+
+    graphene_rect_get_bottom_right (&box, &br);
+    dia_graphene_to_point (&br, &lr);
+
     if (textobj->text_angle == 0) {
       dia_renderer_draw_rect (renderer, &ul, &lr, &textobj->fill_color, NULL);
     } else {
@@ -315,6 +336,7 @@ textobj_draw(Textobj *textobj, DiaRenderer *renderer)
       dia_renderer_draw_polygon (renderer, poly, 4, &textobj->fill_color, NULL);
     }
   }
+
   if (textobj->text_angle == 0) {
     text_draw (textobj->text, renderer);
   } else {
@@ -322,6 +344,7 @@ textobj_draw(Textobj *textobj, DiaRenderer *renderer)
                                     textobj->text,
                                     &textobj->text_handle.pos,
                                     textobj->text_angle);
+
     /* XXX: interactive case not working correctly */
     if (DIA_IS_INTERACTIVE_RENDERER (renderer) &&
         dia_object_is_selected (&textobj->object) &&
@@ -334,22 +357,26 @@ textobj_draw(Textobj *textobj, DiaRenderer *renderer)
 
 
 static void
-textobj_valign_point (Textobj *textobj, Point* p)
+textobj_valign_point (Textobj *textobj, Point *p)
 {
-  DiaRectangle *bb  = &(textobj->object.bounding_box);
-  real offset;
+  graphene_rect_t bbox;
+  DiaRectangle bb;
+  double offset;
+
+  dia_object_get_bounding_box (DIA_OBJECT (textobj), &bbox);
+  dia_graphene_to_rectangle (&bbox, &bb);
 
   switch (textobj->vert_align){
     case VALIGN_BOTTOM:
-      offset = bb->bottom - textobj->object.position.y;
+      offset = bb.bottom - textobj->object.position.y;
       p->y -= offset;
       break;
     case VALIGN_TOP:
-      offset = bb->top - textobj->object.position.y;
+      offset = bb.top - textobj->object.position.y;
       p->y -= offset;
       break;
     case VALIGN_CENTER:
-      offset = (bb->bottom + bb->top)/2 - textobj->object.position.y;
+      offset = ((bb.bottom + bb.top) / 2) - textobj->object.position.y;
       p->y -= offset;
       break;
     case VALIGN_FIRST_LINE:
@@ -365,62 +392,70 @@ textobj_update_data (Textobj *textobj)
 {
   Point to2;
   DiaObject *obj = &textobj->object;
-  DiaRectangle tx_bb;
+  graphene_rect_t bbox, tx_bb;
 
-  text_set_position(textobj->text, &obj->position);
-  text_calc_boundingbox(textobj->text, &obj->bounding_box);
+  text_set_position (textobj->text, &obj->position);
+  text_calc_boundingbox (textobj->text, &bbox);
 
   to2 = obj->position;
-  textobj_valign_point(textobj, &to2);
+  textobj_valign_point (textobj, &to2);
+
   /* shift text position depending on text alignment */
-  if (VALIGN_TOP == textobj->vert_align)
+  if (VALIGN_TOP == textobj->vert_align) {
     to2.y += textobj->margin; /* down */
-  else if (VALIGN_BOTTOM == textobj->vert_align)
+  } else if (VALIGN_BOTTOM == textobj->vert_align) {
     to2.y -= textobj->margin; /* up */
-  if (ALIGN_LEFT == textobj->text->alignment)
+  }
+
+  if (ALIGN_LEFT == textobj->text->alignment) {
     to2.x += textobj->margin; /* right */
-  else if (ALIGN_RIGHT == textobj->text->alignment)
+  } else if (ALIGN_RIGHT == textobj->text->alignment) {
     to2.x -= textobj->margin; /* left */
-  text_set_position(textobj->text, &to2);
+  }
+
+  text_set_position (textobj->text, &to2);
 
   /* always use the unrotated box ... */
-  text_calc_boundingbox(textobj->text, &tx_bb);
+  text_calc_boundingbox (textobj->text, &tx_bb);
+
   /* grow the bounding box by 2x margin */
-  obj->bounding_box.top    -= textobj->margin;
-  obj->bounding_box.left   -= textobj->margin;
-  obj->bounding_box.bottom += textobj->margin;
-  obj->bounding_box.right  += textobj->margin;
+  graphene_rect_inset (&bbox, -textobj->margin, -textobj->margin);
 
   textobj->text_handle.pos = obj->position;
   if (textobj->text_angle == 0) {
-    obj->bounding_box = tx_bb;
-    g_return_if_fail (obj->enclosing_box != NULL);
-    *obj->enclosing_box = tx_bb;
+    dia_object_set_bounding_box (obj, &tx_bb);
+    dia_object_set_enclosing_box (obj, &tx_bb);
   } else {
     /* ... and grow it when necessary */
     Point poly[4];
-    int i;
 
     _textobj_get_poly (textobj, poly);
     /* we don't want the joined box for boundingbox because
      * selection would become too greedy than.
      */
-    obj->bounding_box.left = obj->bounding_box.right = poly[0].x;
-    obj->bounding_box.top = obj->bounding_box.bottom = poly[0].y;
-    for (i = 1; i < 4; ++i)
-      rectangle_add_point (&obj->bounding_box, &poly[i]);
-    g_return_if_fail (obj->enclosing_box != NULL);
-    *obj->enclosing_box = obj->bounding_box;
+
+    graphene_rect_init (&bbox, poly[0].x, poly[0].y, 0, 0);
+
+    for (int i = 1; i < 4; ++i) {
+      graphene_point_t pt;
+      dia_point_to_graphene (&poly[i], &pt);
+      graphene_rect_expand (&bbox, &pt, &bbox);
+    }
+
+    dia_object_set_bounding_box (obj, &bbox);
+
     /* join for editing/selection bbox */
-    rectangle_union (obj->enclosing_box, &tx_bb);
+    graphene_rect_union (&bbox, &tx_bb, &bbox);
+    dia_object_set_enclosing_box (obj, &bbox);
   }
 }
 
+
 static DiaObject *
-textobj_create(Point *startpoint,
-              void *user_data,
-              Handle **handle1,
-              Handle **handle2)
+textobj_create (Point   *startpoint,
+                void    *user_data,
+                Handle **handle1,
+                Handle **handle2)
 {
   Textobj *textobj;
   DiaObject *obj;
@@ -428,9 +463,8 @@ textobj_create(Point *startpoint,
   DiaFont *font = NULL;
   real font_height;
 
-  textobj = g_malloc0(sizeof(Textobj));
+  textobj = g_new0 (Textobj, 1);
   obj = &textobj->object;
-  obj->enclosing_box = g_new0 (DiaRectangle, 1);
 
   obj->type = &textobj_type;
 
@@ -467,23 +501,28 @@ textobj_create(Point *startpoint,
   return &textobj->object;
 }
 
+
 static DiaObject *
-textobj_copy(Textobj *textobj)
+textobj_copy (Textobj *textobj)
 {
-  Textobj *copied = (Textobj *)object_copy_using_properties(&textobj->object);
-  copied->object.enclosing_box = g_new (DiaRectangle, 1);
-  *copied->object.enclosing_box = *textobj->object.enclosing_box;
+  graphene_rect_t ebox;
+  Textobj *copied = (Textobj *) object_copy_using_properties (&textobj->object);
+
+  dia_object_get_enclosing_box (DIA_OBJECT (textobj), &ebox);
+  dia_object_set_enclosing_box (DIA_OBJECT (copied), &ebox);
+
   return &copied->object;
 }
 
+
 static void
-textobj_destroy(Textobj *textobj)
+textobj_destroy (Textobj *textobj)
 {
-  text_destroy(textobj->text);
-  g_clear_pointer (&textobj->object.enclosing_box, g_free);
-  object_destroy(&textobj->object);
+  text_destroy (textobj->text);
+  object_destroy (&textobj->object);
 }
 
+
 static void
 textobj_save(Textobj *textobj, ObjectNode obj_node, DiaContext *ctx)
 {
@@ -512,9 +551,8 @@ textobj_load(ObjectNode obj_node, int version, DiaContext *ctx)
   AttributeNode attr;
   Point startpoint = {0.0, 0.0};
 
-  textobj = g_malloc0(sizeof(Textobj));
+  textobj = g_new0 (Textobj, 1);
   obj = &textobj->object;
-  obj->enclosing_box = g_new0 (DiaRectangle,1);
 
   obj->type = &textobj_type;
   obj->ops = &textobj_ops;
diff --git a/objects/standard/zigzagline.c b/objects/standard/zigzagline.c
index 8e7833397..2ab0811a0 100644
--- a/objects/standard/zigzagline.c
+++ b/objects/standard/zigzagline.c
@@ -317,14 +317,15 @@ zigzagline_copy(Zigzagline *zigzagline)
   return &newzigzagline->orth.object;
 }
 
+
 static void
-zigzagline_update_data(Zigzagline *zigzagline)
+zigzagline_update_data (Zigzagline *zigzagline)
 {
   OrthConn *orth = &zigzagline->orth;
-  DiaObject *obj = &orth->object;
   PolyBBExtras *extra = &orth->extra_spacing;
+  graphene_rect_t bbox, rect;
 
-  orthconn_update_data(&zigzagline->orth);
+  orthconn_update_data (&zigzagline->orth);
 
   extra->start_long =
     extra->end_long =
@@ -332,37 +333,60 @@ zigzagline_update_data(Zigzagline *zigzagline)
     extra->start_trans =
     extra->end_trans = (zigzagline->line_width / 2.0);
 
-  orthconn_update_boundingbox(orth);
+  orthconn_update_boundingbox (orth);
+
+  dia_object_get_bounding_box (DIA_OBJECT (zigzagline), &bbox);
 
   if (zigzagline->start_arrow.type != ARROW_NONE) {
-    DiaRectangle bbox;
     Point move_arrow, move_line;
     Point to = orth->points[0];
     Point from = orth->points[1];
-    calculate_arrow_point(&zigzagline->start_arrow, &to, &from,
-                          &move_arrow, &move_line, zigzagline->line_width);
-    /* move them */
-    point_sub(&to, &move_arrow);
-    point_sub(&from, &move_line);
 
-    arrow_bbox (&zigzagline->start_arrow, zigzagline->line_width, &to, &from, &bbox);
-    rectangle_union (&obj->bounding_box, &bbox);
+    calculate_arrow_point (&zigzagline->start_arrow,
+                           &to,
+                           &from,
+                           &move_arrow,
+                           &move_line,
+                           zigzagline->line_width);
+
+    /* move them */
+    point_sub (&to, &move_arrow);
+    point_sub (&from, &move_line);
+
+    arrow_bbox (&zigzagline->start_arrow,
+                zigzagline->line_width,
+                &to,
+                &from,
+                &rect);
+    graphene_rect_union (&bbox, &rect, &bbox);
   }
+
   if (zigzagline->end_arrow.type != ARROW_NONE) {
-    DiaRectangle bbox;
     Point move_arrow, move_line;
     int n = orth->numpoints;
-    Point to = orth->points[n-1];
-    Point from = orth->points[n-2];
-    calculate_arrow_point(&zigzagline->end_arrow, &to, &from,
-                          &move_arrow, &move_line, zigzagline->line_width);
-    /* move them */
-    point_sub(&to, &move_arrow);
-    point_sub(&from, &move_line);
+    Point to = orth->points[n - 1];
+    Point from = orth->points[n - 2];
+
+    calculate_arrow_point (&zigzagline->end_arrow,
+                           &to,
+                           &from,
+                           &move_arrow,
+                           &move_line,
+                           zigzagline->line_width);
 
-    arrow_bbox (&zigzagline->end_arrow, zigzagline->line_width, &to, &from, &bbox);
-    rectangle_union (&obj->bounding_box, &bbox);
+    /* move them */
+    point_sub (&to, &move_arrow);
+    point_sub (&from, &move_line);
+
+    arrow_bbox (&zigzagline->end_arrow,
+                zigzagline->line_width,
+                &to,
+                &from,
+                &rect);
+    graphene_rect_union (&bbox, &rect, &bbox);
   }
+
+  dia_object_set_bounding_box (DIA_OBJECT (zigzagline), &bbox);
 }
 
 
diff --git a/plug-ins/layout/layout.cpp b/plug-ins/layout/layout.cpp
index 10888a6b9..5d989715f 100644
--- a/plug-ins/layout/layout.cpp
+++ b/plug-ins/layout/layout.cpp
@@ -241,17 +241,25 @@ layout_callback (DiagramData     *data,
   } else {
     IGraph *g = func ? func () : NULL;
 
-    if (!g)
+    if (!g) {
       message_error (_("Graph creation failed"));
-    else {
+    } else {
       std::vector<double> coords;
 
       /* transfer nodes and edges */
-      for (list = nodes; list != NULL; list = g_list_next(list)) {
-        DiaObject *o = (DiaObject *)list->data;
-        const DiaRectangle *bbox = dia_object_get_bounding_box (o);
-        g->AddNode (bbox->left, bbox->top, bbox->right, bbox->bottom);
+      for (list = nodes; list != NULL; list = g_list_next (list)) {
+        DiaObject *o = DIA_OBJECT (list->data);
+        graphene_rect_t bbox;
+        graphene_point_t tl, br;
+
+        dia_object_get_bounding_box (o, &bbox);
+
+        graphene_rect_get_top_left (&bbox, &tl);
+        graphene_rect_get_bottom_right (&bbox, &br);
+
+        g->AddNode (tl.x, tl.y, br.x, br.y);
       }
+
       for (list = edges; list != NULL; list = g_list_next(list)) {
         DiaObject *o = (DiaObject *)list->data;
         DiaObject *src = o->handles[0]->connected_to->object;
diff --git a/plug-ins/metapost/render_metapost.c b/plug-ins/metapost/render_metapost.c
index e20b7a972..b0faa1e68 100644
--- a/plug-ins/metapost/render_metapost.c
+++ b/plug-ins/metapost/render_metapost.c
@@ -840,12 +840,12 @@ draw_text (DiaRenderer *self,
            Text        *text)
 {
   Point pos;
-  int i;
-  pos = text->position;
+
+  dia_text_get_position (text, &pos);
 
   set_font (self, text->font, text->height);
 
-  for (i = 0; i < text->numlines; i++) {
+  for (int i = 0; i < text->numlines; i++) {
     TextLine *text_line = text->lines[i];
 
     draw_string (self,
diff --git a/plug-ins/python/bbox.py b/plug-ins/python/bbox.py
index 8479d9f45..b2f13d704 100644
--- a/plug-ins/python/bbox.py
+++ b/plug-ins/python/bbox.py
@@ -17,44 +17,59 @@
 #   along with this program; if not, write to the Free Software
 #   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-import sys, dia, string
+import sys, dia
 
 import gettext
+
 _ = gettext.gettext
 
-def bbox_cb (data, flags) :
 
-       layer = data.active_layer
-       dest = data.add_layer ("BBox of '%s' (%s)" % (layer.name, sys.platform), -1)
-       box_type = dia.get_object_type ("Standard - Box")
+def bbox_cb(data, flags):
+    layer = data.active_layer
+    dest = data.add_layer("BBox of '%s' (%s)" % (layer.name, sys.platform), -1)
+    box_type = dia.get_object_type("Standard - Box")
+
+    for o in layer.objects:
+        bb = o.enclosing_box
+        b, h1, h2 = box_type.create(bb.left, bb.top)
+        b.move_handle(b.handles[7], (bb.right, bb.bottom), 0, 0)
+        b.properties["show_background"] = 0
+        b.properties["line_width"] = 0
+        b.properties["line_colour"] = "green"
+        dest.add_object(b)
+        bb = o.bounding_box
+        b, h1, h2 = box_type.create(bb.left, bb.top)
+        b.move_handle(b.handles[7], (bb.right, bb.bottom), 0, 0)
+        b.properties["show_background"] = 0
+        b.properties["line_width"] = 0
+        b.properties["line_colour"] = "red"
+        dest.add_object(b)
 
-       for o in layer.objects :
-               bb = o.bounding_box
-               b, h1, h2 = box_type.create (bb.left, bb.top)
-               b.move_handle (b.handles[7], (bb.right, bb.bottom), 0, 0)
-               b.properties["show_background"] = 0
-               b.properties["line_width"] = 0
-               b.properties["line_colour"] = 'red'
-               dest.add_object (b)
 
-def annotate_cb (data, flags) :
+def annotate_cb(data, flags):
+    layer = data.active_layer
+    dest = data.add_layer("Annotated '%s' (%s)" % (layer.name, sys.platform), -1)
+    ann_type = dia.get_object_type("Standard - Text")
 
-       layer = data.active_layer
-       dest = data.add_layer ("Annotated '%s' (%s)" % (layer.name, sys.platform), -1)
-       ann_type = dia.get_object_type ("Standard - Text")
+    for o in layer.objects:
+        bb = o.bounding_box
+        a, h1, h2 = ann_type.create(bb.right, bb.top)
 
-       for o in layer.objects :
-               bb = o.bounding_box
-               a, h1, h2 = ann_type.create (bb.right, bb.top)
+        a.properties["text"] = "h: %g w: %g" % (bb.bottom - bb.top, bb.right - bb.left)
 
-               a.properties["text"] = "h: %g w: %g" % (bb.bottom - bb.top, bb.right - bb.left)
+        dest.add_object(a)
 
-               dest.add_object (a)
 
-dia.register_action ("DrawBoundingbox", "_Draw BoundingBox",
-                     "/DisplayMenu/Debug/DebugExtensionStart",
-                     bbox_cb)
+dia.register_action(
+    "DrawBoundingbox",
+    "_Draw BoundingBox",
+    "/DisplayMenu/Debug/DebugExtensionStart",
+    bbox_cb,
+)
 
-dia.register_action ("AnnotateMeasurements", "_Annotate",
-                     "/DisplayMenu/Debug/DebugExtensionStart",
-                     annotate_cb)
+dia.register_action(
+    "AnnotateMeasurements",
+    "_Annotate",
+    "/DisplayMenu/Debug/DebugExtensionStart",
+    annotate_cb,
+)
diff --git a/plug-ins/python/meson.build b/plug-ins/python/meson.build
index 134b3f0e9..a3af4a551 100644
--- a/plug-ins/python/meson.build
+++ b/plug-ins/python/meson.build
@@ -1,4 +1,5 @@
 py3_dep = dependency('python3-embed', version: '>= 3.7')
+pygobj_dep = dependency('pygobject-3.0')
 
 sources = files(
     'pydia-color.c',
@@ -42,12 +43,21 @@ python_scripts = [
     'select_empty.py',
 ]
 
+python_deps = [
+    libc_dep,
+    libxml_dep,
+    libgtk_dep,
+    py3_dep,
+    pygobj_dep,
+    libdia_dep,
+]
+
 if py3_dep.found()
     # Same as layout plugin.
     shared_module(
         'python_plugin',
         sources + [config_h],
-        dependencies: [libc_dep, libxml_dep, libgtk_dep, py3_dep, libdia_dep],
+        dependencies: python_deps,
         include_directories: [configuration_inc, diaapp_inc],
         link_with: [diaapp], # Naughty
         install: true,
diff --git a/plug-ins/python/pydia-geometry.c b/plug-ins/python/pydia-geometry.c
index 8b44d0f64..f28fa0f78 100644
--- a/plug-ins/python/pydia-geometry.c
+++ b/plug-ins/python/pydia-geometry.c
@@ -19,10 +19,16 @@
 
 #include <config.h>
 
+#include "dia-graphene.h"
+
 #include "pydia-object.h"
 #include "pydia-geometry.h"
 
 #include <structmember.h> /* PyMemberDef */
+#define NO_IMPORT_PYGOBJECT
+#include <pygobject.h>
+#include <graphene-gobject.h>
+
 
 /* Implements wrappers for Point, DiaRectangle, BezPoint */
 
@@ -397,6 +403,10 @@ PyDiaRectangle_GetAttr (PyObject *obj, PyObject *arg)
     return I_OR_F (right);
   } else if (!g_strcmp0 (attr, "bottom")) {
     return I_OR_F (bottom);
+  } else if (!g_strcmp0 (attr, "graphene")) {
+    graphene_rect_t rect;
+    dia_rectangle_to_graphene (&self->r, &rect);
+    return pyg_boxed_new (GRAPHENE_TYPE_RECT, &rect, TRUE, TRUE);
   }
 
 generic:
@@ -692,6 +702,8 @@ static PyMemberDef PyDiaRect_Members[] = {
       "int or double: lower edge y coordinate" },
     { "right", T_INVALID, 0, RESTRICTED|READONLY,
       "int or double: right edge x coordinate" },
+    { "graphene", T_INVALID, 0, RESTRICTED|READONLY,
+      "Graphene.Rectangle: underlying graphene_rect_t" },
     { NULL }
 };
 
diff --git a/plug-ins/python/pydia-object.c b/plug-ins/python/pydia-object.c
index f76e67477..f4699c998 100644
--- a/plug-ins/python/pydia-object.c
+++ b/plug-ins/python/pydia-object.c
@@ -26,6 +26,7 @@
 #include "pydia-properties.h"
 #include "pydia-render.h"
 #include "pydia-menuitem.h"
+#include "dia-graphene.h"
 
 #include <structmember.h> /* PyMemberDef */
 
@@ -296,6 +297,8 @@ static PyMethodDef PyDiaObject_Methods[] = {
 static PyMemberDef PyDiaObject_Members[] = {
     { "bounding_box", T_INVALID, 0, RESTRICTED|READONLY,
       "Box covering all the object." },
+    { "enclosing_box", T_INVALID, 0, RESTRICTED|READONLY,
+      "Box covering all the object and editing points." },
     { "connections", T_INVALID, 0, RESTRICTED|READONLY,
       "Vector of connection points." },
     { "handles", T_INVALID, 0, RESTRICTED|READONLY,
@@ -331,7 +334,21 @@ PyDiaObject_GetAttr (PyObject *obj, PyObject *arg)
   } else if (!g_strcmp0 (attr, "type")) {
     return PyDiaObjectType_New (self->object->type);
   } else if (!g_strcmp0 (attr, "bounding_box")) {
-    return PyDiaRectangle_New (&(self->object->bounding_box));
+    graphene_rect_t bbox;
+    DiaRectangle r;
+
+    dia_object_get_bounding_box (self->object, &bbox);
+    dia_graphene_to_rectangle (&bbox, &r);
+
+    return PyDiaRectangle_New (&r);
+  } else if (!g_strcmp0 (attr, "enclosing_box")) {
+    graphene_rect_t ebox;
+    DiaRectangle r;
+
+    dia_object_get_enclosing_box (self->object, &ebox);
+    dia_graphene_to_rectangle (&ebox, &r);
+
+    return PyDiaRectangle_New (&r);
   } else if (!g_strcmp0 (attr, "handles")) {
     int i;
     PyObject *ret = PyTuple_New (self->object->num_handles);
diff --git a/plug-ins/python/python-startup.py b/plug-ins/python/python-startup.py
index e9b9dad67..04eff1e06 100644
--- a/plug-ins/python/python-startup.py
+++ b/plug-ins/python/python-startup.py
@@ -1,5 +1,12 @@
-import sys, os
+import gi
+
+gi.require_version('Graphene', '1.0')
+
+import os
+import sys
+
 import dia
+from gi.repository import Graphene
 
 # Please don't include pygtk or gtk here. There
 # are quite some PyDia plug-ins which don't require
diff --git a/plug-ins/python/python.c b/plug-ins/python/python.c
index 66f6b55b5..e4d4040af 100644
--- a/plug-ins/python/python.c
+++ b/plug-ins/python/python.c
@@ -22,6 +22,7 @@
 #include <Python.h>
 #include <stdio.h>
 #include <glib.h>
+#include <pygobject.h>
 
 #include "intl.h"
 #include "plug-ins.h"
@@ -108,6 +109,8 @@ dia_plugin_init (PluginInfo *info)
 
   PySys_SetArgv (1, python_argv);
 
+  pygobject_init (3, 38, 0);
+
   /* Sanitize sys.path */
   PyRun_SimpleString ("import sys; sys.path = list(filter(None, sys.path))");
 
diff --git a/plug-ins/shape/shape-export.c b/plug-ins/shape/shape-export.c
index e61585041..8afc6a807 100644
--- a/plug-ins/shape/shape-export.c
+++ b/plug-ins/shape/shape-export.c
@@ -54,6 +54,7 @@
 #include "intl.h"
 #include "diagramdata.h"
 #include "object.h"
+#include "dia-graphene.h"
 
 G_BEGIN_DECLS
 
@@ -273,24 +274,31 @@ shape_renderer_class_init (ShapeRendererClass *klass)
  * \memberof _ShapeRenderer
  */
 static void
-draw_object(DiaRenderer *self,
-            DiaObject   *object,
-           DiaMatrix   *matrix)
+draw_object (DiaRenderer *self,
+             DiaObject   *object,
+             DiaMatrix   *matrix)
 {
   Point center;
   ShapeRenderer *renderer = SHAPE_RENDERER(self);
   gboolean main_point = (0 == strncmp(MAIN_CONNECTION_POINT_SHAPE,
                       object->type->name, strlen(MAIN_CONNECTION_POINT_SHAPE)));
 
-  if ((0 == strncmp(CONNECTION_POINT_SHAPE, object->type->name,
-        strlen(CONNECTION_POINT_SHAPE))) || main_point) {
-         /* add user defined connection point */
-         center.x = (object->bounding_box.left + object->bounding_box.right)/2;
-         center.y = (object->bounding_box.top + object->bounding_box.bottom)/2;
-         add_connection_point(renderer, &center, TRUE, main_point);
+  if ((0 == strncmp (CONNECTION_POINT_SHAPE,
+                     object->type->name,
+                     strlen (CONNECTION_POINT_SHAPE))) || main_point) {
+    graphene_rect_t bbox;
+    graphene_point_t p;
+
+    dia_object_get_bounding_box (object, &bbox);
+    graphene_rect_get_center (&bbox, &p);
+    dia_graphene_to_point (&p, &center);
+
+    /* add user defined connection point */
+
+    add_connection_point (renderer, &center, TRUE, main_point);
   } else {
        /* use base class implementation */
-    DIA_RENDERER_CLASS(parent_class)->draw_object (self, object, matrix);
+    DIA_RENDERER_CLASS (parent_class)->draw_object (self, object, matrix);
   }
 }
 
diff --git a/plug-ins/svg/render_svg.c b/plug-ins/svg/render_svg.c
index fe084553e..15714b4e2 100644
--- a/plug-ins/svg/render_svg.c
+++ b/plug-ins/svg/render_svg.c
@@ -569,15 +569,17 @@ draw_text (DiaRenderer *self, Text *text)
   draw_rotated_text (self, text, NULL, 0.0);
 }
 
+
 static void
-draw_rotated_text (DiaRenderer *self, Text *text, Point *center, real angle)
+draw_rotated_text (DiaRenderer *self, Text *text, Point *center, double angle)
 {
   DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
-  Point pos = text->position;
-  int i;
+  Point pos;
   xmlNodePtr node_text, node_tspan;
   char d_buf[G_ASCII_DTOSTR_BUF_SIZE];
 
+  dia_text_get_position (text, &pos);
+
   node_text = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"text", NULL);
   /* text 'global' properties  */
   node_set_text_style(node_text, renderer, text->font, text->height, text->alignment, &text->color);
@@ -605,8 +607,10 @@ draw_rotated_text (DiaRenderer *self, Text *text, Point *center, real angle)
     dia_svg_dtostr(d_buf, pos.y);
     xmlSetProp(node_text, (const xmlChar *)"y", (xmlChar *) d_buf);
   }
-  pos = text->position;
-  for (i=0;i<text->numlines;i++) {
+
+  dia_text_get_position (text, &pos);
+
+  for (int i = 0; i < text->numlines; i++) {
     TextLine *text_line = text->lines[i];
 
     node_tspan = xmlNewTextChild(node_text, renderer->svg_name_space, (const xmlChar *)"tspan",
@@ -621,6 +625,7 @@ draw_rotated_text (DiaRenderer *self, Text *text, Point *center, real angle)
   }
 }
 
+
 static void
 draw_rotated_image (DiaRenderer *self,
                    Point *point,
diff --git a/tests/test-boundingbox.c b/tests/test-boundingbox.c
index 26cf2605b..955f1f72b 100644
--- a/tests/test-boundingbox.c
+++ b/tests/test-boundingbox.c
@@ -40,6 +40,8 @@
 
 #include "boundingbox.h"
 #include "geometry.h"
+#include "dia-graphene.h"
+
 
 static BezPoint _bz1[2] = { /* SE */
                  /* x, y */
@@ -114,43 +116,52 @@ static BezPoint _bz9[] = { /* heart from assorted shapes */
 #define BEZ(x) sizeof(_bz ##x)/sizeof(BezPoint), _bz ##x
 
 static struct _TestBeziers {
-  int          num;
-  BezPoint    *pts;
-  DiaRectangle box;
-} _test_beziers[] = {                   /* left, top, right, bottom */
-  { BEZ(1), { 0.0-T, 0.5-T, 2.0+T, 2.0+T } },
-  { BEZ(2), {-2.0-T, 0.5-T, 0.0+T, 2.0+T } },
-  { BEZ(3), {-2.0-T,-1.5-T, 0.0+T, 0.0+T } },
-  { BEZ(4), { 0.0-T,-1.5-T, 2.0+T, 0.0+T } },
+  int              num;
+  BezPoint        *pts;
+  graphene_rect_t  box;
+} _test_beziers[] = {         /* left,  top, width, height */
+  { BEZ (1), GRAPHENE_RECT_INIT (-0.1,  0.4,  2.2,   1.7  ) },
+  { BEZ (2), GRAPHENE_RECT_INIT (-2.1,  0.4,  2.2,   1.7  ) },
+  { BEZ (3), GRAPHENE_RECT_INIT (-2.1, -1.6,  2.2,   1.7  ) },
+  { BEZ (4), GRAPHENE_RECT_INIT (-0.1, -1.6,  2.2,   1.7  ) },
   /* it only 'jumps' out of the box with a line width>0 */
-  { BEZ(5), { 0.0-T, 0.5-T, 2.0+T, 2.0+T } },
-  { BEZ(6), { 0.2-T, 0.0-T, 1.8+T, 2.0+T } },
-  { BEZ(7), { 0.25-T,0.25-T, 1.75+T, 1.75+T} },
-  { BEZ(8), { 0-T, 0-T, 3+T, 4+T} },
-  { BEZ(9), { 0-T, 0-T, 2.052+T, 1.897+T } },
+  { BEZ (5), GRAPHENE_RECT_INIT (-0.1,  0.4,  2.2,   1.7  ) },
+  { BEZ (6), GRAPHENE_RECT_INIT ( 0.1, -0.1,  1.8,   2.2  ) },
+  { BEZ (7), GRAPHENE_RECT_INIT ( 0.15, 0.15, 1.7,   1.7  ) },
+  { BEZ (8), GRAPHENE_RECT_INIT (-0.1, -0.1,  3.2,   4.2  ) },
+  { BEZ (9), GRAPHENE_RECT_INIT (-0.1, -0.1,  2.252, 2.097) },
 };
 #undef BEZ
 
+
 static void
 _check_one_bezier (gconstpointer p)
 {
   const struct _TestBeziers *test = p;
-  DiaRectangle rect;
+  graphene_rect_t rect;
   PolyBBExtras extra = {0, T*.7, T*.7, T*.7, 0 };
 
   polybezier_bbox (test->pts, test->num, &extra, FALSE, &rect);
-  g_assert (rectangle_in_rectangle (&test->box, &rect));
+
+  g_assert_true (graphene_rect_contains_rect (&test->box, &rect));
 }
 
 
 static void
 _add_bezier_tests (void)
 {
-  int i, num = sizeof (_test_beziers) / sizeof (struct _TestBeziers);
+  int num = sizeof (_test_beziers) / sizeof (struct _TestBeziers);
 
-  for (i = 0; i < num; ++i) {
+  for (int i = 0; i < num; ++i) {
     char *testpath = g_strdup_printf ("/Dia/BoundingBox/Bezier%d", i+1);
 
+    /* HACK: Tests where failing with calculated box height out by _exactly_
+             FLT_EPSILON, grow the expected box size _very_ slightly */
+    graphene_rect_scale (&_test_beziers[i].box,
+                         1 + FLT_EPSILON,
+                         1 + FLT_EPSILON,
+                         &_test_beziers[i].box);
+
     g_test_add_data_func (testpath, &_test_beziers[i], _check_one_bezier);
 
     g_clear_pointer (&testpath, g_free);
diff --git a/tests/test-objects.c b/tests/test-objects.c
index 37fc7a40a..a595a92a9 100644
--- a/tests/test-objects.c
+++ b/tests/test-objects.c
@@ -34,15 +34,17 @@
 #include "create.h"
 #include "properties.h"
 #include "diapathrenderer.h"
+#include "dia-graphene.h"
 
-const real EPSILON = 1e-6;
+
+const double EPSILON = 1e-6;
 int num_objects = 0;
 
+
 static void
 _test_creation (gconstpointer user_data)
 {
-  const DiaObjectType *type = (const DiaObjectType *)user_data;
-  int i;
+  const DiaObjectType *type = (const DiaObjectType *) user_data;
   Handle *h1 = NULL, *h2 = NULL;
   Point point = {0, 0};
   DiaObject *o = type->ops->create (&point, type->default_user_data, &h1, &h2);
@@ -59,13 +61,13 @@ _test_creation (gconstpointer user_data)
             && o->ops->copy != NULL
             && o->ops->move != NULL
             && o->ops->move_handle != NULL
-           && o->ops->apply_properties_from_dialog != NULL
-           );
+            && o->ops->apply_properties_from_dialog != NULL);
 
   /* can we really assume everything complies with standard props nowadays? */
   g_assert (   o->ops->describe_props
             && o->ops->get_props
-           && o->ops->set_props);
+            && o->ops->set_props);
+
   {
     const PropDescription *pdesc = o->ops->describe_props (o);
     /* get all properties */
@@ -78,67 +80,82 @@ _test_creation (gconstpointer user_data)
      * But the latter is only visible as parameter to object_get_props_from_offsets(),
      * at least for objects not intialzing DiaObjectType::prop_offsets
      */
-    o->ops->get_props (o, props);
-    for (i = 0; i < num_described; ++i) {
-      Property *prop = (Property*)g_ptr_array_index(props,i);
-      if ((prop->experience & PXP_NOTSET) == 0)
+    dia_object_get_properties (o, props);
+
+    for (int i = 0; i < num_described; ++i) {
+      Property *prop = (Property *) g_ptr_array_index (props,i);
+
+      if ((prop->experience & PXP_NOTSET) == 0) {
         ++num_used;
-      else if ((prop->descr->flags & PROP_FLAG_WIDGET_ONLY) != 0)
-       ++num_used; /* ... but not expected to be set */
-      else if (strcmp (prop->descr->type, PROP_TYPE_STATIC) == 0)
-       ++num_used; /* also not to be set */
-      else {
+      } else if ((prop->descr->flags & PROP_FLAG_WIDGET_ONLY) != 0) {
+        ++num_used; /* ... but not expected to be set */
+      } else if (strcmp (prop->descr->type, PROP_TYPE_STATIC) == 0) {
+        ++num_used; /* also not to be set */
+      } else {
         g_printerr ("Not set '%s'\n", prop->descr->name);
       }
     }
+
     g_assert_cmpint (num_used, ==, num_described);
 
     g_assert (props != NULL);
-    prop_list_free(props);
+    prop_list_free (props);
   }
+
   /* not implemented anywhere */
   g_assert (o->ops->edit_text == NULL);
   /* I think this is mandatory */
   g_assert (o->ops->apply_properties_list != NULL);
 
-  /* bounding box must be initialized */
-  g_assert (o->bounding_box.left <= o->bounding_box.right);
-  g_assert (o->bounding_box.top <= o->bounding_box.bottom);
-  /* object position must (should?) be in bounding box */
-  g_assert (o->bounding_box.left <= o->position.x && o->position.x <= o->bounding_box.right);
-  g_assert (o->bounding_box.top <= o->position.y && o->position.y <= o->bounding_box.bottom);
+  {
+    graphene_rect_t bbox;
+    graphene_point_t pt;
+
+    dia_object_get_bounding_box (o, &bbox);
+
+    /* object position must (should?) be in bounding box */
+
+    dia_point_to_graphene (&o->position, &pt);
+
+    g_assert_true (graphene_rect_contains_point (&bbox, &pt));
+  }
 
   g_assert (o->num_handles > 0);
+
   /* both handles can be NULL, but if not they must belong to the object  */
-  for (i = 0; i < o->num_handles; ++i)
-    {
-      if (h1 != NULL && h1 == o->handles[i])
-        h1 = NULL;
-      if (h2 != NULL && h2 == o->handles[i])
-        h2 = NULL;
-      /* handles properly set up? */
-      g_assert (o->handles[i] != NULL);
-      g_assert (o->handles[i]->connected_to == NULL); /* starts not connected */
-      g_assert (   o->handles[i]->type != HANDLE_NON_MOVABLE
-               || (   o->handles[i]->type == HANDLE_NON_MOVABLE /* always together? */
-                   && o->handles[i]->connect_type == HANDLE_NONCONNECTABLE));
+  for (int i = 0; i < o->num_handles; ++i) {
+    if (h1 != NULL && h1 == o->handles[i]) {
+      h1 = NULL;
+    }
+
+    if (h2 != NULL && h2 == o->handles[i]) {
+      h2 = NULL;
     }
+
+    /* handles properly set up? */
+    g_assert (o->handles[i] != NULL);
+    g_assert (o->handles[i]->connected_to == NULL); /* starts not connected */
+    g_assert (   o->handles[i]->type != HANDLE_NON_MOVABLE
+              || (   o->handles[i]->type == HANDLE_NON_MOVABLE /* always together? */
+                  && o->handles[i]->connect_type == HANDLE_NONCONNECTABLE));
+  }
+
   /* handles now found */
   g_assert (NULL == h1 && NULL == h2);
 
-  for (i = 0; i < o->num_connections; ++i)
-    {
-      g_assert (o->connections[i] != NULL);
-      g_assert (o->connections[i]->object == o); /* owner set? */
-      g_assert ((o->connections[i]->directions & ~DIR_ALL) == 0); /* known directions */
-      g_assert ((o->connections[i]->flags & ~CP_FLAGS_MAIN) == 0); /* known flags */
-    }
+  for (int i = 0; i < o->num_connections; ++i) {
+    g_assert (o->connections[i] != NULL);
+    g_assert (o->connections[i]->object == o); /* owner set? */
+    g_assert ((o->connections[i]->directions & ~DIR_ALL) == 0); /* known directions */
+    g_assert ((o->connections[i]->flags & ~CP_FLAGS_MAIN) == 0); /* known flags */
+  }
 
   /* finally */
   o->ops->destroy (o);
   g_clear_pointer (&o, g_free);
 }
 
+
 static void
 _test_copy (gconstpointer user_data)
 {
@@ -146,7 +163,7 @@ _test_copy (gconstpointer user_data)
   Handle *h1 = NULL, *h2 = NULL;
   Point from = {0, 0};
   DiaObject *oc, *o = type->ops->create (&from, type->default_user_data, &h1, &h2);
-  DiaRectangle bbox1, bbox2;
+  graphene_rect_t bbox1, bbox2;
   Point to;
   int i;
 
@@ -154,18 +171,17 @@ _test_copy (gconstpointer user_data)
 
   /* does the object move ... ? */
   from = o->position;
-  bbox1 = o->bounding_box;
+  dia_object_get_bounding_box (o, &bbox1);
   oc = o->ops->copy (o);
 
   g_assert (oc != NULL && oc->type == o->type && oc->ops == o->ops);
 
   to = o->position;
-  bbox2 = o->bounding_box;
+  dia_object_get_bounding_box (o, &bbox2);
 
   /* ... it should not */
   g_assert (fabs(from.x - to.x) < EPSILON && fabs(from.y - to.y) < EPSILON);
-  g_assert (   fabs((bbox2.right - bbox2.left) - (bbox1.right - bbox1.left)) < EPSILON
-            && fabs((bbox2.bottom - bbox2.top) - (bbox1.bottom - bbox1.top)) < EPSILON);
+  g_assert_true (graphene_rect_equal (&bbox1, &bbox2));
 
   /* is copying producing dangling pointers ? */
   g_assert (o->num_handles == oc->num_handles);
@@ -198,11 +214,10 @@ _test_movement (gconstpointer user_data)
   Handle *h1 = NULL, *h2 = NULL;
   Point from = {5, 5};
   DiaObject *o = type->ops->create (&from, type->default_user_data, &h1, &h2);
-  DiaRectangle bbox1, bbox2;
+  graphene_rect_t bbox1, bbox2;
   Point to = {10, 10};
   DiaObjectChange *change;
   Point pos;
-  real epsilon;
   Point *handle_positions;
   Point *cp_positions;
   guint i;
@@ -216,70 +231,78 @@ _test_movement (gconstpointer user_data)
 
   /* does the object move ... ? */
   from = o->position;
-  bbox1 = o->bounding_box;
+  dia_object_get_bounding_box (o, &bbox1);
+
   /* ... not (= hack used to force an update call) */
   change = dia_object_move (o, &o->position);
   g_clear_pointer (&change, dia_object_change_unref);
+
   g_assert (num_connections == o->num_connections);
-  bbox2 = o->bounding_box;
-  if (   strcmp (type->name, "Cybernetics - b-sens") == 0
-      || strcmp (type->name, "Cybernetics - l-sens") == 0
-      || strcmp (type->name, "Cybernetics - r-sens") == 0
-      || strcmp (type->name, "Cybernetics - t-sens") == 0
-      ) /* not nice, but also not a reason to fail */
-    epsilon = 0.5 + EPSILON;
-  else
-    epsilon = EPSILON;
+  dia_object_get_bounding_box (o, &bbox2);
+
+  g_assert_true (graphene_rect_equal (&bbox1, &bbox2));
 
-  g_assert_cmpfloat (fabs(fabs(bbox2.right - bbox2.left) - fabs(bbox1.right - bbox1.left)), <, epsilon);
-  g_assert_cmpfloat (fabs(fabs(bbox2.bottom - bbox2.top) - fabs(bbox1.bottom - bbox1.top)), <, epsilon);
   /* .... really: without changing size ? */
   pos = o->position;
-  bbox1 = o->bounding_box;
+  dia_object_get_bounding_box (o, &bbox1);
+
   /* remember handle and connection point positions ... */
   handle_positions = g_alloca (sizeof(Point) * num_handles);
   /* at least one handle is mandatory */
   g_assert (num_handles > 0);
-  for (i = 0; i < num_handles; ++i)
+
+  for (i = 0; i < num_handles; ++i) {
     handle_positions[i] = o->handles[i]->pos;
-  cp_positions = g_alloca (sizeof(Point) * o->num_connections);
-  for (i = 0; i < num_connections; ++i)
+  }
+
+  cp_positions = g_alloca (sizeof (Point) * o->num_connections);
+
+  for (i = 0; i < num_connections; ++i) {
     cp_positions[i] = o->connections[i]->pos;
+  }
 
   change = dia_object_move (o, &to);
   g_clear_pointer (&change, dia_object_change_unref);
+
   g_assert (num_connections == o->num_connections);
+
   /* does the position reflect the move? */
-  g_assert_cmpfloat (fabs(fabs(pos.x - o->position.x) - fabs(from.x - to.x)), <, EPSILON);
-  g_assert_cmpfloat (fabs(fabs(pos.y - o->position.y) - fabs(from.y - to.y)), <, EPSILON);
+  g_assert_cmpfloat (fabs (fabs (pos.x - o->position.x) - fabs (from.x - to.x)), <, EPSILON);
+  g_assert_cmpfloat (fabs (fabs (pos.y - o->position.y) - fabs (from.y - to.y)), <, EPSILON);
+
   /* ... also for handles and connection points? */
-  for (i = 0; i < num_handles; ++i)
-    {
-      g_assert_cmpfloat (fabs(fabs(handle_positions[i].x - o->handles[i]->pos.x) - fabs(from.x - to.x)), <, 
EPSILON);
-      g_assert_cmpfloat (fabs(fabs(handle_positions[i].y - o->handles[i]->pos.y) - fabs(from.y - to.y)), <, 
EPSILON);
-    }
-  for (i = 0; i < num_connections; ++i)
-    {
-      g_assert_cmpfloat (fabs(fabs(cp_positions[i].x - o->connections[i]->pos.x) - fabs(from.x - to.x)), <, 
EPSILON);
-      g_assert_cmpfloat (fabs(fabs(cp_positions[i].y - o->connections[i]->pos.y) - fabs(from.y - to.y)), <, 
EPSILON);
-    }
+  for (i = 0; i < num_handles; ++i) {
+    g_assert_cmpfloat (fabs (fabs (handle_positions[i].x - o->handles[i]->pos.x) - fabs (from.x - to.x)), <, 
EPSILON);
+    g_assert_cmpfloat (fabs (fabs (handle_positions[i].y - o->handles[i]->pos.y) - fabs (from.y - to.y)), <, 
EPSILON);
+  }
+
+  for (i = 0; i < num_connections; ++i) {
+    g_assert_cmpfloat (fabs (fabs (cp_positions[i].x - o->connections[i]->pos.x) - fabs (from.x - to.x)), <, 
EPSILON);
+    g_assert_cmpfloat (fabs (fabs (cp_positions[i].y - o->connections[i]->pos.y) - fabs (from.y - to.y)), <, 
EPSILON);
+  }
+
+  dia_object_get_bounding_box (o, &bbox2);
 
-  bbox2 = o->bounding_box;
   /* test fails e.g. for 'Cisco - Web cluster' probably due to bezier-bbox-issues: bug 568115 */
   if (/* FIXME: this shape should be simple enough to actually fix the bug */
          strcmp (type->name, "Assorted - Heart") == 0 /* height off 0.05 */
-      || strstr (type->name, "Bugs -") == type->name)
+      || strstr (type->name, "Bugs -") == type->name) {
     g_test_message ("SKIPPED %s! ", type->name);
-  else
-    {
-      g_assert_cmpfloat (fabs((bbox2.right - bbox2.left) - fabs(bbox1.right - bbox1.left)), <, EPSILON);
-      g_assert_cmpfloat (fabs((bbox2.bottom - bbox2.top) - fabs(bbox1.bottom - bbox1.top)), <, EPSILON);
-    }
+  } else {
+    g_assert_cmpfloat_with_epsilon (bbox1.size.width,
+                                    bbox2.size.width,
+                                    EPSILON);
+    g_assert_cmpfloat_with_epsilon (bbox1.size.height,
+                                    bbox2.size.height,
+                                    EPSILON);
+  }
+
   /* finally */
   o->ops->destroy (o);
   g_clear_pointer (&o, g_free);
 }
 
+
 static void
 _test_change (gconstpointer user_data)
 {
@@ -310,6 +333,8 @@ _test_change (gconstpointer user_data)
   o->ops->destroy (o);
   g_clear_pointer (&o, g_free);
 }
+
+
 static void
 _test_move_handle (gconstpointer user_data)
 {
@@ -376,7 +401,10 @@ _test_move_handle (gconstpointer user_data)
   /* second move */
   if (h2) {
     Point to = h2->pos;
-    DiaRectangle bb_org = o->bounding_box;
+    graphene_rect_t bb_org;
+
+    dia_object_get_bounding_box (o, &bb_org);
+
     from = to;
     to.x += 1.0; to.y += 1.0;
     if (cp) {
@@ -406,10 +434,20 @@ _test_move_handle (gconstpointer user_data)
         || strcmp (type->name, "Standard - Outline") == 0) {
       g_test_message ("No restore by '%s'::move_handle", type->name);
     } else {
-      g_assert_cmpfloat (fabs(o->bounding_box.top - bb_org.top), <, EPSILON);
-      g_assert_cmpfloat (fabs(o->bounding_box.left - bb_org.left), <, EPSILON);
-      g_assert_cmpfloat (fabs(o->bounding_box.right - bb_org.right), <, EPSILON);
-      g_assert_cmpfloat (fabs(o->bounding_box.bottom - bb_org.bottom), <, EPSILON);
+      graphene_rect_t bbox;
+
+      dia_object_get_bounding_box (o, &bbox);
+
+      /* Hmm, shouldn't these be more exact? */
+      g_assert_true (graphene_point_near (&bb_org.origin,
+                                          &bbox.origin,
+                                          EPSILON));
+      g_assert_cmpfloat_with_epsilon (bb_org.size.width,
+                                      bbox.size.width,
+                                      EPSILON);
+      g_assert_cmpfloat_with_epsilon (bb_org.size.height,
+                                      bbox.size.height,
+                                      EPSILON);
     }
     h2 = NULL;
   }
@@ -435,32 +473,44 @@ _test_connectionpoint_consistency (gconstpointer user_data)
   int i;
   gboolean any_dir_set = FALSE;
   ConnectionPoint *cp_prev = NULL;
+  graphene_rect_t bbox;
+  graphene_point_t point;
 
   change = dia_object_set_string (o, NULL, "Test me!");
   g_clear_pointer (&change, dia_object_change_unref);
 
   for (i = 0; i < o->num_connections; ++i) {
     ConnectionPoint *cp = o->connections[i];
-    if (cp->directions != DIR_NONE)
+
+    if (cp->directions != DIR_NONE) {
       any_dir_set = TRUE;
+    }
   }
+
   if (!any_dir_set) {
     /* should be connection */
     int start_end = 0; /* counter */
+
     for (i = 0; i < o->num_handles; ++i) {
       Handle *h = o->handles[i];
-      if (h->id == HANDLE_MOVE_STARTPOINT || h->id == HANDLE_MOVE_ENDPOINT)
+
+      if (h->id == HANDLE_MOVE_STARTPOINT || h->id == HANDLE_MOVE_ENDPOINT) {
         ++start_end;
+      }
     }
+
     if (start_end < 2 && o->num_connections > 0) {
       g_printerr ("'%s' with no directions\n", type->name);
     }
+
     return;
   }
 
   pos = o->position;
-  center.x = (o->bounding_box.right + o->bounding_box.left) / 2;
-  center.y = (o->bounding_box.bottom + o->bounding_box.top) / 2;
+
+  dia_object_get_bounding_box (o, &bbox);
+  graphene_rect_get_center (&bbox, &point);
+  dia_graphene_to_point (&point, &center);
 
   for (i = 0; i < o->num_connections; ++i) {
     ConnectionPoint *cp = o->connections[i];
@@ -499,72 +549,78 @@ _test_connectionpoint_consistency (gconstpointer user_data)
         g_assert (o->ops->distance_from (o, &cp->pos) == 0 && "within");
       continue;
     }
+
     if (   strcmp (type->name, "chronogram - reference") == 0
         || strcmp (type->name, "BPMN - Data-Object") == 0
         || strcmp (type->name, "Optics - Scope") == 0
         || strcmp (type->name, "Optics - Spectrum") == 0
         || strcmp (type->name, "GRAFCET - Transition") == 0
         || strcmp (type->name, "Standard - Polygon") == 0
-        || strcmp (type->name, "GRAFCET - Action") == 0)
+        || strcmp (type->name, "GRAFCET - Action") == 0) {
       continue; /* undecided */
+    }
+
     /* Some things which should not be set */
-    if (cp->pos.x > center.x)
-      g_assert ((cp->directions & DIR_WEST) == 0);
-    else if (cp->pos.x < center.x)
-      g_assert ((cp->directions & DIR_EAST) == 0);
-    if (cp->pos.y > center.y)
-      g_assert ((cp->directions & DIR_NORTH) == 0);
-    else if (cp->pos.y < center.y)
-      g_assert ((cp->directions & DIR_SOUTH) == 0);
+    if (cp->pos.x > center.x) {
+      g_assert_cmpint (cp->directions & DIR_WEST, ==, 0);
+    } else if (cp->pos.x < center.x) {
+      g_assert_cmpint (cp->directions & DIR_EAST, ==, 0);
+    }
+
+    if (cp->pos.y > center.y) {
+      g_assert_cmpint (cp->directions & DIR_NORTH, ==, 0);
+    } else if (cp->pos.y < center.y) {
+      g_assert_cmpint (cp->directions & DIR_SOUTH, ==, 0);
+    }
   }
 
-  if (o->num_connections > 1)
+  if (o->num_connections > 1) {
     cp_prev = o->connections[o->num_connections-1];
+  }
+
   for (i = 0; i < o->num_connections; ++i) {
     ConnectionPoint *cp = o->connections[i];
+
     if (cp_prev) {
       /* if the previous cp had the same coordinate x or y it should have the same direction */
-      if (   strcmp (type->name, "GRAFCET - Vergent") == 0
-         || strcmp (type->name, "Standard - Polygon") == 0)
-       continue; /* not a hard requirement */
+      if (   g_strcmp0 (type->name, "GRAFCET - Vergent") == 0
+          || g_strcmp0 (type->name, "Standard - Polygon") == 0) {
+        continue; /* not a hard requirement */
+      }
+
       /* not with main point which usually has DIR_ALL */
       if (cp_prev->directions != DIR_ALL && cp->directions != DIR_ALL) {
-       if (cp_prev->pos.x == cp->pos.x)
-         g_assert_cmpint ((cp_prev->directions & (DIR_WEST|DIR_EAST)), ==, (cp->directions & 
(DIR_WEST|DIR_EAST)));
-       if (cp_prev->pos.y == cp->pos.y)
-         g_assert_cmpint ((cp_prev->directions & (DIR_NORTH|DIR_SOUTH)), ==, (cp->directions & 
(DIR_NORTH|DIR_SOUTH)));
+        if (cp_prev->pos.x == cp->pos.x) {
+          g_assert_cmpint ((cp_prev->directions & (DIR_WEST | DIR_EAST)),
+                           ==,
+                           (cp->directions & (DIR_WEST | DIR_EAST)));
+        }
+
+        if (cp_prev->pos.y == cp->pos.y) {
+          g_assert_cmpint ((cp_prev->directions & (DIR_NORTH | DIR_SOUTH)),
+                           ==,
+                           (cp->directions & (DIR_NORTH | DIR_SOUTH)));
+        }
       }
       cp_prev = cp;
     }
   }
+
   /* every connection point should be in bounds of the object */
   for (i = 0; i < o->num_connections; ++i) {
     ConnectionPoint *cp = o->connections[i];
+    DiaRectangle rect;
+
+    dia_object_get_bounding_box (o, &bbox);
+    dia_graphene_to_rectangle (&bbox, &rect);
+
 #if 1
-    if (   strcmp (type->name, "Racks - Label Anchors 42U") == 0
-        || strcmp (type->name, "Civil - Horizontal Rest") == 0
-        || strcmp (type->name, "Cisco - Data Center Switch") == 0
-        || strcmp (type->name, "Civil - Bivalent Vertical Rest") == 0
-        || strcmp (type->name, "Cisco - VIP") == 0
-        || strcmp (type->name, "Building Site - Proportioning Batcher") == 0
-        || strcmp (type->name, "Civil - Gas Bottle") == 0
-        || strcmp (type->name, "Civil - Water Level") == 0
-        || strcmp (type->name, "UML - Classicon") == 0
-        || strcmp (type->name, "scene graph - field") == 0
-        || strcmp (type->name, "Cisco - Telecommuter") == 0
-        || strcmp (type->name, "Civil - Vertical Rest") == 0
-        || strcmp (type->name, "Cisco - PC Adapter Card") == 0
-        || strcmp (type->name, "Civil - Reference Line") == 0
-        || strcmp (type->name, "Cisco - Dot-Dot") == 0
-        || strcmp (type->name, "Cisco - WLAN controller") == 0
-        || strstr (type->name, "Bugs -") == type->name)
-      break; /* kind of wasteful to check for every connection */
-    g_assert (   o->ops->distance_from (o, &cp->pos) < 0.01
-              || distance_rectangle_point (&o->bounding_box, &cp->pos) < 0.01);
+    g_assert_true (   o->ops->distance_from (o, &cp->pos) < 0.01
+                   || distance_rectangle_point (&rect, &cp->pos) < 0.01);
 #else
     /* generate exception list - after all it is legal to have CPs out of bounds */
     if (   o->ops->distance_from (o, &cp->pos) >= 0.01
-        && distance_rectangle_point (&o->bounding_box, &cp->pos) >= 0.01) {
+        && distance_rectangle_point (&rect, &cp->pos) >= 0.01) {
       g_print ("        || strcmp (type->name, \"%s\") == 0\n", type->name);
       break;
     }
@@ -574,6 +630,8 @@ _test_connectionpoint_consistency (gconstpointer user_data)
   o->ops->destroy (o);
   g_clear_pointer (&o, g_free);
 }
+
+
 static void
 _test_object_menu (gconstpointer user_data)
 {
@@ -610,7 +668,7 @@ _test_object_menu (gconstpointer user_data)
         DiaObjectChange *change;
 
         /* g_test_message() does not show normally */
-        g_test_message ("\n\tCalling '%s'...", item->text);
+        g_test_message ("Calling '%s'...", item->text);
         change = (item->callback) (o, &from, item->callback_data);
         if (!change) {
           g_test_message ("Undo/redo missing: %s\n", item->text);
@@ -654,19 +712,19 @@ _test_draw (gconstpointer user_data)
   DiaObject *p;
 
   p = create_standard_path_from_object (o);
-  if (p) /* play safe, maybe it can not be converted? */
-    {
-      const DiaRectangle *obb = dia_object_get_bounding_box (o);
-      const DiaRectangle *pbb = dia_object_get_bounding_box (p);
-      real epsilon = 0.2; /* XXX: smaller value needs longer exception list */
-
-      /* Bounding boxes of these objects should be close, if not
-       * this could be either some miscalculation within the object
-       * implementation (update_data?) or some more generic problem
-       * with DiaPathRenderer
-       */
-      if (!rectangle_in_rectangle (obb, pbb))
-       {
+  if (p) {
+    /* play safe, maybe it can not be converted? */
+    graphene_rect_t obb, pbb;
+
+    dia_object_get_bounding_box (o, &obb);
+    dia_object_get_bounding_box (p, &pbb);
+
+    /* Bounding boxes of these objects should be close, if not
+     * this could be either some miscalculation within the object
+     * implementation (update_data?) or some more generic problem
+     * with DiaPathRenderer
+     */
+    if (!graphene_rect_contains_rect (&obb, &pbb)) {
 #if 0
          /* Generate exceptions list below with ./test-objects -q */
          real ov = MAX(fabs (obb->top - pbb->top), fabs (obb->left - pbb->left));
@@ -676,141 +734,53 @@ _test_draw (gconstpointer user_data)
            g_print ("\t  else if (strcmp (type->name, \"%s\") == 0)\n"
                     "\t    epsilon = %.2g;\n", type->name, ov + 0.01);
 #else
-         /* drawing _outside_ of objects's bounding box */
-         if (strcmp (type->name, "T-Junction") == 0)
-           epsilon = 0.2;
-         else if (strcmp (type->name, "Cisco - Edge Label Switch Router with NetFlow") == 0)
-           epsilon = 0.22;
-         else if (strcmp (type->name, "Cisco - SSL Terminator") == 0)
-           epsilon = 0.23;
-         else if (strcmp (type->name, "Cisco - VPN concentrator") == 0)
-           epsilon = 0.24;
-         else if (strcmp (type->name, "Cisco - End Office") == 0)
-           epsilon = 0.24;
-         else if (strcmp (type->name, "Cisco - Printer") == 0)
-           epsilon = 0.26;
-         else if (strcmp (type->name, "Circuit - Vertical Resistor") == 0)
-           epsilon = 0.26; /* win32: pass */
-         else if (strcmp (type->name, "Circuit - Horizontal Resistor") == 0)
-           epsilon = 0.26; /* win32: pass */
-         else if (strcmp (type->name, "Cisco - Location server") == 0)
-           epsilon = 0.27; /* win32: pass */
-         else if (strcmp (type->name, "Cisco - System controller") == 0)
-           epsilon = 0.27; /* win32: pass */
-         else if (strcmp (type->name, "Cisco - Pager") == 0)
-           epsilon = 0.28;
-         else if (strcmp (type->name, "Cisco - IAD router") == 0)
-           epsilon = 0.28;
-         else if (strcmp (type->name, "Cisco - Newton") == 0)
-           epsilon = 0.28;
-         else if (strcmp (type->name, "Cisco - Truck") == 0)
-           epsilon = 0.29;
-         else if (strcmp (type->name, "ER - Relationship") == 0)
-           epsilon = 0.29;
-         else if (strcmp (type->name, "Network - Base Station") == 0)
-           epsilon = 0.31; /* win32: pass */
-         else if (strcmp (type->name, "Cisco - Protocol Translator") == 0)
-           epsilon = 0.66; /* win32: 0.30 */
-         else if (strcmp (type->name, "Cisco - Cellular phone") == 0)
-           epsilon = 0.32; /* win32: pass */
-         else if (strcmp (type->name, "UML - Constraint") == 0)
-           epsilon = 0.33; /* win32: pass */
-         else if (strcmp (type->name, "UML - Message") == 0)
-           epsilon = 0.50; /* win32: 0.39 */
-         else if (strcmp (type->name, "Cisco - ICM") == 0)
-           epsilon = 0.34;
-         else if (strcmp (type->name, "Cisco - Access Gateway") == 0)
-           epsilon = 0.39; /* win32: pass */
-         else if (strcmp (type->name, "chemeng - SaT-floatinghead") == 0)
-           epsilon = 0.40;
-         else if (strcmp (type->name, "chemeng - kettle") == 0)
-           epsilon = 0.42;
-         else if (strcmp (type->name, "Cisco - NetRanger") == 0)
-           epsilon = 0.42; /* win32: pass */
-         else if (strcmp (type->name, "Cisco - Mac Woman") == 0)
-           epsilon = 0.47; /* win32: 0.43 */
-         else if (strcmp (type->name, "Pneum - press") == 0)
-           epsilon = 0.45; /* win32: 0.44 */
-         else if (strcmp (type->name, "Pneum - presspn") == 0)
-           epsilon = 0.44;
-         else if (strcmp (type->name, "Pneum - presshy") == 0)
-           epsilon = 0.44;
-         else if (strcmp (type->name, "Cisco - Optical Transport") == 0)
-           epsilon = 0.48; /* win32: 0.47 */
-         else if (strcmp (type->name, "Jackson - phenomenon") == 0)
-           epsilon = 0.51; /* osx: 0.39 */
-         else if (strcmp (type->name, "Cisco - Speaker") == 0)
-           epsilon = 0.58; /* win32: 0.57 */
-         else if (strcmp (type->name, "Cisco - 6705") == 0)
-           epsilon = 0.64;
-         else if (strcmp (type->name, "KAOS - mbr") == 0)
-           epsilon = 0.70; /* win32: 0.69 */
-         else if (strcmp (type->name, "FS - Flow") == 0)
-           epsilon = 0.73; /* osx: 0.58 */
-         else if (strcmp (type->name, "SADT - arrow") == 0)
-           epsilon = 0.75; /* win32: 0.74 */
-         else if (strcmp (type->name, "Network - WAN Connection") == 0)
-           epsilon = 0.86;
-         else if (strcmp (type->name, "Network - General Printer") == 0)
-           epsilon = 0.92;
-         else if (strcmp (type->name, "UML - Constraint") == 0)
-           epsilon = 1.1;
-         else if (strcmp (type->name, "Pneum - SEIJack") == 0)
-           epsilon = 1.1;
-         else if (strcmp (type->name, "Pneum - SEOJack") == 0)
-           epsilon = 1.1;
-         else if (strcmp (type->name, "Pneum - DEJack") == 0)
-           epsilon = 1.1; /* osx: 0.9 */
-         else if (strcmp (type->name, "SDL - Comment") == 0)
-           epsilon = 3.5; /* osx: 3.1 */
-
-         g_assert_cmpfloat (fabs (obb->top - pbb->top), <, epsilon);
-         g_assert_cmpfloat (fabs (obb->left - pbb->left), <, epsilon);
-         g_assert_cmpfloat (fabs (obb->right - pbb->right), <, epsilon);
-         g_assert_cmpfloat (fabs (obb->bottom - pbb->bottom), <, epsilon);
+      graphene_rect_equal (&obb, &pbb);
 #endif
-       }
-      /* destroy path object */
-      p->ops->destroy (p);
-      g_clear_pointer (&p, g_free);
-    }
-  else
-    {
-      g_test_message ("SKIPPED (no path from %s)! ", type->name);
     }
+    /* destroy path object */
+    p->ops->destroy (p);
+    g_clear_pointer (&p, g_free);
+  } else {
+    g_test_message ("SKIPPED (no path from %s)! ", type->name);
+  }
+
   /* finally */
   o->ops->destroy (o);
   g_clear_pointer (&o, g_free);
 }
 
+
 static void
 _test_distance_from (gconstpointer user_data)
 {
-  const DiaObjectType *type = (const DiaObjectType *)user_data;
+  const DiaObjectType *type = (const DiaObjectType *) user_data;
   Handle *h1 = NULL, *h2 = NULL;
   Point from = {0, 0};
   DiaObject *o = type->ops->create (&from, type->default_user_data, &h1, &h2);
-  const DiaRectangle *ebox;
-  Point center;
-  real width, height;
+  graphene_rect_t ebox;
+  graphene_point_t center;
+  double width, height;
   Point test;
-  real outside = 0.01; /* tolerance value for being outside */
+  double outside = 0.01; /* tolerance value for being outside */
 
   /* This shall work for all objects so it does not check for full correctness,
    * but is currently tolerant enough for element and connection objects.
    * If it fails either the bounding calculation is bogus or distance_from method.
    */
+
   /* Outside of the enclosing (bounding) box can not be inside the object */
-  ebox = dia_object_get_enclosing_box (o);
-  center.x = (ebox->left + ebox->right) / 2;
-  center.y = (ebox->top + ebox->bottom) / 2;
-  width = ebox->right - ebox->left;
-  height = ebox->bottom - ebox->top;
+  dia_object_get_enclosing_box (o, &ebox);
+
+  graphene_rect_get_center (&ebox, &center);
+
+  width = graphene_rect_get_width (&ebox);
+  height = graphene_rect_get_height (&ebox);
 
   /* Some custom objects still fail this check otherwise */
   if (   strcmp (type->name, "Civil - Gas Bottle") == 0
-      || strcmp (type->name, "Cybernetics - l-sens") == 0)
+      || strcmp (type->name, "Cybernetics - l-sens") == 0) {
     outside += 0.1;
+  }
 
   test.y = center.y;
   test.x = center.x - width/2 - outside;


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