summaryrefslogtreecommitdiff
path: root/draw
diff options
context:
space:
mode:
Diffstat (limited to 'draw')
-rw-r--r--draw/imagesmooth.c36
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));