diff options
Diffstat (limited to 'draw')
-rw-r--r-- | draw/imagesmooth.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/draw/imagesmooth.c b/draw/imagesmooth.c index 67b5f481..e34c07b2 100644 --- a/draw/imagesmooth.c +++ b/draw/imagesmooth.c @@ -1004,12 +1004,15 @@ fz_smoothscalepixmap(fz_pixmap *src, float x, float y, float w, float h) /* 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, due to - * the different 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. + /* 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. * * Consider the image rectange 'r' to which the image is mapped, * and the (possibly) larger rectangle 'R', given by expanding 'r' to @@ -1017,8 +1020,11 @@ fz_smoothscalepixmap(fz_pixmap *src, float x, float y, float w, float h) * * x can either be r.xmin-R.xmin or R.xmax-r.xmax depending on whether * the image is x flipped or not. Whatever happens 0 <= x < 1. - * y is always r.ymin - R.ymin. + * y is always R.ymax - r.ymax. */ + /* dst_x_int is calculated to be the left of the scaled image, and + * x (the sub_pixel_offset) is the distance in from either the left + * or right pixel expanded edge. */ flip_x = (w < 0); if (flip_x) { @@ -1037,14 +1043,22 @@ fz_smoothscalepixmap(fz_pixmap *src, float x, float y, float w, float h) 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. + */ if (flip_y) { h = -h; - y -= 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 = floor(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)); |