summaryrefslogtreecommitdiff
path: root/draw/draw_scale.c
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2011-08-02 14:06:18 +0100
committerRobin Watts <Robin.Watts@artifex.com>2011-08-02 14:06:18 +0100
commitb076818f88a3ab152897cd2e65c95cef9afb471f (patch)
tree6ecf8bed38034686abb75cea267d47dc13fe0ada /draw/draw_scale.c
parent332b2aed1f1f17bdcafdffe2b9f773e00d7e6a0d (diff)
downloadmupdf-b076818f88a3ab152897cd2e65c95cef9afb471f.tar.xz
Another attempt to fix bug 691629.
To solve bug 691629 we need to ensure that the scaling weights for every pixel in a gridfitted image sum to 256. I had attempted to do that by enabling the 'WRAP' code, but this has the effect of adding too much bias to the outlying source pixels, resulting in thickened serifs etc. A better fix is to extend the code that is already present to check the weights for validity. If an image pixel is completely covered, then force the weights to 256 by adjusting the largest weight. This still skews the output slightly but it's a much less visible result.
Diffstat (limited to 'draw/draw_scale.c')
-rw-r--r--draw/draw_scale.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/draw/draw_scale.c b/draw/draw_scale.c
index 6bf741ca..427512ce 100644
--- a/draw/draw_scale.c
+++ b/draw/draw_scale.c
@@ -16,12 +16,6 @@ and then positioning it at (frac(x),frac(y)).
*/
#define SINGLE_PIXEL_SPECIALS
-/* It's important that we count contributions carefully as they approach the
- * edges, otherwise we end up with weights in the outside pixels of
- * grid-fitted images that don't sum to 256, and hence get lines across the
- * page. See bug #691629. */
-#define WRAP
-
#ifdef DEBUG_SCALING
#ifdef WIN32
#include <windows.h>
@@ -453,8 +447,12 @@ reorder_weights(fz_weights *weights, int j, int src_w)
}
}
+/* Due to rounding and edge effects, the sums for the weights sometimes don't
+ * add up to 256. This causes visible rendering effects. Therefore, we take
+ * pains to ensure that they 1) never exceed 256, and 2) add up to exactly
+ * 256 for all pixels that are completely covered. See bug #691629. */
static void
-check_weights(fz_weights *weights, int j, int w)
+check_weights(fz_weights *weights, int j, int w, float x, float wf)
{
int idx, len;
int sum = 0;
@@ -476,8 +474,18 @@ check_weights(fz_weights *weights, int j, int w)
maxidx = idx;
}
}
+ /* If we aren't the first or last pixel, OR if the sum is too big
+ * then adjust it. */
if (((j != 0) && (j != w-1)) || (sum > 256))
weights->index[maxidx-1] += 256-sum;
+ /* Otherwise, if we are the first pixel, and it's fully covered, then
+ * adjust it. */
+ else if ((j == 0) && (x < 0.0001F) && (sum != 256))
+ weights->index[maxidx-1] += 256-sum;
+ /* Finally, if we are the last pixel, and it's fully covered, then
+ * adjust it. */
+ else if ((j == w-1) && ((float)w-wf < 0.0001F) && (sum != 256))
+ weights->index[maxidx-1] += 256-sum;
DBUG(("total weight %d = %d\n", j, sum));
}
@@ -519,7 +527,7 @@ make_weights(int src_w, float x, float dst_w, fz_scale_filter *filter, int verti
{
add_weight(weights, j, l, filter, x, F, G, src_w, dst_w);
}
- check_weights(weights, j, dst_w_int);
+ check_weights(weights, j, dst_w_int, x, dst_w);
if (vertical)
{
reorder_weights(weights, j, src_w);