From ddd9556689af055355a07cf2766fe95eaed4e38e Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Sun, 2 Oct 2016 16:58:27 +0200 Subject: Add support for HiDPI images This works by creating corresponding hidpi image sizes on startup and letting the machinery generate high resolution images from the source images (no way to use supplied images). However since browsers expect exact image dimension multiples for the particular scale factor, a reference image size (scale factor 1.0x) must be read first, then cropped to match reference aspect ratio and resized to exact dimensions. That way pixel-perfect results can be achieved for the chosen scale factor. TODO: the CSS background-image: image-set() tags are not supported on Firefox. TODO: try the 1.5x scale factor --- src/setup.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'src/setup.c') diff --git a/src/setup.c b/src/setup.c index 9780807..cf23044 100644 --- a/src/setup.c +++ b/src/setup.c @@ -155,6 +155,35 @@ image_sizes_compare_func (TImageSize *a, TImageSize *b) return sa - sb; } +static gdouble * +parse_hidpi_sizes (const gchar *s) +{ + gchar **split; + GArray *arr; + gchar *s2; + int i; + gdouble f; + + if (! s || strlen (s) == 0) + return NULL; + + arr = g_array_new (TRUE, TRUE, sizeof (gdouble)); + split = g_strsplit (s, ",", -1); + + for (i = 0; split[i] != NULL; i++) { + s2 = g_strstrip (split[i]); + if (s2[strlen(s2) - 1] != 'x') + continue; + s2[strlen(s2) - 1] = '\0'; + f = g_ascii_strtod (s2, NULL); + g_array_append_val (arr, f); + } + g_strfreev (split); + + return (gdouble *) g_array_free (arr, FALSE); +} + + /* * parse_design_setup_xml: XML parser for design.xml file */ @@ -166,7 +195,7 @@ parse_design_setup_xml (const gchar *filename) gchar *s2; gchar *s3; TGalleryDesign *design; - TImageSize *image_size; + TImageSize *image_size, *hidpi_image_size; TGalleryDesignTheme *theme; int count, c; int i, j; @@ -202,6 +231,17 @@ parse_design_setup_xml (const gchar *filename) } + /* hidpi section */ + if (xml_file_get_node_attribute_boolean_with_default (xml, "/design_setup/hidpi", "enabled", FALSE)) { + design->hidpi_upscale_threshold = xml_file_get_node_attribute_long_with_default (xml, "/design_setup/hidpi/threshold", "upscale", DEFAULT_UPSCALE_THRESHOLD); + s = xml_file_get_node_value (xml, "/design_setup/hidpi/sizes/text()"); + design->hidpi_sizes = parse_hidpi_sizes (s); + g_free (s); + design->hidpi_quality = xml_file_get_node_attribute_long_with_default (xml, "/design_setup/hidpi/quality", "value", -1); + design->hidpi_thumbnail_quality = xml_file_get_node_attribute_long_with_default (xml, "/design_setup/hidpi/quality", "thumbnail", -1); + } + + /* image_sizes section */ count = xml_file_node_get_children_count (xml, "/design_setup/image_sizes/size"); for (i = 0; i < count; i++) { @@ -268,6 +308,33 @@ parse_design_setup_xml (const gchar *filename) image_size->quality_threshold = xml_file_get_node_attribute_long_with_default (xml, s, "quality", DEFAULT_QUALITY_THRESHOLD); g_free (s); + /* Generate HiDPI sizes */ + if (design->hidpi_sizes) + for (j = 0; design->hidpi_sizes[j] != 0; j++ ) { + hidpi_image_size = g_malloc0 (sizeof (TImageSize)); + memcpy (hidpi_image_size, image_size, sizeof (TImageSize)); + hidpi_image_size->is_hidpi = TRUE; + hidpi_image_size->hidpi_scale_factor = design->hidpi_sizes[j]; + hidpi_image_size->hidpi_ref_size = image_size; + hidpi_image_size->tagname = NULL; + hidpi_image_size->fallback_size = NULL; + hidpi_image_size->quality_threshold = 0; + hidpi_image_size->no_resize_threshold = 0; + hidpi_image_size->availability_threshold = 0; + hidpi_image_size->name = g_strdup_printf (HIDPI_NAME_FORMAT, image_size->name, hidpi_image_size->hidpi_scale_factor); + hidpi_image_size->landscape_width = lround ((gdouble) image_size->landscape_width * hidpi_image_size->hidpi_scale_factor); + hidpi_image_size->landscape_height = lround ((gdouble) image_size->landscape_height * hidpi_image_size->hidpi_scale_factor); + hidpi_image_size->portrait_width = lround ((gdouble) image_size->portrait_width * hidpi_image_size->hidpi_scale_factor); + hidpi_image_size->portrait_height = lround ((gdouble) image_size->portrait_height * hidpi_image_size->hidpi_scale_factor); + hidpi_image_size->square_size = lround ((gdouble) image_size->square_size * hidpi_image_size->hidpi_scale_factor); + hidpi_image_size->crop_width = lround ((gdouble) image_size->crop_width * hidpi_image_size->hidpi_scale_factor); + hidpi_image_size->crop_height = lround ((gdouble) image_size->crop_height * hidpi_image_size->hidpi_scale_factor); + if (! hidpi_image_size->is_thumbnail && design->hidpi_quality > 0) + hidpi_image_size->quality = design->hidpi_quality; + if (hidpi_image_size->is_thumbnail && design->hidpi_thumbnail_quality > 0) + hidpi_image_size->quality = design->hidpi_thumbnail_quality; + design->image_sizes = g_list_append (design->image_sizes, hidpi_image_size); + } } design->image_sizes = g_list_sort (design->image_sizes, (GCompareFunc) image_sizes_compare_func); @@ -676,6 +743,7 @@ free_design_setup_data (TGalleryDesign *design) g_strfreev (design->supplemental_files); g_free (design->imgmagick_resize_opts); g_free (design->imgmagick_thumb_opts); + g_free (design->hidpi_sizes); g_free (design); } } -- cgit v1.2.3