}
static void
+adjust (pixman_vector_t *v, pixman_vector_t *u, pixman_fixed_t adjustment)
+{
+ int delta_v = (adjustment * v->vector[2]) >> 16;
+ int delta_u = (adjustment * u->vector[2]) >> 16;
+
+ v->vector[0] += delta_v;
+ v->vector[1] += delta_v;
+
+ u->vector[0] += delta_u;
+ u->vector[1] += delta_u;
+}
+
+static void
fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
{
uint32_t *bits;
stride = pict->rowstride;
/* reference point is the center of the pixel */
- v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2 - 1;
- v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2 - 1;
+ v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2;
+ v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2;
v.vector[2] = pixman_fixed_1;
/* when using convolution filters or PIXMAN_REPEAT_PAD one might get here without a transform */
unit.vector[2] = 0;
}
+ /* This allows filtering code to pretend that pixels are located at integer coordinates */
+ adjust (&v, &unit, -(pixman_fixed_1 / 2));
+
if (pict->common.filter == PIXMAN_FILTER_NEAREST || pict->common.filter == PIXMAN_FILTER_FAST)
{
+ /* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
+ adjust (&v, &unit, pixman_fixed_1 / 2 - pixman_fixed_e);
+
if (pict->common.repeat == PIXMAN_REPEAT_NORMAL)
{
fbFetchTransformed_Nearest_Normal(pict, width, buffer, mask, maskBits, affine, v, unit);
pict->common.filter == PIXMAN_FILTER_GOOD ||
pict->common.filter == PIXMAN_FILTER_BEST)
{
- /* adjust vector for maximum contribution at 0.5, 0.5 of each texel. */
- v.vector[0] -= v.vector[2] / 2;
- v.vector[1] -= v.vector[2] / 2;
- unit.vector[0] -= unit.vector[2] / 2;
- unit.vector[1] -= unit.vector[2] / 2;
-
if (pict->common.repeat == PIXMAN_REPEAT_NORMAL)
{
fbFetchTransformed_Bilinear_Normal(pict, width, buffer, mask, maskBits, affine, v, unit);
}
else if (pict->common.filter == PIXMAN_FILTER_CONVOLUTION)
{
+ /* Round to closest integer, ensuring that 0.5 rounds to 0, not 1 */
+ adjust (&v, &unit, pixman_fixed_1 / 2 - pixman_fixed_e);
+
fbFetchTransformed_Convolution(pict, width, buffer, mask, maskBits, affine, v, unit);
}