Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 5 additions & 29 deletions src/Services/Thumbnailer.vala
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public class PaperClip.Services.Thumbnailer {
if (image_area >= max_area) {
debug ("Image is too big! Loading it in a reduced size");
retval = yield ThreadManager.run_in_thread<Gdk.Texture> (
() => load_scaled (surface, basename));
() => load_scaled (surface));
} else {
debug ("Loading image in its default size");
retval = yield ThreadManager.run_in_thread<Gdk.Texture> (() => load_memory (surface));
Expand All @@ -66,15 +66,9 @@ public class PaperClip.Services.Thumbnailer {
return retval;
}

private Gdk.Texture load_scaled (Cairo.ImageSurface surface, string basename) throws Error {
private Gdk.Texture load_scaled (Cairo.ImageSurface surface) throws Error {
float max_area = max_size * max_size * area_threshold;
int width = surface.get_width (), height = surface.get_height ();
string save_path = create_cache_file (basename);
Cairo.Status status = surface.write_to_png (save_path);

if (status != SUCCESS) {
throw new ThumbnailError.FAILED_EXPORT (@"Failed to export $save_path: $status");
}

float scale_factor = 0.1f;
for (; scale_factor < 0.8f; scale_factor+=0.1f) {
Expand All @@ -88,30 +82,12 @@ public class PaperClip.Services.Thumbnailer {
float scaled_height = height * scale_factor, scaled_width = width * scale_factor;
debug (@"Height: $height -> $scaled_height. Width: $width -> $scaled_width");

var pixbuf = new Gdk.Pixbuf.from_file_at_size (save_path, (int) scaled_width, (int) scaled_height);
var texture = Gdk.Texture.for_pixbuf (pixbuf);
var pixbuf = Gdk.pixbuf_get_from_surface (surface, 0, 0, width, height);
var scaled_pixbuf = pixbuf.scale_simple ((int) scaled_width, (int) scaled_height, Gdk.InterpType.BILINEAR);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, GdkPixbuf's scaling provides a lower quality thumbnail. In the DocumentThumbnail widget we use either a Trilinear interpolation or a nearest interpolation. The latter is supported by GdkPixbuf but the former is not.

I also want to remove GdkPixbuf from the codebase in favor of Glycin since it plays better with GdkTextures and would allow us to remove this ugly scaling implementation I made.

Gsk.ScalingFilter filter = LINEAR;
if (scaled_width > thumbnail_texture.width || scaled_height > thumbnail_texture.height) {
filter = NEAREST;
} else {
filter = TRILINEAR;
}

var texture = Gdk.Texture.for_pixbuf (scaled_pixbuf);
return texture;
}

private string? create_cache_file (string basename) throws Error {
string destination_path = Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_tmp_dir (),
"thumbnails");
int result = DirUtils.create_with_parents (destination_path, 0777);
if (result < 0) {
throw new ThumbnailError.FAILED_TO_CACHE (@"Unable to create tmp path $destination_path");
}

string destination_file = Path.build_filename (destination_path,
"%s.png".printf (basename));

var file = File.new_for_path (destination_file);
if (!file.query_exists ()) {
file.create (NONE);
}
return destination_file;
}

private Gdk.Texture load_memory (Cairo.ImageSurface surface) throws Error {
int height = surface.get_height (), width = surface.get_width ();
size_t size = height * width * 4;
Expand Down