[gthumb: 7/23] contact_sheet: realized the export function
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 7/23] contact_sheet: realized the export function
- Date: Sun, 26 Dec 2010 19:20:19 +0000 (UTC)
commit 29ad1ebcd88fbc1230c3553131cedaff2c983d21
Author: Paolo Bacchilega <paobac src gnome org>
Date: Fri Dec 24 00:00:00 2010 +0100
contact_sheet: realized the export function
extensions/contact_sheet/Makefile.am | 43 +-
.../contact_sheet/gth-contact-sheet-creator.c | 1098 +++++++++++++++++++-
.../contact_sheet/gth-contact-sheet-creator.h | 3 +-
extensions/contact_sheet/gth-contact-sheet-theme.c | 328 ++++++
extensions/contact_sheet/gth-contact-sheet-theme.h | 93 ++
5 files changed, 1524 insertions(+), 41 deletions(-)
---
diff --git a/extensions/contact_sheet/Makefile.am b/extensions/contact_sheet/Makefile.am
index fadbf4b..bd768b5 100644
--- a/extensions/contact_sheet/Makefile.am
+++ b/extensions/contact_sheet/Makefile.am
@@ -3,17 +3,50 @@ SUBDIRS = data
extensiondir = $(pkglibdir)/extensions
extension_LTLIBRARIES = libcontact_sheet.la
+ENUM_TYPES = \
+ enum-types.h \
+ enum-types.c
+
+HEADER_FILES = \
+ actions.h \
+ callbacks.h \
+ dlg-contact-sheet.h \
+ gth-contact-sheet-creator.h \
+ gth-contact-sheet-theme.h \
+ preferences.h \
+ $(NULL)
+
+enum-types.h: $(HEADER_FILES) $(GLIB_MKENUMS)
+ $(AM_V_GEN)( $(GLIB_MKENUMS) \
+ --fhead "#ifndef ENUM_TYPES_H\n#define ENUM_TYPES_H\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
+ --fprod "/* enumerations from \"@filename \" */\n" \
+ --vhead "GType @enum_name _get_type (void);\n#define GTH_TYPE_ ENUMSHORT@ (@enum_name _get_type())\n" \
+ --ftail "G_END_DECLS\n\n#endif /* ENUM_TYPES_H */" \
+ $^> xgen-$(@F) \
+ && (cmp -s xgen-$(@F) enum-types.h || cp xgen-$(@F) enum-types.h ) \
+ && rm -f xgen-$(@F) )
+
+enum-types.c: $(HEADER_FILES) enum-types.h
+ $(AM_V_GEN)( $(GLIB_MKENUMS) \
+ --fhead "#include <glib-object.h>\n" \
+ --fprod "\n/* enumerations from \"@filename \" */\n#include \"@filename \"" \
+ --vhead "GType\n enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME \", \"@valuenick \" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_ type@_register_static (\"@EnumName \", values);\n }\n return etype;\n}\n" \
+ $^> xgen-$(@F) \
+ && (cmp -s xgen-$(@F) enum-types.c || cp xgen-$(@F) enum-types.c ) \
+ && rm -f xgen-$(@F) )
+
libcontact_sheet_la_SOURCES = \
+ $(ENUM_TYPES) \
+ $(HEADER_FILES) \
actions.c \
- actions.h \
callbacks.c \
- callbacks.h \
dlg-contact-sheet.c \
- dlg-contact-sheet.h \
gth-contact-sheet-creator.c \
- gth-contact-sheet-creator.h \
+ gth-contact-sheet-theme.c \
main.c \
- preferences.h
+ $(NULL)
if RUN_IN_PLACE
contact_sheet_datadir = $(abs_top_srcdir)/extensions/contact_sheet/data
diff --git a/extensions/contact_sheet/gth-contact-sheet-creator.c b/extensions/contact_sheet/gth-contact-sheet-creator.c
index f6276a1..489b277 100644
--- a/extensions/contact_sheet/gth-contact-sheet-creator.c
+++ b/extensions/contact_sheet/gth-contact-sheet-creator.c
@@ -28,36 +28,1027 @@
#include "preferences.h"
#define DEFAULT_THUMB_SIZE 128
+#define DEFAULT_FONT "Sans 12"
static GObjectClass *parent_class = NULL;
+typedef struct {
+ GthFileData *file_data;
+ GdkPixbuf *thumbnail;
+ int original_width;
+ int original_height;
+} ItemData;
+
+
+static ItemData *
+item_data_new (GthFileData *file_data)
+{
+ ItemData *item_data;
+
+ item_data = g_new0 (ItemData, 1);
+ item_data->file_data = g_object_ref (file_data);
+ item_data->thumbnail = NULL;
+ item_data->original_width = 0;
+ item_data->original_height = 0;
+
+ return item_data;
+}
+
+
+static void
+item_data_free (ItemData *item_data)
+{
+ _g_object_unref (item_data->thumbnail);
+ _g_object_unref (item_data->file_data);
+ g_free (item_data);
+}
+
+
struct _GthContactSheetCreatorPrivate {
- GthBrowser *browser;
- GList *gfile_list; /* GFile list */
+ GthBrowser *browser;
+ GList *gfile_list; /* GFile list */
/* options */
- char *header;
- char *footer;
- GFile *destination; /* Save files in this location. */
- GthFileDataSort *sort_type;
- gboolean sort_inverse;
- int images_per_index;
- gboolean single_index;
- int columns_per_page;
- int rows_per_page;
- gboolean squared_thumbnails;
- int thumb_width;
- int thumb_height;
- char *thumbnail_caption;
+ char *header;
+ char *footer;
+ GFile *destination;
+ char *template;
+ char *filetype;
+ gboolean write_image_map;
+ GthContactSheetTheme *theme;
+ int images_per_index;
+ gboolean single_index;
+ int columns_per_page;
+ int rows_per_page;
+ GthFileDataSort *sort_type;
+ gboolean sort_inverse;
+ gboolean same_size;
+ gboolean squared_thumbnails;
+ int thumb_width;
+ int thumb_height;
+ char *thumbnail_caption;
+
+ /* private data */
+
+ cairo_t *cr;
+ PangoContext *pango_context;
+ PangoLayout *pango_layout;
+
+ GthImageLoader *image_loader;
+ GList *files; /* ItemData list */
+ GList *current_file; /* Next file to be loaded. */
+ gint n_files; /* Used for the progress signal. */
+ gint n_loaded_files;
+ GList *created_files;
+ GFile *imagemap_file;
+ GDataOutputStream *imagemap_stream;
+
+ int page_width;
+ int page_height;
+ int *pages_height;
+ int n_pages;
+ char **thumbnail_caption_v;
+ char **template_v;
};
+static int
+get_text_height (GthContactSheetCreator *self,
+ const char *text,
+ const char *font_name,
+ int width)
+{
+ PangoFontDescription *font_desc;
+ PangoRectangle bounds;
+
+ if (text == NULL)
+ return 0;
+
+ if (font_name != NULL)
+ font_desc = pango_font_description_from_string (font_name);
+ else
+ font_desc = pango_font_description_from_string (DEFAULT_FONT);
+ pango_layout_set_font_description (self->priv->pango_layout, font_desc);
+ pango_layout_set_width (self->priv->pango_layout, width * PANGO_SCALE);
+ pango_layout_set_wrap (self->priv->pango_layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_set_text (self->priv->pango_layout, text, -1);
+
+ pango_layout_get_pixel_extents (self->priv->pango_layout, NULL, &bounds);
+
+ if (font_desc != NULL)
+ pango_font_description_free (font_desc);
+
+ return bounds.height;
+}
+
+
+static int
+get_header_height (GthContactSheetCreator *self,
+ int with_spacing)
+{
+ int h;
+
+ if ((self->priv->header == NULL) || (strcmp (self->priv->header, "") == 0))
+ return 0;
+
+ h = get_text_height (self,
+ self->priv->header,
+ self->priv->theme->header_font_name,
+ self->priv->page_width);
+ if (with_spacing)
+ h += (self->priv->theme->row_spacing * 2);
+
+ return h;
+}
+
+
+static int
+get_footer_height (GthContactSheetCreator *self,
+ int with_spacing)
+{
+ int h;
+
+ if ((self->priv->footer == NULL) || (strcmp (self->priv->footer, "") == 0))
+ return 0;
+
+ h = get_text_height (self,
+ self->priv->footer,
+ self->priv->theme->footer_font_name,
+ self->priv->page_width);
+ if (with_spacing)
+ h += (self->priv->theme->row_spacing * 2);
+
+ return h;
+}
+
+
+static int
+get_max_text_height (GthContactSheetCreator *self,
+ GList *first_item,
+ GList *last_item)
+{
+ int max_height = 0;
+ GList *scan;
+
+ for (scan = first_item; scan != last_item; scan = scan->next) {
+ ItemData *item_data = scan->data;
+ int text_height;
+ int i;
+
+ text_height = 0;
+ for (i = 0; self->priv->thumbnail_caption_v[i] != NULL; i++) {
+ char *value;
+
+ value = gth_file_data_get_attribute_as_string (item_data->file_data, self->priv->thumbnail_caption_v[i]);
+ if (value != NULL) {
+ text_height += get_text_height (self, value, self->priv->theme->caption_font_name, self->priv->thumb_width);
+ text_height += self->priv->theme->caption_spacing;
+ }
+
+ g_free (value);
+ }
+
+ max_height = MAX (max_height, text_height);
+ }
+
+ return max_height;
+}
+
+
+static int
+get_page_height (GthContactSheetCreator *self,
+ int page_n)
+{
+ return self->priv->same_size ? self->priv->page_height : self->priv->pages_height[page_n - 1];
+}
+
+
+static void
+begin_page (GthContactSheetCreator *self,
+ int page_n)
+{
+ char *name;
+ char *display_name;
+ int width;
+ int height;
+ cairo_surface_t *surface;
+
+ name = _g_get_name_from_template (self->priv->template_v, page_n - 1);
+ display_name = g_strdup_printf ("%s.%s", name, self->priv->filetype);
+ gth_task_progress (GTH_TASK (self),
+ _("Creating images"),
+ display_name,
+ FALSE,
+ (double) page_n / self->priv->n_pages);
+ g_free (display_name);
+
+ width = self->priv->page_width;
+ height = get_page_height (self, page_n);
+
+ if (self->priv->cr != NULL)
+ cairo_destroy (self->priv->cr);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ self->priv->cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ gth_contact_sheet_theme_paint_background (self->priv->theme, self->priv->cr);
+
+ /* image map file. */
+
+ if (self->priv->write_image_map) {
+ char *display_name;
+ GError *error = NULL;
+ char *uri;
+ char *line;
+
+ _g_object_unref (self->priv->imagemap_file);
+ display_name = g_strdup_printf ("%s.html", name);
+ self->priv->imagemap_file = g_file_get_child_for_display_name (self->priv->destination, display_name, NULL);
+ g_free (display_name);
+
+ _g_object_unref (self->priv->imagemap_stream);
+ self->priv->imagemap_stream = g_data_output_stream_new (G_OUTPUT_STREAM (g_file_open_readwrite (self->priv->imagemap_file, gth_task_get_cancellable (GTH_TASK (self)), NULL)));
+
+ g_data_output_stream_put_string (self->priv->imagemap_stream,
+"\
+<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\
+<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\
+ \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\
+<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\
+<head>\n\
+ <title></title>\n\
+ <style type=\"text/css\">\n\
+ html { margin: 0px; border: 0px; padding: 0px; }\n\
+ body { margin: 0px; }\n\
+ img { border: 0px; }\n\
+ </style>\n\
+</head>\n\
+<body>\n\
+ <div>\n\
+",
+ gth_task_get_cancellable (GTH_TASK (self)),
+ &error);
+
+ uri = g_file_get_uri (self->priv->imagemap_file);
+ line = g_strdup_printf ("<img src=\"%s\" width=\"%d\" height=\"%d\" usemap=\"#map\" alt=\"%s\" />\n",
+ uri,
+ width,
+ height,
+ uri);
+ g_data_output_stream_put_string (self->priv->imagemap_stream,
+ line,
+ gth_task_get_cancellable (GTH_TASK (self)),
+ &error);
+ g_data_output_stream_put_string (self->priv->imagemap_stream,
+ "<map name=\"map\" id=\"map\">\n",
+ gth_task_get_cancellable (GTH_TASK (self)),
+ &error);
+
+ g_free (line);
+ g_free (uri);
+ }
+
+ g_free (name);
+}
+
+
+static void
+end_page (GthContactSheetCreator *self,
+ int page_n)
+{
+ GdkPixbuf *pixbuf;
+ char *buffer;
+ gsize size;
+ GError *error = NULL;
+ char *name;
+ char *display_name;
+ GFile *file;
+
+ pixbuf = _gdk_pixbuf_new_from_cairo_surface (self->priv->cr);
+ if (! gdk_pixbuf_save_to_buffer (pixbuf,
+ &buffer,
+ &size,
+ self->priv->filetype,
+ &error,
+ (g_str_equal(self->priv->filetype, "jpeg") ? "quality" : NULL),
+ "90",
+ NULL))
+ {
+ /* TODO */
+ }
+
+ name = _g_get_name_from_template (self->priv->template_v, page_n - 1);
+ display_name = g_strdup_printf ("%s.%s", name, self->priv->filetype);
+ file = g_file_get_child_for_display_name (self->priv->destination, display_name, NULL);
+
+ if (! g_write_file (file,
+ FALSE,
+ G_FILE_CREATE_REPLACE_DESTINATION,
+ buffer,
+ size,
+ gth_task_get_cancellable (GTH_TASK (self)),
+ &error))
+ {
+ /* TODO */
+ }
+
+ self->priv->created_files = g_list_prepend (self->priv->created_files, g_object_ref (file));
+
+ g_object_unref (file);
+ g_free (display_name);
+ g_free (name);
+ g_object_unref (pixbuf);
+
+ /* image map file. */
+
+ if (self->priv->imagemap_stream != NULL) {
+ g_data_output_stream_put_string (self->priv->imagemap_stream,
+ "</map>\n",
+ gth_task_get_cancellable (GTH_TASK (self)),
+ &error);
+ g_data_output_stream_put_string (self->priv->imagemap_stream,
+ "\
+ </div>\n\
+</body>\n\
+</html>\n\
+",
+ gth_task_get_cancellable (GTH_TASK (self)),
+ &error);
+
+ g_output_stream_close (G_OUTPUT_STREAM (self->priv->imagemap_stream),
+ gth_task_get_cancellable (GTH_TASK (self)),
+ &error);
+
+ self->priv->created_files = g_list_prepend (self->priv->created_files, g_object_ref (self->priv->imagemap_file));
+ }
+}
+
+
+/* -- get_text -- */
+
+
+typedef struct {
+ GthContactSheetCreator *self;
+ int page_n;
+} TemplateData;
+
+
+static gboolean
+text_eval_cb (const GMatchInfo *info,
+ GString *res,
+ gpointer data)
+{
+ TemplateData *template_data = data;
+ char *r = NULL;
+ char *match;
+
+ match = g_match_info_fetch (info, 0);
+
+ if (strncmp (match, "%p", 1) == 0) {
+ r = g_strdup_printf ("%d", template_data->page_n);
+ }
+ else if (strncmp (match, "%n", 1) == 0) {
+ r = g_strdup_printf ("%d", template_data->self->priv->n_pages);
+ }
+
+ if (r != NULL)
+ g_string_append (res, r);
+
+ g_free (r);
+ g_free (match);
+
+ return FALSE;
+}
+
+
+static char *
+get_text (GthContactSheetCreator *self,
+ const char *text,
+ int page_n)
+{
+ GRegex *re;
+ TemplateData template_data;
+ char *new_text;
+
+ re = g_regex_new ("%[pn]", 0, 0, NULL);
+ template_data.self = self;
+ template_data.page_n = page_n;
+ new_text = g_regex_replace_eval (re, text, -1, 0, 0, text_eval_cb, &template_data, NULL);
+
+ g_regex_unref (re);
+
+ return new_text;
+}
+
+
+static void
+paint_text (GthContactSheetCreator *self,
+ const char *font_name,
+ GdkColor *color,
+ int x,
+ int y,
+ int width,
+ const char *text,
+ int *height)
+{
+ PangoFontDescription *font_desc;
+ PangoRectangle bounds;
+
+ if (font_name != NULL)
+ font_desc = pango_font_description_from_string (font_name);
+ else
+ font_desc = pango_font_description_from_string (DEFAULT_FONT);
+ pango_layout_set_font_description (self->priv->pango_layout, font_desc);
+ pango_layout_set_width (self->priv->pango_layout, width * PANGO_SCALE);
+ pango_layout_set_wrap (self->priv->pango_layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_set_text (self->priv->pango_layout, text, -1);
+ pango_layout_get_pixel_extents (self->priv->pango_layout, NULL, &bounds);
+
+ x += self->priv->theme->frame_border;
+
+ cairo_save (self->priv->cr);
+ gdk_cairo_set_source_color (self->priv->cr, color);
+ pango_cairo_update_layout (self->priv->cr, self->priv->pango_layout);
+ cairo_move_to (self->priv->cr, x, y);
+ pango_cairo_show_layout (self->priv->cr, self->priv->pango_layout);
+ cairo_restore (self->priv->cr);
+
+#if 0
+ cairo_set_source_rgb (self->priv->cr, 1.0, 0.0, 0.0);
+ cairo_rectangle (self->priv->cr, x, y, width, bounds.height);
+ cairo_stroke (self->priv->cr);
+#endif
+
+ if (font_desc != NULL)
+ pango_font_description_free (font_desc);
+
+ if (height != NULL)
+ *height = bounds.height;
+}
+
+
+static void
+paint_footer (GthContactSheetCreator *self,
+ int page_n)
+{
+ char *text;
+
+ if (self->priv->footer == NULL)
+ return;
+
+ text = get_text (self, self->priv->footer, page_n);
+ paint_text (self,
+ self->priv->theme->footer_font_name,
+ &self->priv->theme->footer_color,
+ 0,
+ get_page_height (self, page_n) - get_footer_height (self, FALSE) - self->priv->theme->row_spacing / 2,
+ self->priv->page_width,
+ text,
+ NULL);
+
+ g_free (text);
+}
+
+
+static void
+paint_frame (GthContactSheetCreator *self,
+ GdkRectangle *frame_rect,
+ GdkRectangle *image_rect,
+ GthFileData *file_data)
+{
+ gth_contact_sheet_theme_paint_frame (self->priv->theme, self->priv->cr, frame_rect, image_rect);
+
+#if 0
+ switch (self->priv->theme->frame_style) {
+ case GTH_CONTACT_SHEET_FRAME_STYLE_NONE:
+ break;
+
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SLIDE:
+ gthumb_draw_slide_with_colors (self->priv->pixmap,
+ frame_rect->x,
+ frame_rect->y,
+ frame_rect->width,
+ frame_rect->height,
+ image_rect->width,
+ image_rect->height,
+ &self->priv->theme->frame_color,
+ &self->priv->black,
+ &self->priv->dark_gray,
+ &self->priv->gray,
+ &self->priv->white);
+ break;
+
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SIMPLE:
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SHADOW:
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SIMPLE_WITH_SHADOW:
+ if (self->priv->theme->frame_style == GTH_FRAME_STYLE_SHADOW)
+ gthumb_draw_image_shadow (self->priv->pixmap,
+ image_rect->x,
+ image_rect->y,
+ image_rect->width,
+ image_rect->height);
+
+ if (self->priv->theme->frame_style == GTH_FRAME_STYLE_SIMPLE_WITH_SHADOW)
+ gthumb_draw_frame_shadow (self->priv->pixmap,
+ image_rect->x,
+ image_rect->y,
+ image_rect->width,
+ image_rect->height);
+
+ if ((self->priv->theme->frame_style == GTH_FRAME_STYLE_SIMPLE)
+ || (self->priv->theme->frame_style == GTH_FRAME_STYLE_SIMPLE_WITH_SHADOW))
+ {
+ gthumb_draw_frame (self->priv->pixmap,
+ image_rect->x,
+ image_rect->y,
+ image_rect->width,
+ image_rect->height,
+ &self->priv->theme->frame_color);
+ }
+ break;
+
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SHADOW_IN:
+ gthumb_draw_image_shadow_in (self->priv->pixmap,
+ image_rect->x,
+ image_rect->y,
+ image_rect->width,
+ image_rect->height);
+ break;
+
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SHADOW_OUT:
+ gthumb_draw_image_shadow_out (self->priv->pixmap,
+ image_rect->x,
+ image_rect->y,
+ image_rect->width,
+ image_rect->height);
+ break;
+ }
+#endif
+
+ if (self->priv->imagemap_stream != NULL) {
+ char *file;
+ char *destination;
+ char *relative_uri;
+ char *relative_path;
+ char *alt_attribute;
+ char *line;
+ GError *error = NULL;
+
+ file = g_file_get_uri (file_data->file);
+ destination = g_file_get_uri (self->priv->destination);
+ relative_uri = _g_uri_get_relative_path (file, destination);
+ relative_path = g_uri_unescape_string (relative_uri, "");
+ alt_attribute = _g_escape_for_html (relative_path, -1);
+
+ line = g_strdup_printf ("<area shape=\"rect\" coords=\"%d,%d,%d,%d\" href=\"%s\" alt=\"%s\" />\n",
+ frame_rect->x,
+ frame_rect->y,
+ frame_rect->x + frame_rect->width,
+ frame_rect->y + frame_rect->height,
+ relative_path,
+ alt_attribute);
+ g_data_output_stream_put_string (self->priv->imagemap_stream,
+ line,
+ gth_task_get_cancellable (GTH_TASK (self)),
+ &error);
+
+ g_free (line);
+ g_free (alt_attribute);
+ g_free (relative_path);
+ g_free (relative_uri);
+ g_free (destination);
+ g_free (file);
+ }
+}
+
+
+static void
+paint_image (GthContactSheetCreator *self,
+ GdkRectangle *image_rect,
+ GdkPixbuf *image)
+{
+ cairo_save (self->priv->cr);
+ gdk_cairo_set_source_pixbuf (self->priv->cr, image, image_rect->x, image_rect->y);
+ cairo_rectangle (self->priv->cr, image_rect->x, image_rect->y, image_rect->width, image_rect->height);
+ cairo_fill (self->priv->cr);
+ cairo_restore (self->priv->cr);
+}
+
+
+static void
+export (GthContactSheetCreator *self)
+{
+ int columns;
+ gboolean first_row;
+ int page_n = 0;
+ int page_height;
+ int header_height;
+ int footer_height;
+ int x, y;
+ GList *scan;
+ ItemData *item_data;
+
+ columns = ((self->priv->page_width - self->priv->theme->col_spacing) / (self->priv->thumb_width + (self->priv->theme->frame_hpadding * 2) + self->priv->theme->col_spacing));
+ first_row = TRUE;
+ begin_page (self, ++page_n);
+ page_height = get_page_height (self, page_n);
+ header_height = get_header_height (self, TRUE);
+ footer_height = get_footer_height (self, TRUE);
+ y = self->priv->theme->col_spacing;
+ scan = self->priv->files;
+ item_data = (ItemData*) scan->data;
+ do {
+ GList *first_item, *last_item;
+ int i;
+ int row_height;
+ GList *scan_row;
+
+ /* FIXME
+ if (ce->interrupted) {
+ if (ce->file_list != NULL) {
+ g_list_foreach (ce->file_list, (GFunc) image_data_free, NULL);
+ g_list_free (ce->file_list);
+ ce->file_list = NULL;
+ }
+ goto export_end;
+ }
+ */
+
+ /* get items to paint. */
+
+ first_item = scan;
+ last_item = NULL;
+ for (i = 0; i < columns; i++) {
+ if (scan == NULL) {
+ columns = i;
+ break;
+ }
+
+ last_item = scan = scan->next;
+ if (scan != NULL)
+ item_data = (ItemData *) scan->data;
+ }
+
+ if (columns == 0) {
+ paint_footer (self, page_n);
+ end_page (self, page_n);
+ goto export_end;
+ }
+
+ /* check whether the row fit the current page. */
+
+ row_height = (self->priv->thumb_height
+ + (self->priv->theme->frame_vpadding * 2)
+ + get_max_text_height (self, first_item, last_item)
+ + self->priv->theme->row_spacing);
+
+ g_print ("%d <=> %d\n",
+ y + row_height,
+ self->priv->page_height - (first_row ? header_height : 0) - footer_height);
+
+ while (y + row_height > (self->priv->page_height
+ - (first_row ? header_height : 0)
+ - footer_height))
+ {
+ if (first_row) {
+ /* this row has an height greater than the
+ * page height, close and exit. */
+ goto export_end;
+ }
+
+ /* the row does not fit this page, create a new
+ * page. */
+
+ if (page_n > 0) {
+ paint_footer (self, page_n);
+ end_page (self, page_n);
+ }
+
+ first_row = TRUE;
+ begin_page (self, ++page_n);
+ page_height = get_page_height (self, page_n);
+ header_height = get_header_height (self, TRUE);
+ footer_height = get_footer_height (self, TRUE);
+ y = self->priv->theme->row_spacing;
+ }
+
+ /* paint the header. */
+
+ if (first_row && (g_strcmp0 (self->priv->header, "") != 0)) {
+ char *text;
+
+ text = get_text (self, self->priv->header, page_n);
+ paint_text (self,
+ self->priv->theme->header_font_name,
+ &self->priv->theme->header_color,
+ 0,
+ y,
+ self->priv->page_width,
+ text,
+ NULL);
+ g_free (text);
+
+ y += header_height;
+ }
+
+ /* paint a row. */
+
+ x = self->priv->theme->col_spacing;
+ for (scan_row = first_item; scan_row != last_item; scan_row = scan_row->next) {
+ ItemData *row_item = scan_row->data;
+ int frame_width;
+ int frame_height;
+ GdkRectangle frame_rect;
+ int text_y;
+ int i;
+
+ frame_width = self->priv->thumb_width + (self->priv->theme->frame_hpadding * 2);
+ frame_height = self->priv->thumb_height + (self->priv->theme->frame_vpadding * 2);
+ frame_rect.x = x;
+ frame_rect.y = y;
+ frame_rect.width = frame_width;
+ frame_rect.height = frame_height;
+
+ /* paint the thumbnail */
+
+ if (row_item->thumbnail != NULL) {
+ int thumbnail_width;
+ int thumbnail_height;
+ GdkRectangle image_rect;
+
+ thumbnail_width = gdk_pixbuf_get_width (row_item->thumbnail);
+ thumbnail_height = gdk_pixbuf_get_height (row_item->thumbnail);
+
+ image_rect.x = x + (frame_width - thumbnail_width) / 2 + 1;
+ image_rect.y = y + (frame_height - thumbnail_height) / 2 + 1;
+ image_rect.width = thumbnail_width;
+ image_rect.height = thumbnail_height;
+
+ paint_frame (self, &frame_rect, &image_rect, row_item->file_data);
+ paint_image (self, &image_rect, row_item->thumbnail);
+ }
+
+ /* paint the caption */
+
+ text_y = y + frame_height + self->priv->theme->caption_spacing;
+
+ for (i = 0; self->priv->thumbnail_caption_v[i] != NULL; i++) {
+ char *text;
+ int h;
+
+ text = gth_file_data_get_attribute_as_string (row_item->file_data, self->priv->thumbnail_caption_v[i]);
+ if (text == NULL)
+ continue;
+
+ paint_text (self,
+ self->priv->theme->caption_font_name,
+ &self->priv->theme->caption_color,
+ x + self->priv->theme->frame_hpadding,
+ text_y,
+ self->priv->thumb_width,
+ text,
+ &h);
+ text_y += h + self->priv->theme->caption_spacing;
+
+ g_free (text);
+ }
+
+ x += self->priv->thumb_width + (self->priv->theme->frame_hpadding * 2) + self->priv->theme->col_spacing;
+ }
+
+ y += row_height;
+ first_row = FALSE;
+ }
+ while (TRUE);
+
+ export_end:
+
+ if (self->priv->created_files != NULL) {
+ gth_monitor_folder_changed (gth_main_get_default_monitor (),
+ self->priv->destination,
+ self->priv->created_files,
+ GTH_MONITOR_EVENT_CREATED);
+ _g_object_list_unref (self->priv->created_files);
+ self->priv->created_files = NULL;
+ }
+
+ gth_task_completed (GTH_TASK (self), NULL);
+}
+
+
+static void
+compute_pages_size (GthContactSheetCreator *self)
+{
+ int n_pages;
+ int columns;
+ GList *scan;
+
+ self->priv->page_width = self->priv->theme->col_spacing + self->priv->columns_per_page * (self->priv->thumb_width + (self->priv->theme->frame_hpadding * 2) + self->priv->theme->col_spacing);
+ self->priv->page_height = 0;
+
+ n_pages = self->priv->n_files / (self->priv->columns_per_page * self->priv->rows_per_page) + 1;
+ self->priv->pages_height = g_new (int, n_pages);
+ self->priv->n_pages = 0;
+ columns = self->priv->columns_per_page;
+ for (scan = self->priv->files; scan != NULL; /* void */) {
+ ItemData *idata = (ItemData *) scan->data;
+ int page_height;
+ int r;
+
+ page_height = self->priv->theme->row_spacing;
+
+ /* header */
+
+ page_height += get_header_height (self, TRUE);
+
+ /* images */
+
+ g_print ("rows per page: %d\n", self->priv->rows_per_page);
+
+ for (r = 0; r < self->priv->rows_per_page; r++) {
+ GList *first_item;
+ GList *last_item;
+ int c;
+ int row_height;
+
+ /* get row items. */
+
+ first_item = scan;
+ last_item = NULL;
+ for (c = 0; c < columns; c++) {
+ if (scan == NULL) {
+ columns = c;
+ break;
+ }
+
+ last_item = scan = scan->next;
+ if (scan != NULL)
+ idata = (ItemData*) scan->data;
+ }
+
+ if (columns == 0)
+ break;
+
+ row_height = (self->priv->thumb_height
+ + (self->priv->theme->frame_hpadding * 2)
+ + get_max_text_height (self, first_item, last_item)
+ + self->priv->theme->row_spacing);
+ page_height += row_height;
+ }
+
+ /* footer */
+
+ page_height += get_footer_height (self, TRUE);
+
+ /**/
+
+ self->priv->pages_height[self->priv->n_pages] = page_height;
+ self->priv->page_height = MAX (self->priv->page_height, page_height);
+ self->priv->n_pages++;
+ }
+}
+
+
+static int
+item_data_compare_func (gconstpointer a,
+ gconstpointer b,
+ gpointer user_data)
+{
+ GthContactSheetCreator *self = user_data;
+ ItemData *item_data_a = (ItemData *) a;
+ ItemData *item_data_b = (ItemData *) b;
+ int result;
+
+ result = self->priv->sort_type->cmp_func (item_data_a->file_data, item_data_b->file_data);
+ if (self->priv->sort_inverse)
+ result = result * -1;
+
+ return result;
+}
+
+
+static void image_loader_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data);
+
+
+static void
+load_current_image (GthContactSheetCreator *self)
+{
+ ItemData *item_data;
+
+ if (self->priv->current_file == NULL) {
+ if (self->priv->sort_type->cmp_func != 0)
+ self->priv->files = g_list_sort_with_data (self->priv->files, item_data_compare_func, self);
+ compute_pages_size (self);
+ export (self);
+ return;
+ }
+
+ item_data = self->priv->current_file->data;
+
+ gth_task_progress (GTH_TASK (self),
+ _("Generating thumbnails"),
+ g_file_info_get_display_name (item_data->file_data->info),
+ FALSE,
+ ((double) ++self->priv->n_loaded_files) / (self->priv->n_files + 1));
+
+ gth_image_loader_load (self->priv->image_loader,
+ item_data->file_data,
+ MIN (self->priv->thumb_height, self->priv->thumb_width),
+ G_PRIORITY_DEFAULT,
+ gth_task_get_cancellable (GTH_TASK (self)),
+ image_loader_ready_cb,
+ self);
+}
+
+
+static void
+image_loader_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GthContactSheetCreator *self = user_data;
+ GdkPixbuf *pixbuf;
+ int original_width;
+ int original_height;
+ GError *error = NULL;
+ ItemData *item_data;
+
+ if (! gth_image_loader_load_image_finish (GTH_IMAGE_LOADER (source_object),
+ result,
+ &pixbuf,
+ &original_width,
+ &original_height,
+ &error))
+ {
+ gth_task_completed (GTH_TASK (self), error);
+ return;
+ }
+
+ item_data = self->priv->current_file->data;
+ item_data->thumbnail = pixbuf;
+ item_data->original_width = original_width;
+ item_data->original_height = original_height;
+
+ self->priv->current_file = self->priv->current_file->next;
+ load_current_image (self);
+}
+
+
+static void
+file_list_info_ready_cb (GList *files,
+ GError *error,
+ gpointer user_data)
+{
+ GthContactSheetCreator *self = user_data;
+ GList *scan;
+
+ if (error != NULL) {
+ gth_task_completed (GTH_TASK (self), error);
+ return;
+ }
+
+ self->priv->files = NULL;
+ for (scan = files; scan; scan = scan->next)
+ self->priv->files = g_list_prepend (self->priv->files, item_data_new ((GthFileData *) scan->data));
+ self->priv->files = g_list_reverse (self->priv->files);
+
+ if (self->priv->image_loader == NULL)
+ self->priv->image_loader = gth_image_loader_new (NULL, NULL);
+
+ self->priv->current_file = self->priv->files;
+ load_current_image (self);
+}
+
+
static void
gth_contact_sheet_creator_exec (GthTask *task)
{
- /* TODO */
+ GthContactSheetCreator *self = GTH_CONTACT_SHEET_CREATOR (task);
+ int n_files;
+
+ self->priv->n_files = g_list_length (self->priv->gfile_list);
+ self->priv->n_loaded_files = 0;
+
+ n_files = self->priv->single_index ? self->priv->n_files : self->priv->images_per_index;
+ self->priv->rows_per_page = n_files / self->priv->columns_per_page;
+ if (n_files % self->priv->columns_per_page > 0)
+ self->priv->rows_per_page += 1;
+
+ self->priv->pango_context = gdk_pango_context_get ();
+ pango_context_set_language (self->priv->pango_context, gtk_get_default_language ());
+ self->priv->pango_layout = pango_layout_new (self->priv->pango_context);
+ pango_layout_set_alignment (self->priv->pango_layout, PANGO_ALIGN_CENTER);
+
+ _g_query_all_metadata_async (self->priv->gfile_list,
+ GTH_LIST_DEFAULT,
+ self->priv->thumbnail_caption,
+ gth_task_get_cancellable (GTH_TASK (self)),
+ file_list_info_ready_cb,
+ self);
}
@@ -76,9 +1067,26 @@ gth_contact_sheet_creator_finalize (GObject *object)
g_return_if_fail (GTH_IS_CONTACT_SHEET_CREATOR (object));
self = GTH_CONTACT_SHEET_CREATOR (object);
- g_free (self->priv->header);
- g_free (self->priv->footer);
+ g_strfreev (self->priv->thumbnail_caption_v);
+ g_strfreev (self->priv->template_v);
+ g_free (self->priv->pages_height);
+ _g_object_unref (self->priv->imagemap_stream);
+ _g_object_unref (self->priv->imagemap_file);
+ _g_object_list_unref (self->priv->created_files);
+ g_list_foreach (self->priv->files, (GFunc) item_data_free, NULL);
+ g_list_free (self->priv->files);
+ _g_object_unref (self->priv->image_loader);
+ _g_object_unref (self->priv->pango_layout);
+ _g_object_unref (self->priv->pango_context);
+ if (self->priv->cr != NULL)
+ cairo_destroy (self->priv->cr);
g_free (self->priv->thumbnail_caption);
+ gth_contact_sheet_theme_ref (self->priv->theme);
+ g_free (self->priv->filetype);
+ g_free (self->priv->template);
+ _g_object_unref (self->priv->destination);
+ g_free (self->priv->footer);
+ g_free (self->priv->header);
_g_object_list_unref (self->priv->gfile_list);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -109,12 +1117,18 @@ gth_contact_sheet_creator_init (GthContactSheetCreator *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_CONTACT_SHEET_CREATOR, GthContactSheetCreatorPrivate);
self->priv->header = NULL;
self->priv->footer = NULL;
- self->priv->sort_type = NULL;
- self->priv->sort_inverse = FALSE;
+ self->priv->destination = NULL;
+ self->priv->template = NULL;
+ self->priv->filetype = NULL;
+ self->priv->write_image_map = FALSE;
self->priv->images_per_index = 0;
+ self->priv->single_index = FALSE;
self->priv->columns_per_page = 0;
self->priv->rows_per_page = 0;
- self->priv->single_index = FALSE;
+ self->priv->sort_type = NULL;
+ self->priv->sort_inverse = FALSE;
+ self->priv->same_size = FALSE;
+ self->priv->squared_thumbnails = FALSE;
self->priv->thumb_width = DEFAULT_THUMB_SIZE;
self->priv->thumb_height = DEFAULT_THUMB_SIZE;
self->priv->thumbnail_caption = NULL;
@@ -169,7 +1183,7 @@ void
gth_contact_sheet_creator_set_header (GthContactSheetCreator *self,
const char *value)
{
-
+ _g_strset (&self->priv->header, value);
}
@@ -177,7 +1191,7 @@ void
gth_contact_sheet_creator_set_footer (GthContactSheetCreator *self,
const char *value)
{
-
+ _g_strset (&self->priv->footer, value);
}
@@ -185,7 +1199,8 @@ void
gth_contact_sheet_creator_set_destination (GthContactSheetCreator *self,
GFile *destination)
{
-
+ _g_clear_object (&self->priv->destination);
+ self->priv->destination = _g_object_ref (destination);
}
@@ -193,7 +1208,10 @@ void
gth_contact_sheet_creator_set_filename_template (GthContactSheetCreator *self,
const char *filename_template)
{
-
+ _g_strset (&self->priv->template, filename_template);
+ if (self->priv->template_v != NULL)
+ g_strfreev (self->priv->template_v);
+ self->priv->template_v = _g_get_template_from_text (self->priv->template);
}
@@ -201,7 +1219,7 @@ void
gth_contact_sheet_creator_set_filetype (GthContactSheetCreator *self,
const char *filetype)
{
-
+ _g_strset (&self->priv->filetype, filetype);
}
@@ -209,15 +1227,21 @@ void
gth_contact_sheet_creator_set_write_image_map (GthContactSheetCreator *self,
gboolean value)
{
-
+ self->priv->write_image_map = value;
}
void
gth_contact_sheet_creator_set_theme (GthContactSheetCreator *self,
- const char *theme_name)
+ GthContactSheetTheme *theme)
{
+ if (self->priv->theme != NULL) {
+ gth_contact_sheet_theme_unref (self->priv->theme);
+ self->priv->theme = NULL;
+ }
+ if (theme != NULL)
+ self->priv->theme = gth_contact_sheet_theme_ref (theme);
}
@@ -225,7 +1249,7 @@ void
gth_contact_sheet_creator_set_images_per_index (GthContactSheetCreator *self,
int value)
{
-
+ self->priv->images_per_index = value;
}
@@ -233,7 +1257,7 @@ void
gth_contact_sheet_creator_set_single_index (GthContactSheetCreator *self,
gboolean value)
{
-
+ self->priv->single_index = value;
}
@@ -241,7 +1265,7 @@ void
gth_contact_sheet_creator_set_columns (GthContactSheetCreator *self,
int columns)
{
-
+ self->priv->columns_per_page = columns;
}
@@ -250,7 +1274,8 @@ gth_contact_sheet_creator_set_sort_order (GthContactSheetCreator *self,
GthFileDataSort *sort_type,
gboolean sort_inverse)
{
-
+ self->priv->sort_type = sort_type;
+ self->priv->sort_inverse = sort_inverse;
}
@@ -258,7 +1283,7 @@ void
gth_contact_sheet_creator_set_same_size (GthContactSheetCreator *self,
gboolean value)
{
-
+ self->priv->same_size = value;
}
@@ -268,7 +1293,9 @@ gth_contact_sheet_creator_set_thumb_size (GthContactSheetCreator *self,
int width,
int height)
{
-
+ self->priv->squared_thumbnails = squared;
+ self->priv->thumb_width = width;
+ self->priv->thumb_height = height;
}
@@ -276,5 +1303,6 @@ void
gth_contact_sheet_creator_set_thumbnail_caption (GthContactSheetCreator *self,
const char *caption)
{
-
+ _g_strset (&self->priv->thumbnail_caption, caption);
+ self->priv->thumbnail_caption_v = g_strsplit (self->priv->thumbnail_caption, ",", -1);
}
diff --git a/extensions/contact_sheet/gth-contact-sheet-creator.h b/extensions/contact_sheet/gth-contact-sheet-creator.h
index ceaddaf..6d37e9f 100644
--- a/extensions/contact_sheet/gth-contact-sheet-creator.h
+++ b/extensions/contact_sheet/gth-contact-sheet-creator.h
@@ -26,6 +26,7 @@
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <gthumb.h>
+#include "gth-contact-sheet-theme.h"
#define GTH_TYPE_CONTACT_SHEET_CREATOR (gth_contact_sheet_creator_get_type ())
#define GTH_CONTACT_SHEET_CREATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_CONTACT_SHEET_CREATOR, GthContactSheetCreator))
@@ -64,7 +65,7 @@ void gth_contact_sheet_creator_set_filetype (GthContactSheetCreat
void gth_contact_sheet_creator_set_write_image_map (GthContactSheetCreator *self,
gboolean value);
void gth_contact_sheet_creator_set_theme (GthContactSheetCreator *self,
- const char *theme_name);
+ GthContactSheetTheme *theme);
void gth_contact_sheet_creator_set_images_per_index (GthContactSheetCreator *self,
int value);
void gth_contact_sheet_creator_set_single_index (GthContactSheetCreator *self,
diff --git a/extensions/contact_sheet/gth-contact-sheet-theme.c b/extensions/contact_sheet/gth-contact-sheet-theme.c
new file mode 100644
index 0000000..fc70da4
--- /dev/null
+++ b/extensions/contact_sheet/gth-contact-sheet-theme.c
@@ -0,0 +1,328 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gthumb.h>
+#include "enum-types.h"
+#include "gth-contact-sheet-theme.h"
+
+
+static void
+_g_key_file_get_color (GKeyFile *key_file,
+ char *group_name,
+ char *key,
+ GdkColor *color,
+ GError **error)
+{
+ char *spec;
+
+ spec = g_key_file_get_string (key_file, group_name, key, error);
+ if (spec != NULL)
+ gdk_color_parse (spec, color);
+
+ g_free (spec);
+}
+
+
+GthContactSheetTheme *
+gth_contact_sheet_theme_new_from_key_file (GKeyFile *key_file)
+{
+ GthContactSheetTheme *theme;
+ char *nick;
+
+ theme = g_new0 (GthContactSheetTheme, 1);
+ theme->ref = 1;
+
+ theme->display_name = g_key_file_get_string (key_file, "Theme", "Name", NULL);
+ theme->authors = g_key_file_get_string (key_file, "Theme", "Authors", NULL);
+ theme->copyright = g_key_file_get_string (key_file, "Theme", "Copyright", NULL);
+ theme->version = g_key_file_get_string (key_file, "Theme", "Version", NULL);
+
+ nick = g_key_file_get_string (key_file, "Background", "Type", NULL);
+ theme->background_type = _g_enum_type_get_value_by_nick (GTH_TYPE_CONTACT_SHEET_BACKGROUND_TYPE, nick)->value;
+ g_free (nick);
+
+ _g_key_file_get_color (key_file, "Background", "Color1", &theme->background_color1, NULL);
+ _g_key_file_get_color (key_file, "Background", "Color2", &theme->background_color2, NULL);
+ _g_key_file_get_color (key_file, "Background", "Color3", &theme->background_color3, NULL);
+ _g_key_file_get_color (key_file, "Background", "Color4", &theme->background_color4, NULL);
+
+ nick = g_key_file_get_string (key_file, "Frame", "Style", NULL);
+ theme->frame_style = _g_enum_type_get_value_by_nick (GTH_TYPE_CONTACT_SHEET_FRAME_STYLE, nick)->value;
+ g_free (nick);
+
+ _g_key_file_get_color (key_file, "Frame", "Color", &theme->frame_color, NULL);
+ theme->frame_hpadding = 8 /*g_key_file_get_integer (key_file, "Frame", "HPadding", NULL)*/;
+ theme->frame_vpadding = 8 /*g_key_file_get_integer (key_file, "Frame", "VPadding", NULL)*/;
+
+ theme->header_font_name = g_key_file_get_string (key_file, "Header", "Font", NULL);
+ _g_key_file_get_color (key_file, "Header", "Color", &theme->header_color, NULL);
+
+ theme->footer_font_name = g_key_file_get_string (key_file, "Footer", "Font", NULL);
+ _g_key_file_get_color (key_file, "Footer", "Color", &theme->footer_color, NULL);
+
+ theme->caption_font_name = g_key_file_get_string (key_file, "Caption", "Font", NULL);
+ _g_key_file_get_color (key_file, "Caption", "Color", &theme->caption_color, NULL);
+ theme->caption_spacing = 3; /* g_key_file_get_integer (key_file, "Caption", "Spacing", NULL); */
+
+ theme->row_spacing = 15;
+ theme->col_spacing = 15;
+ theme->frame_border = 0;
+
+ return theme;
+}
+
+
+GthContactSheetTheme *
+gth_contact_sheet_theme_ref (GthContactSheetTheme *theme)
+{
+ theme->ref++;
+ return theme;
+}
+
+
+void
+gth_contact_sheet_theme_unref (GthContactSheetTheme *theme)
+{
+ theme->ref--;
+ if (theme->ref > 0)
+ return;
+
+ g_free (theme->display_name);
+ g_free (theme->authors);
+ g_free (theme->copyright);
+ g_free (theme->version);
+ g_free (theme->header_font_name);
+ g_free (theme->footer_font_name);
+ g_free (theme->caption_font_name);
+ g_free (theme);
+}
+
+
+void
+gth_contact_sheet_theme_paint_background (GthContactSheetTheme *theme,
+ cairo_t *cr)
+{
+ cairo_surface_t *surface;
+ int width;
+ int height;
+ cairo_pattern_t *pattern;
+ cairo_color_t color;
+
+ surface = cairo_get_target (cr);
+ if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
+ return;
+
+ width = cairo_image_surface_get_width (surface);
+ height = cairo_image_surface_get_height (surface);
+
+ switch (theme->background_type) {
+ case GTH_CONTACT_SHEET_BACKGROUND_TYPE_SOLID:
+ gdk_cairo_set_source_color (cr, &theme->background_color1);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ break;
+
+ case GTH_CONTACT_SHEET_BACKGROUND_TYPE_VERTICAL:
+ pattern = cairo_pattern_create_linear (0.0, 0.0, 0.0, height);
+ _gdk_color_to_cairo_color (&theme->background_color1, &color);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, color.r, color.g, color.b, 1.0);
+ _gdk_color_to_cairo_color (&theme->background_color2, &color);
+ cairo_pattern_add_color_stop_rgba (pattern, height, color.r, color.g, color.b, 1.0);
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+ break;
+
+ case GTH_CONTACT_SHEET_BACKGROUND_TYPE_HORIZONTAL:
+ pattern = cairo_pattern_create_linear (0.0, 0.0, width, 0.0);
+ _gdk_color_to_cairo_color (&theme->background_color1, &color);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, color.r, color.g, color.b, 1.0);
+ _gdk_color_to_cairo_color (&theme->background_color2, &color);
+ cairo_pattern_add_color_stop_rgba (pattern, width, color.r, color.g, color.b, 1.0);
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+ break;
+
+ case GTH_CONTACT_SHEET_BACKGROUND_TYPE_FULL:
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ _cairo_paint_full_gradient (surface,
+ &theme->background_color1,
+ &theme->background_color2,
+ &theme->background_color3,
+ &theme->background_color4);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ cairo_surface_destroy (surface);
+ break;
+ }
+}
+
+
+void
+gth_contact_sheet_theme_paint_frame (GthContactSheetTheme *theme,
+ cairo_t *cr,
+ GdkRectangle *frame_rect,
+ GdkRectangle *image_rect)
+{
+ switch (theme->frame_style) {
+ case GTH_CONTACT_SHEET_FRAME_STYLE_NONE:
+ break;
+
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SHADOW:
+ _cairo_draw_drop_shadow (cr,
+ image_rect->x,
+ image_rect->y,
+ image_rect->width,
+ image_rect->height,
+ 3);
+ break;
+
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SIMPLE:
+ gdk_cairo_set_source_color (cr, &theme->frame_color);
+ _cairo_draw_frame (cr,
+ image_rect->x,
+ image_rect->y,
+ image_rect->width,
+ image_rect->height,
+ 3);
+ break;
+
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SIMPLE_WITH_SHADOW:
+ _cairo_draw_drop_shadow (cr,
+ image_rect->x,
+ image_rect->y,
+ image_rect->width,
+ image_rect->height,
+ 5);
+
+ gdk_cairo_set_source_color (cr, &theme->frame_color);
+ _cairo_draw_frame (cr,
+ image_rect->x,
+ image_rect->y,
+ image_rect->width,
+ image_rect->height,
+ 3);
+ break;
+
+ case GTH_CONTACT_SHEET_FRAME_STYLE_SLIDE:
+ _cairo_draw_slide (cr,
+ frame_rect->x,
+ frame_rect->y,
+ frame_rect->width,
+ frame_rect->height,
+ image_rect->width,
+ image_rect->height,
+ &theme->frame_color,
+ TRUE);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+GdkPixbuf *
+gth_contact_sheet_theme_create_preview (GthContactSheetTheme *theme,
+ int preview_size)
+{
+ const int preview_frame_border = 5;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ GdkRectangle frame_rect;
+ GdkRectangle image_rect;
+ GdkRectangle text_rect;
+ /*
+ PangoContext *pango_context;
+ PangoLayout *pango_layout;
+ */
+ GdkPixbuf *pixbuf;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, preview_size, preview_size);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ gth_contact_sheet_theme_paint_background (theme, cr);
+ image_rect.width = preview_size / 2;
+ image_rect.height = preview_size / 2;
+ image_rect.x = (preview_size - image_rect.width) / 2;
+ image_rect.y = (preview_size - image_rect.height) / 2;
+ frame_rect.x = image_rect.x - preview_frame_border;
+ frame_rect.y = image_rect.y - preview_frame_border;
+ frame_rect.width = image_rect.width + (preview_frame_border * 2);
+ frame_rect.height = image_rect.height + (preview_frame_border * 2);
+ gth_contact_sheet_theme_paint_frame (theme, cr, &frame_rect, &image_rect);
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_rectangle (cr, image_rect.x, image_rect.y, image_rect.width, image_rect.height);
+ cairo_fill (cr);
+
+ /* header */
+
+ gdk_cairo_set_source_color (cr, &theme->header_color);
+ text_rect.width = preview_size / 3;
+ text_rect.height = 6;
+ text_rect.x = (preview_size - text_rect.width) / 2;
+ text_rect.y = 4;
+ cairo_rectangle (cr, text_rect.x, text_rect.y, text_rect.width, text_rect.height);
+ cairo_fill (cr);
+
+ /* footer */
+
+ gdk_cairo_set_source_color (cr, &theme->footer_color);
+ text_rect.width = preview_size / 5;
+ text_rect.height = 4;
+ text_rect.x = (preview_size - text_rect.width) / 2;
+ text_rect.y = preview_size - text_rect.height - 4;
+ cairo_rectangle (cr, text_rect.x, text_rect.y, text_rect.width, text_rect.height);
+ cairo_fill (cr);
+
+ /*
+ pango_context = gdk_pango_context_get ();
+ pango_context_set_language (pango_context, gtk_get_default_language ());
+ pango_layout = pango_layout_new (pango_context);
+ pango_layout_set_alignment (pango_layout, PANGO_ALIGN_CENTER);
+
+ if (font_name != NULL)
+ font_desc = pango_font_description_from_string (font_name);
+ else
+ font_desc = pango_font_description_from_string (DEFAULT_FONT);
+ pango_layout_set_font_description (pango_layout, font_desc);
+ pango_layout_set_text (pango_layout, text, -1);
+ pango_layout_set_width (pango_layout, width * PANGO_SCALE);
+ pango_layout_get_pixel_extents (pango_layout, NULL, &bounds);
+ */
+
+ pixbuf = _gdk_pixbuf_new_from_cairo_surface (cr);
+
+ cairo_destroy (cr);
+
+ return pixbuf;
+}
diff --git a/extensions/contact_sheet/gth-contact-sheet-theme.h b/extensions/contact_sheet/gth-contact-sheet-theme.h
new file mode 100644
index 0000000..cc31b5b
--- /dev/null
+++ b/extensions/contact_sheet/gth-contact-sheet-theme.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTH_CONTACT_SHEET_THEME_H
+#define GTH_CONTACT_SHEET_THEME_H
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <gthumb.h>
+
+typedef enum {
+ GTH_CONTACT_SHEET_BACKGROUND_TYPE_SOLID,
+ GTH_CONTACT_SHEET_BACKGROUND_TYPE_VERTICAL,
+ GTH_CONTACT_SHEET_BACKGROUND_TYPE_HORIZONTAL,
+ GTH_CONTACT_SHEET_BACKGROUND_TYPE_FULL
+} GthContactSheetBackgroundType;
+
+typedef enum {
+ GTH_CONTACT_SHEET_FRAME_STYLE_NONE,
+ GTH_CONTACT_SHEET_FRAME_STYLE_SIMPLE,
+ GTH_CONTACT_SHEET_FRAME_STYLE_SIMPLE_WITH_SHADOW,
+ GTH_CONTACT_SHEET_FRAME_STYLE_SHADOW,
+ GTH_CONTACT_SHEET_FRAME_STYLE_SLIDE,
+ GTH_CONTACT_SHEET_FRAME_STYLE_SHADOW_IN,
+ GTH_CONTACT_SHEET_FRAME_STYLE_SHADOW_OUT
+} GthContactSheetFrameStyle;
+
+typedef struct {
+ int ref;
+ char *name;
+ char *display_name;
+ char *authors;
+ char *copyright;
+ char *version;
+
+ GthContactSheetBackgroundType background_type;
+ GdkColor background_color1;
+ GdkColor background_color2;
+ GdkColor background_color3;
+ GdkColor background_color4;
+
+ GthContactSheetFrameStyle frame_style;
+ GdkColor frame_color;
+ int frame_hpadding;
+ int frame_vpadding;
+ int frame_border;
+
+ char *header_font_name;
+ GdkColor header_color;
+
+ char *footer_font_name;
+ GdkColor footer_color;
+
+ char *caption_font_name;
+ GdkColor caption_color;
+ int caption_spacing;
+
+ int row_spacing;
+ int col_spacing;
+} GthContactSheetTheme;
+
+GthContactSheetTheme * gth_contact_sheet_theme_new_from_key_file (GKeyFile *key_file);
+GthContactSheetTheme * gth_contact_sheet_theme_ref (GthContactSheetTheme *theme);
+void gth_contact_sheet_theme_unref (GthContactSheetTheme *theme);
+void gth_contact_sheet_theme_paint_background (GthContactSheetTheme *theme,
+ cairo_t *cr);
+void gth_contact_sheet_theme_paint_frame (GthContactSheetTheme *theme,
+ cairo_t *cr,
+ GdkRectangle *frame_rect,
+ GdkRectangle *image_rect);
+GdkPixbuf * gth_contact_sheet_theme_create_preview (GthContactSheetTheme *theme,
+ int preview_size);
+
+#endif /* GTH_CONTACT_SHEET_THEME_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]