Fix SVG thumbnailing
They're not loaded as image surfaces.
This commit is contained in:
parent
feda4fd70f
commit
3274b64f5a
45
fiv-io.c
45
fiv-io.c
@ -2969,51 +2969,72 @@ fiv_io_save(cairo_surface_t *page, cairo_surface_t *frame, FivIoProfile target,
|
|||||||
|
|
||||||
// --- Metadata ----------------------------------------------------------------
|
// --- Metadata ----------------------------------------------------------------
|
||||||
|
|
||||||
gboolean
|
void
|
||||||
fiv_io_orientation_is_sideways(FivIoOrientation orientation)
|
fiv_io_orientation_dimensions(cairo_surface_t *surface,
|
||||||
|
FivIoOrientation orientation, double *w, double *h)
|
||||||
{
|
{
|
||||||
|
cairo_rectangle_t extents = {};
|
||||||
|
switch (cairo_surface_get_type(surface)) {
|
||||||
|
case CAIRO_SURFACE_TYPE_IMAGE:
|
||||||
|
extents.width = cairo_image_surface_get_width(surface);
|
||||||
|
extents.height = cairo_image_surface_get_height(surface);
|
||||||
|
break;
|
||||||
|
case CAIRO_SURFACE_TYPE_RECORDING:
|
||||||
|
if (!cairo_recording_surface_get_extents(surface, &extents))
|
||||||
|
cairo_recording_surface_ink_extents(surface,
|
||||||
|
&extents.x, &extents.y, &extents.width, &extents.height);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
switch (orientation) {
|
switch (orientation) {
|
||||||
case FivIoOrientation90:
|
case FivIoOrientation90:
|
||||||
case FivIoOrientationMirror90:
|
case FivIoOrientationMirror90:
|
||||||
case FivIoOrientation270:
|
case FivIoOrientation270:
|
||||||
case FivIoOrientationMirror270:
|
case FivIoOrientationMirror270:
|
||||||
return TRUE;
|
*w = extents.height;
|
||||||
|
*h = extents.width;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
*w = extents.width;
|
||||||
|
*h = extents.height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_matrix_t
|
cairo_matrix_t
|
||||||
fiv_io_orientation_matrix(
|
fiv_io_orientation_apply(cairo_surface_t *surface,
|
||||||
FivIoOrientation orientation, double width, double height)
|
FivIoOrientation orientation, double *width, double *height)
|
||||||
{
|
{
|
||||||
|
fiv_io_orientation_dimensions(surface, orientation, width, height);
|
||||||
|
|
||||||
cairo_matrix_t matrix = {};
|
cairo_matrix_t matrix = {};
|
||||||
cairo_matrix_init_identity(&matrix);
|
cairo_matrix_init_identity(&matrix);
|
||||||
switch (orientation) {
|
switch (orientation) {
|
||||||
case FivIoOrientation90:
|
case FivIoOrientation90:
|
||||||
cairo_matrix_rotate(&matrix, -M_PI_2);
|
cairo_matrix_rotate(&matrix, -M_PI_2);
|
||||||
cairo_matrix_translate(&matrix, -width, 0);
|
cairo_matrix_translate(&matrix, -*width, 0);
|
||||||
break;
|
break;
|
||||||
case FivIoOrientation180:
|
case FivIoOrientation180:
|
||||||
cairo_matrix_scale(&matrix, -1, -1);
|
cairo_matrix_scale(&matrix, -1, -1);
|
||||||
cairo_matrix_translate(&matrix, -width, -height);
|
cairo_matrix_translate(&matrix, -*width, -*height);
|
||||||
break;
|
break;
|
||||||
case FivIoOrientation270:
|
case FivIoOrientation270:
|
||||||
cairo_matrix_rotate(&matrix, +M_PI_2);
|
cairo_matrix_rotate(&matrix, +M_PI_2);
|
||||||
cairo_matrix_translate(&matrix, 0, -height);
|
cairo_matrix_translate(&matrix, 0, -*height);
|
||||||
break;
|
break;
|
||||||
case FivIoOrientationMirror0:
|
case FivIoOrientationMirror0:
|
||||||
cairo_matrix_scale(&matrix, -1, +1);
|
cairo_matrix_scale(&matrix, -1, +1);
|
||||||
cairo_matrix_translate(&matrix, -width, 0);
|
cairo_matrix_translate(&matrix, -*width, 0);
|
||||||
break;
|
break;
|
||||||
case FivIoOrientationMirror90:
|
case FivIoOrientationMirror90:
|
||||||
cairo_matrix_rotate(&matrix, +M_PI_2);
|
cairo_matrix_rotate(&matrix, +M_PI_2);
|
||||||
cairo_matrix_scale(&matrix, -1, +1);
|
cairo_matrix_scale(&matrix, -1, +1);
|
||||||
cairo_matrix_translate(&matrix, -width, -height);
|
cairo_matrix_translate(&matrix, -*width, -*height);
|
||||||
break;
|
break;
|
||||||
case FivIoOrientationMirror180:
|
case FivIoOrientationMirror180:
|
||||||
cairo_matrix_scale(&matrix, +1, -1);
|
cairo_matrix_scale(&matrix, +1, -1);
|
||||||
cairo_matrix_translate(&matrix, 0, -height);
|
cairo_matrix_translate(&matrix, 0, -*height);
|
||||||
break;
|
break;
|
||||||
case FivIoOrientationMirror270:
|
case FivIoOrientationMirror270:
|
||||||
cairo_matrix_rotate(&matrix, -M_PI_2);
|
cairo_matrix_rotate(&matrix, -M_PI_2);
|
||||||
|
11
fiv-io.h
11
fiv-io.h
@ -130,12 +130,11 @@ typedef enum _FivIoOrientation {
|
|||||||
FivIoOrientation270 = 8
|
FivIoOrientation270 = 8
|
||||||
} FivIoOrientation;
|
} FivIoOrientation;
|
||||||
|
|
||||||
/// Returns whether dimensions need to be swapped for rendering.
|
/// Returns a rendering matrix for a surface, and its target dimensions.
|
||||||
gboolean fiv_io_orientation_is_sideways(FivIoOrientation orientation);
|
cairo_matrix_t fiv_io_orientation_apply(cairo_surface_t *surface,
|
||||||
|
FivIoOrientation orientation, double *width, double *height);
|
||||||
/// Returns a rendering matrix for a surface. Dimensions need to be pre-swapped.
|
void fiv_io_orientation_dimensions(cairo_surface_t *surface,
|
||||||
cairo_matrix_t fiv_io_orientation_matrix(
|
FivIoOrientation orientation, double *width, double *height);
|
||||||
FivIoOrientation orientation, double width, double height);
|
|
||||||
|
|
||||||
/// Extracts the orientation field from Exif, if there's any.
|
/// Extracts the orientation field from Exif, if there's any.
|
||||||
FivIoOrientation fiv_io_exif_orientation(const guint8 *exif, gsize len);
|
FivIoOrientation fiv_io_exif_orientation(const guint8 *exif, gsize len);
|
||||||
|
@ -108,16 +108,13 @@ fiv_thumbnail_get_root(void)
|
|||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
adjust_thumbnail(cairo_surface_t *thumbnail, double row_height)
|
adjust_thumbnail(cairo_surface_t *thumbnail, double row_height)
|
||||||
{
|
{
|
||||||
cairo_format_t format = cairo_image_surface_get_format(thumbnail);
|
|
||||||
int w = 0, width = cairo_image_surface_get_width(thumbnail);
|
|
||||||
int h = 0, height = cairo_image_surface_get_height(thumbnail);
|
|
||||||
|
|
||||||
// Hardcode orientation.
|
// Hardcode orientation.
|
||||||
FivIoOrientation orientation = (uintptr_t) cairo_surface_get_user_data(
|
FivIoOrientation orientation = (uintptr_t) cairo_surface_get_user_data(
|
||||||
thumbnail, &fiv_io_key_orientation);
|
thumbnail, &fiv_io_key_orientation);
|
||||||
cairo_matrix_t matrix = fiv_io_orientation_is_sideways(orientation)
|
|
||||||
? fiv_io_orientation_matrix(orientation, (w = height), (h = width))
|
double w = 0, h = 0;
|
||||||
: fiv_io_orientation_matrix(orientation, (w = width), (h = height));
|
cairo_matrix_t matrix =
|
||||||
|
fiv_io_orientation_apply(thumbnail, orientation, &w, &h);
|
||||||
|
|
||||||
double scale_x = 1;
|
double scale_x = 1;
|
||||||
double scale_y = 1;
|
double scale_y = 1;
|
||||||
@ -128,7 +125,11 @@ adjust_thumbnail(cairo_surface_t *thumbnail, double row_height)
|
|||||||
scale_y = row_height / h;
|
scale_y = row_height / h;
|
||||||
scale_x = round(scale_y * w) / w;
|
scale_x = round(scale_y * w) / w;
|
||||||
}
|
}
|
||||||
if (orientation <= FivIoOrientation0 && scale_x == 1 && scale_y == 1)
|
|
||||||
|
// This will be CAIRO_FORMAT_INVALID with non-image surfaces, which is fine.
|
||||||
|
cairo_format_t format = cairo_image_surface_get_format(thumbnail);
|
||||||
|
if (format != CAIRO_FORMAT_INVALID &&
|
||||||
|
orientation <= FivIoOrientation0 && scale_x == 1 && scale_y == 1)
|
||||||
return cairo_surface_reference(thumbnail);
|
return cairo_surface_reference(thumbnail);
|
||||||
|
|
||||||
int projected_width = round(scale_x * w);
|
int projected_width = round(scale_x * w);
|
||||||
@ -265,10 +266,13 @@ fiv_thumbnail_produce(GFile *target, FivThumbnailSize max_size, GError **error)
|
|||||||
thum, "%s%c%ld%c", THUMB_MTIME, 0, (long) st.st_mtim.tv_sec, 0);
|
thum, "%s%c%ld%c", THUMB_MTIME, 0, (long) st.st_mtim.tv_sec, 0);
|
||||||
g_string_append_printf(
|
g_string_append_printf(
|
||||||
thum, "%s%c%ld%c", THUMB_SIZE, 0, (long) filesize, 0);
|
thum, "%s%c%ld%c", THUMB_SIZE, 0, (long) filesize, 0);
|
||||||
g_string_append_printf(thum, "%s%c%d%c", THUMB_IMAGE_WIDTH, 0,
|
|
||||||
cairo_image_surface_get_width(surface), 0);
|
if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE) {
|
||||||
g_string_append_printf(thum, "%s%c%d%c", THUMB_IMAGE_HEIGHT, 0,
|
g_string_append_printf(thum, "%s%c%d%c", THUMB_IMAGE_WIDTH, 0,
|
||||||
cairo_image_surface_get_height(surface), 0);
|
cairo_image_surface_get_width(surface), 0);
|
||||||
|
g_string_append_printf(thum, "%s%c%d%c", THUMB_IMAGE_HEIGHT, 0,
|
||||||
|
cairo_image_surface_get_height(surface), 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Without a CMM, no conversion is attempted.
|
// Without a CMM, no conversion is attempted.
|
||||||
if (sRGB) {
|
if (sRGB) {
|
||||||
|
39
fiv-view.c
39
fiv-view.c
@ -207,25 +207,10 @@ get_surface_dimensions(FivView *self)
|
|||||||
if (!self->image)
|
if (!self->image)
|
||||||
return (Dimensions) {};
|
return (Dimensions) {};
|
||||||
|
|
||||||
cairo_rectangle_t extents = {};
|
Dimensions dimensions = {};
|
||||||
switch (cairo_surface_get_type(self->page)) {
|
fiv_io_orientation_dimensions(
|
||||||
case CAIRO_SURFACE_TYPE_IMAGE:
|
self->page, self->orientation, &dimensions.width, &dimensions.height);
|
||||||
extents.width = cairo_image_surface_get_width(self->page);
|
return dimensions;
|
||||||
extents.height = cairo_image_surface_get_height(self->page);
|
|
||||||
break;
|
|
||||||
case CAIRO_SURFACE_TYPE_RECORDING:
|
|
||||||
if (!cairo_recording_surface_get_extents(self->page, &extents))
|
|
||||||
cairo_recording_surface_ink_extents(self->page,
|
|
||||||
&extents.x, &extents.y, &extents.width, &extents.height);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fiv_io_orientation_is_sideways(self->orientation))
|
|
||||||
return (Dimensions) {extents.height, extents.width};
|
|
||||||
|
|
||||||
return (Dimensions) {extents.width, extents.height};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -398,9 +383,11 @@ fiv_view_draw(GtkWidget *widget, cairo_t *cr)
|
|||||||
if (h < allocation.height)
|
if (h < allocation.height)
|
||||||
y = round((allocation.height - h) / 2.);
|
y = round((allocation.height - h) / 2.);
|
||||||
|
|
||||||
Dimensions surface_dimensions = get_surface_dimensions(self);
|
Dimensions surface_dimensions = {};
|
||||||
cairo_matrix_t matrix = fiv_io_orientation_matrix(
|
cairo_matrix_t matrix =
|
||||||
self->orientation, surface_dimensions.width, surface_dimensions.height);
|
fiv_io_orientation_apply(self->page, self->orientation,
|
||||||
|
&surface_dimensions.width, &surface_dimensions.height);
|
||||||
|
|
||||||
cairo_translate(cr, x, y);
|
cairo_translate(cr, x, y);
|
||||||
if (self->checkerboard) {
|
if (self->checkerboard) {
|
||||||
gtk_style_context_save(style);
|
gtk_style_context_save(style);
|
||||||
@ -686,7 +673,11 @@ on_draw_page(G_GNUC_UNUSED GtkPrintOperation *operation,
|
|||||||
{
|
{
|
||||||
// Any DPI will be wrong, unless we import that information from the image.
|
// Any DPI will be wrong, unless we import that information from the image.
|
||||||
double scale = 1 / 96.;
|
double scale = 1 / 96.;
|
||||||
Dimensions surface_dimensions = get_surface_dimensions(self);
|
Dimensions surface_dimensions = {};
|
||||||
|
cairo_matrix_t matrix =
|
||||||
|
fiv_io_orientation_apply(self->page, self->orientation,
|
||||||
|
&surface_dimensions.width, &surface_dimensions.height);
|
||||||
|
|
||||||
double w = surface_dimensions.width * scale;
|
double w = surface_dimensions.width * scale;
|
||||||
double h = surface_dimensions.height * scale;
|
double h = surface_dimensions.height * scale;
|
||||||
|
|
||||||
@ -698,8 +689,6 @@ on_draw_page(G_GNUC_UNUSED GtkPrintOperation *operation,
|
|||||||
cairo_t *cr = gtk_print_context_get_cairo_context(context);
|
cairo_t *cr = gtk_print_context_get_cairo_context(context);
|
||||||
cairo_scale(cr, scale, scale);
|
cairo_scale(cr, scale, scale);
|
||||||
cairo_set_source_surface(cr, self->frame, 0, 0);
|
cairo_set_source_surface(cr, self->frame, 0, 0);
|
||||||
cairo_matrix_t matrix = fiv_io_orientation_matrix(
|
|
||||||
self->orientation, surface_dimensions.width, surface_dimensions.height);
|
|
||||||
cairo_pattern_set_matrix(cairo_get_source(cr), &matrix);
|
cairo_pattern_set_matrix(cairo_get_source(cr), &matrix);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user