From 4efd7b287f8fd4eb7966b37b7ab72b0b3993364b Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Sat, 21 Jan 2012 03:04:23 +0100 Subject: Update image scaling subpixel offset calculations for top-down images. --- draw/draw_device.c | 2 +- draw/draw_scale.c | 42 +++++++++++++++++++++--------------------- draw/draw_simple_scale.c | 48 +++++++++++++++++++++++++----------------------- 3 files changed, 47 insertions(+), 45 deletions(-) (limited to 'draw') diff --git a/draw/draw_device.c b/draw/draw_device.c index 1cb3e4b9..12810420 100644 --- a/draw/draw_device.c +++ b/draw/draw_device.c @@ -504,7 +504,7 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm, } else { - fz_matrix ctm = {glyph->w, 0.0, 0.0, -glyph->h, x + glyph->x, y + glyph->y + glyph->h}; + fz_matrix ctm = {glyph->w, 0.0, 0.0, glyph->h, x + glyph->x, y + glyph->y}; fz_paint_image(state->dest, state->scissor, state->shape, glyph, ctm, alpha * 255); } fz_drop_pixmap(dev->ctx, glyph); diff --git a/draw/draw_scale.c b/draw/draw_scale.c index 65baee4f..b34f9770 100644 --- a/draw/draw_scale.c +++ b/draw/draw_scale.c @@ -1214,15 +1214,13 @@ fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, floa /* Find the destination bbox, width/height, and sub pixel offset, * allowing for whether we're flipping or not. */ - /* Note that the x and y sub pixel offsets here are different. - * The (x,y) position given describes where the bottom left corner - * of the source image should be mapped to (i.e. where (0,h) in image - * space ends up, not the more logical and sane (0,0)). Also there - * are differences in the way we scale horizontally and vertically. - * When scaling rows horizontally, we always read forwards through - * the source, and store either forwards or in reverse as required. - * When scaling vertically, we always store out forwards, but may - * feed source rows in in a different order. + /* The (x,y) position given describes where the top left corner + * of the source image should be mapped to (i.e. where (0,0) in image + * space ends up). Also there are differences in the way we scale + * horizontally and vertically. When scaling rows horizontally, we + * always read forwards through the source, and store either forwards + * or in reverse as required. When scaling vertically, we always store + * out forwards, but may feed source rows in in a different order. * * Consider the image rectangle 'r' to which the image is mapped, * and the (possibly) larger rectangle 'R', given by expanding 'r' to @@ -1240,7 +1238,7 @@ fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, floa { float tmp; w = -w; - dst_x_int = floor(x-w); + dst_x_int = floorf(x-w); tmp = ceilf(x); dst_w_int = (int)tmp; x = tmp - x; @@ -1248,27 +1246,29 @@ fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, floa } else { - dst_x_int = floor(x); + dst_x_int = floorf(x); x -= (float)dst_x_int; dst_w_int = (int)ceilf(x + w); } flip_y = (h < 0); - /* dst_y_int is calculated to be the bottom of the scaled image, but - * y (the sub pixel offset) has to end up being the value at the top. + /* dst_y_int is calculated to be the top of the scaled image, and + * y (the sub pixel offset) is the distance in from either the top + * or bottom pixel expanded edge. */ if (flip_y) { + float tmp; h = -h; - dst_y_int = floor(y-h); - dst_h_int = (int)ceilf(y) - dst_y_int; + dst_y_int = floorf(y-h); + tmp = ceilf(y); + dst_h_int = (int)tmp; + y = tmp - y; + dst_h_int -= dst_y_int; } else { - dst_y_int = floor(y); - y += h; - dst_h_int = (int)ceilf(y) - dst_y_int; + dst_y_int = floorf(y); + y -= (float)dst_y_int; + dst_h_int = (int)ceilf(y + h); } - /* y is the top edge position in floats. We want it to be the - * distance down from the next pixel boundary. */ - y = ceilf(y) - y; DBUG(("Result image: (%d,%d) at (%d,%d) (subpix=%g,%g)\n", dst_w_int, dst_h_int, dst_x_int, dst_y_int, x, y)); diff --git a/draw/draw_simple_scale.c b/draw/draw_simple_scale.c index b3a76565..1329b0e0 100644 --- a/draw/draw_simple_scale.c +++ b/draw/draw_simple_scale.c @@ -1192,15 +1192,13 @@ fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, floa /* Find the destination bbox, width/height, and sub pixel offset, * allowing for whether we're flipping or not. */ - /* Note that the x and y sub pixel offsets here are different. - * The (x,y) position given describes where the bottom left corner - * of the source image should be mapped to (i.e. where (0,h) in image - * space ends up, not the more logical and sane (0,0)). Also there - * are differences in the way we scale horizontally and vertically. - * When scaling rows horizontally, we always read forwards through - * the source, and store either forwards or in reverse as required. - * When scaling vertically, we always store out forwards, but may - * feed source rows in in a different order. + /* The (x,y) position given describes where the top left corner of the + * source image should be mapped to (i.e. where (0,0) in image space ends + * up). Also there are differences in the way we scale horizontally and + * vertically. When scaling rows horizontally, we always read forwards + * through the source, and store either forwards or in reverse as required. + * When scaling vertically, we always store out forwards, but may feed + * source rows in in a different order. * * Consider the image rectangle 'r' to which the image is mapped, * and the (possibly) larger rectangle 'R', given by expanding 'r' to @@ -1218,7 +1216,7 @@ fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, floa { float tmp; w = -w; - dst_x_int = floor(x-w); + dst_x_int = floorf(x-w); tmp = ceilf(x); dst_w_int = (int)tmp; x = tmp - x; @@ -1226,27 +1224,31 @@ fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, floa } else { - dst_x_int = floor(x); + dst_x_int = floorf(x); x -= (float)dst_x_int; dst_w_int = (int)ceilf(x + w); } - flip_y = (h < 0); - /* dst_y_int is calculated to be the bottom of the scaled image, but - * y (the sub pixel offset) has to end up being the value at the top. + /* dst_y_int is calculated to be the top of the scaled image, and + * y (the sub_pixel_offset) is the distance in from either the top + * or bottom pixel expanded edge. */ + flip_y = (h < 0); if (flip_y) { + float tmp; h = -h; - dst_y_int = floor(y-h); - dst_h_int = (int)ceilf(y) - dst_y_int; - } else { - dst_y_int = floor(y); - y += h; - dst_h_int = (int)ceilf(y) - dst_y_int; + dst_y_int = floorf(y-h); + tmp = ceilf(y); + dst_h_int = (int)tmp; + y = tmp - y; + dst_h_int -= dst_y_int; + } + else + { + dst_y_int = floorf(y); + y -= (float)dst_y_int; + dst_h_int = (int)ceilf(y + h); } - /* y is the top edge position in floats. We want it to be the - * distance down from the next pixel boundary. */ - y = ceilf(y) - y; DBUG(("Result image: (%d,%d) at (%d,%d) (subpix=%g,%g)\n", dst_w_int, dst_h_int, dst_x_int, dst_y_int, x, y)); -- cgit v1.2.3