[balsa] Migrate print objects to new scheme



commit 3815561048069e99042944f458cf397e8c92f67c
Author: Albrecht Dreß <albrecht dress arcor de>
Date:   Sat Jun 29 16:26:00 2019 -0400

    Migrate print objects to new scheme
    
    Migrate the various print objects to the modern GObject scheme
    using G_DECLARE_*_TYPE() and G_DEFINE_TYPE().
    
    The main difficulty was the elimination of the direct access to
    the internal fields of BalsaPrintObject, i.e. the surrounding
    rectangle of the respective object, the page number and the
    logical depth.  I added setters/getters for this purpose, which
    required some refactoring in the derived classes.  However,
    IMO the result is actually cleaner…
    
    * src/balsa-print-object-decor.c
      (balsa_print_object_decor_class_init),
      (balsa_print_object_decor_init),
      (balsa_print_object_decor_destroy), (decor_new_real),
      (balsa_print_object_frame_begin), (bpo_decor_print_separator),
      (bpo_decor_print_frame_end), (bpo_decor_print_frame_begin),
      (balsa_print_object_decor_draw):
    * src/balsa-print-object-decor.h:
    * src/balsa-print-object-default.c
      (balsa_print_object_default_class_init),
      (balsa_print_object_default_init),
      (balsa_print_object_default_destroy), (balsa_print_object_default),
      (balsa_print_object_default_full),
      (balsa_print_object_default_draw):
    * src/balsa-print-object-default.h:
    * src/balsa-print-object-header.c
      (balsa_print_object_header_class_init),
      (balsa_print_object_header_init),
      (balsa_print_object_header_destroy),
      (balsa_print_object_header_new_real),
      (balsa_print_object_header_crypto),
      (balsa_print_object_header_draw):
    * src/balsa-print-object-header.h:
    * src/balsa-print-object-html.c
      (balsa_print_object_html_class_init), (balsa_print_object_html),
      (balsa_print_object_html_draw):
    * src/balsa-print-object-html.h:
    * src/balsa-print-object-image.c
      (balsa_print_object_image_class_init),
      (balsa_print_object_image_init),
      (balsa_print_object_image_destroy), (balsa_print_object_image),
      (balsa_print_object_image_draw):
    * src/balsa-print-object-image.h:
    * src/balsa-print-object-text.c
      (balsa_print_object_text_class_init),
      (balsa_print_object_text_init), (balsa_print_object_text_destroy),
      (balsa_print_object_text_plain), (balsa_print_object_text),
      (get_icon), (balsa_print_object_text_vcard),

 ChangeLog                        |  62 ++++
 src/balsa-print-object-decor.c   | 239 +++++++------
 src/balsa-print-object-decor.h   |  50 +--
 src/balsa-print-object-default.c | 290 +++++++++-------
 src/balsa-print-object-default.h |  52 +--
 src/balsa-print-object-header.c  | 355 +++++++++----------
 src/balsa-print-object-header.h  |  65 ++--
 src/balsa-print-object-html.c    |  46 ++-
 src/balsa-print-object-html.h    |  38 +--
 src/balsa-print-object-image.c   | 124 +++----
 src/balsa-print-object-image.h   |  42 +--
 src/balsa-print-object-text.c    | 718 +++++++++++++++------------------------
 src/balsa-print-object-text.h    |  74 ++--
 src/balsa-print-object.c         | 140 +++++---
 src/balsa-print-object.h         |  67 ++--
 src/print-gtk.c                  |   2 +-
 16 files changed, 1072 insertions(+), 1292 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4503206d3..18047e393 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,65 @@
+2019-06-29  Albrecht Dreß  <albrecht dress arcor de>
+
+       Migrate print objects to new scheme
+
+       Migrate the various print objects to the modern GObject scheme
+       using G_DECLARE_*_TYPE() and G_DEFINE_TYPE().
+
+       The main difficulty was the elimination of the direct access to
+       the internal fields of BalsaPrintObject, i.e. the surrounding
+       rectangle of the respective object, the page number and the
+       logical depth.  I added setters/getters for this purpose, which
+       required some refactoring in the derived classes.  However,
+       IMO the result is actually cleaner…
+
+       * src/balsa-print-object-decor.c
+       (balsa_print_object_decor_class_init),
+       (balsa_print_object_decor_init),
+       (balsa_print_object_decor_destroy), (decor_new_real),
+       (balsa_print_object_frame_begin), (bpo_decor_print_separator),
+       (bpo_decor_print_frame_end), (bpo_decor_print_frame_begin),
+       (balsa_print_object_decor_draw):
+       * src/balsa-print-object-decor.h:
+       * src/balsa-print-object-default.c
+       (balsa_print_object_default_class_init),
+       (balsa_print_object_default_init),
+       (balsa_print_object_default_destroy), (balsa_print_object_default),
+       (balsa_print_object_default_full),
+       (balsa_print_object_default_draw):
+       * src/balsa-print-object-default.h:
+       * src/balsa-print-object-header.c
+       (balsa_print_object_header_class_init),
+       (balsa_print_object_header_init),
+       (balsa_print_object_header_destroy),
+       (balsa_print_object_header_new_real),
+       (balsa_print_object_header_crypto),
+       (balsa_print_object_header_draw):
+       * src/balsa-print-object-header.h:
+       * src/balsa-print-object-html.c
+       (balsa_print_object_html_class_init), (balsa_print_object_html),
+       (balsa_print_object_html_draw):
+       * src/balsa-print-object-html.h:
+       * src/balsa-print-object-image.c
+       (balsa_print_object_image_class_init),
+       (balsa_print_object_image_init),
+       (balsa_print_object_image_destroy), (balsa_print_object_image),
+       (balsa_print_object_image_draw):
+       * src/balsa-print-object-image.h:
+       * src/balsa-print-object-text.c
+       (balsa_print_object_text_class_init),
+       (balsa_print_object_text_init), (balsa_print_object_text_destroy),
+       (balsa_print_object_text_plain), (balsa_print_object_text),
+       (get_icon), (balsa_print_object_text_vcard),
+       (balsa_print_object_text_calendar), (balsa_print_object_text_draw):
+       * src/balsa-print-object-text.h:
+       * src/balsa-print-object.c (balsa_print_object_init),
+       (balsa_print_object_class_init), (balsa_print_object_draw),
+       (balsa_print_object_get_page), (balsa_print_object_get_rect),
+       (balsa_print_object_set_page_depth), (balsa_print_object_set_rect),
+       (balsa_print_object_set_height), (balsa_print_object_destroy):
+       * src/balsa-print-object.h:
+       * src/print-gtk.c (draw_page):
+
 2019-06-29  Albrecht Dreß  <albrecht dress arcor de>
 
        Fix build error on Buster
diff --git a/src/balsa-print-object-decor.c b/src/balsa-print-object-decor.c
index 81003c4ce..82fb0cfe3 100644
--- a/src/balsa-print-object-decor.c
+++ b/src/balsa-print-object-decor.c
@@ -1,7 +1,7 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
- * Written by (C) Albrecht Dre� <albrecht dress arcor de> 2007
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
+ * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,65 +25,44 @@
 #include <gtk/gtk.h>
 
 
-/* object related functions */
-static void
-balsa_print_object_decor_class_init(BalsaPrintObjectDecorClass *klass);
-static void balsa_print_object_decor_init (GTypeInstance *instance, gpointer g_class);
-static void balsa_print_object_decor_destroy(GObject * self);
+typedef enum {
+    BALSA_PRINT_DECOR_FRAME_BEGIN,
+    BALSA_PRINT_DECOR_FRAME_END,
+    BALSA_PRINT_DECOR_SEPARATOR
+} BalsaPrintDecorType;
 
-static void balsa_print_object_decor_draw(BalsaPrintObject * self,
-                                         GtkPrintContext * context,
-                                         cairo_t * cairo_ctx);
 
+struct _BalsaPrintObjectDecor {
+    BalsaPrintObject parent;
 
-static BalsaPrintObjectClass *parent_class = NULL;
+    BalsaPrintDecorType mode;
+    gchar * label;
+};
 
 
-GType
-balsa_print_object_decor_get_type()
-{
-    static GType balsa_print_object_decor_type = 0;
-
-    if (!balsa_print_object_decor_type) {
-       static const GTypeInfo balsa_print_object_decor_info = {
-           sizeof(BalsaPrintObjectDecorClass),
-           NULL,               /* base_init */
-           NULL,               /* base_finalize */
-           (GClassInitFunc) balsa_print_object_decor_class_init,
-           NULL,               /* class_finalize */
-           NULL,               /* class_data */
-           sizeof(BalsaPrintObjectDecor),
-           0,                  /* n_preallocs */
-           (GInstanceInitFunc) balsa_print_object_decor_init
-       };
-
-       balsa_print_object_decor_type =
-           g_type_register_static(BALSA_TYPE_PRINT_OBJECT,
-                                  "BalsaPrintObjectDecor",
-                                  &balsa_print_object_decor_info, 0);
-    }
+G_DEFINE_TYPE(BalsaPrintObjectDecor, balsa_print_object_decor, BALSA_TYPE_PRINT_OBJECT)
 
-    return balsa_print_object_decor_type;
-}
+
+/* object related functions */
+static void balsa_print_object_decor_destroy(GObject * self);
+
+static void balsa_print_object_decor_draw(BalsaPrintObject * self,
+                                         GtkPrintContext * context,
+                                         cairo_t * cairo_ctx);
 
 
 static void
 balsa_print_object_decor_class_init(BalsaPrintObjectDecorClass *klass)
 {
-    parent_class = g_type_class_ref(BALSA_TYPE_PRINT_OBJECT);
-    BALSA_PRINT_OBJECT_CLASS(klass)->draw =
-       balsa_print_object_decor_draw;
+    BALSA_PRINT_OBJECT_CLASS(klass)->draw = balsa_print_object_decor_draw;
     G_OBJECT_CLASS(klass)->finalize = balsa_print_object_decor_destroy;
 }
 
 
 static void
-balsa_print_object_decor_init(GTypeInstance * instance,
-                             gpointer g_class)
+balsa_print_object_decor_init(BalsaPrintObjectDecor *self)
 {
-    BalsaPrintObjectDecor *po = BALSA_PRINT_OBJECT_DECOR(instance);
-
-    po->label = NULL;
+    self->label = NULL;
 }
 
 
@@ -93,8 +72,7 @@ balsa_print_object_decor_destroy(GObject * self)
     BalsaPrintObjectDecor *po = BALSA_PRINT_OBJECT_DECOR(self);
 
     g_free(po->label);
-
-    G_OBJECT_CLASS(parent_class)->finalize(self);
+    G_OBJECT_CLASS(balsa_print_object_decor_parent_class)->finalize(self);
 }
 
 
@@ -102,6 +80,7 @@ static BalsaPrintObject *
 decor_new_real(BalsaPrintSetup * psetup, BalsaPrintDecorType mode)
 {
     BalsaPrintObjectDecor *pod;
+    BalsaPrintRect rect;
     BalsaPrintObject *po;
 
     pod = g_object_new(BALSA_TYPE_PRINT_OBJECT_DECOR, NULL);
@@ -109,7 +88,6 @@ decor_new_real(BalsaPrintSetup * psetup, BalsaPrintDecorType mode)
     po = BALSA_PRINT_OBJECT(pod);
 
     /* create the part */
-    po->depth = psetup->curr_depth;
     pod->mode = mode;
 
     /* check if it should start on a new page */
@@ -119,11 +97,12 @@ decor_new_real(BalsaPrintSetup * psetup, BalsaPrintDecorType mode)
     }
 
     /* remember the extent */
-    po->on_page = psetup->page_count - 1;
-    po->c_at_x = psetup->c_x0 + po->depth * C_LABEL_SEP;
-    po->c_at_y = psetup->c_y0 + psetup->c_y_pos;
-    po->c_width = psetup->c_width - 2 * po->depth * C_LABEL_SEP;
-    po->c_height = C_SEPARATOR;
+    balsa_print_object_set_page_depth(po, psetup->page_count - 1, psetup->curr_depth);
+    rect.c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
+    rect.c_at_y = psetup->c_y0 + psetup->c_y_pos;
+    rect.c_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    rect.c_height = C_SEPARATOR;
+    balsa_print_object_set_rect(po, &rect);
 
     /* adjust the y position */
     psetup->c_y_pos += C_SEPARATOR;
@@ -143,6 +122,7 @@ GList *
 balsa_print_object_frame_begin(GList * list, const gchar * label, BalsaPrintSetup * psetup)
 {
     BalsaPrintObjectDecor *pod;
+    BalsaPrintRect rect;
     BalsaPrintObject *po;
 
     pod = g_object_new(BALSA_TYPE_PRINT_OBJECT_DECOR, NULL);
@@ -150,30 +130,29 @@ balsa_print_object_frame_begin(GList * list, const gchar * label, BalsaPrintSetu
     po = BALSA_PRINT_OBJECT(pod);
 
     /* create the part */
-    po->depth = psetup->curr_depth++;
     pod->mode = BALSA_PRINT_DECOR_FRAME_BEGIN;
-    if (label) {
-       pod->label = g_strdup(label);
-       po->c_height = MAX(P_TO_C(psetup->p_hdr_font_height), C_SEPARATOR) +
-           C_SEPARATOR * 0.5;
-    } else
-       po->c_height = C_SEPARATOR;
-
-    /* check if it should start on a new page */
-    if (psetup->c_y_pos + po->c_height +
-       3 * P_TO_C(psetup->p_body_font_height) > psetup->c_height) {
-       psetup->page_count++;
-       psetup->c_y_pos = 0;
+    if (label != NULL) {
+       pod->label = g_strdup(label);
+       rect.c_height = MAX(P_TO_C(psetup->p_hdr_font_height), C_SEPARATOR) + C_SEPARATOR * 0.5;
+    } else {
+       rect.c_height = C_SEPARATOR;
     }
+    /* check if it should start on a new page */
+    if (psetup->c_y_pos + rect.c_height + 3 * P_TO_C(psetup->p_body_font_height) > psetup->c_height) {
+       psetup->page_count++;
+       psetup->c_y_pos = 0;
+       }
 
     /* remember the extent */
-    po->on_page = psetup->page_count - 1;
-    po->c_at_x = psetup->c_x0 + po->depth * C_LABEL_SEP;
-    po->c_at_y = psetup->c_y0 + psetup->c_y_pos;
-    po->c_width = psetup->c_width - 2 * po->depth * C_LABEL_SEP;
+    balsa_print_object_set_page_depth(po, psetup->page_count - 1, psetup->curr_depth);
+    rect.c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
+    rect.c_at_y = psetup->c_y0 + psetup->c_y_pos;
+    rect.c_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    balsa_print_object_set_rect(po, &rect);
+    psetup->curr_depth++;
 
     /* adjust the y position */
-    psetup->c_y_pos += po->c_height;
+    psetup->c_y_pos += rect.c_height;
 
     return g_list_append(list, po);
 }
@@ -188,14 +167,76 @@ balsa_print_object_frame_end(GList * list, BalsaPrintSetup * psetup)
 }
 
 
+static void
+bpo_decor_print_separator(cairo_t              *cairo_ctx,
+                                         const BalsaPrintRect *rect)
+{
+       cairo_set_line_width(cairo_ctx, 1.0);
+       cairo_move_to(cairo_ctx, rect->c_at_x, rect->c_at_y + 0.5 * C_SEPARATOR);
+       cairo_line_to(cairo_ctx, rect->c_at_x + rect->c_width, rect->c_at_y + 0.5 * C_SEPARATOR);
+}
+
+
+static void
+bpo_decor_print_frame_end(cairo_t              *cairo_ctx,
+                                             const BalsaPrintRect *rect)
+{
+       cairo_set_line_width(cairo_ctx, 0.25);
+       cairo_move_to(cairo_ctx, rect->c_at_x, rect->c_at_y);
+       cairo_line_to(cairo_ctx, rect->c_at_x, rect->c_at_y + 0.5 * C_SEPARATOR);
+       cairo_line_to(cairo_ctx, rect->c_at_x + rect->c_width, rect->c_at_y + 0.5 * C_SEPARATOR);
+       cairo_line_to(cairo_ctx, rect->c_at_x + rect->c_width, rect->c_at_y);
+}
+
+
+static void
+bpo_decor_print_frame_begin(cairo_t              *cairo_ctx,
+                                                       const BalsaPrintRect *rect,
+                                                       const gchar          *label,
+                                                       GtkPrintContext      *context)
+{
+       cairo_set_line_width(cairo_ctx, 0.25);
+       cairo_move_to(cairo_ctx, rect->c_at_x, rect->c_at_y + rect->c_height);
+       if (label != NULL) {
+               PangoLayout *layout;
+               PangoFontDescription *font;
+               gint p_label_width;
+               gint p_label_height;
+               gdouble c_y_hor_line;
+
+               /* print the label */
+               font = pango_font_description_from_string(balsa_app.print_header_font);
+               layout = gtk_print_context_create_pango_layout(context);
+               pango_layout_set_font_description(layout, font);
+               pango_font_description_free(font);
+               pango_layout_set_text(layout, label, -1);
+               pango_layout_get_size(layout, &p_label_width, &p_label_height);
+               c_y_hor_line = rect->c_at_y + rect->c_height - MAX(P_TO_C(p_label_height), C_SEPARATOR) * 0.5;
+               cairo_line_to(cairo_ctx, rect->c_at_x, c_y_hor_line);
+               cairo_line_to(cairo_ctx, rect->c_at_x + C_LABEL_SEP, c_y_hor_line);
+               cairo_move_to(cairo_ctx, rect->c_at_x + 1.5 * C_LABEL_SEP, c_y_hor_line - 0.5 * 
P_TO_C(p_label_height));
+               pango_cairo_show_layout(cairo_ctx, layout);
+               g_object_unref(G_OBJECT(layout));
+               cairo_move_to(cairo_ctx, rect->c_at_x + 2.0 * C_LABEL_SEP + P_TO_C(p_label_width), 
c_y_hor_line);
+               cairo_line_to(cairo_ctx, rect->c_at_x + rect->c_width, c_y_hor_line);
+       } else {
+               cairo_line_to(cairo_ctx, rect->c_at_x, rect->c_at_y + rect->c_height - 0.5 * C_SEPARATOR);
+               cairo_line_to(cairo_ctx, rect->c_at_x + rect->c_width, rect->c_at_y + rect->c_height - 0.5 * 
C_SEPARATOR);
+       }
+       cairo_line_to(cairo_ctx, rect->c_at_x + rect->c_width, rect->c_at_y + rect->c_height);
+}
+
+
 static void
 balsa_print_object_decor_draw(BalsaPrintObject * self,
                              GtkPrintContext * context,
                              cairo_t * cairo_ctx)
 {
     BalsaPrintObjectDecor *pod;
+    const BalsaPrintRect *rect;
 
     pod = BALSA_PRINT_OBJECT_DECOR(self);
+    rect = balsa_print_object_get_rect(self);
     g_assert(pod != NULL);
 
     /* draw the decor */
@@ -204,58 +245,16 @@ balsa_print_object_decor_draw(BalsaPrintObject * self,
 
     switch (pod->mode) {
     case BALSA_PRINT_DECOR_SEPARATOR:
-       cairo_set_line_width(cairo_ctx, 1.0);
-       cairo_move_to(cairo_ctx, self->c_at_x, self->c_at_y + 0.5 * C_SEPARATOR);
-       cairo_line_to(cairo_ctx, self->c_at_x + self->c_width,
-                     self->c_at_y + 0.5 * C_SEPARATOR);
-       break;
-
+               bpo_decor_print_separator(cairo_ctx, rect);
+               break;
     case BALSA_PRINT_DECOR_FRAME_END:
-       cairo_set_line_width(cairo_ctx, 0.25);
-       cairo_move_to(cairo_ctx, self->c_at_x, self->c_at_y);
-       cairo_line_to(cairo_ctx, self->c_at_x, self->c_at_y + 0.5 * C_SEPARATOR);
-       cairo_line_to(cairo_ctx, self->c_at_x + self->c_width,
-                     self->c_at_y + 0.5 * C_SEPARATOR);
-       cairo_line_to(cairo_ctx, self->c_at_x + self->c_width, self->c_at_y);
-       break;
-
+               bpo_decor_print_frame_end(cairo_ctx, rect);
+               break;
     case BALSA_PRINT_DECOR_FRAME_BEGIN:
-       cairo_set_line_width(cairo_ctx, 0.25);
-       cairo_move_to(cairo_ctx, self->c_at_x, self->c_at_y + self->c_height);
-       if (pod->label) {
-           PangoLayout *layout;
-           PangoFontDescription *font;
-           gint p_label_width;
-           gint p_label_height;
-           gdouble c_y_hor_line;
-
-           /* print the label */
-           font = pango_font_description_from_string(balsa_app.print_header_font);
-           layout = gtk_print_context_create_pango_layout(context);
-           pango_layout_set_font_description(layout, font);
-           pango_font_description_free(font);
-           pango_layout_set_text(layout, pod->label, -1);
-           pango_layout_get_size(layout, &p_label_width, &p_label_height);
-           c_y_hor_line = self->c_at_y + self->c_height -
-               MAX(P_TO_C(p_label_height), C_SEPARATOR) * 0.5;
-           cairo_line_to(cairo_ctx, self->c_at_x, c_y_hor_line);
-           cairo_line_to(cairo_ctx, self->c_at_x + C_LABEL_SEP, c_y_hor_line);
-           cairo_move_to(cairo_ctx, self->c_at_x + 1.5 * C_LABEL_SEP,
-                         c_y_hor_line - 0.5 * P_TO_C(p_label_height));
-           pango_cairo_show_layout(cairo_ctx, layout);
-           g_object_unref(G_OBJECT(layout));
-           cairo_move_to(cairo_ctx, self->c_at_x + 2.0 * C_LABEL_SEP + P_TO_C(p_label_width),
-                         c_y_hor_line);
-           cairo_line_to(cairo_ctx, self->c_at_x + self->c_width, c_y_hor_line);
-       } else {
-           cairo_line_to(cairo_ctx, self->c_at_x,
-                         self->c_at_y + self->c_height - 0.5 * C_SEPARATOR);
-           cairo_line_to(cairo_ctx, self->c_at_x + self->c_width,
-                         self->c_at_y + self->c_height - 0.5 * C_SEPARATOR);
-       }
-       cairo_line_to(cairo_ctx, self->c_at_x + self->c_width,
-                     self->c_at_y + self->c_height);
-       break;
+               bpo_decor_print_frame_begin(cairo_ctx, rect, pod->label, context);
+               break;
+    default:
+       g_assert_not_reached();
     }
 
     cairo_stroke(cairo_ctx);
diff --git a/src/balsa-print-object-decor.h b/src/balsa-print-object-decor.h
index 90a2cac3b..daa7138ee 100644
--- a/src/balsa-print-object-decor.h
+++ b/src/balsa-print-object-decor.h
@@ -1,7 +1,7 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
- * Written by (C) Albrecht Dre� <albrecht dress arcor de> 2007
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
+ * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,42 +24,20 @@
 
 G_BEGIN_DECLS
 
-#define BALSA_TYPE_PRINT_OBJECT_DECOR  \
-    (balsa_print_object_decor_get_type())
-#define BALSA_PRINT_OBJECT_DECOR(obj)                          \
-    G_TYPE_CHECK_INSTANCE_CAST(obj, BALSA_TYPE_PRINT_OBJECT_DECOR, BalsaPrintObjectDecor)
-#define BALSA_PRINT_OBJECT_DECOR_CLASS(klass)                  \
-    G_TYPE_CHECK_CLASS_CAST(klass, BALSA_TYPE_PRINT_OBJECT_DECOR, BalsaPrintObjectDecorClass)
-#define BALSA_IS_PRINT_OBJECT_DECOR(obj)                       \
-    G_TYPE_CHECK_INSTANCE_TYPE(obj, BALSA_TYPE_PRINT_OBJECT_DECOR)
+#define BALSA_TYPE_PRINT_OBJECT_DECOR  balsa_print_object_decor_get_type()
+G_DECLARE_FINAL_TYPE(BalsaPrintObjectDecor, balsa_print_object_decor, BALSA_PRINT, OBJECT_DECOR, 
BalsaPrintObject)
 
-typedef struct _BalsaPrintObjectDecorClass BalsaPrintObjectDecorClass;
-typedef struct _BalsaPrintObjectDecor BalsaPrintObjectDecor;
 
-typedef enum {
-    BALSA_PRINT_DECOR_FRAME_BEGIN,
-    BALSA_PRINT_DECOR_FRAME_END,
-    BALSA_PRINT_DECOR_SEPARATOR
-} BalsaPrintDecorType;
-
-struct _BalsaPrintObjectDecor {
-    BalsaPrintObject parent;
-
-    BalsaPrintDecorType mode;
-    gchar * label;
-};
-
-
-struct _BalsaPrintObjectDecorClass {
-    BalsaPrintObjectClass parent;
-};
-
-
-GType balsa_print_object_decor_get_type(void);
-GList *balsa_print_object_separator(GList * list, BalsaPrintSetup * psetup);
-GList *balsa_print_object_frame_begin(GList * list, const gchar * label,
-                                     BalsaPrintSetup * psetup);
-GList *balsa_print_object_frame_end(GList * list, BalsaPrintSetup * psetup);
+GList *balsa_print_object_separator(GList           *list,
+                                                                       BalsaPrintSetup *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
+GList *balsa_print_object_frame_begin(GList           *list,
+                                                                         const gchar     *label,
+                                                                         BalsaPrintSetup *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
+GList *balsa_print_object_frame_end(GList           *list,
+                                                                       BalsaPrintSetup *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
 
 
 G_END_DECLS
diff --git a/src/balsa-print-object-default.c b/src/balsa-print-object-default.c
index d221c5a1b..b2ccad69a 100644
--- a/src/balsa-print-object-default.c
+++ b/src/balsa-print-object-default.c
@@ -1,7 +1,7 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
- * Written by (C) Albrecht Dre� <albrecht dress arcor de> 2007
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
+ * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,67 +28,42 @@
 #include "libbalsa-vfs.h"
 
 
-/* object related functions */
-static void
-balsa_print_object_default_class_init(BalsaPrintObjectDefaultClass *
-                                     klass);
-static void balsa_print_object_default_init(GTypeInstance * instance,
-                                           gpointer g_class);
-static void balsa_print_object_default_destroy(GObject * self);
+struct _BalsaPrintObjectDefault {
+    BalsaPrintObject parent;
 
-static void balsa_print_object_default_draw(BalsaPrintObject * self,
-                                           GtkPrintContext * context,
-                                           cairo_t * cairo_ctx);
+    gint p_label_width;
+    gdouble c_image_width;
+    gdouble c_image_height;
+    gdouble c_text_height;
+    gchar *description;
+    GdkPixbuf *pixbuf;
+};
 
 
-static BalsaPrintObjectClass *parent_class = NULL;
+G_DEFINE_TYPE(BalsaPrintObjectDefault, balsa_print_object_default, BALSA_TYPE_PRINT_OBJECT)
 
 
-GType
-balsa_print_object_default_get_type()
-{
-    static GType balsa_print_object_default_type = 0;
-
-    if (!balsa_print_object_default_type) {
-       static const GTypeInfo balsa_print_object_default_info = {
-           sizeof(BalsaPrintObjectDefaultClass),
-           NULL,               /* base_init */
-           NULL,               /* base_finalize */
-           (GClassInitFunc) balsa_print_object_default_class_init,
-           NULL,               /* class_finalize */
-           NULL,               /* class_data */
-           sizeof(BalsaPrintObjectDefault),
-           0,                  /* n_preallocs */
-           (GInstanceInitFunc) balsa_print_object_default_init
-       };
-
-       balsa_print_object_default_type =
-           g_type_register_static(BALSA_TYPE_PRINT_OBJECT,
-                                  "BalsaPrintObjectDefault",
-                                  &balsa_print_object_default_info, 0);
-    }
+/* object related functions */
+static void balsa_print_object_default_destroy(GObject * self);
 
-    return balsa_print_object_default_type;
-}
+static void balsa_print_object_default_draw(BalsaPrintObject * self,
+                                           GtkPrintContext * context,
+                                           cairo_t * cairo_ctx);
 
 
 static void
 balsa_print_object_default_class_init(BalsaPrintObjectDefaultClass * klass)
 {
-    parent_class = g_type_class_ref(BALSA_TYPE_PRINT_OBJECT);
-    BALSA_PRINT_OBJECT_CLASS(klass)->draw =
-       balsa_print_object_default_draw;
+    BALSA_PRINT_OBJECT_CLASS(klass)->draw = balsa_print_object_default_draw;
     G_OBJECT_CLASS(klass)->finalize = balsa_print_object_default_destroy;
 }
 
 
 static void
-balsa_print_object_default_init(GTypeInstance * instance, gpointer g_class)
+balsa_print_object_default_init(BalsaPrintObjectDefault *self)
 {
-    BalsaPrintObjectDefault *po = BALSA_PRINT_OBJECT_DEFAULT(instance);
-
-    po->pixbuf = NULL;
-    po->description = NULL;
+    self->pixbuf = NULL;
+    self->description = NULL;
 }
 
 
@@ -97,112 +72,175 @@ balsa_print_object_default_destroy(GObject * self)
 {
     BalsaPrintObjectDefault *po = BALSA_PRINT_OBJECT_DEFAULT(self);
 
-    if (po->pixbuf)
-       g_object_unref(po->pixbuf);
+    if (po->pixbuf != NULL) {
+       g_object_unref(po->pixbuf);
+    }
     g_free(po->description);
-
-    G_OBJECT_CLASS(parent_class)->finalize(self);
+    G_OBJECT_CLASS(balsa_print_object_default_parent_class)->finalize(self);
 }
 
 
 GList *
-balsa_print_object_default(GList * list,
-                          GtkPrintContext * context,
-                          LibBalsaMessageBody * body,
-                          BalsaPrintSetup * psetup)
+balsa_print_object_default(GList                          *list,
+                                                  GtkPrintContext         *context,
+                                                  LibBalsaMessageBody *body,
+                                                  BalsaPrintSetup     *psetup)
 {
-    BalsaPrintObjectDefault *pod;
-    BalsaPrintObject *po;
-    gchar *conttype;
+       GdkPixbuf *pixbuf;
+       gint p_label_width;
     PangoFontDescription *header_font;
     PangoLayout *test_layout;
-    PangoTabArray *tabs;
+    gchar *conttype;
     GString *desc_buf;
-    gdouble c_max_height;
     gchar *part_desc;
+    gchar *description;
 
-    pod = g_object_new(BALSA_TYPE_PRINT_OBJECT_DEFAULT, NULL);
-    g_assert(pod != NULL);
-    po = BALSA_PRINT_OBJECT(pod);
-
-    /* create the part */
-    po->depth = psetup->curr_depth;
-    po->c_width =
-       psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    g_return_val_if_fail((context != NULL) && (body != NULL) && (psetup != NULL), list);
 
     /* get a pixbuf according to the mime type */
     conttype = libbalsa_message_body_get_mime_type(body);
-    pod->pixbuf =
-       libbalsa_icon_finder(NULL, conttype, NULL, NULL,
-                             GTK_ICON_SIZE_DND);
-    pod->c_image_width = gdk_pixbuf_get_width(pod->pixbuf);
-    pod->c_image_height = gdk_pixbuf_get_height(pod->pixbuf);
-
+    pixbuf = libbalsa_icon_finder(NULL, conttype, NULL, NULL, GTK_ICON_SIZE_DND);
 
     /* create a layout for calculating the maximum label width */
-    header_font =
-       pango_font_description_from_string(balsa_app.print_header_font);
+    header_font = pango_font_description_from_string(balsa_app.print_header_font);
     test_layout = gtk_print_context_create_pango_layout(context);
     pango_layout_set_font_description(test_layout, header_font);
     pango_font_description_free(header_font);
     desc_buf = g_string_new("");
 
     /* add type and filename (if available) */
-    pod->p_label_width =
-       p_string_width_from_layout(test_layout, _("Type:"));
-    if ((part_desc = libbalsa_vfs_content_description(conttype)))
-       g_string_append_printf(desc_buf, "%s\t%s (%s)", _("Type:"),
-                              part_desc, conttype);
-    else
-       g_string_append_printf(desc_buf, "%s\t%s", _("Type:"), conttype);
-    g_free(part_desc);
+    p_label_width = p_string_width_from_layout(test_layout, _("Type:"));
+    part_desc = libbalsa_vfs_content_description(conttype);
+    if (part_desc != NULL) {
+       g_string_append_printf(desc_buf, "%s\t%s (%s)", _("Type:"), part_desc, conttype);
+       g_free(part_desc);
+    } else {
+       g_string_append_printf(desc_buf, "%s\t%s", _("Type:"), conttype);
+    }
     g_free(conttype);
-    if (body->filename) {
-       gint p_fnwidth =
-           p_string_width_from_layout(test_layout, _("File name:"));
-
-       if (p_fnwidth > pod->p_label_width)
-           pod->p_label_width = p_fnwidth;
-       g_string_append_printf(desc_buf, "\n%s\t%s", _("File name:"),
-                              body->filename);
+
+    if (body->filename != NULL) {
+       gint p_fnwidth = p_string_width_from_layout(test_layout, _("File name:"));
+
+       if (p_fnwidth > p_label_width) {
+               p_label_width = p_fnwidth;
+       }
+       g_string_append_printf(desc_buf, "\n%s\t%s", _("File name:"), body->filename);
     }
+    g_object_unref(test_layout);
 
     /* add a small space between label and value */
-    pod->p_label_width += C_TO_P(C_LABEL_SEP);
+    p_label_width += C_TO_P(C_LABEL_SEP);
+
+    /* create the part and clean up */
+    description = g_string_free(desc_buf, FALSE);
+    list = balsa_print_object_default_full(list, context, pixbuf, description, p_label_width, psetup);
+    g_object_unref(pixbuf);
+    g_free(description);
 
-    /* configure the layout so we can calculate the text height */
+    return list;
+}
+
+
+GList *
+balsa_print_object_default_full(GList           *list,
+                                                               GtkPrintContext *context,
+                                                               GdkPixbuf       *pixbuf,
+                                                               const gchar     *description,
+                                                               gint             p_label_width,
+                                                               BalsaPrintSetup *psetup)
+{
+    BalsaPrintObjectDefault *pod;
+    BalsaPrintObject *po;
+    BalsaPrintRect rect;
+    PangoFontDescription *header_font;
+    PangoLayout *test_layout;
+    PangoTabArray *tabs;
+    guint first_page;
+    GList *par_parts;
+    GList *this_par_part;
+    gdouble c_at_y;
+
+       g_return_val_if_fail((context != NULL) && (pixbuf != NULL) && (description != NULL) && (psetup != 
NULL), list);
+
+    pod = g_object_new(BALSA_TYPE_PRINT_OBJECT_DEFAULT, NULL);
+    g_assert(pod != NULL);
+    po = BALSA_PRINT_OBJECT(pod);
+
+    /* icon: ref pixbuf, get size */
+    pod->pixbuf = g_object_ref(pixbuf);
+    pod->c_image_width = gdk_pixbuf_get_width(pod->pixbuf);
+    pod->c_image_height = gdk_pixbuf_get_height(pod->pixbuf);
+
+    /* move to the next page if the icon doesn't fit */
+    if (psetup->c_y_pos + pod->c_image_height > psetup->c_height) {
+       psetup->c_y_pos = 0.0;
+       psetup->page_count++;
+    }
+
+    /* some basics */
+    rect.c_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    pod->p_label_width = p_label_width;
+
+    /* configure a layout so we can calculate the text height */
+    header_font = pango_font_description_from_string(balsa_app.print_header_font);
+    test_layout = gtk_print_context_create_pango_layout(context);
+    pango_layout_set_font_description(test_layout, header_font);
+    pango_font_description_free(header_font);
     pango_layout_set_indent(test_layout, -pod->p_label_width);
-    tabs =
-       pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT,
-                                          pod->p_label_width);
+    tabs = pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT, pod->p_label_width);
     pango_layout_set_tabs(test_layout, tabs);
     pango_tab_array_free(tabs);
-    pango_layout_set_width(test_layout,
-                          C_TO_P(po->c_width -
-                                 4 * C_LABEL_SEP - pod->c_image_width));
+    pango_layout_set_width(test_layout, C_TO_P(rect.c_width - 4 * C_LABEL_SEP - pod->c_image_width));
     pango_layout_set_alignment(test_layout, PANGO_ALIGN_LEFT);
-    pod->c_text_height =
-       P_TO_C(p_string_height_from_layout(test_layout, desc_buf->str));
-    pod->description = g_string_free(desc_buf, FALSE);
 
-    /* check if we should move to the next page */
-    c_max_height = MAX(pod->c_text_height, pod->c_image_height);
-    if (psetup->c_y_pos + c_max_height > psetup->c_height) {
-       psetup->c_y_pos = 0;
-       psetup->page_count++;
+    /* split text if necessary */
+    first_page = psetup->page_count - 1;
+    c_at_y = psetup->c_y_pos;
+    par_parts = split_for_layout(test_layout, description, NULL, psetup, TRUE, NULL);
+
+    /* set the parameters of the first part */
+    pod->description = (gchar *) par_parts->data;
+    pod->c_text_height = P_TO_C(p_string_height_from_layout(test_layout, pod->description));
+    balsa_print_object_set_page_depth(po, first_page++, psetup->curr_depth);
+    rect.c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
+    rect.c_at_y = psetup->c_y0 + c_at_y;
+    rect.c_height = MAX(pod->c_image_height, pod->c_text_height);
+    balsa_print_object_set_rect(po, &rect);
+    list = g_list_append(list, pod);
+
+    /* adjust printing position calculated by split_for_layout if a single text chunk is smaller than the 
pixmap */
+    if ((par_parts->next == NULL) && (pod->c_image_height > pod->c_text_height)) {
+       psetup->c_y_pos += pod->c_image_height - pod->c_text_height;
     }
 
-    /* remember the extent */
-    po->on_page = psetup->page_count - 1;
-    po->c_at_x = psetup->c_x0 + po->depth * C_LABEL_SEP;
-    po->c_at_y = psetup->c_y0 + psetup->c_y_pos;
-    po->c_width = psetup->c_width - 2 * po->depth * C_LABEL_SEP;
-    po->c_height = c_max_height;
-
-    /* adjust the y position */
-    psetup->c_y_pos += c_max_height;
+    /* add more parts */
+    for (this_par_part = par_parts->next; this_par_part != NULL; this_par_part = this_par_part->next) {
+        BalsaPrintObjectDefault *new_pod;
+        BalsaPrintObject *new_po;
+
+        /* create a new object */
+        new_pod = g_object_new(BALSA_TYPE_PRINT_OBJECT_DEFAULT, NULL);
+        g_assert(new_pod != NULL);
+        new_po = BALSA_PRINT_OBJECT(new_pod);
+
+        /* fill data */
+        new_pod->p_label_width = pod->p_label_width;
+        new_pod->c_image_width = pod->c_image_width;
+        new_pod->description = (gchar *) this_par_part->data;
+        new_pod->c_text_height = P_TO_C(p_string_height_from_layout(test_layout, new_pod->description));
+        balsa_print_object_set_page_depth(new_po, first_page++, psetup->curr_depth);
+        rect.c_at_y = psetup->c_y0;
+        rect.c_height = new_pod->c_text_height;
+        balsa_print_object_set_rect(new_po, &rect);
+
+        /* append */
+        list = g_list_append(list, new_pod);
+    }
+    g_list_free(par_parts);
+    g_object_unref(G_OBJECT(test_layout));
 
-    return g_list_append(list, po);
+    return list;
 }
 
 
@@ -212,6 +250,7 @@ balsa_print_object_default_draw(BalsaPrintObject * self,
                                cairo_t * cairo_ctx)
 {
     BalsaPrintObjectDefault *pod;
+    const BalsaPrintRect *rect;
     gdouble c_max_height;
     gdouble c_offset;
     PangoLayout *layout;
@@ -220,14 +259,16 @@ balsa_print_object_default_draw(BalsaPrintObject * self,
 
     /* set up */
     pod = BALSA_PRINT_OBJECT_DEFAULT(self);
+    rect = balsa_print_object_get_rect(self);
     g_assert(pod != NULL);
+
     c_max_height = MAX(pod->c_text_height, pod->c_image_height);
     c_offset = pod->c_image_width + 4 * C_LABEL_SEP;
 
     /* print the icon */
-    if (pod->pixbuf)
-        cairo_print_pixbuf(cairo_ctx, pod->pixbuf, self->c_at_x,
-                           self->c_at_y, 1.0);
+    if (pod->pixbuf != NULL) {
+        cairo_print_pixbuf(cairo_ctx, pod->pixbuf, rect->c_at_x, rect->c_at_y, 1.0);
+    }
 
     /* print the description */
     font = pango_font_description_from_string(balsa_app.print_header_font);
@@ -240,12 +281,11 @@ balsa_print_object_default_draw(BalsaPrintObject * self,
                                           pod->p_label_width);
     pango_layout_set_tabs(layout, tabs);
     pango_tab_array_free(tabs);
-    pango_layout_set_width(layout, C_TO_P(self->c_width - c_offset));
+    pango_layout_set_width(layout, C_TO_P(rect->c_width - c_offset));
     pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
     pango_layout_set_text(layout, pod->description, -1);
-    cairo_move_to(cairo_ctx, self->c_at_x + c_offset,
-                 self->c_at_y + (c_max_height -
-                                 pod->c_text_height) * 0.5);
+    cairo_move_to(cairo_ctx, rect->c_at_x + c_offset,
+               rect->c_at_y + (c_max_height - pod->c_text_height) * 0.5);
     pango_cairo_show_layout(cairo_ctx, layout);
-    g_object_unref(G_OBJECT(layout));
+    g_object_unref(layout);
 }
diff --git a/src/balsa-print-object-default.h b/src/balsa-print-object-default.h
index 73756122b..c499ee89c 100644
--- a/src/balsa-print-object-default.h
+++ b/src/balsa-print-object-default.h
@@ -1,7 +1,7 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
- * Written by (C) Albrecht Dre� <albrecht dress arcor de> 2007
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
+ * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,42 +24,24 @@
 
 G_BEGIN_DECLS
 
-#define BALSA_TYPE_PRINT_OBJECT_DEFAULT        \
-    (balsa_print_object_default_get_type())
-#define BALSA_PRINT_OBJECT_DEFAULT(obj)                                \
-    G_TYPE_CHECK_INSTANCE_CAST(obj, BALSA_TYPE_PRINT_OBJECT_DEFAULT, BalsaPrintObjectDefault)
-#define BALSA_PRINT_OBJECT_DEFAULT_CLASS(klass)                        \
-    G_TYPE_CHECK_CLASS_CAST(klass, BALSA_TYPE_PRINT_OBJECT_DEFAULT, BalsaPrintObjectDefaultClass)
-#define BALSA_IS_PRINT_OBJECT_DEFAULT(obj)                     \
-    G_TYPE_CHECK_INSTANCE_TYPE(obj, BALSA_TYPE_PRINT_OBJECT_DEFAULT)
+#define BALSA_TYPE_PRINT_OBJECT_DEFAULT        balsa_print_object_default_get_type()
+G_DECLARE_FINAL_TYPE(BalsaPrintObjectDefault, balsa_print_object_default, BALSA_PRINT, OBJECT_DEFAULT, 
BalsaPrintObject)
 
 
-typedef struct _BalsaPrintObjectDefaultClass BalsaPrintObjectDefaultClass;
-typedef struct _BalsaPrintObjectDefault BalsaPrintObjectDefault;
+GList *balsa_print_object_default(GList               *list,
+                                                                 GtkPrintContext     *context,
+                                                                 LibBalsaMessageBody *body,
+                                                                 BalsaPrintSetup     *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
 
-
-struct _BalsaPrintObjectDefault {
-    BalsaPrintObject parent;
-
-    gint p_label_width;
-    gdouble c_image_width;
-    gdouble c_image_height;
-    gdouble c_text_height;
-    gchar *description;
-    GdkPixbuf *pixbuf;
-};
-
-
-struct _BalsaPrintObjectDefaultClass {
-    BalsaPrintObjectClass parent;
-};
-
-
-GType balsa_print_object_default_get_type(void);
-GList *balsa_print_object_default(GList * list,
-                                 GtkPrintContext *context,
-                                 LibBalsaMessageBody *body,
-                                 BalsaPrintSetup *psetup);
+/* note: adds a reference to the passed pixbuf */
+GList *balsa_print_object_default_full(GList           *list,
+                                                                          GtkPrintContext *context,
+                                                                          GdkPixbuf       *pixbuf,
+                                                                          const gchar     *description,
+                                                                          gint             p_label_width,
+                                                                          BalsaPrintSetup *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
 
 
 G_END_DECLS
diff --git a/src/balsa-print-object-header.c b/src/balsa-print-object-header.c
index ce1f587ee..39921fc5b 100644
--- a/src/balsa-print-object-header.c
+++ b/src/balsa-print-object-header.c
@@ -1,6 +1,6 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
  * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
@@ -29,10 +29,21 @@
 #include "balsa-print-object-default.h"
 #include "libbalsa-gpgme.h"
 
+
+struct _BalsaPrintObjectHeader {
+    BalsaPrintObject parent;
+
+    gint p_label_width;
+    gint p_layout_width;
+    gchar *headers;
+    GdkPixbuf *face;
+};
+
+
+G_DEFINE_TYPE(BalsaPrintObjectHeader, balsa_print_object_header, BALSA_TYPE_PRINT_OBJECT)
+
+
 /* object related functions */
-static void balsa_print_object_header_class_init(BalsaPrintObjectHeaderClass * klass);
-static void balsa_print_object_header_init(GTypeInstance * instance,
-                                           gpointer g_class);
 static void balsa_print_object_header_destroy(GObject * self);
 
 static void balsa_print_object_header_draw(BalsaPrintObject * self,
@@ -50,53 +61,18 @@ static void header_add_list(PangoLayout * layout, GString * header_buf,
                            gboolean print_all_headers);
 
 
-static BalsaPrintObjectClass *parent_class = NULL;
-
-
-GType
-balsa_print_object_header_get_type()
-{
-    static GType balsa_print_object_header_type = 0;
-
-    if (!balsa_print_object_header_type) {
-       static const GTypeInfo balsa_print_object_header_info = {
-           sizeof(BalsaPrintObjectHeaderClass),
-           NULL,               /* base_init */
-           NULL,               /* base_finalize */
-           (GClassInitFunc) balsa_print_object_header_class_init,
-           NULL,               /* class_finalize */
-           NULL,               /* class_data */
-           sizeof(BalsaPrintObjectHeader),
-           0,                  /* n_preallocs */
-           (GInstanceInitFunc) balsa_print_object_header_init
-       };
-
-       balsa_print_object_header_type =
-           g_type_register_static(BALSA_TYPE_PRINT_OBJECT,
-                                  "BalsaPrintObjectHeader",
-                                  &balsa_print_object_header_info, 0);
-    }
-
-    return balsa_print_object_header_type;
-}
-
-
 static void
 balsa_print_object_header_class_init(BalsaPrintObjectHeaderClass * klass)
 {
-    parent_class = g_type_class_ref(BALSA_TYPE_PRINT_OBJECT);
-    BALSA_PRINT_OBJECT_CLASS(klass)->draw =
-       balsa_print_object_header_draw;
+    BALSA_PRINT_OBJECT_CLASS(klass)->draw = balsa_print_object_header_draw;
     G_OBJECT_CLASS(klass)->finalize = balsa_print_object_header_destroy;
 }
 
 
 static void
-balsa_print_object_header_init(GTypeInstance * instance, gpointer g_class)
+balsa_print_object_header_init(BalsaPrintObjectHeader *self)
 {
-    BalsaPrintObjectHeader *po = BALSA_PRINT_OBJECT_HEADER(instance);
-
-    po->headers = NULL;
+    self->headers = NULL;
 }
 
 
@@ -106,10 +82,10 @@ balsa_print_object_header_destroy(GObject * self)
     BalsaPrintObjectHeader *po = BALSA_PRINT_OBJECT_HEADER(self);
 
     g_free(po->headers);
-    if (po->face)
-       g_object_unref(po->face);
-
-    G_OBJECT_CLASS(parent_class)->finalize(self);
+    if (po->face) {
+       g_object_unref(po->face);
+    }
+    G_OBJECT_CLASS(balsa_print_object_header_parent_class)->finalize(self);
 }
 
 static GList *
@@ -128,8 +104,7 @@ balsa_print_object_header_new_real(GList * list,
     PangoTabArray *tabs;
     GString *header_buf;
     PangoLayout *test_layout;
-    gdouble c_use_width;
-    gdouble c_at_x;
+    BalsaPrintRect rect;
     gdouble c_at_y;
     GList *chunks;
     GList *this_chunk;
@@ -241,31 +216,29 @@ balsa_print_object_header_new_real(GList * list,
     /* strip the trailing '\n' */
     header_buf = g_string_truncate(header_buf, header_buf->len - 1);
 
-    /* check if we have a face */
-    c_use_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
-    if (face) {
-       p_layout_width = C_TO_P(c_use_width - gdk_pixbuf_get_width(face) - C_LABEL_SEP);
-       c_face_height = gdk_pixbuf_get_height(face);
+    /* check if we have a face pixbuf */
+    rect.c_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    if (face != NULL) {
+       p_layout_width = C_TO_P(rect.c_width - gdk_pixbuf_get_width(face) - C_LABEL_SEP);
+       c_face_height = gdk_pixbuf_get_height(face);
     } else {
-       p_layout_width = C_TO_P(c_use_width);
-       c_face_height = 0;
+       p_layout_width = C_TO_P(rect.c_width);
+       c_face_height = 0.0;
     }
 
     /* start on new page if less than 2 header lines can be printed or if
      * the face doesn't fit */
     if (psetup->c_y_pos + 2 * P_TO_C(psetup->p_hdr_font_height) > psetup->c_height ||
-       psetup->c_y_pos + c_face_height > psetup->c_height) {
-       psetup->c_y_pos = 0;
-       psetup->page_count++;
+               psetup->c_y_pos + c_face_height > psetup->c_height) {
+       psetup->c_y_pos = 0;
+       psetup->page_count++;
     }
     first_page = psetup->page_count - 1;
     c_at_y = psetup->c_y_pos;
 
     /* configure the layout so we can use Pango to split the text into pages */
     pango_layout_set_indent(test_layout, -p_label_width);
-    tabs =
-       pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT,
-                                          p_label_width);
+    tabs = pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT, p_label_width);
     pango_layout_set_tabs(test_layout, tabs);
     pango_tab_array_free(tabs);
     pango_layout_set_width(test_layout, p_layout_width);
@@ -273,47 +246,43 @@ balsa_print_object_header_new_real(GList * list,
     pango_layout_set_alignment(test_layout, PANGO_ALIGN_LEFT);
 
     /* split the headers into a list fitting on one or more pages */
-    chunks =
-       split_for_layout(test_layout, header_buf->str, NULL, psetup, TRUE,
-                        NULL);
+    chunks = split_for_layout(test_layout, header_buf->str, NULL, psetup, TRUE, NULL);
     g_string_free(header_buf, TRUE);
 
     /* create a list of objects */
-    this_chunk = chunks;
-    c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
-    while (this_chunk) {
-       BalsaPrintObjectHeader *po;
-
-       po = g_object_new(BALSA_TYPE_PRINT_OBJECT_HEADER, NULL);
-       g_assert(po != NULL);
-       BALSA_PRINT_OBJECT(po)->on_page = first_page++;
-       BALSA_PRINT_OBJECT(po)->c_at_x = c_at_x;
-       BALSA_PRINT_OBJECT(po)->c_at_y = psetup->c_y0 + c_at_y;
-       BALSA_PRINT_OBJECT(po)->depth = psetup->curr_depth;
-       c_at_y = 0.0;
-       BALSA_PRINT_OBJECT(po)->c_width = c_use_width;
-       /* note: height is calculated when the object is drawn */
-       po->headers = (gchar *) this_chunk->data;
-       po->p_label_width = p_label_width;
-       po->p_layout_width = p_layout_width;
-       if (face) {
-           po->face = face;
-           if (!this_chunk->next) {
-               gint p_height;
-
-               /* verify that the image is not higher than the headers
-                * if there is a next part, we checked before that the
-                * image fits */
-               pango_layout_set_text(test_layout, po->headers, -1);
-               pango_layout_get_size(test_layout, NULL, &p_height);
-               if (c_face_height > P_TO_C(p_height))
-                   psetup->c_y_pos += c_face_height - P_TO_C(p_height);
-           }
-           face = NULL;
-       }
-       list = g_list_append(list, po);
-
-       this_chunk = g_list_next(this_chunk);
+    rect.c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;     /* fixed for all chunks */
+    rect.c_height = -1.0;      /* note: height is calculated when the object is drawn */
+    for (this_chunk = chunks; this_chunk != NULL; this_chunk = this_chunk->next) {
+       BalsaPrintObjectHeader *po;
+
+       po = g_object_new(BALSA_TYPE_PRINT_OBJECT_HEADER, NULL);
+       g_assert(po != NULL);
+       balsa_print_object_set_page_depth(BALSA_PRINT_OBJECT(po), first_page++, psetup->curr_depth);
+       rect.c_at_y = psetup->c_y0 + c_at_y;
+       balsa_print_object_set_rect(BALSA_PRINT_OBJECT(po), &rect);
+       c_at_y = 0.0;
+
+       /* note: height is calculated when the object is drawn */
+       po->headers = (gchar *) this_chunk->data;
+       po->p_label_width = p_label_width;
+       po->p_layout_width = p_layout_width;
+       if (face != NULL) {
+               po->face = face;
+               if (this_chunk->next == NULL) {
+                       gint p_height;
+
+                       /* verify that the image is not higher than the headers
+                        * if there is a next part, we checked before that the
+                        * image fits */
+                       pango_layout_set_text(test_layout, po->headers, -1);
+                       pango_layout_get_size(test_layout, NULL, &p_height);
+                       if (c_face_height > P_TO_C(p_height)) {
+                               psetup->c_y_pos += c_face_height - P_TO_C(p_height);
+                       }
+               }
+               face = NULL;
+       }
+       list = g_list_append(list, po);
     }
     g_list_free(chunks);
     g_object_unref(G_OBJECT(test_layout));
@@ -351,80 +320,75 @@ balsa_print_object_header_from_body(GList *list,
 
 
 GList *
-balsa_print_object_header_crypto(GList *list, GtkPrintContext * context,
-                                LibBalsaMessageBody * body,
-                                BalsaPrintSetup * psetup)
+balsa_print_object_header_crypto(GList                                  *list,
+                                                                GtkPrintContext     *context,
+                                                                LibBalsaMessageBody *body,
+                                                                BalsaPrintSetup     *psetup)
 {
-    gint first_page;
-    gdouble c_at_x;
-    gdouble c_at_y;
-    gdouble c_use_width;
-    PangoFontDescription *header_font;
-    PangoLayout *test_layout;
-    gchar *textbuf;
-    GList *chunks;
-    GList *this_chunk;
-
-    /* only if the body has an attached signature info */
-    if ((body->sig_info == NULL) || (g_mime_gpgme_sigstat_status(body->sig_info) == GPG_ERR_NOT_SIGNED)) {
-       return balsa_print_object_default(list, context, body, psetup);
-    }
-    
-    /* start on new page if less than 2 header lines can be printed */
-    if (psetup->c_y_pos + 2 * P_TO_C(psetup->p_hdr_font_height) >
-       psetup->c_height) {
-       psetup->c_y_pos = 0;
-       psetup->page_count++;
-    }
-    first_page = psetup->page_count - 1;
-    c_at_y = psetup->c_y_pos;
-    c_use_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
-
-    /* create a layout for wrapping */
-    header_font =
-       pango_font_description_from_string(balsa_app.print_header_font);
-    test_layout = gtk_print_context_create_pango_layout(context);
-    pango_layout_set_font_description(test_layout, header_font);
-    pango_font_description_free(header_font);
-
-    /* create a buffer with the signature info */
-    textbuf = g_mime_gpgme_sigstat_to_gchar(body->sig_info, TRUE, balsa_app.date_string);
-
-    /* configure the layout so we can use Pango to split the text into pages */
-    pango_layout_set_width(test_layout, C_TO_P(c_use_width));
-    pango_layout_set_wrap(test_layout, PANGO_WRAP_WORD_CHAR);
-    pango_layout_set_alignment(test_layout, PANGO_ALIGN_LEFT);
-
-    /* split the headers into a list fitting on one or more pages */
-    chunks = split_for_layout(test_layout, textbuf, NULL, psetup, FALSE, NULL);
-    g_object_unref(G_OBJECT(test_layout));
-    g_free(textbuf);
+       gint first_page;
+       BalsaPrintRect rect;
+       gdouble c_at_y;
+       PangoFontDescription *header_font;
+       PangoLayout *test_layout;
+       gchar *textbuf;
+       GList *chunks;
+       GList *this_chunk;
+
+       /* only if the body has an attached signature info */
+       if ((body->sig_info == NULL) || (g_mime_gpgme_sigstat_status(body->sig_info) == GPG_ERR_NOT_SIGNED)) {
+               return balsa_print_object_default(list, context, body, psetup);
+       }
 
-    /* create a list of objects */
-    this_chunk = chunks;
-    c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
-    while (this_chunk) {
-       BalsaPrintObjectHeader *po;
-
-       po = g_object_new(BALSA_TYPE_PRINT_OBJECT_HEADER, NULL);
-       g_assert(po != NULL);
-       BALSA_PRINT_OBJECT(po)->on_page = first_page++;
-       BALSA_PRINT_OBJECT(po)->c_at_x = c_at_x;
-       BALSA_PRINT_OBJECT(po)->c_at_y = psetup->c_y0 + c_at_y;
-       BALSA_PRINT_OBJECT(po)->depth = psetup->curr_depth;
-       c_at_y = 0.0;
-       BALSA_PRINT_OBJECT(po)->c_width = c_use_width;
-       /* note: height is calculated when the object is drawn */
-       po->headers = (gchar *) this_chunk->data;
-       po->p_label_width = 0;
-       po->p_layout_width = C_TO_P(c_use_width);
-       list = g_list_append(list, po);
-
-       this_chunk = g_list_next(this_chunk);
-    }
-    g_list_free(chunks);
+       /* start on new page if less than 2 header lines can be printed */
+       if (psetup->c_y_pos + 2 * P_TO_C(psetup->p_hdr_font_height) > psetup->c_height) {
+               psetup->c_y_pos = 0;
+               psetup->page_count++;
+       }
+       first_page = psetup->page_count - 1;
+       c_at_y = psetup->c_y_pos;
+       rect.c_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+
+       /* create a layout for wrapping */
+       header_font = pango_font_description_from_string(balsa_app.print_header_font);
+       test_layout = gtk_print_context_create_pango_layout(context);
+       pango_layout_set_font_description(test_layout, header_font);
+       pango_font_description_free(header_font);
+
+       /* create a buffer with the signature info */
+       textbuf = g_mime_gpgme_sigstat_to_gchar(body->sig_info, TRUE, balsa_app.date_string);
+
+       /* configure the layout so we can use Pango to split the text into pages */
+       pango_layout_set_width(test_layout, C_TO_P(rect.c_width));
+       pango_layout_set_wrap(test_layout, PANGO_WRAP_WORD_CHAR);
+       pango_layout_set_alignment(test_layout, PANGO_ALIGN_LEFT);
+
+       /* split the headers into a list fitting on one or more pages */
+       chunks = split_for_layout(test_layout, textbuf, NULL, psetup, FALSE, NULL);
+       g_object_unref(G_OBJECT(test_layout));
+       g_free(textbuf);
+
+       /* create a list of objects */
+       rect.c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
+    rect.c_height = -1.0;      /* note: height is calculated when the object is drawn */
+       for (this_chunk = chunks; this_chunk != NULL; this_chunk = this_chunk->next) {
+               BalsaPrintObjectHeader *po;
+
+               po = g_object_new(BALSA_TYPE_PRINT_OBJECT_HEADER, NULL);
+               g_assert(po != NULL);
+               balsa_print_object_set_page_depth(BALSA_PRINT_OBJECT(po), first_page++, psetup->curr_depth);
+               rect.c_at_y = psetup->c_y0 + c_at_y;
+               balsa_print_object_set_rect(BALSA_PRINT_OBJECT(po), &rect);
+               c_at_y = 0.0;
+
+               /* note: height is calculated when the object is drawn */
+               po->headers = (gchar *) this_chunk->data;
+               po->p_label_width = 0;
+               po->p_layout_width = C_TO_P(rect.c_width);
+               list = g_list_append(list, po);
+       }
+       g_list_free(chunks);
 
-    return list;
+       return list;
 }
 
 
@@ -434,50 +398,57 @@ balsa_print_object_header_draw(BalsaPrintObject * self,
                                cairo_t * cairo_ctx)
 {
     BalsaPrintObjectHeader *po;
+    const BalsaPrintRect *rect;
     PangoLayout *layout;
     PangoFontDescription *font;
     gint p_height;
+    gdouble c_height;
 
     po = BALSA_PRINT_OBJECT_HEADER(self);
+    rect = balsa_print_object_get_rect(self);
     g_assert(po != NULL);
 
     font = pango_font_description_from_string(balsa_app.print_header_font);
     layout = gtk_print_context_create_pango_layout(context);
     pango_layout_set_font_description(layout, font);
     pango_font_description_free(font);
-    if (po->p_label_width) {
-       PangoTabArray *tabs;
-       
-       pango_layout_set_indent(layout, -po->p_label_width);
-       tabs = pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT,
-                                                 po->p_label_width);
-       pango_layout_set_tabs(layout, tabs);
-       pango_tab_array_free(tabs);
+    if (po->p_label_width > 0) {
+       PangoTabArray *tabs;
+
+       pango_layout_set_indent(layout, -po->p_label_width);
+       tabs = pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT,
+                       po->p_label_width);
+       pango_layout_set_tabs(layout, tabs);
+       pango_tab_array_free(tabs);
     }
     pango_layout_set_width(layout, po->p_layout_width);
     pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
     pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
     pango_layout_set_text(layout, po->headers, -1);
     pango_layout_get_size(layout, NULL, &p_height);
-    self->c_height = P_TO_C(p_height); /* needed to properly print borders */
-    cairo_move_to(cairo_ctx, self->c_at_x, self->c_at_y);
+    c_height = P_TO_C(p_height);       /* needed to properly print borders */
+    cairo_move_to(cairo_ctx, rect->c_at_x, rect->c_at_y);
     pango_cairo_show_layout(cairo_ctx, layout);
     g_object_unref(G_OBJECT(layout));
 
     /* print a face image */
-    if (po->face) {
-       gdouble c_face_h;
-       gdouble c_face_w;
-
-       c_face_h = gdk_pixbuf_get_height(po->face);
-       c_face_w = gdk_pixbuf_get_width(po->face);
-
-       cairo_print_pixbuf(cairo_ctx, po->face,
-                          self->c_at_x + self->c_width - c_face_w,
-                          self->c_at_y, 1.0);
-       if (c_face_h > self->c_height)
-           self->c_height = c_face_h;
+    if (po->face != NULL) {
+       gdouble c_face_h;
+       gdouble c_face_w;
+
+       c_face_h = gdk_pixbuf_get_height(po->face);
+       c_face_w = gdk_pixbuf_get_width(po->face);
+
+       cairo_print_pixbuf(cairo_ctx, po->face,
+                       rect->c_at_x + rect->c_width - c_face_w,
+                               rect->c_at_y, 1.0);
+       if (c_face_h > c_height) {
+               c_height = c_face_h;
+       }
     }
+
+    /* update object height to the calculated value */
+    balsa_print_object_set_height(self, c_height);
 }
 
 
diff --git a/src/balsa-print-object-header.h b/src/balsa-print-object-header.h
index d072146f8..71623aa08 100644
--- a/src/balsa-print-object-header.h
+++ b/src/balsa-print-object-header.h
@@ -1,6 +1,6 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
  * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
@@ -28,49 +28,26 @@
 
 G_BEGIN_DECLS
 
-#define BALSA_TYPE_PRINT_OBJECT_HEADER \
-    (balsa_print_object_header_get_type())
-#define BALSA_PRINT_OBJECT_HEADER(obj)                         \
-    G_TYPE_CHECK_INSTANCE_CAST(obj, BALSA_TYPE_PRINT_OBJECT_HEADER, BalsaPrintObjectHeader)
-#define BALSA_PRINT_OBJECT_HEADER_CLASS(klass)                 \
-    G_TYPE_CHECK_CLASS_CAST(klass, BALSA_TYPE_PRINT_OBJECT_HEADER, BalsaPrintObjectHeaderClass)
-#define BALSA_IS_PRINT_OBJECT_HEADER(obj)                      \
-    G_TYPE_CHECK_INSTANCE_TYPE(obj, BALSA_TYPE_PRINT_OBJECT_HEADER)
-
-
-typedef struct _BalsaPrintObjectHeaderClass BalsaPrintObjectHeaderClass;
-typedef struct _BalsaPrintObjectHeader BalsaPrintObjectHeader;
-
-
-struct _BalsaPrintObjectHeader {
-    BalsaPrintObject parent;
-
-    gint p_label_width;
-    gint p_layout_width;
-    gchar *headers;
-    GdkPixbuf *face;
-};
-
-
-struct _BalsaPrintObjectHeaderClass {
-    BalsaPrintObjectClass parent;
-};
-
-
-GType balsa_print_object_header_get_type(void);
-GList *balsa_print_object_header_from_message(GList *list,
-                                             GtkPrintContext * context,
-                                             LibBalsaMessage * message,
-                                             const gchar * subject,
-                                              BalsaPrintSetup * psetup);
-GList *balsa_print_object_header_from_body(GList *list,
-                                          GtkPrintContext * context,
-                                          LibBalsaMessageBody * body,
-                                          BalsaPrintSetup * psetup);
-GList *balsa_print_object_header_crypto(GList *list,
-                                       GtkPrintContext * context,
-                                       LibBalsaMessageBody * body,
-                                       BalsaPrintSetup * psetup);
+#define BALSA_TYPE_PRINT_OBJECT_HEADER balsa_print_object_header_get_type()
+G_DECLARE_FINAL_TYPE(BalsaPrintObjectHeader, balsa_print_object_header, BALSA_PRINT, OBJECT_HEADER, 
BalsaPrintObject)
+
+
+GList *balsa_print_object_header_from_message(GList           *list,
+                                                                                         GtkPrintContext 
*context,
+                                                                                         LibBalsaMessage 
*message,
+                                                                                         const gchar     
*subject,
+                                                                                         BalsaPrintSetup 
*psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
+GList *balsa_print_object_header_from_body(GList               *list,
+                                                                                  GtkPrintContext     
*context,
+                                                                                  LibBalsaMessageBody *body,
+                                                                                  BalsaPrintSetup     
*psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
+GList *balsa_print_object_header_crypto(GList               *list,
+                                                                               GtkPrintContext     *context,
+                                                                               LibBalsaMessageBody *body,
+                                                                               BalsaPrintSetup     *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
 
 
 G_END_DECLS
diff --git a/src/balsa-print-object-html.c b/src/balsa-print-object-html.c
index a173eb2c6..718ae20fe 100644
--- a/src/balsa-print-object-html.c
+++ b/src/balsa-print-object-html.c
@@ -27,6 +27,15 @@
 #include "html.h"
 
 
+struct _BalsaPrintObjectHtml {
+    BalsaPrintObject parent;
+
+    cairo_surface_t *html_surface;
+    gdouble c_y_offs;
+    gdouble scale;
+};
+
+
 G_DEFINE_TYPE(BalsaPrintObjectHtml, balsa_print_object_html, BALSA_TYPE_PRINT_OBJECT)
 
 
@@ -40,7 +49,6 @@ static void balsa_print_object_html_draw(BalsaPrintObject *self,
 static void
 balsa_print_object_html_class_init(BalsaPrintObjectHtmlClass *klass)
 {
-       balsa_print_object_html_parent_class = g_type_class_ref(BALSA_TYPE_PRINT_OBJECT);
     BALSA_PRINT_OBJECT_CLASS(klass)->draw = balsa_print_object_html_draw;
     G_OBJECT_CLASS(klass)->finalize = balsa_print_object_html_destroy;
 }
@@ -76,7 +84,6 @@ balsa_print_object_html(GList                                 *list,
        BalsaPrintObjectHtml *poh;
     BalsaPrintObject *po;
     gdouble surface_width;
-    gdouble surface_height;
     gdouble height_left;
     gdouble chunk_y_offs;
     gdouble c_use_width;
@@ -98,37 +105,38 @@ balsa_print_object_html(GList                              *list,
     } else {
        scale = 1.0;
     }
-    surface_height = (gdouble) cairo_image_surface_get_height(html_surface) * scale;
+    height_left = (gdouble) cairo_image_surface_get_height(html_surface) * scale;
 
     /* split the surface into parts fitting on pages */
-    height_left = surface_height;
     chunk_y_offs = 0.0;
     do {
+       BalsaPrintRect rect;
+
         /* create the part */
         poh = g_object_new(BALSA_TYPE_PRINT_OBJECT_HTML, NULL);
         g_assert(poh != NULL);
         po = BALSA_PRINT_OBJECT(poh);
-        po->depth = psetup->curr_depth;
         poh->html_surface = cairo_surface_reference(html_surface);
         poh->scale = scale;
         poh->c_y_offs = chunk_y_offs;
 
         /* extent */
-        po->on_page = psetup->page_count - 1;
-        po->c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
-        po->c_at_y = psetup->c_y0 + psetup->c_y_pos;
-        po->c_width = surface_width;
+        balsa_print_object_set_page_depth(po, psetup->page_count - 1, psetup->curr_depth);
+        rect.c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
+        rect.c_at_y = psetup->c_y0 + psetup->c_y_pos;
+        rect.c_width = surface_width;
         if (psetup->c_y_pos + height_left > psetup->c_height) {
-               po->c_height = psetup->c_height - psetup->c_y_pos;
-               chunk_y_offs += po->c_height;
-               height_left -= po->c_height;
+               rect.c_height = psetup->c_height - psetup->c_y_pos;
+               chunk_y_offs += rect.c_height;
+               height_left -= rect.c_height;
                psetup->c_y_pos = 0.0;
                psetup->page_count++;
         } else {
-               po->c_height = height_left;
+               rect.c_height = height_left;
                psetup->c_y_pos += height_left;
                height_left = 0.0;
         }
+        balsa_print_object_set_rect(po, &rect);
         list = g_list_append(list, po);
     } while (height_left > 0.0);
 
@@ -145,18 +153,20 @@ balsa_print_object_html_draw(BalsaPrintObject *self,
                                                         cairo_t                  *cairo_ctx)
 {
        BalsaPrintObjectHtml *poh;
+       const BalsaPrintRect *rect;
     cairo_pattern_t *pattern;
     cairo_matrix_t matrix;
 
     /* prepare */
     poh = BALSA_PRINT_OBJECT_HTML(self);
+    rect = balsa_print_object_get_rect(self);
     g_assert(poh != NULL);
 
     /* save current state */
     cairo_save(cairo_ctx);
 
     /* set surface */
-    cairo_set_source_surface(cairo_ctx, poh->html_surface, self->c_at_x, self->c_at_y);
+    cairo_set_source_surface(cairo_ctx, poh->html_surface, rect->c_at_x, rect->c_at_y);
 
     /* scale */
     pattern = cairo_get_source(cairo_ctx);
@@ -169,10 +179,10 @@ balsa_print_object_html_draw(BalsaPrintObject *self,
 
     /* clip around the chunk */
     cairo_new_path(cairo_ctx);
-    cairo_move_to(cairo_ctx, self->c_at_x, self->c_at_y);
-    cairo_line_to(cairo_ctx, self->c_at_x + self->c_width, self->c_at_y);
-    cairo_line_to(cairo_ctx, self->c_at_x + self->c_width, self->c_at_y + self->c_height);
-    cairo_line_to(cairo_ctx, self->c_at_x, self->c_at_y + self->c_height);
+    cairo_move_to(cairo_ctx, rect->c_at_x, rect->c_at_y);
+    cairo_line_to(cairo_ctx, rect->c_at_x + rect->c_width, rect->c_at_y);
+    cairo_line_to(cairo_ctx, rect->c_at_x + rect->c_width, rect->c_at_y + rect->c_height);
+    cairo_line_to(cairo_ctx, rect->c_at_x, rect->c_at_y + rect->c_height);
     cairo_close_path(cairo_ctx);
     cairo_clip(cairo_ctx);
 
diff --git a/src/balsa-print-object-html.h b/src/balsa-print-object-html.h
index 601252a91..f1d51c4dd 100644
--- a/src/balsa-print-object-html.h
+++ b/src/balsa-print-object-html.h
@@ -38,39 +38,15 @@
 
 G_BEGIN_DECLS
 
-#define BALSA_TYPE_PRINT_OBJECT_HTML                   \
-       (balsa_print_object_html_get_type())
-#define BALSA_PRINT_OBJECT_HTML(obj)                   \
-       G_TYPE_CHECK_INSTANCE_CAST(obj, BALSA_TYPE_PRINT_OBJECT_HTML, BalsaPrintObjectHtml)
-#define BALSA_PRINT_OBJECT_HTML_CLASS(klass)   \
-       G_TYPE_CHECK_CLASS_CAST(klass, BALSA_TYPE_PRINT_OBJECT_HTML, BalsaPrintObjectHtmlClass)
-#define BALSA_IS_PRINT_OBJECT_HTML(obj)                        \
-       G_TYPE_CHECK_INSTANCE_TYPE(obj, BALSA_TYPE_PRINT_OBJECT_HTML)
+#define BALSA_TYPE_PRINT_OBJECT_HTML   balsa_print_object_html_get_type()
+G_DECLARE_FINAL_TYPE(BalsaPrintObjectHtml, balsa_print_object_html, BALSA_PRINT, OBJECT_HTML, 
BalsaPrintObject)
 
 
-typedef struct _BalsaPrintObjectHtmlClass BalsaPrintObjectHtmlClass;
-typedef struct _BalsaPrintObjectHtml BalsaPrintObjectHtml;
-
-
-struct _BalsaPrintObjectHtml {
-    BalsaPrintObject parent;
-
-    cairo_surface_t *html_surface;
-    gdouble c_y_offs;
-    gdouble scale;
-};
-
-
-struct _BalsaPrintObjectHtmlClass {
-    BalsaPrintObjectClass parent;
-};
-
-
-GType balsa_print_object_html_get_type(void);
-GList *balsa_print_object_html(GList *list,
-                               GtkPrintContext *context,
-                               LibBalsaMessageBody *body,
-                               BalsaPrintSetup *psetup);
+GList *balsa_print_object_html(GList               *list,
+                                                          GtkPrintContext     *context,
+                                                          LibBalsaMessageBody *body,
+                                                          BalsaPrintSetup     *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
 
 
 G_END_DECLS
diff --git a/src/balsa-print-object-image.c b/src/balsa-print-object-image.c
index 090bbf39a..6421ae3c9 100644
--- a/src/balsa-print-object-image.c
+++ b/src/balsa-print-object-image.c
@@ -1,7 +1,7 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
- * Written by (C) Albrecht Dre� <albrecht dress arcor de> 2007
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
+ * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,66 +25,40 @@
 
 #include <gtk/gtk.h>
 
-/* object related functions */
-static void
-balsa_print_object_image_class_init(BalsaPrintObjectImageClass * klass);
-static void balsa_print_object_image_init (GTypeInstance *instance,
-                                          gpointer g_class);
-static void balsa_print_object_image_destroy(GObject * self);
 
-static void balsa_print_object_image_draw(BalsaPrintObject * self,
-                                         GtkPrintContext * context,
-                                         cairo_t * cairo_ctx);
+struct _BalsaPrintObjectImage {
+    BalsaPrintObject parent;
 
+    GdkPixbuf *pixbuf;
+    gdouble c_img_offs;
+    gdouble scale;
+};
 
-static BalsaPrintObjectClass *parent_class = NULL;
 
+G_DEFINE_TYPE(BalsaPrintObjectImage, balsa_print_object_image, BALSA_TYPE_PRINT_OBJECT)
 
-GType
-balsa_print_object_image_get_type()
-{
-    static GType balsa_print_object_image_type = 0;
-
-    if (!balsa_print_object_image_type) {
-       static const GTypeInfo balsa_print_object_image_info = {
-           sizeof(BalsaPrintObjectImageClass),
-           NULL,               /* base_init */
-           NULL,               /* base_finalize */
-           (GClassInitFunc) balsa_print_object_image_class_init,
-           NULL,               /* class_finalize */
-           NULL,               /* class_data */
-           sizeof(BalsaPrintObjectImage),
-           0,                  /* n_preallocs */
-           (GInstanceInitFunc) balsa_print_object_image_init
-       };
-
-       balsa_print_object_image_type =
-           g_type_register_static(BALSA_TYPE_PRINT_OBJECT,
-                                  "BalsaPrintObjectImage",
-                                  &balsa_print_object_image_info, 0);
-    }
 
-    return balsa_print_object_image_type;
-}
+/* object related functions */
+static void balsa_print_object_image_destroy(GObject * self);
+
+static void balsa_print_object_image_draw(BalsaPrintObject * self,
+                                         GtkPrintContext * context,
+                                         cairo_t * cairo_ctx);
 
 
 static void
 balsa_print_object_image_class_init(BalsaPrintObjectImageClass * klass)
 {
-    parent_class = g_type_class_ref(BALSA_TYPE_PRINT_OBJECT);
-    BALSA_PRINT_OBJECT_CLASS(klass)->draw =
-       balsa_print_object_image_draw;
+    BALSA_PRINT_OBJECT_CLASS(klass)->draw =    balsa_print_object_image_draw;
     G_OBJECT_CLASS(klass)->finalize = balsa_print_object_image_destroy;
 }
 
 
 static void
-balsa_print_object_image_init(GTypeInstance * instance, gpointer g_class)
+balsa_print_object_image_init(BalsaPrintObjectImage *self)
 {
-    BalsaPrintObjectImage *po = BALSA_PRINT_OBJECT_IMAGE(instance);
-
-    po->pixbuf = NULL;
-    po->scale = 1.0;
+    self->pixbuf = NULL;
+    self->scale = 1.0;
 }
 
 
@@ -93,10 +67,10 @@ balsa_print_object_image_destroy(GObject * self)
 {
     BalsaPrintObjectImage *po = BALSA_PRINT_OBJECT_IMAGE(self);
 
-    if (po->pixbuf)
-       g_object_unref(po->pixbuf);
-
-    G_OBJECT_CLASS(parent_class)->finalize(self);
+    if (po->pixbuf != NULL) {
+       g_object_unref(po->pixbuf);
+    }
+    G_OBJECT_CLASS(balsa_print_object_image_parent_class)->finalize(self);
 }
 
 
@@ -106,11 +80,10 @@ balsa_print_object_image(GList * list, GtkPrintContext *context,
 {
     BalsaPrintObjectImage *poi;
     BalsaPrintObject *po;
+    BalsaPrintRect rect;
     GdkPixbuf *pixbuf;
     GError *err = NULL;
     gdouble c_use_width;
-    gdouble c_img_width;
-    gdouble c_img_height;
 
     /* check if we can handle the image */
     pixbuf = libbalsa_message_body_get_pixbuf(body, &err);
@@ -127,44 +100,43 @@ balsa_print_object_image(GList * list, GtkPrintContext *context,
     poi = g_object_new(BALSA_TYPE_PRINT_OBJECT_IMAGE, NULL);
     g_assert(poi != NULL);
     po = BALSA_PRINT_OBJECT(poi);
-    po->depth = psetup->curr_depth;
     poi->pixbuf = pixbuf;
     c_use_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
-    c_img_width = gdk_pixbuf_get_width(pixbuf);
-    c_img_height = gdk_pixbuf_get_height(pixbuf);
+    rect.c_width = gdk_pixbuf_get_width(pixbuf);
+    rect.c_height = gdk_pixbuf_get_height(pixbuf);
     poi->scale = 1.0;
 
     /* check if we should scale the width */
-    if (c_img_width > c_use_width) {
-       poi->scale = c_use_width / c_img_width;
-       c_img_height *= poi->scale;
-       c_img_width = c_use_width;
+    if (rect.c_width > c_use_width) {
+       poi->scale = c_use_width / rect.c_width;
+       rect.c_height *= poi->scale;
+       rect.c_width = c_use_width;
     }
 
     /* check if the image is too high for one full page */
-    if (c_img_height > psetup->c_height) {
-       gdouble hscale = psetup->c_height / c_img_height;
-       poi->scale *= hscale;
-       c_img_width *= hscale;
-       c_img_height = psetup->c_height;
+    if (rect.c_height > psetup->c_height) {
+       gdouble hscale = psetup->c_height / rect.c_height;
+
+       poi->scale *= hscale;
+       rect.c_width *= hscale;
+       rect.c_height = psetup->c_height;
     }
 
     /* check if we should move to the next page */
-    if (psetup->c_y_pos + c_img_height > psetup->c_height) {
-       psetup->c_y_pos = 0;
-       psetup->page_count++;
+    if (psetup->c_y_pos + rect.c_height > psetup->c_height) {
+       psetup->c_y_pos = 0;
+       psetup->page_count++;
     }
 
     /* remember the extent */
-    po->on_page = psetup->page_count - 1;
-    po->c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
-    po->c_at_y = psetup->c_y0 + psetup->c_y_pos;
-    po->c_width = c_img_width;
-    poi->c_img_offs = 0.5 * (c_use_width - c_img_width);
-    po->c_height = c_img_height;
+    balsa_print_object_set_page_depth(po, psetup->page_count - 1, psetup->curr_depth);
+    rect.c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
+    rect.c_at_y = psetup->c_y0 + psetup->c_y_pos;
+    poi->c_img_offs = 0.5 * (c_use_width - rect.c_width);
+    balsa_print_object_set_rect(po, &rect);
 
     /* adjust the y position */
-    psetup->c_y_pos += c_img_height;
+    psetup->c_y_pos += rect.c_height;
 
     return g_list_append(list, po);
 }
@@ -176,12 +148,14 @@ balsa_print_object_image_draw(BalsaPrintObject * self,
                              cairo_t * cairo_ctx)
 {
     BalsaPrintObjectImage *poi;
+       const BalsaPrintRect *rect;
 
     /* prepare */
     poi = BALSA_PRINT_OBJECT_IMAGE(self);
+    rect = balsa_print_object_get_rect(self);
     g_assert(poi != NULL);
 
     /* print the image */
-    cairo_print_pixbuf(cairo_ctx, poi->pixbuf, self->c_at_x + poi->c_img_offs,
-                      self->c_at_y, poi->scale);
+    cairo_print_pixbuf(cairo_ctx, poi->pixbuf, rect->c_at_x + poi->c_img_offs,
+               rect->c_at_y, poi->scale);
 }
diff --git a/src/balsa-print-object-image.h b/src/balsa-print-object-image.h
index e52fa77f2..fae1ef99b 100644
--- a/src/balsa-print-object-image.h
+++ b/src/balsa-print-object-image.h
@@ -1,7 +1,7 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
- * Written by (C) Albrecht Dre� <albrecht dress arcor de> 2007
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
+ * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,39 +24,15 @@
 
 G_BEGIN_DECLS
 
-#define BALSA_TYPE_PRINT_OBJECT_IMAGE  \
-    (balsa_print_object_image_get_type())
-#define BALSA_PRINT_OBJECT_IMAGE(obj)                          \
-    G_TYPE_CHECK_INSTANCE_CAST(obj, BALSA_TYPE_PRINT_OBJECT_IMAGE, BalsaPrintObjectImage)
-#define BALSA_PRINT_OBJECT_IMAGE_CLASS(klass)                  \
-    G_TYPE_CHECK_CLASS_CAST(klass, BALSA_TYPE_PRINT_OBJECT_IMAGE, BalsaPrintObjectImageClass)
-#define BALSA_IS_PRINT_OBJECT_IMAGE(obj)                       \
-    G_TYPE_CHECK_INSTANCE_TYPE(obj, BALSA_TYPE_PRINT_OBJECT_IMAGE)
+#define BALSA_TYPE_PRINT_OBJECT_IMAGE  balsa_print_object_image_get_type()
+G_DECLARE_FINAL_TYPE(BalsaPrintObjectImage, balsa_print_object_image, BALSA_PRINT, OBJECT_IMAGE, 
BalsaPrintObject)
 
 
-typedef struct _BalsaPrintObjectImageClass BalsaPrintObjectImageClass;
-typedef struct _BalsaPrintObjectImage BalsaPrintObjectImage;
-
-
-struct _BalsaPrintObjectImage {
-    BalsaPrintObject parent;
-
-    GdkPixbuf *pixbuf;
-    gdouble c_img_offs;
-    gdouble scale;
-};
-
-
-struct _BalsaPrintObjectImageClass {
-    BalsaPrintObjectClass parent;
-};
-
-
-GType balsa_print_object_image_get_type(void);
-GList *balsa_print_object_image(GList *list,
-                               GtkPrintContext *context,
-                               LibBalsaMessageBody *body,
-                               BalsaPrintSetup *psetup);
+GList *balsa_print_object_image(GList               *list,
+                                                               GtkPrintContext     *context,
+                                                               LibBalsaMessageBody *body,
+                                                               BalsaPrintSetup     *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
 
 
 G_END_DECLS
diff --git a/src/balsa-print-object-text.c b/src/balsa-print-object-text.c
index 37fb79b5f..955c0f62d 100644
--- a/src/balsa-print-object-text.c
+++ b/src/balsa-print-object-text.c
@@ -1,6 +1,6 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
  * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
@@ -48,9 +48,6 @@ typedef struct {
 
 
 /* object related functions */
-static void balsa_print_object_text_class_init(BalsaPrintObjectTextClass * klass);
-static void balsa_print_object_text_init(GTypeInstance * instance,
-                                        gpointer g_class);
 static void balsa_print_object_text_destroy(GObject * self);
 
 static void balsa_print_object_text_draw(BalsaPrintObject * self,
@@ -63,54 +60,32 @@ static GList * phrase_highlight(const gchar * buffer, gunichar tag_char,
                                PhraseType tag_type, GList * phrase_list);
 
 
-static BalsaPrintObjectClass *parent_class = NULL;
+struct _BalsaPrintObjectText {
+    BalsaPrintObject parent;
 
+    gint p_label_width;
+    gchar *text;
+    guint cite_level;
+    GList *attributes;
+};
 
-GType
-balsa_print_object_text_get_type()
-{
-    static GType balsa_print_object_text_type = 0;
-
-    if (!balsa_print_object_text_type) {
-       static const GTypeInfo balsa_print_object_text_info = {
-           sizeof(BalsaPrintObjectTextClass),
-           NULL,               /* base_init */
-           NULL,               /* base_finalize */
-           (GClassInitFunc) balsa_print_object_text_class_init,
-           NULL,               /* class_finalize */
-           NULL,               /* class_data */
-           sizeof(BalsaPrintObjectText),
-           0,                  /* n_preallocs */
-           (GInstanceInitFunc) balsa_print_object_text_init
-       };
-
-       balsa_print_object_text_type =
-           g_type_register_static(BALSA_TYPE_PRINT_OBJECT,
-                                  "BalsaPrintObjectText",
-                                  &balsa_print_object_text_info, 0);
-    }
 
-    return balsa_print_object_text_type;
-}
+G_DEFINE_TYPE(BalsaPrintObjectText, balsa_print_object_text, BALSA_TYPE_PRINT_OBJECT)
 
 
 static void
-balsa_print_object_text_class_init(BalsaPrintObjectTextClass * klass)
+balsa_print_object_text_class_init(BalsaPrintObjectTextClass *klass)
 {
-    parent_class = g_type_class_ref(BALSA_TYPE_PRINT_OBJECT);
-    BALSA_PRINT_OBJECT_CLASS(klass)->draw =
-       balsa_print_object_text_draw;
+    BALSA_PRINT_OBJECT_CLASS(klass)->draw =    balsa_print_object_text_draw;
     G_OBJECT_CLASS(klass)->finalize = balsa_print_object_text_destroy;
 }
 
 
 static void
-balsa_print_object_text_init(GTypeInstance * instance, gpointer g_class)
+balsa_print_object_text_init(BalsaPrintObjectText *self)
 {
-    BalsaPrintObjectText *po = BALSA_PRINT_OBJECT_TEXT(instance);
-
-    po->text = NULL;
-    po->attributes = NULL;
+       self->text = NULL;
+       self->attributes = NULL;
 }
 
 
@@ -122,7 +97,7 @@ balsa_print_object_text_destroy(GObject * self)
     g_list_free_full(po->attributes, g_free);
     g_free(po->text);
 
-    G_OBJECT_CLASS(parent_class)->finalize(self);
+    G_OBJECT_CLASS(balsa_print_object_text_parent_class)->finalize(self);
 }
 
 /* prepare a text/plain part, which gets
@@ -137,8 +112,7 @@ balsa_print_object_text_plain(GList *list, GtkPrintContext * context,
     GRegex *rex;
     gchar *textbuf;
     PangoFontDescription *font;
-    gdouble c_at_x;
-    gdouble c_use_width;
+    BalsaPrintRect rect;
     guint first_page;
     gchar * par_start;
     gchar * eol;
@@ -149,39 +123,38 @@ balsa_print_object_text_plain(GList *list, GtkPrintContext * context,
        return balsa_print_object_default(list, context, body, psetup);
 
     /* start on new page if less than 2 lines can be printed */
-    if (psetup->c_y_pos + 2 * P_TO_C(psetup->p_body_font_height) >
-       psetup->c_height) {
-       psetup->c_y_pos = 0;
-       psetup->page_count++;
+    if (psetup->c_y_pos + 2 * P_TO_C(psetup->p_body_font_height) > psetup->c_height) {
+       psetup->c_y_pos = 0;
+       psetup->page_count++;
     }
-    c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
-    c_use_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    rect.c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
+    rect.c_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    rect.c_height = -1.0;      /* height is calculated when the object is drawn */
 
     /* copy the text body to a buffer */
-    if (body->buffer)
-       textbuf = g_strdup(body->buffer);
-    else
-       libbalsa_message_body_get_content(body, &textbuf, NULL);
+    if (body->buffer != NULL) {
+       textbuf = g_strdup(body->buffer);
+    } else {
+       libbalsa_message_body_get_content(body, &textbuf, NULL);
+    }
 
     /* fake an empty buffer if textbuf is NULL */
-    if (!textbuf)
-       textbuf = g_strdup("");
+    if (textbuf == NULL) {
+       textbuf = g_strdup("");
+    }
 
     /* be sure the we have correct utf-8 stuff here... */
     libbalsa_utf8_sanitize(&textbuf, balsa_app.convert_unknown_8bit, NULL);
 
     /* apply flowed if requested */
     if (libbalsa_message_body_is_flowed(body)) {
-       GString *flowed;
-
-       flowed =
-           libbalsa_process_text_rfc2646(textbuf, G_MAXINT, FALSE, FALSE,
-                                         FALSE,
-                                         libbalsa_message_body_is_delsp
-                                         (body));
-       g_free(textbuf);
-       textbuf = flowed->str;
-       g_string_free(flowed, FALSE);
+       GString *flowed;
+
+       flowed = libbalsa_process_text_rfc2646(textbuf, G_MAXINT, FALSE, FALSE,
+                                       FALSE, libbalsa_message_body_is_delsp(body));
+       g_free(textbuf);
+       textbuf = flowed->str;
+       g_string_free(flowed, FALSE);
     }
 
     /* get the font */
@@ -192,126 +165,113 @@ balsa_print_object_text_plain(GList *list, GtkPrintContext * context,
     eol = strchr(par_start, '\n');
     par_len = eol ? eol - par_start : (gint) strlen(par_start);
     while (*par_start) {
-       GString *level_buf;
-       guint curr_level;
-       guint cite_level;
-       GList *par_parts;
-       GList *this_par_part;
-       GList *attr_list;
-       PangoLayout *layout;
-       PangoAttrList *pango_attr_list;
-       GArray *attr_offs;
-       gdouble c_at_y;
-
-       level_buf = NULL;
-       curr_level = 0;         /* just to make the compiler happy */
-       do {
-           gchar *thispar;
-           guint cite_idx;
-
-           thispar = g_strndup(par_start, par_len);
-
-           /* get the cite level and strip off the prefix */
-           if (libbalsa_match_regex(thispar, rex, &cite_level, &cite_idx))
-            {
-               gchar *new;
-
-               new = thispar + cite_idx;
-               if (g_unichar_isspace(g_utf8_get_char(new)))
-                   new = g_utf8_next_char(new);
-               new = g_strdup(new);
-               g_free(thispar);
-               thispar = new;
-           }
-
-           /* glue paragraphs with the same cite level together */
-           if (!level_buf || (curr_level == cite_level)) {
-               if (!level_buf) {
-                   level_buf = g_string_new(thispar);
-                   curr_level = cite_level;
-               } else {
-                   level_buf = g_string_append_c(level_buf, '\n');
-                   level_buf = g_string_append(level_buf, thispar);
-               }
-
-               par_start = eol ? eol + 1 : par_start + par_len;
-               eol = strchr(par_start, '\n');
-               par_len = eol ? eol - par_start : (gint) strlen(par_start);
-           }
-
-           g_free(thispar);
-       } while (*par_start && (curr_level == cite_level));
-       
-       /* configure the layout so we can use Pango to split the text into pages */
-       layout = gtk_print_context_create_pango_layout(context);
-       pango_layout_set_font_description(layout, font);
-       pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
-       pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
-
-       /* leave place for the citation bars */
-       pango_layout_set_width(layout,
-                              C_TO_P(c_use_width - curr_level * C_LABEL_SEP));
-
-       /* highlight structured phrases if requested */
-       if (balsa_app.print_highlight_phrases) {
-           attr_list =
-               phrase_highlight(level_buf->str, '*', PHRASE_BF, NULL);
-           attr_list =
-               phrase_highlight(level_buf->str, '/', PHRASE_EM, attr_list);
-           attr_list =
-               phrase_highlight(level_buf->str, '_', PHRASE_UL, attr_list);
-       } else
-           attr_list = NULL;
-
-       /* start on new page if less than one line can be printed */
-       if (psetup->c_y_pos + P_TO_C(psetup->p_body_font_height) >
-           psetup->c_height) {
-           psetup->c_y_pos = 0;
-           psetup->page_count++;
-       }
-
-       /* split paragraph if necessary */
-       pango_attr_list = phrase_list_to_pango(attr_list);
-       first_page = psetup->page_count - 1;
-       c_at_y = psetup->c_y_pos;
-       par_parts =
-           split_for_layout(layout, level_buf->str, pango_attr_list,
-                            psetup, FALSE, &attr_offs);
-       if (pango_attr_list)
-           pango_attr_list_unref(pango_attr_list);
-       g_object_unref(G_OBJECT(layout));
-       g_string_free(level_buf, TRUE);
-
-       /* each part is a new text object */
-       this_par_part = par_parts;
-       while (this_par_part) {
-           BalsaPrintObjectText *pot;
-
-           pot = g_object_new(BALSA_TYPE_PRINT_OBJECT_TEXT, NULL);
-           g_assert(pot != NULL);
-           BALSA_PRINT_OBJECT(pot)->on_page = first_page++;
-           BALSA_PRINT_OBJECT(pot)->c_at_x = c_at_x;
-           BALSA_PRINT_OBJECT(pot)->c_at_y = psetup->c_y0 + c_at_y;
-           BALSA_PRINT_OBJECT(pot)->depth = psetup->curr_depth;
-           c_at_y = 0.0;
-           BALSA_PRINT_OBJECT(pot)->c_width = c_use_width;
-           /* note: height is calculated when the object is drawn */
-           pot->text = (gchar *) this_par_part->data;
-           pot->cite_level = curr_level;
-           pot->attributes =
-               collect_attrs(attr_list,
-                             g_array_index(attr_offs, guint, 0),
-                             strlen(pot->text));
-
-           list = g_list_append(list, pot);
-           g_array_remove_index(attr_offs, 0);
-           this_par_part = g_list_next(this_par_part);
-       }
-       if (attr_list) {
-           g_list_free_full(attr_list, g_free);
-       }
-       g_list_free(par_parts);
-       g_array_free(attr_offs, TRUE);
+       GString *level_buf;
+       guint curr_level;
+       guint cite_level;
+       GList *par_parts;
+       GList *this_par_part;
+       GList *attr_list;
+       PangoLayout *layout;
+       PangoAttrList *pango_attr_list;
+       GArray *attr_offs;
+       gdouble c_at_y;
+
+       level_buf = NULL;
+       curr_level = 0;         /* just to make the compiler happy */
+       do {
+               gchar *thispar;
+               guint cite_idx;
+
+               thispar = g_strndup(par_start, par_len);
+
+               /* get the cite level and strip off the prefix */
+               if (libbalsa_match_regex(thispar, rex, &cite_level, &cite_idx))
+               {
+                       gchar *new;
+
+                       new = thispar + cite_idx;
+                       if (g_unichar_isspace(g_utf8_get_char(new)))
+                               new = g_utf8_next_char(new);
+                       new = g_strdup(new);
+                       g_free(thispar);
+                       thispar = new;
+               }
+
+               /* glue paragraphs with the same cite level together */
+               if (!level_buf || (curr_level == cite_level)) {
+                       if (!level_buf) {
+                               level_buf = g_string_new(thispar);
+                               curr_level = cite_level;
+                       } else {
+                               level_buf = g_string_append_c(level_buf, '\n');
+                               level_buf = g_string_append(level_buf, thispar);
+                       }
+
+                       par_start = eol ? eol + 1 : par_start + par_len;
+                       eol = strchr(par_start, '\n');
+                       par_len = eol ? eol - par_start : (gint) strlen(par_start);
+               }
+
+               g_free(thispar);
+       } while (*par_start && (curr_level == cite_level));
+
+       /* configure the layout so we can use Pango to split the text into pages */
+       layout = gtk_print_context_create_pango_layout(context);
+       pango_layout_set_font_description(layout, font);
+       pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
+       pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+
+       /* leave place for the citation bars */
+       pango_layout_set_width(layout, C_TO_P(rect.c_width - curr_level * C_LABEL_SEP));
+
+       /* highlight structured phrases if requested */
+       if (balsa_app.print_highlight_phrases) {
+               attr_list = phrase_highlight(level_buf->str, '*', PHRASE_BF, NULL);
+               attr_list = phrase_highlight(level_buf->str, '/', PHRASE_EM, attr_list);
+               attr_list = phrase_highlight(level_buf->str, '_', PHRASE_UL, attr_list);
+       } else {
+               attr_list = NULL;
+       }
+
+       /* start on new page if less than one line can be printed */
+       if (psetup->c_y_pos + P_TO_C(psetup->p_body_font_height) > psetup->c_height) {
+               psetup->c_y_pos = 0;
+               psetup->page_count++;
+       }
+
+       /* split paragraph if necessary */
+       pango_attr_list = phrase_list_to_pango(attr_list);
+       first_page = psetup->page_count - 1;
+       c_at_y = psetup->c_y_pos;
+       par_parts = split_for_layout(layout, level_buf->str, pango_attr_list, psetup, FALSE, &attr_offs);
+       if (pango_attr_list != NULL) {
+               pango_attr_list_unref(pango_attr_list);
+       }
+       g_object_unref(G_OBJECT(layout));
+       g_string_free(level_buf, TRUE);
+
+       /* each part is a new text object */
+       for (this_par_part = par_parts; this_par_part != NULL; this_par_part = this_par_part->next) {
+               BalsaPrintObjectText *pot;
+
+               pot = g_object_new(BALSA_TYPE_PRINT_OBJECT_TEXT, NULL);
+               g_assert(pot != NULL);
+               balsa_print_object_set_page_depth(BALSA_PRINT_OBJECT(pot), first_page++, psetup->curr_depth);
+               rect.c_at_y = psetup->c_y0 + c_at_y;
+               balsa_print_object_set_rect(BALSA_PRINT_OBJECT(pot), &rect);
+               c_at_y = 0.0;
+               pot->text = (gchar *) this_par_part->data;
+               pot->cite_level = curr_level;
+               pot->attributes = collect_attrs(attr_list, g_array_index(attr_offs, guint, 0), 
strlen(pot->text));
+
+               list = g_list_append(list, pot);
+               g_array_remove_index(attr_offs, 0);
+       }
+       if (attr_list) {
+               g_list_free_full(attr_list, g_free);
+       }
+       g_list_free(par_parts);
+       g_array_free(attr_offs, TRUE);
     }
 
     /* clean up */
@@ -331,8 +291,7 @@ balsa_print_object_text(GList *list, GtkPrintContext * context,
 {
     gchar *textbuf;
     PangoFontDescription *font;
-    gdouble c_at_x;
-    gdouble c_use_width;
+    BalsaPrintRect rect;
     guint first_page;
     GList *par_parts;
     GList *this_par_part;
@@ -340,13 +299,13 @@ balsa_print_object_text(GList *list, GtkPrintContext * context,
     gdouble c_at_y;
 
     /* start on new page if less than 2 lines can be printed */
-    if (psetup->c_y_pos + 2 * P_TO_C(psetup->p_body_font_height) >
-       psetup->c_height) {
-       psetup->c_y_pos = 0;
-       psetup->page_count++;
+    if (psetup->c_y_pos + 2 * P_TO_C(psetup->p_body_font_height) > psetup->c_height) {
+       psetup->c_y_pos = 0;
+       psetup->page_count++;
     }
-    c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
-    c_use_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    rect.c_at_x = psetup->c_x0 + psetup->curr_depth * C_LABEL_SEP;
+    rect.c_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    rect.c_height = -1.0;      /* height is calculated when the object is drawn */
 
     /* copy the text body to a buffer */
     if (body->buffer)
@@ -369,7 +328,7 @@ balsa_print_object_text(GList *list, GtkPrintContext * context,
     pango_layout_set_font_description(layout, font);
     pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
     pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
-    pango_layout_set_width(layout, C_TO_P(c_use_width));
+    pango_layout_set_width(layout, C_TO_P(rect.c_width));
 
     /* split paragraph if necessary */
     first_page = psetup->page_count - 1;
@@ -380,31 +339,49 @@ balsa_print_object_text(GList *list, GtkPrintContext * context,
     g_free(textbuf);
 
     /* each part is a new text object */
-    this_par_part = par_parts;
-    while (this_par_part) {
-       BalsaPrintObjectText *pot;
-
-       pot = g_object_new(BALSA_TYPE_PRINT_OBJECT_TEXT, NULL);
-       g_assert(pot != NULL);
-       BALSA_PRINT_OBJECT(pot)->on_page = first_page++;
-       BALSA_PRINT_OBJECT(pot)->c_at_x = c_at_x;
-       BALSA_PRINT_OBJECT(pot)->c_at_y = psetup->c_y0 + c_at_y;
-       BALSA_PRINT_OBJECT(pot)->depth = psetup->curr_depth;
-       c_at_y = 0.0;
-       BALSA_PRINT_OBJECT(pot)->c_width = c_use_width;
-       /* note: height is calculated when the object is drawn */
-       pot->text = (gchar *) this_par_part->data;
-       pot->cite_level = 0;
-       pot->attributes = NULL;
-
-       list = g_list_append(list, pot);
-       this_par_part = g_list_next(this_par_part);
+    for (this_par_part = par_parts; this_par_part != NULL; this_par_part = this_par_part->next) {
+       BalsaPrintObjectText *pot;
+
+       pot = g_object_new(BALSA_TYPE_PRINT_OBJECT_TEXT, NULL);
+       g_assert(pot != NULL);
+       balsa_print_object_set_page_depth(BALSA_PRINT_OBJECT(pot), first_page++, psetup->curr_depth);
+       rect.c_at_y = psetup->c_y0 + c_at_y;
+       balsa_print_object_set_rect(BALSA_PRINT_OBJECT(pot), &rect);
+       c_at_y = 0.0;
+
+       pot->text = (gchar *) this_par_part->data;
+       pot->cite_level = 0;
+       pot->attributes = NULL;
+
+       list = g_list_append(list, pot);
     }
     g_list_free(par_parts);
 
     return list;
 }
 
+static GdkPixbuf *
+get_icon(const gchar         *icon_name,
+                LibBalsaMessageBody *body)
+{
+    gint width;
+    gint height;
+    GdkPixbuf *pixbuf;
+
+    if (!gtk_icon_size_lookup(GTK_ICON_SIZE_DND, &width, &height)) {
+        width = 16;
+    }
+
+    pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), icon_name, width, 
GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
+    if (pixbuf == NULL) {
+       gchar *conttype = libbalsa_message_body_get_mime_type(body);
+
+       pixbuf = libbalsa_icon_finder(NULL, conttype, NULL, NULL, GTK_ICON_SIZE_DND);
+       g_free(conttype);
+    }
+
+    return pixbuf;
+}
 
 /* note: a vcard is an icon plus a series of labels/text, so this function actually
  * returns a BalsaPrintObjectDefault... */
@@ -422,120 +399,67 @@ balsa_print_object_text(GList *list, GtkPrintContext * context,
     } while(0)
 
 GList *
-balsa_print_object_text_vcard(GList * list,
-                             GtkPrintContext * context,
-                             LibBalsaMessageBody * body,
-                             BalsaPrintSetup * psetup)
+balsa_print_object_text_vcard(GList               *list,
+                                                 GtkPrintContext     *context,
+                                                         LibBalsaMessageBody *body,
+                                                         BalsaPrintSetup     *psetup)
 {
-    BalsaPrintObjectDefault *pod;
-    BalsaPrintObject *po;
+    GdkPixbuf *pixbuf;
     PangoFontDescription *header_font;
     PangoLayout *test_layout;
-    PangoTabArray *tabs;
     GString *desc_buf;
-    gdouble c_max_height;
+    gint p_label_width;
     LibBalsaAddress * address = NULL;
     gchar *textbuf;
+    GList *result;
+
+    g_return_val_if_fail((context != NULL) && (body != NULL) && (psetup != NULL), list);
 
     /* check if we can create an address from the body and fall back to default if 
-    * this fails */
-    if (body->buffer)
-       textbuf = g_strdup(body->buffer);
-    else
-       libbalsa_message_body_get_content(body, &textbuf, NULL);
-    if (textbuf)
-        address = libbalsa_address_new_from_vcard(textbuf, body->charset);
-    if (address == NULL) {
-       g_free(textbuf);
-       return balsa_print_object_text(list, context, body, psetup);
+     * this fails */
+    if (body->buffer != NULL) {
+       textbuf = g_strdup(body->buffer);
+    } else {
+       libbalsa_message_body_get_content(body, &textbuf, NULL);
     }
-
-    /* proceed with the address information */
-    pod = g_object_new(BALSA_TYPE_PRINT_OBJECT_DEFAULT, NULL);
-    g_assert(pod != NULL);
-    po = BALSA_PRINT_OBJECT(pod);
-
-    /* create the part */
-    po->depth = psetup->curr_depth;
-    po->c_width =
-       psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
-
-    /* get the stock contacts icon or the mime type icon on fail */
-    pod->pixbuf =
-       gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
-                                BALSA_PIXMAP_IDENTITY, 48,
-                                GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
-    if (!pod->pixbuf) {
-       gchar *conttype = libbalsa_message_body_get_mime_type(body);
-
-       pod->pixbuf = libbalsa_icon_finder(NULL, conttype, NULL, NULL,
-                                           GTK_ICON_SIZE_DND);
+    if (textbuf != NULL) {
+       address = libbalsa_address_new_from_vcard(textbuf, body->charset);
+    }
+    if (address == NULL) {
+       g_free(textbuf);
+       return balsa_print_object_text(list, context, body, psetup);
     }
-    pod->c_image_width = gdk_pixbuf_get_width(pod->pixbuf);
-    pod->c_image_height = gdk_pixbuf_get_height(pod->pixbuf);
 
+    /* get the identity icon or the mime type icon on fail */
+    pixbuf = get_icon("x-office-address-book", body);
 
     /* create a layout for calculating the maximum label width */
-    header_font =
-       pango_font_description_from_string(balsa_app.print_header_font);
+    header_font = pango_font_description_from_string(balsa_app.print_header_font);
     test_layout = gtk_print_context_create_pango_layout(context);
     pango_layout_set_font_description(test_layout, header_font);
     pango_font_description_free(header_font);
 
     /* add fields from the address */
     desc_buf = g_string_new("");
-    pod->p_label_width = 0;
-    ADD_VCARD_FIELD(desc_buf, pod->p_label_width, test_layout,
-                   libbalsa_address_get_full_name(address),    _("Full Name"));
-    ADD_VCARD_FIELD(desc_buf, pod->p_label_width, test_layout,
-                   libbalsa_address_get_nick_name(address),    _("Nick Name"));
-    ADD_VCARD_FIELD(desc_buf, pod->p_label_width, test_layout,
-                   libbalsa_address_get_first_name(address),   _("First Name"));
-    ADD_VCARD_FIELD(desc_buf, pod->p_label_width, test_layout,
-                   libbalsa_address_get_last_name(address),    _("Last Name"));
-    ADD_VCARD_FIELD(desc_buf, pod->p_label_width, test_layout,
-                   libbalsa_address_get_organization(address), _("Organization"));
-    ADD_VCARD_FIELD(desc_buf, pod->p_label_width, test_layout,
-                    libbalsa_address_get_addr(address),         _("Email Address"));
-
+    p_label_width = 0;
+    ADD_VCARD_FIELD(desc_buf, p_label_width, test_layout, libbalsa_address_get_full_name(address), _("Full 
Name"));
+    ADD_VCARD_FIELD(desc_buf, p_label_width, test_layout, libbalsa_address_get_nick_name(address), _("Nick 
Name"));
+    ADD_VCARD_FIELD(desc_buf, p_label_width, test_layout, libbalsa_address_get_first_name(address), _("First 
Name"));
+    ADD_VCARD_FIELD(desc_buf, p_label_width, test_layout, libbalsa_address_get_last_name(address), _("Last 
Name"));
+    ADD_VCARD_FIELD(desc_buf, p_label_width, test_layout, libbalsa_address_get_organization(address), 
_("Organization"));
+    ADD_VCARD_FIELD(desc_buf, p_label_width, test_layout, libbalsa_address_get_addr(address), _("Email 
Address"));
     g_object_unref(address);
 
     /* add a small space between label and value */
-    pod->p_label_width += C_TO_P(C_LABEL_SEP);
-
-    /* configure the layout so we can calculate the text height */
-    pango_layout_set_indent(test_layout, -pod->p_label_width);
-    tabs =
-       pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT,
-                                          pod->p_label_width);
-    pango_layout_set_tabs(test_layout, tabs);
-    pango_tab_array_free(tabs);
-    pango_layout_set_width(test_layout,
-                          C_TO_P(po->c_width -
-                                 4 * C_LABEL_SEP - pod->c_image_width));
-    pango_layout_set_alignment(test_layout, PANGO_ALIGN_LEFT);
-    pod->c_text_height =
-       P_TO_C(p_string_height_from_layout(test_layout, desc_buf->str));
-    pod->description = g_string_free(desc_buf, FALSE);
-
-    /* check if we should move to the next page */
-    c_max_height = MAX(pod->c_text_height, pod->c_image_height);
-    if (psetup->c_y_pos + c_max_height > psetup->c_height) {
-       psetup->c_y_pos = 0;
-       psetup->page_count++;
-    }
+    p_label_width += C_TO_P(C_LABEL_SEP);
 
-    /* remember the extent */
-    po->on_page = psetup->page_count - 1;
-    po->c_at_x = psetup->c_x0 + po->depth * C_LABEL_SEP;
-    po->c_at_y = psetup->c_y0 + psetup->c_y_pos;
-    po->c_width = psetup->c_width - 2 * po->depth * C_LABEL_SEP;
-    po->c_height = c_max_height;
-
-    /* adjust the y position */
-    psetup->c_y_pos += c_max_height;
+    /* create the part and clean up */
+    textbuf = g_string_free(desc_buf, FALSE);
+    result = balsa_print_object_default_full(list, context, pixbuf, textbuf, p_label_width, psetup);
+    g_object_unref(pixbuf);
+    g_free(textbuf);
 
-    return g_list_append(list, po);
+    return result;
 }
 
 
@@ -577,182 +501,90 @@ balsa_print_object_text_vcard(GList * list,
 
 
 GList *
-balsa_print_object_text_calendar(GList * list,
-                                 GtkPrintContext * context,
-                                 LibBalsaMessageBody * body,
-                                 BalsaPrintSetup * psetup)
+balsa_print_object_text_calendar(GList               *list,
+                                 GtkPrintContext     *context,
+                                 LibBalsaMessageBody *body,
+                                 BalsaPrintSetup     *psetup)
 {
-    BalsaPrintObjectDefault *pod;
-    BalsaPrintObject *po;
+    LibBalsaVCal *vcal_obj;
+    GdkPixbuf *pixbuf;
     PangoFontDescription *header_font;
     PangoLayout *test_layout;
-    PangoTabArray *tabs;
     GString *desc_buf;
-    LibBalsaVCal * vcal_obj;
+    gint p_label_width;
+    gchar *textbuf;
     guint event_no;
-    guint first_page;
-    GList *par_parts;
-    GList *this_par_part;
-    gdouble c_at_y;
-
-    /* check if we can evaluate the body as calendar object and fall back
-     * to text if not */
-    if (!(vcal_obj = libbalsa_vcal_new_from_body(body)))
-       return balsa_print_object_text(list, context, body, psetup);
-
-    /* proceed with the address information */
-    pod = g_object_new(BALSA_TYPE_PRINT_OBJECT_DEFAULT, NULL);
-    g_assert(pod != NULL);
-    po = BALSA_PRINT_OBJECT(pod);
 
-    /* create the part */
-    po->depth = psetup->curr_depth;
-    po->c_width =
-       psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
+    g_return_val_if_fail((context != NULL) && (body != NULL) && (psetup != NULL), list);
 
-    /* get the stock calendar icon or the mime type icon on fail */
-    pod->pixbuf =
-       gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
-                                "x-office-calendar", 48,
-                                GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
-    if (!pod->pixbuf) {
-       gchar *conttype = libbalsa_message_body_get_mime_type(body);
-
-       pod->pixbuf = libbalsa_icon_finder(NULL, conttype, NULL, NULL,
-                                           GTK_ICON_SIZE_DND);
+    /* check if we can evaluate the body as calendar object and fall back to text if not */
+    vcal_obj = libbalsa_vcal_new_from_body(body);
+    if (vcal_obj == NULL) {
+       return balsa_print_object_text(list, context, body, psetup);
     }
-    pod->c_image_width = gdk_pixbuf_get_width(pod->pixbuf);
-    pod->c_image_height = gdk_pixbuf_get_height(pod->pixbuf);
 
-    /* move to the next page if the icon doesn't fit */
-    if (psetup->c_y_pos + pod->c_image_height > psetup->c_height) {
-       psetup->c_y_pos = 0;
-       psetup->page_count++;
-    }
+    /* get the stock calendar icon or the mime type icon on fail */
+    pixbuf = get_icon("x-office-calendar", body);
 
-    /* create a layout for calculating the maximum label width and for splitting
-     * the body (if necessary) */
-    header_font =
-       pango_font_description_from_string(balsa_app.print_header_font);
+    /* create a layout for calculating the maximum label width */
+    header_font = pango_font_description_from_string(balsa_app.print_header_font);
     test_layout = gtk_print_context_create_pango_layout(context);
     pango_layout_set_font_description(test_layout, header_font);
     pango_font_description_free(header_font);
 
     /* add fields from the events*/
     desc_buf = g_string_new("");
-    pod->p_label_width = 0;
+    p_label_width = 0;
     for (event_no = 0U; event_no < libbalsa_vcal_vevents(vcal_obj); event_no++) {
-        LibBalsaVEvent * event = libbalsa_vcal_vevent(vcal_obj, event_no);
+        LibBalsaVEvent *event = libbalsa_vcal_vevent(vcal_obj, event_no);
         const gchar *description;
         guint attendees;
 
-        if (desc_buf->len > 0)
+        if (desc_buf->len > 0) {
             g_string_append_c(desc_buf, '\n');
-        ADD_VCAL_FIELD(desc_buf, pod->p_label_width, test_layout,
-               libbalsa_vevent_summary(event), _("Summary:"));
-        ADD_VCAL_ADDRESS(desc_buf, pod->p_label_width, test_layout,
-               libbalsa_vevent_organizer(event), _("Organizer:"));
-        ADD_VCAL_DATE(desc_buf, pod->p_label_width, test_layout,
-                      event, VEVENT_DATETIME_STAMP, _("Created:"));
-        ADD_VCAL_DATE(desc_buf, pod->p_label_width, test_layout,
-                      event, VEVENT_DATETIME_START, _("Start:"));
-        ADD_VCAL_DATE(desc_buf, pod->p_label_width, test_layout,
-                      event, VEVENT_DATETIME_END, _("End:"));
-        ADD_VCAL_FIELD(desc_buf, pod->p_label_width, test_layout,
-               libbalsa_vevent_location(event), _("Location:"));
+        }
+        ADD_VCAL_FIELD(desc_buf, p_label_width, test_layout, libbalsa_vevent_summary(event), _("Summary:"));
+        ADD_VCAL_ADDRESS(desc_buf, p_label_width, test_layout, libbalsa_vevent_organizer(event), 
_("Organizer:"));
+        ADD_VCAL_DATE(desc_buf, p_label_width, test_layout, event, VEVENT_DATETIME_STAMP, _("Created:"));
+        ADD_VCAL_DATE(desc_buf, p_label_width, test_layout, event, VEVENT_DATETIME_START, _("Start:"));
+        ADD_VCAL_DATE(desc_buf, p_label_width, test_layout, event, VEVENT_DATETIME_END, _("End:"));
+        ADD_VCAL_FIELD(desc_buf, p_label_width, test_layout, libbalsa_vevent_location(event), 
_("Location:"));
         attendees = libbalsa_vevent_attendees(event);
         if (attendees > 0U) {
-            gchar * this_att;
+            gchar *this_att;
             guint n;
 
-            this_att =
-                libbalsa_vcal_attendee_to_str(libbalsa_vevent_attendee(event, 0U));
-            ADD_VCAL_FIELD(desc_buf, pod->p_label_width, test_layout,
-                           this_att, (attendees > 1U) ? _("Attendees:") : _("Attendee:"));
+            this_att = libbalsa_vcal_attendee_to_str(libbalsa_vevent_attendee(event, 0U));
+            ADD_VCAL_FIELD(desc_buf, p_label_width, test_layout, this_att, (attendees > 1U) ? 
_("Attendees:") : _("Attendee:"));
             g_free(this_att);
             for (n = 1U; n < attendees; n++) {
-                this_att =
-                    libbalsa_vcal_attendee_to_str(libbalsa_vevent_attendee(event, n));
+                this_att = libbalsa_vcal_attendee_to_str(libbalsa_vevent_attendee(event, n));
                 g_string_append_printf(desc_buf, "\n\t%s", this_att);
                 g_free(this_att);
             }
         }
         description = libbalsa_vevent_description(event);
         if (description != NULL) {
-            gchar ** desc_lines = g_strsplit(description, "\n", -1);
+            gchar **desc_lines = g_strsplit(description, "\n", -1);
             gint i;
 
-            ADD_VCAL_FIELD(desc_buf, pod->p_label_width, test_layout,
-                           desc_lines[0], _("Description:"));
-            for (i = 1; desc_lines[i]; i++)
+            ADD_VCAL_FIELD(desc_buf, p_label_width, test_layout, desc_lines[0], _("Description:"));
+            for (i = 1; desc_lines[i]; i++) {
                 g_string_append_printf(desc_buf, "\n\t%s", desc_lines[i]);
+            }
             g_strfreev(desc_lines);
         }
     }
     g_object_unref(vcal_obj);
 
     /* add a small space between label and value */
-    pod->p_label_width += C_TO_P(C_LABEL_SEP);
-
-    /* configure the layout so we can split the text */
-    pango_layout_set_indent(test_layout, -pod->p_label_width);
-    tabs =
-       pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT,
-                                          pod->p_label_width);
-    pango_layout_set_tabs(test_layout, tabs);
-    pango_tab_array_free(tabs);
-    pango_layout_set_width(test_layout,
-                          C_TO_P(po->c_width -
-                                 4 * C_LABEL_SEP - pod->c_image_width));
-    pango_layout_set_alignment(test_layout, PANGO_ALIGN_LEFT);
+    p_label_width += C_TO_P(C_LABEL_SEP);
 
-    /* split paragraph if necessary */
-    first_page = psetup->page_count - 1;
-    c_at_y = psetup->c_y_pos;
-    par_parts =
-        split_for_layout(test_layout, desc_buf->str, NULL, psetup, TRUE, NULL);
-    g_string_free(desc_buf, TRUE);
-
-    /* set the parameters of the first part */
-    pod->description = (gchar *) par_parts->data;
-    pod->c_text_height =
-       P_TO_C(p_string_height_from_layout(test_layout, pod->description));
-    po->on_page = first_page++;
-    po->c_at_x = psetup->c_x0 + po->depth * C_LABEL_SEP;
-    po->c_at_y = psetup->c_y0 + c_at_y;
-    po->c_height = MAX(pod->c_image_height, pod->c_text_height);
-    list = g_list_append(list, pod);
-
-    /* add more parts */
-    for (this_par_part = g_list_next(par_parts); this_par_part;
-         this_par_part = g_list_next(this_par_part)) {
-        BalsaPrintObjectDefault * new_pod;
-        BalsaPrintObject *new_po;
-        
-        /* create a new object */
-        new_pod = g_object_new(BALSA_TYPE_PRINT_OBJECT_DEFAULT, NULL);
-        g_assert(new_pod != NULL);
-        new_po = BALSA_PRINT_OBJECT(new_pod);
-
-        /* fill data */
-        new_pod->p_label_width = pod->p_label_width;
-        new_pod->c_image_width = pod->c_image_width;
-        new_pod->description = (gchar *) this_par_part->data;
-        new_pod->c_text_height =
-            P_TO_C(p_string_height_from_layout(test_layout, new_pod->description));
-        new_po->on_page = first_page++;
-        new_po->c_at_x = psetup->c_x0 + po->depth * C_LABEL_SEP;
-        new_po->c_at_y = psetup->c_y0;
-        new_po->c_height = new_pod->c_text_height;
-        new_po->depth = psetup->curr_depth;
-        new_po->c_width =
-            psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP;
-        
-        /* append */
-        list = g_list_append(list, new_pod);
-    }
-    g_list_free(par_parts);
-    g_object_unref(G_OBJECT(test_layout));
+    /* create the part and clean up */
+    textbuf = g_string_free(desc_buf, FALSE);
+    list = balsa_print_object_default_full(list, context, pixbuf, textbuf, p_label_width, psetup);
+    g_object_unref(pixbuf);
+    g_free(textbuf);
 
     return list;
 }
@@ -764,12 +596,14 @@ balsa_print_object_text_draw(BalsaPrintObject * self,
                             cairo_t * cairo_ctx)
 {
     BalsaPrintObjectText *po;
+    const BalsaPrintRect *rect;
     PangoFontDescription *font;
     gint p_height;
     PangoLayout *layout;
     PangoAttrList *attr_list;
 
     po = BALSA_PRINT_OBJECT_TEXT(self);
+    rect = balsa_print_object_get_rect(self);
     g_assert(po != NULL);
 
     /* prepare */
@@ -777,8 +611,7 @@ balsa_print_object_text_draw(BalsaPrintObject * self,
     layout = gtk_print_context_create_pango_layout(context);
     pango_layout_set_font_description(layout, font);
     pango_font_description_free(font);
-    pango_layout_set_width(layout,
-                          C_TO_P(self->c_width - po->cite_level * C_LABEL_SEP));
+    pango_layout_set_width(layout, C_TO_P(rect->c_width - po->cite_level * C_LABEL_SEP));
     pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
     pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
     pango_layout_set_text(layout, po->text, -1);
@@ -798,8 +631,7 @@ balsa_print_object_text_draw(BalsaPrintObject * self,
                                 balsa_app.quoted_color[k].blue);
        }
     }
-    cairo_move_to(cairo_ctx, self->c_at_x + po->cite_level * C_LABEL_SEP,
-                 self->c_at_y);
+    cairo_move_to(cairo_ctx, rect->c_at_x + po->cite_level * C_LABEL_SEP, rect->c_at_y);
     pango_cairo_show_layout(cairo_ctx, layout);
     g_object_unref(G_OBJECT(layout));
     if (po->cite_level > 0) {
@@ -808,16 +640,16 @@ balsa_print_object_text_draw(BalsaPrintObject * self,
        cairo_new_path(cairo_ctx);
        cairo_set_line_width(cairo_ctx, 1.0);
        for (n = 0; n < po->cite_level; n++) {
-           gdouble c_xpos = self->c_at_x + 0.5 + n * C_LABEL_SEP;
+           gdouble c_xpos = rect->c_at_x + 0.5 + n * C_LABEL_SEP;
 
-           cairo_move_to(cairo_ctx, c_xpos, self->c_at_y);
-           cairo_line_to(cairo_ctx, c_xpos, self->c_at_y + P_TO_C(p_height));
+           cairo_move_to(cairo_ctx, c_xpos, rect->c_at_y);
+           cairo_line_to(cairo_ctx, c_xpos, rect->c_at_y + P_TO_C(p_height));
        }
        cairo_stroke(cairo_ctx);
        cairo_restore(cairo_ctx);
     }
 
-    self->c_height = P_TO_C(p_height); /* needed to properly print borders */
+    balsa_print_object_set_height(self, P_TO_C(p_height));     /* needed to properly print borders */
 }
 
 
diff --git a/src/balsa-print-object-text.h b/src/balsa-print-object-text.h
index 784740258..05b44cd05 100644
--- a/src/balsa-print-object-text.h
+++ b/src/balsa-print-object-text.h
@@ -1,7 +1,7 @@
 /* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
 /* Balsa E-Mail Client
- * Copyright (C) 1997-2016 Stuart Parmenter and others
- * Written by (C) Albrecht Dre� <albrecht dress arcor de> 2007
+ * Copyright (C) 1997-2019 Stuart Parmenter and others
+ * Written by (C) Albrecht Dreß <albrecht dress arcor de> 2007
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,52 +24,30 @@
 
 G_BEGIN_DECLS
 
-#define BALSA_TYPE_PRINT_OBJECT_TEXT   \
-    (balsa_print_object_text_get_type())
-#define BALSA_PRINT_OBJECT_TEXT(obj)                           \
-    G_TYPE_CHECK_INSTANCE_CAST(obj, BALSA_TYPE_PRINT_OBJECT_TEXT, BalsaPrintObjectText)
-#define BALSA_PRINT_OBJECT_TEXT_CLASS(klass)                   \
-    G_TYPE_CHECK_CLASS_CAST(klass, BALSA_TYPE_PRINT_OBJECT_TEXT, BalsaPrintObjectTextClass)
-#define BALSA_IS_PRINT_OBJECT_TEXT(obj)                        \
-    G_TYPE_CHECK_INSTANCE_TYPE(obj, BALSA_TYPE_PRINT_OBJECT_TEXT)
-
-
-typedef struct _BalsaPrintObjectTextClass BalsaPrintObjectTextClass;
-typedef struct _BalsaPrintObjectText BalsaPrintObjectText;
-
-
-struct _BalsaPrintObjectText {
-    BalsaPrintObject parent;
-
-    gint p_label_width;
-    gchar *text;
-    guint cite_level;
-    GList *attributes;
-};
-
-
-struct _BalsaPrintObjectTextClass {
-    BalsaPrintObjectClass parent;
-};
-
-
-GType balsa_print_object_text_get_type(void);
-GList *balsa_print_object_text_plain(GList *list,
-                                    GtkPrintContext * context,
-                                    LibBalsaMessageBody * body,
-                                    BalsaPrintSetup * psetup);
-GList *balsa_print_object_text(GList *list,
-                              GtkPrintContext * context,
-                              LibBalsaMessageBody * body,
-                              BalsaPrintSetup * psetup);
-GList *balsa_print_object_text_vcard(GList *list,
-                                    GtkPrintContext * context,
-                                    LibBalsaMessageBody * body,
-                                    BalsaPrintSetup * psetup);
-GList *balsa_print_object_text_calendar(GList *list,
-                                        GtkPrintContext * context,
-                                        LibBalsaMessageBody * body,
-                                        BalsaPrintSetup * psetup);
+#define BALSA_TYPE_PRINT_OBJECT_TEXT   balsa_print_object_text_get_type()
+G_DECLARE_FINAL_TYPE(BalsaPrintObjectText, balsa_print_object_text, BALSA_PRINT, OBJECT_TEXT, 
BalsaPrintObject)
+
+
+GList *balsa_print_object_text_plain(GList               *list,
+                                                                GtkPrintContext     *context,
+                                                                        LibBalsaMessageBody *body,
+                                                                        BalsaPrintSetup     *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
+GList *balsa_print_object_text(GList               *list,
+                                                  GtkPrintContext     *context,
+                                                          LibBalsaMessageBody *body,
+                                                          BalsaPrintSetup     *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
+GList *balsa_print_object_text_vcard(GList               *list,
+                                                                GtkPrintContext     *context,
+                                                                        LibBalsaMessageBody *body,
+                                                                        BalsaPrintSetup     *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
+GList *balsa_print_object_text_calendar(GList               *list,
+                                        GtkPrintContext     *context,
+                                        LibBalsaMessageBody *body,
+                                        BalsaPrintSetup     *psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
 
 
 G_END_DECLS
diff --git a/src/balsa-print-object.c b/src/balsa-print-object.c
index fbb9d0ed6..5f3ae19ad 100644
--- a/src/balsa-print-object.c
+++ b/src/balsa-print-object.c
@@ -35,54 +35,31 @@
 #include "balsa-print-object-html.h"
 
 
-/* object related functions */
-static void balsa_print_object_init(GTypeInstance * instance,
-                                   gpointer g_class);
-static void balsa_print_object_class_init(BalsaPrintObjectClass * klass);
-static void balsa_print_object_destroy(GObject * object);
-
+typedef struct {
+    gint on_page;
+    guint depth;
 
-static GObjectClass *parent_class = NULL;
+    BalsaPrintRect rect;
+} BalsaPrintObjectPrivate;
 
+G_DEFINE_TYPE_WITH_PRIVATE(BalsaPrintObject, balsa_print_object, G_TYPE_OBJECT)
 
-GType
-balsa_print_object_get_type()
-{
-    static GType balsa_print_object_type = 0;
-
-    if (!balsa_print_object_type) {
-       static const GTypeInfo balsa_print_object_info = {
-           sizeof(BalsaPrintObjectClass),
-           NULL,               /* base_init */
-           NULL,               /* base_finalize */
-           (GClassInitFunc) balsa_print_object_class_init,
-           NULL,               /* class_finalize */
-           NULL,               /* class_data */
-           sizeof(BalsaPrintObject),
-           0,                  /* n_preallocs */
-           (GInstanceInitFunc) balsa_print_object_init
-       };
-
-       balsa_print_object_type =
-           g_type_register_static(G_TYPE_OBJECT, "BalsaPrintObject",
-                                  &balsa_print_object_info, 0);
-    }
 
-    return balsa_print_object_type;
-}
+/* object related functions */
+static void balsa_print_object_destroy(GObject * object);
 
 
 static void
-balsa_print_object_init(GTypeInstance * instance, gpointer g_class)
+balsa_print_object_init(BalsaPrintObject *self)
 {
-    BalsaPrintObject *self = (BalsaPrintObject *) instance;
-
-    self->on_page = 0;
-    self->depth = 0;
-    self->c_at_x = 0.0;
-    self->c_at_y = 0.0;
-    self->c_width = 0.0;
-    self->c_height = 0.0;
+       BalsaPrintObjectPrivate *priv = balsa_print_object_get_instance_private(self);
+
+       priv->on_page = 0;
+       priv->depth = 0;
+       priv->rect.c_at_x = 0.0;
+       priv->rect.c_at_y = 0.0;
+       priv->rect.c_width = 0.0;
+       priv->rect.c_height = 0.0;
 }
 
 
@@ -91,7 +68,6 @@ balsa_print_object_class_init(BalsaPrintObjectClass * klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
-    parent_class = g_type_class_ref(G_TYPE_OBJECT);
     object_class->finalize = balsa_print_object_destroy;
     klass->draw = balsa_print_object_draw;
 }
@@ -175,38 +151,94 @@ void
 balsa_print_object_draw(BalsaPrintObject * self, GtkPrintContext * context,
                        cairo_t * cairo_ctx)
 {
+       BalsaPrintObjectPrivate *priv = balsa_print_object_get_instance_private(self);
     guint level;
 
+    g_return_if_fail(BALSA_IS_PRINT_OBJECT(self) && (context != NULL) && (cairo_ctx != NULL));
+
     BALSA_PRINT_OBJECT_CLASS(G_OBJECT_GET_CLASS(self))->draw(self, context, cairo_ctx);
 
     /* print borders if the depth is > 0 */
-    if (self->depth == 0)
+    if (priv->depth == 0)
        return;
 
     /* print the requested number of border lines */
     cairo_save(cairo_ctx);
     cairo_set_line_width(cairo_ctx, 0.25);
     cairo_new_path(cairo_ctx);
-    for (level = self->depth; level; level--) {
-       gdouble level_sep = level * C_LABEL_SEP;
-
-       cairo_move_to(cairo_ctx, self->c_at_x - level_sep, self->c_at_y);
-       cairo_line_to(cairo_ctx, self->c_at_x - level_sep,
-                     self->c_at_y + self->c_height);
-       cairo_move_to(cairo_ctx, self->c_at_x + self->c_width + level_sep,
-                     self->c_at_y);
-       cairo_line_to(cairo_ctx, self->c_at_x + self->c_width + level_sep,
-                     self->c_at_y + self->c_height);
+    for (level = priv->depth; level > 0U; level--) {
+       gdouble level_sep = level * C_LABEL_SEP;
+       BalsaPrintRect *rect = &priv->rect;
+
+       cairo_move_to(cairo_ctx, rect->c_at_x - level_sep, rect->c_at_y);
+       cairo_line_to(cairo_ctx, rect->c_at_x - level_sep, rect->c_at_y + rect->c_height);
+       cairo_move_to(cairo_ctx, rect->c_at_x + rect->c_width + level_sep, rect->c_at_y);
+       cairo_line_to(cairo_ctx, rect->c_at_x + rect->c_width + level_sep, rect->c_at_y + rect->c_height);
     }
     cairo_stroke(cairo_ctx);
     cairo_restore(cairo_ctx);
 }
 
 
+gint
+balsa_print_object_get_page(BalsaPrintObject *self)
+{
+       BalsaPrintObjectPrivate *priv = balsa_print_object_get_instance_private(self);
+
+       g_return_val_if_fail(BALSA_IS_PRINT_OBJECT(self), -1);
+       return priv->on_page;
+}
+
+
+const BalsaPrintRect *
+balsa_print_object_get_rect(BalsaPrintObject *self)
+{
+       BalsaPrintObjectPrivate *priv = balsa_print_object_get_instance_private(self);
+
+       g_return_val_if_fail(BALSA_IS_PRINT_OBJECT(self), NULL);
+       return &priv->rect;
+}
+
+
+void
+balsa_print_object_set_page_depth(BalsaPrintObject *self,
+                                                                 gint              page,
+                                                                 guint             depth)
+{
+       BalsaPrintObjectPrivate *priv = balsa_print_object_get_instance_private(self);
+
+       g_return_if_fail(BALSA_IS_PRINT_OBJECT(self));
+       priv->depth = depth;
+       priv->on_page = page;
+}
+
+
+void
+balsa_print_object_set_rect(BalsaPrintObject     *self,
+                                                       const BalsaPrintRect *rect)
+{
+       BalsaPrintObjectPrivate *priv = balsa_print_object_get_instance_private(self);
+
+       g_return_if_fail(BALSA_IS_PRINT_OBJECT(self));
+       memcpy(&priv->rect, rect, sizeof(BalsaPrintRect));
+}
+
+
+void
+balsa_print_object_set_height(BalsaPrintObject *self,
+                                                         gdouble           height)
+{
+       BalsaPrintObjectPrivate *priv = balsa_print_object_get_instance_private(self);
+
+       g_return_if_fail(BALSA_IS_PRINT_OBJECT(self));
+       priv->rect.c_height = height;
+}
+
+
 static void
-balsa_print_object_destroy(GObject * object)
+balsa_print_object_destroy(GObject *object)
 {
-    parent_class->finalize(object);
+    G_OBJECT_CLASS(balsa_print_object_parent_class)->finalize(object);
 }
 
 
diff --git a/src/balsa-print-object.h b/src/balsa-print-object.h
index 4e5fc97e7..aa88ba50d 100644
--- a/src/balsa-print-object.h
+++ b/src/balsa-print-object.h
@@ -53,6 +53,14 @@ typedef struct {
 } BalsaPrintSetup;
 
 
+typedef struct {
+    gdouble c_at_x;
+    gdouble c_at_y;
+    gdouble c_width;
+    gdouble c_height;
+} BalsaPrintRect;
+
+
 #define P_TO_C(x)               ((gdouble)(x) / (gdouble)PANGO_SCALE)
 #define C_TO_P(x)               ((gdouble)(x) * (gdouble)PANGO_SCALE)
 
@@ -73,51 +81,36 @@ GList *split_for_layout(PangoLayout * layout, const gchar * text,
 
 /*  == print object base class stuff ==  */
 
-#define BALSA_TYPE_PRINT_OBJECT                        \
-    (balsa_print_object_get_type())
-#define BALSA_PRINT_OBJECT(obj)                                                \
-    G_TYPE_CHECK_INSTANCE_CAST(obj, BALSA_TYPE_PRINT_OBJECT, BalsaPrintObject)
-#define BALSA_PRINT_OBJECT_CLASS(klass)                                        \
-    G_TYPE_CHECK_CLASS_CAST(klass, BALSA_TYPE_PRINT_OBJECT, BalsaPrintObjectClass)
-#define BALSA_IS_PRINT_OBJECT(obj)                     \
-    G_TYPE_CHECK_INSTANCE_TYPE(obj, BALSA_TYPE_PRINT_OBJECT)
-
-
-typedef struct _BalsaPrintObjectClass BalsaPrintObjectClass;
-typedef struct _BalsaPrintObject BalsaPrintObject;
-
-
-struct _BalsaPrintObject {
-    GObject parent;
-
-    gint on_page;
-    guint depth;
-
-    gdouble c_at_x;
-    gdouble c_at_y;
-    gdouble c_width;
-    gdouble c_height;
-};
+#define BALSA_TYPE_PRINT_OBJECT                balsa_print_object_get_type()
+G_DECLARE_DERIVABLE_TYPE(BalsaPrintObject, balsa_print_object, BALSA, PRINT_OBJECT, GObject)
 
 
 struct _BalsaPrintObjectClass {
     GObjectClass parent;
 
-    void (*draw) (BalsaPrintObject * self, GtkPrintContext * context,
-                 cairo_t * cairo_ctx);
+    void (*draw) (BalsaPrintObject *self, GtkPrintContext *context, cairo_t *cairo_ctx);
 };
 
 
-GType balsa_print_object_get_type(void);
-GList *balsa_print_objects_append_from_body(GList * list,
-                                           GtkPrintContext * context,
-                                           LibBalsaMessageBody *
-                                           mime_body,
-                                           BalsaPrintSetup * psetup);
-void balsa_print_object_draw(BalsaPrintObject * self,
-                            GtkPrintContext * context,
-                            cairo_t * cairo_ctx);
-
+GList *balsa_print_objects_append_from_body(GList               *list,
+                                                                               GtkPrintContext     *context,
+                                                                                       LibBalsaMessageBody 
*mime_body,
+                                                                                       BalsaPrintSetup     
*psetup)
+       G_GNUC_WARN_UNUSED_RESULT;
+void balsa_print_object_draw(BalsaPrintObject *self,
+                                                GtkPrintContext  *context,
+                                                        cairo_t          *cairo_ctx);
+
+gint balsa_print_object_get_page(BalsaPrintObject *self);
+const BalsaPrintRect *balsa_print_object_get_rect(BalsaPrintObject *self);
+
+void balsa_print_object_set_page_depth(BalsaPrintObject *self,
+                                                                          gint              page,
+                                                                      guint             depth);
+void balsa_print_object_set_rect(BalsaPrintObject     *self,
+                                                                const BalsaPrintRect *rect);
+void balsa_print_object_set_height(BalsaPrintObject *self,
+                                                                  gdouble           height);
 
 G_END_DECLS
 
diff --git a/src/print-gtk.c b/src/print-gtk.c
index 3bb22ddc7..53fccf530 100644
--- a/src/print-gtk.c
+++ b/src/print-gtk.c
@@ -425,7 +425,7 @@ draw_page(GtkPrintOperation * operation, GtkPrintContext * context,
     while (p) {
        BalsaPrintObject *po = BALSA_PRINT_OBJECT(p->data);
 
-       if (po->on_page == page_nr)
+       if (balsa_print_object_get_page(po) == page_nr)
            balsa_print_object_draw(po, context, cairo_ctx);
 
        p = g_list_next(p);


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