Improve thumbnail scaling and alignment
Stretch thumbnails by up to half a pixel so that they align nicely. Make use of pixman's sRGB mode.
This commit is contained in:
parent
d6ac386dbd
commit
dbc500ae9f
|
@ -18,8 +18,8 @@ a package with the latest development version from Archlinux's AUR.
|
||||||
Building and Running
|
Building and Running
|
||||||
--------------------
|
--------------------
|
||||||
Build dependencies: Meson, pkg-config +
|
Build dependencies: Meson, pkg-config +
|
||||||
Runtime dependencies: gtk+-3.0, shared-mime-info, libpng>=1.5.4, libturbojpeg,
|
Runtime dependencies: gtk+-3.0, pixman-1, shared-mime-info, libpng>=1.5.4,
|
||||||
LibRaw (optional)
|
libturbojpeg, LibRaw (optional)
|
||||||
|
|
||||||
$ git clone --recursive https://git.janouch.name/p/fastiv.git
|
$ git clone --recursive https://git.janouch.name/p/fastiv.git
|
||||||
$ meson builddir
|
$ meson builddir
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <pixman.h>
|
||||||
|
|
||||||
#include "fastiv-browser.h"
|
#include "fastiv-browser.h"
|
||||||
#include "fastiv-io.h"
|
#include "fastiv-io.h"
|
||||||
|
@ -145,12 +146,49 @@ fastiv_browser_draw(GtkWidget *widget, cairo_t *cr)
|
||||||
int width = cairo_image_surface_get_width(entry->thumbnail);
|
int width = cairo_image_surface_get_width(entry->thumbnail);
|
||||||
int height = cairo_image_surface_get_height(entry->thumbnail);
|
int height = cairo_image_surface_get_height(entry->thumbnail);
|
||||||
|
|
||||||
double scale = row_height / height;
|
double scale_x = 1;
|
||||||
if (width * scale > 2 * row_height)
|
double scale_y = 1;
|
||||||
scale = 2 * row_height / width;
|
if (width > 2 * height) {
|
||||||
|
scale_x = 2 * row_height / width;
|
||||||
|
scale_y = round(scale_x * height) / height;
|
||||||
|
} else {
|
||||||
|
scale_y = row_height / height;
|
||||||
|
scale_x = round(scale_y * width) / width;
|
||||||
|
}
|
||||||
|
|
||||||
int projected_width = round(scale * width);
|
int projected_width = round(scale_x * width);
|
||||||
int projected_height = round(scale * height);
|
int projected_height = round(scale_y * height);
|
||||||
|
cairo_surface_t *scaled = cairo_image_surface_create(
|
||||||
|
CAIRO_FORMAT_ARGB32, projected_width, projected_height);
|
||||||
|
|
||||||
|
// pixman can take gamma into account when scaling, unlike Cairo.
|
||||||
|
struct pixman_f_transform xform_floating;
|
||||||
|
struct pixman_transform xform;
|
||||||
|
|
||||||
|
pixman_image_t *src = pixman_image_create_bits(
|
||||||
|
PIXMAN_a8r8g8b8_sRGB, width, height,
|
||||||
|
(uint32_t *) cairo_image_surface_get_data(entry->thumbnail),
|
||||||
|
cairo_image_surface_get_stride(entry->thumbnail));
|
||||||
|
pixman_image_t *dest = pixman_image_create_bits(
|
||||||
|
PIXMAN_a8r8g8b8_sRGB,
|
||||||
|
cairo_image_surface_get_width(scaled),
|
||||||
|
cairo_image_surface_get_height(scaled),
|
||||||
|
(uint32_t *) cairo_image_surface_get_data(scaled),
|
||||||
|
cairo_image_surface_get_stride(scaled));
|
||||||
|
|
||||||
|
pixman_f_transform_init_scale(&xform_floating, scale_x, scale_y);
|
||||||
|
pixman_f_transform_invert(&xform_floating, &xform_floating);
|
||||||
|
pixman_transform_from_pixman_f_transform(&xform, &xform_floating);
|
||||||
|
pixman_image_set_transform(src, &xform);
|
||||||
|
pixman_image_set_filter(src, PIXMAN_FILTER_BILINEAR, NULL, 0);
|
||||||
|
pixman_image_set_repeat(src, PIXMAN_REPEAT_PAD);
|
||||||
|
|
||||||
|
pixman_image_composite(PIXMAN_OP_SRC, src, NULL, dest, 0, 0, 0, 0, 0, 0,
|
||||||
|
projected_width, projected_height);
|
||||||
|
pixman_image_unref(src);
|
||||||
|
pixman_image_unref(dest);
|
||||||
|
|
||||||
|
cairo_surface_mark_dirty(scaled);
|
||||||
|
|
||||||
if (occupied_width != 0 &&
|
if (occupied_width != 0 &&
|
||||||
occupied_width + projected_width > allocation.width) {
|
occupied_width + projected_width > allocation.width) {
|
||||||
|
@ -160,8 +198,8 @@ fastiv_browser_draw(GtkWidget *widget, cairo_t *cr)
|
||||||
|
|
||||||
cairo_save(cr);
|
cairo_save(cr);
|
||||||
cairo_translate(cr, occupied_width, y + row_height - projected_height);
|
cairo_translate(cr, occupied_width, y + row_height - projected_height);
|
||||||
cairo_scale(cr, scale, scale);
|
cairo_set_source_surface(cr, scaled, 0, 0);
|
||||||
cairo_set_source_surface(cr, entry->thumbnail, 0, 0);
|
cairo_surface_destroy(scaled);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
cairo_restore(cr);
|
cairo_restore(cr);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ dependencies = [
|
||||||
dependency('gtk+-3.0'),
|
dependency('gtk+-3.0'),
|
||||||
dependency('libturbojpeg'),
|
dependency('libturbojpeg'),
|
||||||
dependency('libpng', version : '>=1.5.4'),
|
dependency('libpng', version : '>=1.5.4'),
|
||||||
|
dependency('pixman-1'),
|
||||||
libraw,
|
libraw,
|
||||||
meson.get_compiler('c').find_library('m', required : false),
|
meson.get_compiler('c').find_library('m', required : false),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue