static void balsa_print_object_default_draw(BalsaPrintObject * self, GtkPrintContext * context, cairo_t * cairo_ctx) { BalsaPrintObjectDefault *pod; gdouble c_max_height; gdouble c_offset; PangoLayout *layout; PangoFontDescription *font; PangoTabArray *tabs; /* set up */ pod = BALSA_PRINT_OBJECT_DEFAULT(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); /* print the description */ 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_indent(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(layout, tabs); pango_tab_array_free(tabs); pango_layout_set_width(layout, C_TO_P(self->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); pango_cairo_show_layout(cairo_ctx, layout); g_object_unref(G_OBJECT(layout)); }
/* split a text buffer into chunks using the passed Pango layout */ GList * split_for_layout(PangoLayout * layout, const gchar * text, PangoAttrList * attributes, BalsaPrintSetup * psetup, gboolean is_header, GArray ** offsets) { GList *split_list = NULL; PangoLayoutIter *iter; const gchar *start; gint p_offset; gboolean add_tab; gint p_y0; gint p_y1; gint p_y_pos; gint p_height; /* set the text and its attributes, then get an iter */ pango_layout_set_text(layout, text, -1); if (attributes) pango_layout_set_attributes(layout, attributes); if (offsets) *offsets = g_array_new(FALSE, FALSE, sizeof(guint)); iter = pango_layout_get_iter(layout); /* loop over lines */ start = text; p_offset = 0; add_tab = FALSE; p_y_pos = C_TO_P(psetup->c_y_pos); p_height = C_TO_P(psetup->c_height); do { pango_layout_iter_get_line_yrange(iter, &p_y0, &p_y1); if (p_y_pos + p_y1 - p_offset > p_height) { gint index; gint tr; gchar *chunk; gboolean ends_with_nl; if (offsets) { guint offs = start - text; *offsets = g_array_append_val(*offsets, offs); } pango_layout_xy_to_index(layout, 0, p_y0, &index, &tr); ends_with_nl = text[index - 1] == '\n'; if (ends_with_nl) index--; chunk = g_strndup(start, text + index - start); if (add_tab) split_list = g_list_append(split_list, g_strconcat("\t", chunk, NULL)); else split_list = g_list_append(split_list, g_strdup(chunk)); add_tab = is_header && !ends_with_nl; g_free(chunk); start = text + index; if (ends_with_nl) start++; if (*start == '\0') p_y_pos = p_height; else { p_y_pos = 0; psetup->page_count++; } p_offset = p_y0; } } while (pango_layout_iter_next_line(iter)); pango_layout_iter_free(iter); /* append any remaining stuff */ if (*start != '\0') { p_y_pos += p_y1 - p_offset; if (offsets) { guint offs = start - text; *offsets = g_array_append_val(*offsets, offs); } if (add_tab) split_list = g_list_append(split_list, g_strconcat("\t", start, NULL)); else split_list = g_list_append(split_list, g_strdup(start)); } /* remember the new y position in cairo units */ psetup->c_y_pos = P_TO_C(p_y_pos); /* return the list */ return split_list; }
GList * balsa_print_object_default(GList * list, GtkPrintContext * context, LibBalsaMessageBody * body, BalsaPrintSetup * psetup) { BalsaPrintObjectDefault *pod; BalsaPrintObject *po; gchar *conttype; PangoFontDescription *header_font; PangoLayout *test_layout; PangoTabArray *tabs; GString *desc_buf; gdouble c_max_height; gchar *part_desc; 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 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); /* 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); 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); 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); } /* 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++; } /* 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; return g_list_append(list, po); }