[evince] Switch to specifying rendered output in pixels, not as a scale



commit 6b50ba7172d84de19f1215bed289698d82ea4187
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Mon Mar 3 15:22:30 2014 -0500

    Switch to specifying rendered output in pixels, not as a scale
    
    Passing a scale to the backend meant that we were implicitly counting
    on the backend code and front-end code to do exactly the same calculation
    to get the rendered size of a page. Instead switch to passing a
    target size in pixels to the backend.
    
    This, among other things, allows us to make sure that we render at a size
    that is integer device pixels in both X and Y directions.
    
    ev-render-context.[ch]: Add ev_render_context_set_target_size() and
    three helper functions:
    
     ev_render_context_compute_scaled_size(): get the pixel size to render at
     ev_render_context_compute_transformed_size(): size including effect of rotation
     ev_render_context_compute_scales(): get the corresponding xscale/yscale.
    
    ev-jobs.[ch]: Add ev_job_thumbnail_new_with_target_size(), and pass the
    target size for thumbnail and render jobs (which already had a target
    size) to the backends.
    
    backend/*: Use the helper functions rather than directly accessing
     render_context->scale.
    
    ev-pixbuf-cache.c ev-view.c ev-view-presentation.c ev-sidebar-thumbnails.c
    ev-window.c: Switch to passing target sizes rather than scales when
    rendering.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=723431

 backend/comics/comics-document.c                   |   18 +++--
 backend/djvu/djvu-document.c                       |   49 ++++++------
 backend/dvi/cairo-device.c                         |   18 +++--
 backend/dvi/cairo-device.h                         |    3 +-
 backend/dvi/dvi-document.c                         |   13 ++-
 backend/pdf/ev-poppler.cc                          |   71 +++++++----------
 backend/ps/ev-spectre.c                            |    5 +-
 backend/tiff/tiff-document.c                       |   12 ++-
 backend/xps/xps-document.c                         |   17 ++--
 .../libdocument/libevdocument-sections.txt         |    4 +
 help/reference/libview/libevview-sections.txt      |    1 +
 libdocument/ev-render-context.c                    |   83 +++++++++++++++++++-
 libdocument/ev-render-context.h                    |   21 +++++-
 libview/ev-jobs.c                                  |   22 +++++
 libview/ev-jobs.h                                  |    7 ++
 libview/ev-pixbuf-cache.c                          |   19 ++++-
 libview/ev-view-presentation.c                     |   82 +++++++++-----------
 libview/ev-view.c                                  |    7 +-
 shell/ev-sidebar-thumbnails.c                      |   30 +++++--
 shell/ev-window.c                                  |   12 ++-
 20 files changed, 328 insertions(+), 166 deletions(-)
---
diff --git a/backend/comics/comics-document.c b/backend/comics/comics-document.c
index ae643c5..00f8258 100644
--- a/backend/comics/comics-document.c
+++ b/backend/comics/comics-document.c
@@ -677,7 +677,7 @@ comics_document_render_pixbuf (EvDocument      *document,
                loader = gdk_pixbuf_loader_new ();
                g_signal_connect (loader, "size-prepared",
                                  G_CALLBACK (render_pixbuf_size_prepared_cb), 
-                                 &rc->scale);
+                                 &rc);
 
                while (outpipe >= 0) {
                        bytes = read (outpipe, buf, 4096);
@@ -698,17 +698,21 @@ comics_document_render_pixbuf (EvDocument      *document,
                g_spawn_close_pid (child_pid);
                g_object_unref (loader);
        } else {
+               int scaled_width, scaled_height;
+
                filename = 
                        g_build_filename (comics_document->dir,
                                           (char *) comics_document->page_names->pdata[rc->page->index],
                                          NULL);
           
                gdk_pixbuf_get_file_info (filename, &width, &height);
+
+               ev_render_context_compute_scaled_size (rc, width, height,
+                                                      &scaled_width, &scaled_height);
                
                tmp_pixbuf =
                        gdk_pixbuf_new_from_file_at_size (
-                                   filename, width * (rc->scale) + 0.5,
-                                   height * (rc->scale) + 0.5, NULL);
+                                   filename, scaled_width, scaled_height, NULL);
                rotated_pixbuf =
                        gdk_pixbuf_rotate_simple (tmp_pixbuf,
                                                  360 - rc->rotation);
@@ -738,11 +742,11 @@ render_pixbuf_size_prepared_cb (GdkPixbufLoader *loader,
                                gint             height,
                                gpointer         data)
 {
-       double *scale = data;
-       int w = (width  * (*scale) + 0.5);
-       int h = (height * (*scale) + 0.5);
+       EvRenderContext *rc = data;
+       int scaled_width, scaled_height;
 
-       gdk_pixbuf_loader_set_size (loader, w, h);
+       ev_render_context_compute_scaled_size (rc, width, height, &scaled_width, &scaled_height);
+       gdk_pixbuf_loader_set_size (loader, scaled_width, scaled_height);
 }
 
 /**
diff --git a/backend/djvu/djvu-document.c b/backend/djvu/djvu-document.c
index 13402f6..9c30a22 100644
--- a/backend/djvu/djvu-document.c
+++ b/backend/djvu/djvu-document.c
@@ -340,7 +340,8 @@ djvu_document_render (EvDocument      *document,
        ddjvu_page_t *d_page;
        ddjvu_page_rotation_t rotation;
        gint buffer_modified;
-       double page_width, page_height, tmp;
+       double page_width, page_height;
+       gint transformed_width, transformed_height;
 
        d_page = ddjvu_page_create_by_pageno (djvu_document->d_document, rc->page->index);
        
@@ -350,15 +351,12 @@ djvu_document_render (EvDocument      *document,
        document_get_page_size (djvu_document, rc->page->index, &page_width, &page_height, NULL);
        rotation = ddjvu_page_get_initial_rotation (d_page);
 
-       page_width = page_width * rc->scale + 0.5;
-       page_height = page_height * rc->scale + 0.5;
-       
+       ev_render_context_compute_transformed_size (rc, page_width, page_height,
+                                                   &transformed_width, &transformed_height);
+
        switch (rc->rotation) {
                case 90:
                        rotation += DDJVU_ROTATE_90;
-                       tmp = page_height;
-                       page_height = page_width;
-                       page_width = tmp;
                        
                        break;
                case 180:
@@ -367,9 +365,6 @@ djvu_document_render (EvDocument      *document,
                        break;
                case 270:
                        rotation += DDJVU_ROTATE_270;
-                       tmp = page_height;
-                       page_height = page_width;
-                       page_width = tmp;
                        
                        break;
                default:
@@ -378,15 +373,15 @@ djvu_document_render (EvDocument      *document,
        rotation = rotation % 4;
 
        surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
-                                             page_width, page_height);
+                                             transformed_width, transformed_height);
 
        rowstride = cairo_image_surface_get_stride (surface);
        pixels = (gchar *)cairo_image_surface_get_data (surface);
 
        prect.x = 0;
        prect.y = 0;
-       prect.w = page_width;
-       prect.h = page_height;
+       prect.w = transformed_width;
+       prect.h = transformed_height;
        rrect = prect;
 
        ddjvu_page_set_rotation (d_page, rotation);
@@ -447,8 +442,8 @@ djvu_document_get_thumbnail (EvDocument      *document,
        djvu_document_get_page_size (EV_DOCUMENT(djvu_document), rc->page,
                                     &page_width, &page_height);
        
-       thumb_width = (gint) (page_width * rc->scale);
-       thumb_height = (gint) (page_height * rc->scale);
+       ev_render_context_compute_scaled_size (rc, page_width, page_height,
+                                              &thumb_width, &thumb_height);
 
        pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
                                 thumb_width, thumb_height);
@@ -486,8 +481,8 @@ djvu_document_get_thumbnail_surface (EvDocument      *document,
        djvu_document_get_page_size (EV_DOCUMENT(djvu_document), rc->page,
                                     &page_width, &page_height);
 
-       thumb_width = (gint) (page_width * rc->scale + 0.5);
-       thumb_height = (gint) (page_height * rc->scale + 0.5);
+       ev_render_context_compute_scaled_size (rc, page_width, page_height,
+                                              &thumb_width, &thumb_height);
 
        surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
                                              thumb_width, thumb_height);
@@ -632,7 +627,8 @@ djvu_selection_get_selection_rects (DjvuDocument    *djvu_document,
 static cairo_region_t *
 djvu_get_selection_region (DjvuDocument *djvu_document,
                            gint page,
-                           gdouble scale,
+                           gdouble scale_x,
+                           gdouble scale_y,
                            EvRectangle *points)
 {
        double          height, dpi;
@@ -654,10 +650,10 @@ djvu_get_selection_region (DjvuDocument *djvu_document,
                r->y1 = height - r->y2 * 72 / dpi;
                r->y2 = height - tmp * 72 / dpi;
 
-               rect.x = (gint) ((r->x1 * scale) + 0.5);
-               rect.y = (gint) ((r->y1 * scale) + 0.5);
-               rect.width = (gint) (((r->x2 - r->x1) * scale) + 0.5);
-               rect.height = (gint) (((r->y2 - r->y1) * scale) + 0.5);
+               rect.x = (gint) ((r->x1 * scale_x) + 0.5);
+               rect.y = (gint) ((r->y1 * scale_y) + 0.5);
+               rect.width = (gint) ((r->x2 * scale_x) + 0.5) - rect.x;
+               rect.height = (gint) ((r->y2 * scale_y) + 0.5) - rect.y;
                cairo_region_union_rectangle (region, &rect);
                ev_rectangle_free (r);
        }
@@ -673,9 +669,14 @@ djvu_selection_get_selection_region (EvSelection    *selection,
                                     EvRectangle     *points)
 {
        DjvuDocument *djvu_document = DJVU_DOCUMENT (selection);
+       gdouble page_width, page_height;
+       gdouble scale_x, scale_y;
+
+       document_get_page_size (djvu_document, rc->page->index, &page_width, &page_height, NULL);
+       ev_render_context_compute_scales (rc, page_width, page_height, &scale_x, &scale_y);
 
        return djvu_get_selection_region (djvu_document, rc->page->index,
-                                         rc->scale, points);
+                                         scale_x, scale_y, points);
 }
 
 static gchar *
@@ -720,7 +721,7 @@ djvu_document_text_get_text_mapping (EvDocumentText *document_text,
                                &points.x2, &points.y2, NULL);
 
        return djvu_get_selection_region (djvu_document, page->index,
-                                         1.0, &points);
+                                         1.0, 1.0, &points);
 }
 
 static gchar *
diff --git a/backend/dvi/cairo-device.c b/backend/dvi/cairo-device.c
index 9f4badb..f46da99 100644
--- a/backend/dvi/cairo-device.c
+++ b/backend/dvi/cairo-device.c
@@ -32,7 +32,8 @@ typedef struct {
        gint xmargin;
        gint ymargin;
 
-       gdouble scale;
+       gdouble xscale;
+       gdouble yscale;
        
        Ulong fg;
        Ulong bg;
@@ -104,18 +105,17 @@ dvi_cairo_draw_rule (DviContext *dvi,
        color = cairo_device->fg;
        
        cairo_save (cairo_device->cr);
+       cairo_scale (cairo_device->cr, cairo_device->xscale, cairo_device->yscale);
 
-       cairo_set_line_width (cairo_device->cr,
-                             cairo_get_line_width (cairo_device->cr) * cairo_device->scale);
        cairo_set_source_rgb (cairo_device->cr,
                              ((color >> 16) & 0xff) / 255.,
                              ((color >> 8) & 0xff) / 255.,
                              ((color >> 0) & 0xff) / 255.);
 
        cairo_rectangle (cairo_device->cr,
-                        x + cairo_device->xmargin,
-                        y + cairo_device->ymargin,
-                        width, height);
+                        (x + cairo_device->xmargin) / cairo_device->xscale,
+                        (y + cairo_device->ymargin) / cairo_device->yscale,
+                        width / cairo_device->xscale, height / cairo_device->yscale);
        if (fill == 0) {
                cairo_stroke (cairo_device->cr);
        } else {
@@ -362,11 +362,13 @@ mdvi_cairo_device_set_margins (DviDevice *device,
 
 void
 mdvi_cairo_device_set_scale (DviDevice *device,
-                            gdouble    scale)
+                            gdouble    xscale,
+                            gdouble    yscale)
 {
        DviCairoDevice *cairo_device;
 
        cairo_device = (DviCairoDevice *) device->device_data;
 
-       cairo_device->scale = scale;
+       cairo_device->xscale = xscale;
+       cairo_device->yscale = yscale;
 }
diff --git a/backend/dvi/cairo-device.h b/backend/dvi/cairo-device.h
index bf76d2a..9ef6b6f 100644
--- a/backend/dvi/cairo-device.h
+++ b/backend/dvi/cairo-device.h
@@ -34,7 +34,8 @@ void             mdvi_cairo_device_set_margins (DviDevice *device,
                                                gint       xmargin,
                                                gint       ymargin);
 void             mdvi_cairo_device_set_scale   (DviDevice *device,
-                                               gdouble    scale);
+                                                gdouble    xscale,
+                                                gdouble    yscale);
 
 G_END_DECLS
 
diff --git a/backend/dvi/dvi-document.c b/backend/dvi/dvi-document.c
index 74f91cb..cbb3f8a 100644
--- a/backend/dvi/dvi-document.c
+++ b/backend/dvi/dvi-document.c
@@ -164,6 +164,7 @@ dvi_document_render (EvDocument      *document,
        cairo_surface_t *surface;
        cairo_surface_t *rotated_surface;
        DviDocument *dvi_document = DVI_DOCUMENT(document);
+       gdouble xscale, yscale;
        gint required_width, required_height;
        gint proposed_width, proposed_height;
        gint xmargin = 0, ymargin = 0;
@@ -176,12 +177,14 @@ dvi_document_render (EvDocument      *document,
        
        mdvi_setpage (dvi_document->context, rc->page->index);
        
+       ev_render_context_compute_scales (rc, dvi_document->base_width, dvi_document->base_height,
+                                         &xscale, &yscale);
        mdvi_set_shrink (dvi_document->context, 
-                        (int)((dvi_document->params->hshrink - 1) / rc->scale) + 1,
-                        (int)((dvi_document->params->vshrink - 1) / rc->scale) + 1);
+                        (int)((dvi_document->params->hshrink - 1) / xscale) + 1,
+                        (int)((dvi_document->params->vshrink - 1) / yscale) + 1);
 
-       required_width = dvi_document->base_width * rc->scale + 0.5;
-       required_height = dvi_document->base_height * rc->scale + 0.5;
+       ev_render_context_compute_scaled_size (rc, dvi_document->base_width, dvi_document->base_height,
+                                              &required_width, &required_height);
        proposed_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv;
        proposed_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv;
        
@@ -191,7 +194,7 @@ dvi_document_render (EvDocument      *document,
            ymargin = (required_height - proposed_height) / 2;
            
        mdvi_cairo_device_set_margins (&dvi_document->context->device, xmargin, ymargin);
-       mdvi_cairo_device_set_scale (&dvi_document->context->device, rc->scale);
+       mdvi_cairo_device_set_scale (&dvi_document->context->device, xscale, yscale);
        mdvi_cairo_device_render (dvi_document->context);
        surface = mdvi_cairo_device_get_surface (&dvi_document->context->device);
 
diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc
index b6e34e7..f418191 100644
--- a/backend/pdf/ev-poppler.cc
+++ b/backend/pdf/ev-poppler.cc
@@ -385,6 +385,8 @@ pdf_page_render (PopplerPage     *page,
 {
        cairo_surface_t *surface;
        cairo_t *cr;
+       double page_width, page_height;
+       double xscale, yscale;
 
        surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                              width, height);
@@ -403,7 +405,12 @@ pdf_page_render (PopplerPage     *page,
                default:
                        cairo_translate (cr, 0, 0);
        }
-       cairo_scale (cr, rc->scale, rc->scale);
+
+       poppler_page_get_size (page,
+                              &page_width, &page_height);
+
+       ev_render_context_compute_scales (rc, page_width, page_height, &xscale, &yscale);
+       cairo_scale (cr, xscale, yscale);
        cairo_rotate (cr, rc->rotation * G_PI / 180.0);
        poppler_page_render (page, cr);
 
@@ -428,15 +435,9 @@ pdf_document_render (EvDocument      *document,
 
        poppler_page_get_size (poppler_page,
                               &width_points, &height_points);
-       
-       if (rc->rotation == 90 || rc->rotation == 270) {
-               width = (int) ((height_points * rc->scale) + 0.5);
-               height = (int) ((width_points * rc->scale) + 0.5);
-       } else {
-               width = (int) ((width_points * rc->scale) + 0.5);
-               height = (int) ((height_points * rc->scale) + 0.5);
-       }
-       
+
+       ev_render_context_compute_transformed_size (rc, width_points, height_points,
+                                                   &width, &height);
        return pdf_page_render (poppler_page,
                                width, height, rc);
 }
@@ -475,16 +476,8 @@ pdf_document_get_thumbnail (EvDocument      *document,
        poppler_page_get_size (poppler_page,
                               &page_width, &page_height);
 
-       width = MAX ((gint)(page_width * rc->scale + 0.5), 1);
-       height = MAX ((gint)(page_height * rc->scale + 0.5), 1);
-
-       if (rc->rotation == 90 || rc->rotation == 270) {
-               gint  temp;
-
-               temp = width;
-               width = height;
-               height = temp;
-       }
+       ev_render_context_compute_transformed_size (rc, page_width, page_height,
+                                                   &width, &height);
 
        surface = poppler_page_get_thumbnail (poppler_page);
        if (surface) {
@@ -533,16 +526,8 @@ pdf_document_get_thumbnail_surface (EvDocument      *document,
        poppler_page_get_size (poppler_page,
                               &page_width, &page_height);
 
-       width = MAX ((gint)(page_width * rc->scale + 0.5), 1);
-       height = MAX ((gint)(page_height * rc->scale + 0.5), 1);
-
-       if (rc->rotation == 90 || rc->rotation == 270) {
-               gint  temp;
-
-               temp = width;
-               width = height;
-               height = temp;
-       }
+       ev_render_context_compute_transformed_size (rc, page_width, page_height,
+                                                   &width, &height);
 
        surface = poppler_page_get_thumbnail (poppler_page);
        if (surface) {
@@ -2073,13 +2058,13 @@ pdf_selection_render_selection (EvSelection      *selection,
        PopplerColor text_color, base_color;
        double width_points, height_points;
        gint width, height;
+       double xscale, yscale;
 
        poppler_page = POPPLER_PAGE (rc->page->backend_page);
 
        poppler_page_get_size (poppler_page,
                               &width_points, &height_points);
-       width = (int) ((width_points * rc->scale) + 0.5);
-       height = (int) ((height_points * rc->scale) + 0.5);
+       ev_render_context_compute_scaled_size (rc, width_points, height_points, &width, &height);
 
        text_color.red = text->red;
        text_color.green = text->green;
@@ -2096,7 +2081,8 @@ pdf_selection_render_selection (EvSelection      *selection,
        }
 
        cr = cairo_create (*surface);
-       cairo_scale (cr, rc->scale, rc->scale);
+       ev_render_context_compute_scales (rc, width_points, height_points, &xscale, &yscale);
+       cairo_scale (cr, xscale, yscale);
        cairo_surface_set_device_offset (*surface, 0, 0);
        memset (cairo_image_surface_get_data (*surface), 0x00,
                cairo_image_surface_get_height (*surface) *
@@ -2125,7 +2111,7 @@ pdf_selection_get_selected_text (EvSelection     *selection,
 }
 
 static cairo_region_t *
-create_region_from_poppler_region (GList *region, gdouble scale)
+create_region_from_poppler_region (GList *region, gdouble xscale, gdouble yscale)
 {
        GList *l;
        cairo_region_t *retval;
@@ -2138,10 +2124,10 @@ create_region_from_poppler_region (GList *region, gdouble scale)
 
                rectangle = (PopplerRectangle *)l->data;
 
-               rect.x = (gint) ((rectangle->x1 * scale) + 0.5);
-               rect.y = (gint) ((rectangle->y1 * scale) + 0.5);
-               rect.width  = (gint) (((rectangle->x2 - rectangle->x1) * scale) + 0.5);
-               rect.height = (gint) (((rectangle->y2 - rectangle->y1) * scale) + 0.5);
+               rect.x = (gint) ((rectangle->x1 * xscale) + 0.5);
+               rect.y = (gint) ((rectangle->y1 * yscale) + 0.5);
+               rect.width  = (gint) ((rectangle->x2 * xscale) + 0.5) - rect.x;
+               rect.height = (gint) ((rectangle->y2 * yscale) + 0.5) - rect.y;
                cairo_region_union_rectangle (retval, &rect);
 
                poppler_rectangle_free (rectangle);
@@ -2159,13 +2145,18 @@ pdf_selection_get_selection_region (EvSelection     *selection,
        PopplerPage    *poppler_page;
        cairo_region_t *retval;
        GList          *region;
+       double page_width, page_height;
+       double xscale, yscale;
 
        poppler_page = POPPLER_PAGE (rc->page->backend_page);
        region = poppler_page_get_selection_region (poppler_page,
                                                    1.0,
                                                    (PopplerSelectionStyle)style,
                                                    (PopplerRectangle *) points);
-       retval = create_region_from_poppler_region (region, rc->scale);
+       poppler_page_get_size (poppler_page,
+                              &page_width, &page_height);
+       ev_render_context_compute_scales (rc, page_width, page_height, &xscale, &yscale);
+       retval = create_region_from_poppler_region (region, xscale, yscale);
        g_list_free (region);
        
        return retval;
@@ -2201,7 +2192,7 @@ pdf_document_text_get_text_mapping (EvDocumentText *document_text,
        region = poppler_page_get_selection_region (poppler_page, 1.0,
                                                    POPPLER_SELECTION_GLYPH,
                                                    &points);
-       retval = create_region_from_poppler_region (region, 1.0);
+       retval = create_region_from_poppler_region (region, 1.0, 1.0);
        g_list_free (region);
 
        return retval;
diff --git a/backend/ps/ev-spectre.c b/backend/ps/ev-spectre.c
index e47e5fb..265fed3 100644
--- a/backend/ps/ev-spectre.c
+++ b/backend/ps/ev-spectre.c
@@ -299,8 +299,9 @@ ps_document_render (EvDocument      *document,
        
        spectre_page_get_size (ps_page, &width_points, &height_points);
 
-       width = (gint) ((width_points * rc->scale) + 0.5);
-       height = (gint) ((height_points * rc->scale) + 0.5);
+       ev_render_context_compute_scaled_size (rc, width_points, height_points,
+                                              &width, &height);
+
        rotation = (rc->rotation + get_page_rotation (ps_page)) % 360;
 
        src = spectre_render_context_new ();
diff --git a/backend/tiff/tiff-document.c b/backend/tiff/tiff-document.c
index 7813eb8..80ac0f5 100644
--- a/backend/tiff/tiff-document.c
+++ b/backend/tiff/tiff-document.c
@@ -225,6 +225,7 @@ tiff_document_render (EvDocument      *document,
 {
        TiffDocument *tiff_document = TIFF_DOCUMENT (document);
        int width, height;
+       int scaled_width, scaled_height;
        float x_res, y_res;
        gint rowstride, bytes;
        guchar *pixels = NULL;
@@ -323,9 +324,10 @@ tiff_document_render (EvDocument      *document,
                p += 4;
        }
 
+       ev_render_context_compute_scaled_size (rc, width, height * (x_res / y_res),
+                                              &scaled_width, &scaled_height);
        rotated_surface = ev_document_misc_surface_rotate_and_scale (surface,
-                                                                    (width * rc->scale) + 0.5,
-                                                                    (height * rc->scale * (x_res / y_res)) + 
0.5,
+                                                                    scaled_width, scaled_height,
                                                                     rc->rotation);
        cairo_surface_destroy (surface);
        
@@ -338,6 +340,7 @@ tiff_document_get_thumbnail (EvDocument      *document,
 {
        TiffDocument *tiff_document = TIFF_DOCUMENT (document);
        int width, height;
+       int scaled_width, scaled_height;
        float x_res, y_res;
        gint rowstride, bytes;
        guchar *pixels = NULL;
@@ -392,9 +395,10 @@ tiff_document_get_thumbnail (EvDocument      *document,
                                   ORIENTATION_TOPLEFT, 0);
        pop_handlers ();
 
+       ev_render_context_compute_scaled_size (rc, width, height * (x_res / y_res),
+                                              &scaled_width, &scaled_height);
        scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
-                                                width * rc->scale,
-                                                height * rc->scale * (x_res / y_res),
+                                                scaled_width, scaled_height,
                                                 GDK_INTERP_BILINEAR);
        g_object_unref (pixbuf);
        
diff --git a/backend/xps/xps-document.c b/backend/xps/xps-document.c
index b759098..149705a 100644
--- a/backend/xps/xps-document.c
+++ b/backend/xps/xps-document.c
@@ -202,7 +202,8 @@ xps_document_render (EvDocument      *document,
 {
        GXPSPage        *xps_page;
        gdouble          page_width, page_height;
-       guint            width, height;
+       gint             width, height;
+       double           scale_x, scale_y;
        cairo_surface_t *surface;
        cairo_t         *cr;
        GError          *error = NULL;
@@ -210,13 +211,8 @@ xps_document_render (EvDocument      *document,
        xps_page = GXPS_PAGE (rc->page->backend_page);
 
        gxps_page_get_size (xps_page, &page_width, &page_height);
-       if (rc->rotation == 90 || rc->rotation == 270) {
-               width = (guint) ((page_height * rc->scale) + 0.5);
-               height = (guint) ((page_width * rc->scale) + 0.5);
-       } else {
-               width = (guint) ((page_width * rc->scale) + 0.5);
-               height = (guint) ((page_height * rc->scale) + 0.5);
-       }
+       ev_render_context_compute_transformed_size (rc, page_width, page_height,
+                                                    &width, &height);
 
        surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                              width, height);
@@ -239,7 +235,10 @@ xps_document_render (EvDocument      *document,
                cairo_translate (cr, 0, 0);
        }
 
-       cairo_scale (cr, rc->scale, rc->scale);
+       ev_render_context_compute_scales (rc, page_width, page_height,
+                                         &scale_x, &scale_y);
+       cairo_scale (cr, scale_x, scale_y);
+
        cairo_rotate (cr, rc->rotation * G_PI / 180.0);
        gxps_page_render (xps_page, cr, &error);
        cairo_destroy (cr);
diff --git a/help/reference/libdocument/libevdocument-sections.txt 
b/help/reference/libdocument/libevdocument-sections.txt
index f21c798..1ad8a85 100644
--- a/help/reference/libdocument/libevdocument-sections.txt
+++ b/help/reference/libdocument/libevdocument-sections.txt
@@ -248,6 +248,10 @@ ev_render_context_new
 ev_render_context_set_page
 ev_render_context_set_rotation
 ev_render_context_set_scale
+ev_render_context_set_target_size
+ev_render_context_compute_scaled_size
+ev_render_context_compute_transformed_size
+ev_render_context_compute_scales
 <SUBSECTION Standard>
 EV_RENDER_CONTEXT
 EV_IS_RENDER_CONTEXT
diff --git a/help/reference/libview/libevview-sections.txt b/help/reference/libview/libevview-sections.txt
index c9f7ac2..9a3e1a3 100644
--- a/help/reference/libview/libevview-sections.txt
+++ b/help/reference/libview/libevview-sections.txt
@@ -214,6 +214,7 @@ ev_job_render_new
 ev_job_render_set_selection_info
 ev_job_page_data_new
 ev_job_thumbnail_new
+ev_job_thumbnail_new_with_target_size
 ev_job_thumbnail_set_has_frame
 ev_job_thumbnail_set_output_format
 ev_job_fonts_new
diff --git a/libdocument/ev-render-context.c b/libdocument/ev-render-context.c
index 9e728a6..11bdf09 100644
--- a/libdocument/ev-render-context.c
+++ b/libdocument/ev-render-context.c
@@ -23,9 +23,10 @@
 static void ev_render_context_init       (EvRenderContext      *rc);
 static void ev_render_context_class_init (EvRenderContextClass *class);
 
-
 G_DEFINE_TYPE (EvRenderContext, ev_render_context, G_TYPE_OBJECT);
 
+#define FLIP_DIMENSIONS(rc) ((rc)->rotation == 90 || (rc)->rotation == 270)
+
 static void ev_render_context_init (EvRenderContext *rc) { /* Do Nothing */ }
 
 static void
@@ -65,6 +66,8 @@ ev_render_context_new (EvPage *page,
        rc->page = page ? g_object_ref (page) : NULL;
        rc->rotation = rotation;
        rc->scale = scale;
+       rc->target_width = -1;
+       rc->target_height = -1;
 
        return rc;
 }
@@ -99,3 +102,81 @@ ev_render_context_set_scale (EvRenderContext *rc,
        rc->scale = scale;
 }
 
+void
+ev_render_context_set_target_size (EvRenderContext *rc,
+                                  int              target_width,
+                                  int              target_height)
+{
+       g_return_if_fail (rc != NULL);
+
+       rc->target_width = target_width;
+       rc->target_height = target_height;
+}
+
+void
+ev_render_context_compute_scaled_size (EvRenderContext *rc,
+                                      double           width_points,
+                                      double           height_points,
+                                      int             *scaled_width,
+                                      int             *scaled_height)
+{
+       g_return_if_fail (rc != NULL);
+
+       if (scaled_width) {
+               if (rc->target_width >= 0) {
+                       *scaled_width = FLIP_DIMENSIONS (rc) ? rc->target_height : rc->target_width;
+               } else {
+                       *scaled_width = (int) (width_points * rc->scale + 0.5);
+               }
+       }
+
+       if (scaled_height) {
+               if (rc->target_height >= 0) {
+                       *scaled_height = FLIP_DIMENSIONS (rc) ? rc->target_width : rc->target_height;
+               } else {
+                       *scaled_height = (int) (height_points * rc->scale + 0.5);
+               }
+       }
+}
+
+void
+ev_render_context_compute_transformed_size (EvRenderContext *rc,
+                                           double           width_points,
+                                           double           height_points,
+                                           int             *transformed_width,
+                                           int             *transformed_height)
+{
+       int scaled_width, scaled_height;
+
+       g_return_if_fail (rc != NULL);
+
+       ev_render_context_compute_scaled_size (rc, width_points, height_points,
+                                              &scaled_width, &scaled_height);
+
+       if (transformed_width)
+               *transformed_width = FLIP_DIMENSIONS (rc) ? scaled_height : scaled_width;
+
+       if (transformed_height)
+               *transformed_height = FLIP_DIMENSIONS (rc) ? scaled_width : scaled_height;
+}
+
+void
+ev_render_context_compute_scales (EvRenderContext *rc,
+                                 double           width_points,
+                                 double           height_points,
+                                 double          *scale_x,
+                                 double          *scale_y)
+{
+       int scaled_width, scaled_height;
+
+       g_return_if_fail (rc != NULL);
+
+       ev_render_context_compute_scaled_size (rc, width_points, height_points,
+                                              &scaled_width, &scaled_height);
+
+       if (scale_x)
+               *scale_x = scaled_width / width_points;
+
+       if (scale_y)
+               *scale_y = scaled_height / height_points;
+}
diff --git a/libdocument/ev-render-context.h b/libdocument/ev-render-context.h
index 7091c49..76b3740 100644
--- a/libdocument/ev-render-context.h
+++ b/libdocument/ev-render-context.h
@@ -50,6 +50,8 @@ struct _EvRenderContext
        EvPage *page;
        gint    rotation;
        gdouble scale;
+       gint    target_width;
+       gint    target_height;
 };
 
 
@@ -63,7 +65,24 @@ void             ev_render_context_set_rotation    (EvRenderContext *rc,
                                                    gint             rotation);
 void             ev_render_context_set_scale       (EvRenderContext *rc,
                                                    gdouble          scale);
-
+void             ev_render_context_set_target_size (EvRenderContext *rc,
+                                                    int              target_width,
+                                                    int              target_height);
+void             ev_render_context_compute_scaled_size      (EvRenderContext *rc,
+                                                             double           width_points,
+                                                             double           height_points,
+                                                             int             *scaled_width,
+                                                             int             *scaled_height);
+void             ev_render_context_compute_transformed_size (EvRenderContext *rc,
+                                                             double          width_points,
+                                                             double          height_points,
+                                                             int            *transformed_width,
+                                                             int            *transformed_height);
+void             ev_render_context_compute_scales  (EvRenderContext *rc,
+                                                    double           width_points,
+                                                    double           height_points,
+                                                    double          *scale_x,
+                                                    double          *scale_y);
 
 G_END_DECLS
 
diff --git a/libview/ev-jobs.c b/libview/ev-jobs.c
index 83c50d8..e118855 100644
--- a/libview/ev-jobs.c
+++ b/libview/ev-jobs.c
@@ -631,6 +631,8 @@ ev_job_render_run (EvJob *job)
 
        ev_page = ev_document_get_page (job->document, job_render->page);
        rc = ev_render_context_new (ev_page, job_render->rotation, job_render->scale);
+       ev_render_context_set_target_size (rc,
+                                          job_render->target_width, job_render->target_height);
        g_object_unref (ev_page);
 
        job_render->surface = ev_document_render (job->document, rc);
@@ -848,6 +850,8 @@ ev_job_thumbnail_run (EvJob *job)
 
        page = ev_document_get_page (job->document, job_thumb->page);
        rc = ev_render_context_new (page, job_thumb->rotation, job_thumb->scale);
+       ev_render_context_set_target_size (rc,
+                                          job_thumb->target_width, job_thumb->target_height);
        g_object_unref (page);
 
         if (job_thumb->format == EV_JOB_THUMBNAIL_PIXBUF)
@@ -897,10 +901,28 @@ ev_job_thumbnail_new (EvDocument *document,
        job->scale = scale;
         job->has_frame = TRUE;
         job->format = EV_JOB_THUMBNAIL_PIXBUF;
+        job->target_width = -1;
+        job->target_height = -1;
 
        return EV_JOB (job);
 }
 
+EvJob *
+ev_job_thumbnail_new_with_target_size (EvDocument *document,
+                                       gint        page,
+                                       gint        rotation,
+                                       gint        target_width,
+                                       gint        target_height)
+{
+        EvJob *job = ev_job_thumbnail_new (document, page, rotation, 1.);
+        EvJobThumbnail  *job_thumb = EV_JOB_THUMBNAIL (job);
+
+        job_thumb->target_width = target_width;
+        job_thumb->target_height = target_height;
+
+        return job;
+}
+
 /**
  * ev_job_thumbnail_set_has_frame:
  * @job:
diff --git a/libview/ev-jobs.h b/libview/ev-jobs.h
index 634b41b..057bdae 100644
--- a/libview/ev-jobs.h
+++ b/libview/ev-jobs.h
@@ -343,6 +343,8 @@ struct _EvJobThumbnail
        gint page;
        gint rotation;
        gdouble scale;
+       gint target_width;
+       gint target_height;
 
        GdkPixbuf *thumbnail;
         gboolean has_frame;
@@ -542,6 +544,11 @@ EvJob          *ev_job_thumbnail_new           (EvDocument      *document,
                                                 gint             page,
                                                 gint             rotation,
                                                 gdouble          scale);
+EvJob         *ev_job_thumbnail_new_with_target_size (EvDocument      *document,
+                                                      gint             page,
+                                                      gint             rotation,
+                                                      gint             target_width,
+                                                      gint             target_height);
 void            ev_job_thumbnail_set_has_frame (EvJobThumbnail  *job,
                                                 gboolean         has_frame);
 void            ev_job_thumbnail_set_output_format (EvJobThumbnail      *job,
diff --git a/libview/ev-pixbuf-cache.c b/libview/ev-pixbuf-cache.c
index 897d3de..4d0f876 100644
--- a/libview/ev-pixbuf-cache.c
+++ b/libview/ev-pixbuf-cache.c
@@ -652,7 +652,7 @@ add_job (EvPixbufCache  *pixbuf_cache,
        job_info->region = region ? cairo_region_reference (region) : NULL;
 
        job_info->job = ev_job_render_new (pixbuf_cache->document,
-                                          page, rotation, scale,
+                                           page, rotation, 0.,
                                           width, height);
 
        if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) {
@@ -1033,6 +1033,7 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache   *pixbuf_cache,
                GdkColor text, base;
                EvRenderContext *rc;
                EvPage *ev_page;
+               gint width, height;
 
                /* we need to get a new selection pixbuf */
                ev_document_doc_mutex_lock ();
@@ -1044,7 +1045,12 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache   *pixbuf_cache,
                }
 
                ev_page = ev_document_get_page (pixbuf_cache->document, page);
-               rc = ev_render_context_new (ev_page, 0, scale);
+                _get_page_size_for_scale_and_rotation (pixbuf_cache->document,
+                                                       page, scale, 0,
+                                                       &width, &height);
+
+                rc = ev_render_context_new (ev_page, 0, 0.);
+                ev_render_context_set_target_size (rc, width, height);
                g_object_unref (ev_page);
 
                get_selection_colors (EV_VIEW (pixbuf_cache->view), &text, &base);
@@ -1098,10 +1104,17 @@ ev_pixbuf_cache_get_selection_region (EvPixbufCache *pixbuf_cache,
        if (ev_rect_cmp (&(job_info->target_points), &(job_info->selection_region_points))) {
                EvRenderContext *rc;
                EvPage *ev_page;
+               gint width, height;
 
                ev_document_doc_mutex_lock ();
                ev_page = ev_document_get_page (pixbuf_cache->document, page);
-               rc = ev_render_context_new (ev_page, 0, scale);
+
+               _get_page_size_for_scale_and_rotation (pixbuf_cache->document,
+                                                      page, scale, 0,
+                                                      &width, &height);
+
+               rc = ev_render_context_new (ev_page, 0, 0.);
+               ev_render_context_set_target_size (rc, width, height);
                g_object_unref (ev_page);
 
                if (job_info->selection_region)
diff --git a/libview/ev-view-presentation.c b/libview/ev-view-presentation.c
index 7707b7c..3bdf4e6 100644
--- a/libview/ev-view-presentation.c
+++ b/libview/ev-view-presentation.c
@@ -65,7 +65,6 @@ struct _EvViewPresentation
        guint                  rotation;
        gboolean               inverted_colors;
        EvPresentationState    state;
-       gdouble                scale;
        gint                   monitor_width;
        gint                   monitor_height;
 
@@ -168,25 +167,30 @@ ev_view_presentation_set_end (EvViewPresentation *pview)
        gtk_widget_queue_draw (widget);
 }
 
-static gdouble
-ev_view_presentation_get_scale_for_page (EvViewPresentation *pview,
-                                        guint               page)
+static void
+ev_view_presentation_get_view_size (EvViewPresentation *pview,
+                                   guint               page,
+                                   int                *view_width,
+                                   int                *view_height)
 {
-       if (!ev_document_is_page_size_uniform (pview->document) || pview->scale == 0) {
-               gdouble width, height;
+       gdouble width, height;
 
-               ev_document_get_page_size (pview->document, page, &width, &height);
-               if (pview->rotation == 90 || pview->rotation == 270) {
-                       gdouble tmp;
+       ev_document_get_page_size (pview->document, page, &width, &height);
+       if (pview->rotation == 90 || pview->rotation == 270) {
+               gdouble tmp;
 
-                       tmp = width;
-                       width = height;
-                       height = tmp;
-               }
-               pview->scale = MIN (pview->monitor_width / width, pview->monitor_height / height);
+               tmp = width;
+               width = height;
+               height = tmp;
        }
 
-       return pview->scale;
+       if (pview->monitor_width / width < pview->monitor_height / height) {
+               *view_width = pview->monitor_width;
+               *view_height = (int)((pview->monitor_width / width) * height + 0.5);
+       } else {
+               *view_width = (int)((pview->monitor_height / height) * width + 0.5);
+               *view_height = pview->monitor_height;
+       }
 }
 
 static void
@@ -195,22 +199,10 @@ ev_view_presentation_get_page_area (EvViewPresentation *pview,
 {
        GtkWidget    *widget = GTK_WIDGET (pview);
        GtkAllocation allocation;
-       gdouble       doc_width, doc_height;
        gint          view_width, view_height;
-       gdouble       scale;
 
-       ev_document_get_page_size (pview->document,
-                                  pview->current_page,
-                                  &doc_width, &doc_height);
-       scale = ev_view_presentation_get_scale_for_page (pview, pview->current_page);
-
-       if (pview->rotation == 90 || pview->rotation == 270) {
-               view_width = (gint)((doc_height * scale) + 0.5);
-               view_height = (gint)((doc_width * scale) + 0.5);
-       } else {
-               view_width = (gint)((doc_width * scale) + 0.5);
-               view_height = (gint)((doc_height * scale) + 0.5);
-       }
+       ev_view_presentation_get_view_size (pview, pview->current_page,
+                                           &view_width, &view_height);
 
        gtk_widget_get_allocation (widget, &allocation);
 
@@ -353,14 +345,15 @@ ev_view_presentation_schedule_new_job (EvViewPresentation *pview,
                                       gint                page,
                                       EvJobPriority       priority)
 {
-       EvJob  *job;
-       gdouble scale;
+       EvJob *job;
+        int    view_width, view_height;
 
        if (page < 0 || page >= ev_document_get_n_pages (pview->document))
                return NULL;
 
-       scale = ev_view_presentation_get_scale_for_page (pview, page);
-       job = ev_job_render_new (pview->document, page, pview->rotation, scale, 0, 0);
+        ev_view_presentation_get_view_size (pview, page, &view_width, &view_height);
+        job = ev_job_render_new (pview->document, page, pview->rotation, 0.,
+                                 view_width, view_height);
        g_signal_connect (job, "finished",
                          G_CALLBACK (job_finished_cb),
                          pview);
@@ -794,33 +787,31 @@ ev_view_presentation_get_link_at_location (EvViewPresentation *pview,
        EvLink        *link;
        gdouble        width, height;
        gdouble        new_x, new_y;
-       gdouble        scale;
 
        if (!pview->page_cache)
                return NULL;
 
        ev_document_get_page_size (pview->document, pview->current_page, &width, &height);
        ev_view_presentation_get_page_area (pview, &page_area);
-       scale = ev_view_presentation_get_scale_for_page (pview, pview->current_page);
-       x = (x - page_area.x) / scale;
-       y = (y - page_area.y) / scale;
+       x = (x - page_area.x) / page_area.width;
+       y = (y - page_area.y) / page_area.height;
        switch (pview->rotation) {
        case 0:
        case 360:
-               new_x = x;
-               new_y = y;
+               new_x = width * x;
+               new_y = height * y;
                break;
        case 90:
-               new_x = y;
-               new_y = height - x;
+               new_x = width * y;
+               new_y = height * (1 - x);
                break;
        case 180:
-               new_x = width - x;
-               new_y = height - y;
+               new_x = width * (1 - x);
+               new_y = height * (1 - y);
                break;
        case 270:
-               new_x = width - y;
-               new_y = x;
+               new_x = width * (1 - y);
+               new_y = height * x;
                break;
        default:
                g_assert_not_reached ();
@@ -1601,7 +1592,6 @@ ev_view_presentation_set_rotation (EvViewPresentation *pview,
         if (pview->is_constructing)
                 return;
 
-        pview->scale = 0;
         ev_view_presentation_reset_jobs (pview);
         ev_view_presentation_update_current_page (pview, pview->current_page);
 }
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 7560084..acd9890 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -890,7 +890,10 @@ compute_scroll_increment (EvView        *view,
 
                cairo_region_get_rectangle (region, 0, &rect);
                ev_page = ev_document_get_page (view->document, page);
-               rc = ev_render_context_new (ev_page, view->rotation, view->scale);
+               rc = ev_render_context_new (ev_page, view->rotation, 0.);
+               ev_render_context_set_target_size (rc,
+                                                  page_area.width - (border.left + border.right),
+                                                  page_area.height - (border.left + border.right));
                g_object_unref (ev_page);
                /* Get the selection region to know the height of the line */
                doc_rect.x1 = doc_rect.x2 = rect.x + 0.5;
@@ -6005,7 +6008,7 @@ draw_surface (cairo_t           *cr,
                scale_x = (gdouble)target_width / width;
                scale_y = (gdouble)target_height / height;
                cairo_pattern_set_filter (cairo_get_source (cr),
-                                         CAIRO_FILTER_FAST);
+                                         CAIRO_FILTER_NEAREST);
                cairo_scale (cr, scale_x, scale_y);
 
                offset_x /= scale_x;
diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c
index 8ab8fa8..38d71d9 100644
--- a/shell/ev-sidebar-thumbnails.c
+++ b/shell/ev-sidebar-thumbnails.c
@@ -453,16 +453,27 @@ clear_range (EvSidebarThumbnails *sidebar_thumbnails,
        gtk_tree_path_free (path);
 }
 
-static gdouble
-get_scale_for_page (EvSidebarThumbnails *sidebar_thumbnails,
-                   gint                 page)
+static void
+get_size_for_page (EvSidebarThumbnails *sidebar_thumbnails,
+                   gint                 page,
+                   gint                *width_return,
+                   gint                *height_return)
 {
        EvSidebarThumbnailsPrivate *priv = sidebar_thumbnails->priv;
-       gdouble width;
+        gdouble width, height;
+        gint thumbnail_height;
 
        ev_document_get_page_size (priv->document, page, &width, NULL);
+        ev_document_get_page_size (priv->document, page, &width, &height);
+        thumbnail_height = (int)(THUMBNAIL_WIDTH * height / width + 0.5);
 
-       return (gdouble)THUMBNAIL_WIDTH / width;
+        if (priv->rotation == 90 || priv->rotation == 270) {
+                *width_return = thumbnail_height;
+                *height_return = THUMBNAIL_WIDTH;
+        } else {
+                *width_return = THUMBNAIL_WIDTH;
+                *height_return = thumbnail_height;
+        }
 }
 
 static void
@@ -491,9 +502,12 @@ add_range (EvSidebarThumbnails *sidebar_thumbnails,
                                    -1);
 
                if (job == NULL && !thumbnail_set) {
-                       job = ev_job_thumbnail_new (priv->document,
-                                                   page, priv->rotation,
-                                                   get_scale_for_page (sidebar_thumbnails, page));
+                       gint thumbnail_width, thumbnail_height;
+                       get_size_for_page (sidebar_thumbnails, page, &thumbnail_width, &thumbnail_height);
+
+                       job = ev_job_thumbnail_new_with_target_size (priv->document,
+                                                                    page, priv->rotation,
+                                                                    thumbnail_width, thumbnail_height);
                         ev_job_thumbnail_set_has_frame (EV_JOB_THUMBNAIL (job), FALSE);
                         ev_job_thumbnail_set_output_format (EV_JOB_THUMBNAIL (job), 
EV_JOB_THUMBNAIL_SURFACE);
                        g_object_set_data_full (G_OBJECT (job), "tree_iter",
diff --git a/shell/ev-window.c b/shell/ev-window.c
index 978c55f..a4f8a8a 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -1396,8 +1396,8 @@ ev_window_set_icon_from_thumbnail (EvJobThumbnail *job,
 static void
 ev_window_refresh_window_thumbnail (EvWindow *ev_window)
 {
-       gdouble page_width;
-       gdouble scale;
+       gdouble page_width, page_height;
+       gint width, height;
        gint rotation;
        EvDocument *document = ev_window->priv->document;
 
@@ -1408,11 +1408,13 @@ ev_window_refresh_window_thumbnail (EvWindow *ev_window)
 
        ev_window_clear_thumbnail_job (ev_window);
 
-       ev_document_get_page_size (document, 0, &page_width, NULL);
-       scale = 128. / page_width;
+       ev_document_get_page_size (document, 0, &page_width, &page_height);
+       width = 128;
+       height = (int)(width * page_height / page_width + 0.5);
        rotation = ev_document_model_get_rotation (ev_window->priv->model);
 
-       ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, 0, rotation, scale);
+       ev_window->priv->thumbnail_job = ev_job_thumbnail_new_with_target_size (document, 0, rotation,
+                                                                               width, height);
        g_signal_connect (ev_window->priv->thumbnail_job, "finished",
                          G_CALLBACK (ev_window_set_icon_from_thumbnail),
                          ev_window);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]