Commit 6b50ba71 authored by Owen W. Taylor's avatar Owen W. Taylor Committed by Carlos Garcia Campos

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
parent d74d4447
......@@ -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);
}
/**
......
......@@ -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 *
......
......@@ -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;
}
......@@ -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
......
......@@ -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);
......
......@@ -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;
......
......@@ -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 ();
......
......@@ -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);
......
......@@ -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);
......
......@@ -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
......
......@@ -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
......
......@@ -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;
}
......@@ -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
......
......@@ -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);