summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2015-01-25 18:23:03 +0100
committerTomas Bzatek <tbzatek@users.sourceforge.net>2015-01-25 18:23:03 +0100
commit6fffe1a21d5acaa544f7796241e13ff37e75349f (patch)
tree83e0cf3237f11742a89fbc925ac327595b930068
parent7779510229bb478f591cc67c0cb0e2fbb84fdb98 (diff)
downloadcataract-6fffe1a21d5acaa544f7796241e13ff37e75349f.tar.xz
theming: Make custom image size handling fully flexible
This commit brings full flexibility of custom image size definition and usage. When a custom image size is defined, it automatically maps to the album <item> tag arguments. Alternatively, this automatic name matching can be overriden by <size tagname="..."> theme setup tags. This allows us to supply image of different sizes that can be also used in templates. Legacy behaviour of "fullsize" and "preview" image size fallback is retained (though not recommended in new theming setups).
-rw-r--r--sample/src/CIAF_1/index.xml2
-rw-r--r--src/generators.c97
-rw-r--r--src/items.c46
-rw-r--r--src/items.h19
-rw-r--r--src/job-manager.c48
-rw-r--r--src/setup.c2
-rw-r--r--src/setup.h1
-rw-r--r--templates/default.xml14
8 files changed, 129 insertions, 100 deletions
diff --git a/sample/src/CIAF_1/index.xml b/sample/src/CIAF_1/index.xml
index ed9e150..cf53d61 100644
--- a/sample/src/CIAF_1/index.xml
+++ b/sample/src/CIAF_1/index.xml
@@ -14,7 +14,7 @@
]]>
</footnote>
- <!-- you can override global settings in each album: -->
+ <!-- legacy behaviour: you can override global settings in each album (applies only to the "preview" image size): -->
<images quality="60" landscape_w="640" landscape_h="480" portrait_w="480" portrait_h="640" />
<!-- override global preview image border style -->
<border style="border_none" />
diff --git a/src/generators.c b/src/generators.c
index a7f94cb..e1bedf9 100644
--- a/src/generators.c
+++ b/src/generators.c
@@ -190,7 +190,6 @@ get_item_titles (TGallerySetup *setup,
*title_desc = g_strstrip (*title_desc);
}
-/* FIXME: this badly needs port to the new theming system */
static void
get_image_paths (TGallerySetup *setup,
TAlbum *items,
@@ -202,7 +201,6 @@ get_image_paths (TGallerySetup *setup,
gchar **page_img_dst)
{
gboolean nofullsize;
- gboolean is_preview;
gboolean is_original;
gchar *s1, *s2, *s3;
gchar *target_image_dir;
@@ -214,10 +212,8 @@ get_image_paths (TGallerySetup *setup,
*full_img_dst = NULL;
if (page_img_dst)
*page_img_dst = NULL;
- preview_image_size = NULL;
nofullsize = IS_NOFULLSIZE (item, items, setup);
- is_preview = g_ascii_strcasecmp ("preview", image_size->name) == 0;
is_original = g_ascii_strcasecmp ("original", image_size->name) == 0;
/* ignore combinations that are not valid */
@@ -226,52 +222,48 @@ get_image_paths (TGallerySetup *setup,
(image_size->is_thumbnail && items->type == GALLERY_TYPE_INDEX && (item->thumbnail == NULL || strlen (item->thumbnail) == 0)))
return;
- /* nofullsize specified, fall back to preview if available */
- if (is_original && nofullsize)
- preview_image_size = lookup_image_size_for_name (setup, "preview");
- target_image_dir = g_strdup_printf ("%s%s", TARGET_IMAGE_DIR_PREFIX, preview_image_size ? preview_image_size->name : image_size->name);
+ s1 = NULL;
+ if (image_size->is_thumbnail && items->type == GALLERY_TYPE_INDEX)
+ s1 = item->thumbnail;
+ if (s1 == NULL && ! is_original && item->image_sizes != NULL) {
+ s1 = g_hash_table_lookup (item->image_sizes, image_size->name);
+ }
+ if (s1 == NULL)
+ s1 = item->path;
+
+ /* legacy behaviour fallback */
+ if (s1 == NULL && item->image_sizes != NULL)
+ s1 = g_hash_table_lookup (item->image_sizes, "preview");
+ if (s1 == NULL) {
+ log_error ("Unable to find image source for item #%d (\"%s\") for image size \"%s\"\n", get_item_index (items, item), item->title, image_size->name);
+ return;
+ }
- /* Thumbnail special case */
- if (image_size->is_thumbnail) {
- s1 = NULL;
- if (items->type == GALLERY_TYPE_INDEX) {
- s1 = item->thumbnail;
- } else
- if (items->type == GALLERY_TYPE_ALBUM) {
- s1 = (item->path == NULL && item->preview) ? item->preview : item->path;
- s1 = (item->thumbnail) ? item->thumbnail : s1;
+ if (full_img_src)
+ *full_img_src = g_build_filename (path_info->src_dir, s1, NULL);
+
+ /* Use preview image for targets but leave original source if nofullsize is defined (legacy behaviour) */
+ preview_image_size = NULL;
+ if (is_original && nofullsize && item->image_sizes != NULL) {
+ s2 = g_hash_table_lookup (item->image_sizes, "preview");
+ if (s2 != NULL) {
+ s1 = s2;
+ preview_image_size = lookup_image_size_for_name (setup, "preview");
}
- s2 = g_path_get_basename (s1);
- if (full_img_src)
- *full_img_src = g_build_filename (path_info->src_dir, s1, NULL);
- s3 = g_strdup_printf (THUMBNAIL_NAME_FORMAT, get_item_index (items, item), s2);
- g_free (s2);
- if (full_img_dst)
- *full_img_dst = g_build_filename (path_info->dest_dir, target_image_dir, s3, NULL);
- if (page_img_dst)
- *page_img_dst = g_build_filename (target_image_dir, s3, NULL);
- g_free (s3);
}
+ target_image_dir = g_strdup_printf ("%s%s", TARGET_IMAGE_DIR_PREFIX, preview_image_size ? preview_image_size->name : image_size->name);
- /* Other image sizes */
- else {
- if (is_preview)
- s1 = (item->preview) ? item->preview : item->path;
- else
- s1 = (item->path == NULL && item->preview) ? item->preview : item->path;
- if (full_img_src)
- *full_img_src = g_build_filename (path_info->src_dir, s1, NULL);
- /* Use preview image for targets but leave original source if nofullsize is defined */
- if (is_original && nofullsize)
- s1 = (item->preview) ? item->preview : item->path;
- s2 = g_path_get_basename (s1);
- if (full_img_dst)
- *full_img_dst = g_build_filename (path_info->dest_dir, target_image_dir, s2, NULL);
- if (page_img_dst)
- *page_img_dst = g_build_filename (target_image_dir, s2, NULL);
+ s2 = g_path_get_basename (s1);
+ if (image_size->is_thumbnail) {
+ s3 = g_strdup_printf (THUMBNAIL_NAME_FORMAT, get_item_index (items, item), s2);
g_free (s2);
+ s2 = s3;
}
-
+ if (full_img_dst)
+ *full_img_dst = g_build_filename (path_info->dest_dir, target_image_dir, s2, NULL);
+ if (page_img_dst)
+ *page_img_dst = g_build_filename (target_image_dir, s2, NULL);
+ g_free (s2);
g_free (target_image_dir);
}
@@ -369,9 +361,8 @@ generate_image (TGallerySetup *setup,
for (l = g_list_first (setup->design->image_sizes); l; l = g_list_next (l)) {
image_size = l->data;
- /* TODO: this is too specific */
- is_preview = g_ascii_strcasecmp ("preview", image_size->name) == 0;
is_original = g_ascii_strcasecmp ("original", image_size->name) == 0;
+ is_preview = g_ascii_strcasecmp ("preview", image_size->name) == 0;
if (is_original && IS_NOFULLSIZE (item, items, setup))
continue;
@@ -392,8 +383,8 @@ generate_image (TGallerySetup *setup,
/* Do something when required */
res = res || needs_update (img_src, img_dst);
if (! query_update) {
- /* Copy the source file */
- if (! image_size->is_thumbnail && image_size->no_resize && ((is_preview && item->preview) || is_original)) {
+ /* Determine whether to perform file copy or resize */
+ if (! image_size->is_thumbnail && image_size->no_resize && (is_original || (item->image_sizes && g_hash_table_lookup (item->image_sizes, image_size->name)))) {
if (! copy_file (img_src, img_dst))
log_error (" Error copying image %s to %s\n", img_src, img_dst);
}
@@ -417,7 +408,7 @@ generate_image (TGallerySetup *setup,
}
}
else {
- /* Only the "preview" size is affected by deprecated item and album overrides */
+ /* Only the "preview" size is affected by legacy item and album overrides */
if (is_preview) {
tmpw = get_prop_int (items, item, PROP_WIDTH, img_w);
tmph = get_prop_int (items, item, PROP_HEIGHT, img_h);
@@ -669,7 +660,7 @@ add_next_prev_links (TGallerySetup *setup,
}
if (next_item) {
- s = GET_ITEM_TARGET_FILENAME (next_item);
+ s = get_item_target_filename (next_item);
replace_table_add_key_printf (replace_table, "LINK_NEXT", theme->picture_filename, s);
g_free (s);
}
@@ -677,7 +668,7 @@ add_next_prev_links (TGallerySetup *setup,
replace_table_add_key (replace_table, "LINK_NEXT", get_index_filename (items, theme, NULL, NULL));
if (previous_item) {
- s = GET_ITEM_TARGET_FILENAME (previous_item);
+ s = get_item_target_filename (previous_item);
replace_table_add_key_printf (replace_table, "LINK_PREV", theme->picture_filename, s);
g_free (s);
}
@@ -822,7 +813,7 @@ process_img_item (TGallerySetup *setup,
g_free (s3);
}
- s1 = GET_ITEM_TARGET_FILENAME (item);
+ s1 = get_item_target_filename (item);
replace_table_add_key_printf (replace_table, "IMG_SUBPAGE", theme->picture_filename, s1);
replace_table_add_key (replace_table, "IMG_FILENAME", s1);
g_free (s1);
@@ -1096,7 +1087,7 @@ write_html_page (TGallerySetup *setup,
}
if (block_parser_has_unused_data (block_parser, "NAV_BAR")) {
- s2 = item != NULL ? GET_ITEM_TARGET_FILENAME (item) : NULL;
+ s2 = item != NULL ? get_item_target_filename (item) : NULL;
s1 = make_navbar_string (setup, theme, block_parser, defines, items, item ? get_item_index (items, item) : -1, s2 ? s2 : items->ID);
g_free (s2);
replace_table_process (&s1, global_replace_table);
diff --git a/src/items.c b/src/items.c
index d720415..af36ab9 100644
--- a/src/items.c
+++ b/src/items.c
@@ -113,18 +113,20 @@ parse_thumbnail_crop_hint (const gchar *str)
* parse_album_xml: XML parser for gallery index.xml files
*/
TAlbum *
-parse_album_xml (const gchar *filename, TPathInfo *path_info)
+parse_album_xml (TGallerySetup *setup, const gchar *filename, TPathInfo *path_info)
{
TXMLFile *xml;
gchar *gallery_type;
int count;
int i;
+ GList *l;
gchar *s, *s2;
gchar *node_name;
gchar *base_dir;
TIndexItem *item;
TAtomFeedItem *feed_item;
TAlbum *index;
+ TImageSize *image_size;
xml = xml_parser_load (filename);
if (xml == NULL)
@@ -263,13 +265,22 @@ parse_album_xml (const gchar *filename, TPathInfo *path_info)
item->path = xml_file_get_node_attribute (xml, s, "path");
else
item->path = xml_file_get_node_attribute (xml, s, "src");
- item->preview = xml_file_get_node_attribute (xml, s, "preview");
prop_xml_attr_long (item->properties, PROP_QUALITY, xml, s, "quality");
prop_xml_attr_long (item->properties, PROP_WIDTH, xml, s, "width");
prop_xml_attr_long (item->properties, PROP_HEIGHT, xml, s, "height");
prop_xml_attr (item->properties, PROP_BORDER_STYLE, xml, s, "border");
- if (index->type == GALLERY_TYPE_ALBUM)
- item->thumbnail = xml_file_get_node_attribute (xml, s, "thumbnail");
+
+ /* custom image size attributes */
+ for (l = g_list_first (setup->design->image_sizes); l; l = g_list_next (l)) {
+ image_size = l->data;
+ g_assert (image_size != NULL);
+ s2 = xml_file_get_node_attribute (xml, s, image_size->tagname ? image_size->tagname : image_size->name);
+ if (s2) {
+ if (item->image_sizes == NULL)
+ item->image_sizes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ g_assert (g_hash_table_insert (item->image_sizes, g_strdup (image_size->tagname ? image_size->tagname : image_size->name), s2));
+ }
+ }
g_free (s);
s = g_strdup_printf ("/gallery/items/*[%d]/title/text()", i + 1);
@@ -349,10 +360,10 @@ parse_album_xml (const gchar *filename, TPathInfo *path_info)
g_free (s2);
}
- if (item->path || item->preview) {
+ if (item->path || item->image_sizes) {
g_ptr_array_add (index->items, item);
} else {
- log_error ("%s: No image src specified, skipping!\n", filename);
+ log_error ("%s: No image src specified (title = '%s'), skipping!\n", filename, item->title);
free_index_item (item);
}
}
@@ -407,9 +418,10 @@ dup_index_item (TIndexItem *item)
i->title = g_strdup (item->title);
i->title_description = g_strdup (item->title_description);
i->thumbnail = g_strdup (item->thumbnail);
- i->preview = g_strdup (item->preview);
i->metadata_external_exif = g_strdup (item->metadata_external_exif);
i->properties = properties_table_dup (item->properties);
+ if (item->image_sizes)
+ i->image_sizes = clone_string_hash_table (item->image_sizes);
return i;
}
@@ -425,9 +437,10 @@ free_index_item (TIndexItem *item)
g_free (item->title);
g_free (item->title_description);
g_free (item->thumbnail);
- g_free (item->preview);
g_free (item->metadata_external_exif);
properties_table_free (item->properties);
+ if (item->image_sizes)
+ g_hash_table_destroy (item->image_sizes);
g_free (item);
}
}
@@ -566,6 +579,23 @@ free_path_info (TPathInfo *path_info)
}
}
+/*
+ * get_item_target_filename: get target item filename
+ */
+gchar *
+get_item_target_filename (TIndexItem *item)
+{
+ const gchar *s;
+
+ s = item->path;
+ if (s == NULL && item->image_sizes)
+ s = g_hash_table_lookup (item->image_sizes, "preview");
+ if (s == NULL)
+ return NULL;
+
+ return g_path_get_basename (s);
+}
+
/*
* get_prop_*: retrieve attribute value from properties tables, with item taking priority, using items otherwise or falling back to default if not set anywhere
diff --git a/src/items.h b/src/items.h
index 8c14dda..b465a46 100644
--- a/src/items.h
+++ b/src/items.h
@@ -20,6 +20,7 @@
#include <glib.h>
#include "properties-table.h"
+#include "setup.h"
G_BEGIN_DECLS
@@ -76,8 +77,8 @@ typedef struct {
gchar *path;
gchar *title;
gchar *title_description;
- gchar *thumbnail; /* FIXME: port to flexible image sizes */
- gchar *preview; /* FIXME: port to flexible image sizes */
+ gchar *thumbnail; /* index pages */
+ GHashTable *image_sizes;
gboolean force_nofullsize;
gboolean force_fullsize;
gboolean hidden;
@@ -111,15 +112,9 @@ typedef enum {
} PropertyName;
/*
- * GET_ITEM_TARGET_FILENAME: get target item filename
- */
-/* FIXME: port to flexible image sizes */
-#define GET_ITEM_TARGET_FILENAME(i) g_path_get_basename ((i->path == NULL && i->preview) ? i->preview : i->path)
-
-/*
* parse_album_xml: XML parser for gallery index.xml files
*/
-TAlbum * parse_album_xml (const gchar *filename, TPathInfo *path_info);
+TAlbum * parse_album_xml (TGallerySetup *setup, const gchar *filename, TPathInfo *path_info);
/*
* free_album_data: free allocated album data
@@ -156,6 +151,12 @@ TIndexItem *dup_index_item (TIndexItem *item);
*/
void free_index_item (TIndexItem *item);
+/*
+ * get_item_target_filename: get target item filename
+ */
+gchar * get_item_target_filename (TIndexItem *item);
+
+
/*
* get_prop_*: retrieve attribute value from properties tables, with item taking priority, using items otherwise or falling back to default if not set anywhere
diff --git a/src/job-manager.c b/src/job-manager.c
index 3f13b93..28e81ff 100644
--- a/src/job-manager.c
+++ b/src/job-manager.c
@@ -138,35 +138,37 @@ thread_func (gpointer data)
/* actually do some work */
if (item != NULL && job_item != NULL) {
- imgname = GET_ITEM_TARGET_FILENAME (item);
/* Two-pass check whether images need to be updated. First check does no I/O except of stat() calls. */
needs_update = job->force_update;
if (! needs_update)
needs_update = generate_image (job->setup, job->items, item, job->path_info, TRUE);
- if (needs_update)
+
+ if (needs_update) {
+ imgname = get_item_target_filename (item);
+ if (job->setup->verbose) {
+ G_LOCK (items_print);
+ g_print (" [%d/%d] Processing item \"%s\"\n", job_item->index, job->total_items, imgname);
+ G_UNLOCK (items_print);
+ }
+
generate_image (job->setup, job->items, item, job->path_info, FALSE);
-
- if (needs_update && job->setup->verbose) {
- G_LOCK (items_print);
- g_print (" [%d/%d] Processing item \"%s\"\n", job_item->index, job->total_items, imgname);
- G_UNLOCK (items_print);
- }
- if (needs_update && job->items->type == GALLERY_TYPE_ALBUM)
- for (l = g_list_first (job->setup->design->themes); l; l = g_list_next (l)) {
- theme = l->data;
- /* Do not generate particular image pages when theme doesn't define it */
- if (theme->enabled && theme->picture_template && theme->picture_filename) {
- s1 = g_build_filename (job->path_info->templates_root, theme->picture_template, NULL);
- s2 = g_strdup_printf (theme->picture_filename, imgname);
- s3 = g_build_filename (job->path_info->dest_dir, s2, NULL);
- write_html_page (job->setup, job->path_info, theme, s1, s3, job->items, item);
- g_free (s1);
- g_free (s2);
- g_free (s3);
+ if (job->items->type == GALLERY_TYPE_ALBUM)
+ for (l = g_list_first (job->setup->design->themes); l; l = g_list_next (l)) {
+ theme = l->data;
+ /* Do not generate particular image pages when theme doesn't define it */
+ if (theme->enabled && theme->picture_template && theme->picture_filename) {
+ s1 = g_build_filename (job->path_info->templates_root, theme->picture_template, NULL);
+ s2 = g_strdup_printf (theme->picture_filename, imgname);
+ s3 = g_build_filename (job->path_info->dest_dir, s2, NULL);
+ write_html_page (job->setup, job->path_info, theme, s1, s3, job->items, item);
+ g_free (s1);
+ g_free (s2);
+ g_free (s3);
+ }
}
- }
- g_free (imgname);
+ g_free (imgname);
+ }
}
} while (item != NULL);
@@ -232,7 +234,7 @@ build_tree (TGallerySetup *setup,
}
/* Read the index file and fill items array */
- items = parse_album_xml (idx_file, path_info);
+ items = parse_album_xml (setup, idx_file, path_info);
if (! items) {
log_error ("error reading index file '%s'\n", idx_file);
g_free (idx_file);
diff --git a/src/setup.c b/src/setup.c
index aa980b5..9cdf7d5 100644
--- a/src/setup.c
+++ b/src/setup.c
@@ -189,6 +189,7 @@ parse_design_setup_xml (const gchar *filename)
design->image_sizes = g_list_append (design->image_sizes, image_size);
image_size->name = s2;
+ image_size->tagname = xml_file_get_node_attribute (xml, s, "tagname");
s2 = xml_file_get_node_attribute (xml, s, "type");
if (s2 && g_ascii_strcasecmp (s2, "thumbnail") == 0)
image_size->is_thumbnail = TRUE;
@@ -575,6 +576,7 @@ free_image_size_data (TImageSize *image_size)
{
if (image_size) {
g_free (image_size->name);
+ g_free (image_size->tagname);
g_free (image_size);
}
}
diff --git a/src/setup.h b/src/setup.h
index f49eb9a..d772360 100644
--- a/src/setup.h
+++ b/src/setup.h
@@ -94,6 +94,7 @@ typedef enum {
typedef struct {
gchar *name;
+ gchar *tagname;
gboolean is_thumbnail;
int landscape_width;
int landscape_height;
diff --git a/templates/default.xml b/templates/default.xml
index 3948538..2ac8354 100644
--- a/templates/default.xml
+++ b/templates/default.xml
@@ -3,6 +3,11 @@
<!-- image size definitions -->
<image_sizes>
+ <!-- Every image size automatically corresponds to the <item> tag parameter
+ of the same name in album source files. E.g. image size named "hires"
+ would correspond to <item hires=".."> tags. Use the image size parameter
+ "tagname" to override that. -->
+
<!-- "original", "preview" and "thumbnail" sizes are somewhat special here
in order to keep compatibility with previous versions. In case when
"original" size is not available due to <nofullsize> tag present,
@@ -26,9 +31,7 @@
<!-- The "preview" size is considered default and should be displayed
on a first visit. -->
- <!-- Corresponds with optional <item preview="..."> tag in album source file.
- No resizing is made when the attribute is present (legacy behaviour). -->
- <size name="preview">
+ <size name="preview" tagname="preview">
<!-- Note that "preview" sizes can be further overriden by album legacy
<images> tag and also per-image by "width"/"height" <item> tag
attributes. Same goes for quality. -->
@@ -44,16 +47,15 @@
</size>
<!-- Thumbnail section is mandatory. -->
- <!-- Corresponds with optional <item thumbnail> tag in album source file.
- Note that thumbnail images are always resized even for custom supplied files. -->
<!-- The "type" attribute has to be set to "thumbnail" to be treated as such. -->
+ <!-- Note that thumbnail images are always resized even for custom supplied files. -->
<!-- An optional "style" attribute affects cropping:
* normal - image is resized to fit the dimension limits, maintaining
aspect ratio without any crop (default)
* squared - image is cropped to a squared size and resized to fit
* fixed - image is cropped to a specified dimension and cropped to
fit the specified aspect ratio
- An optional album item <thumbnail crop> tags may affect crop area. -->
+ An optional album item <thumbnail crop> tags may affect the crop area. -->
<size name="thumbnail" type="thumbnail" style="normal">
<landscape w="180" h="120" />
<portrait w="120" h="180" />