Index: app/display/gimpdisplayshell-render.c =================================================================== --- app/display/gimpdisplayshell-render.c (revision 23613) +++ app/display/gimpdisplayshell-render.c (working copy) @@ -78,8 +78,11 @@ struct _RenderInfo gint dest_bpp; gint dest_bpl; gint dest_width; + + /* Bresenham helpers */ + gint dest_inc; /* amount to increment for each dest. pixel */ + gint src_dec; /* amount to decrement for each source pixel */ gint xstart; - gint xdelta; gint yfraction; }; @@ -879,17 +882,15 @@ gimp_display_shell_render_info_scale (Re info->scalex = scale_x; info->scaley = scale_y; - info->src_x = (gdouble) info->x / info->scalex; info->src_y = (gdouble) info->y / info->scaley; - info->xdelta = (1 << 16) * (1.0 / info->scalex); - info->xstart = (gdouble) info->x / info->scalex * 65536.0; + info->dest_inc = tile_manager_width (src_tiles); + info->src_dec = ceil (tile_manager_width (src_tiles) * info->scalex); - /* avoid aliasing errors when zooming in */ - if (info->scalex > 1) - { - info->xstart += info->xdelta / 2; - } + info->xstart = info->dest_inc * info->x + info->dest_inc/2; + + info->src_x = info->xstart / info->src_dec; + info->xstart = info->xstart % info->src_dec; } static const guint * @@ -1048,11 +1049,10 @@ render_image_tile_fault (RenderInfo *inf sample pair */ gint tilexL; /* the current x-tile indice used for the left sample pair */ - gint xdelta; /* fixed point amount to increment source x - coordinas for each horizontal integer destination - pixel increment */ gint bpp; glong x; + gint src_x; + gint skipped; gint footprint_x; gint footprint_y; @@ -1109,7 +1109,7 @@ render_image_tile_fault (RenderInfo *inf } footprint_y = (1.0 / info->scaley) * 256; - footprint_x = (1.0 / info->scalex) * 256; + footprint_x = info->dest_inc; foosum = footprint_x * footprint_y; @@ -1241,6 +1241,7 @@ render_image_tile_fault (RenderInfo *inf dest = tile_buf; x = info->xstart; + src_x = info->src_x; width = info->w; @@ -1248,53 +1249,38 @@ render_image_tile_fault (RenderInfo *inf tilex1 = (info->src_x + 1) / TILE_WIDTH; tilexL = (info->src_x - 1) / TILE_WIDTH; - xdelta = info->xdelta; - do { - gint src_x = x >> 16; - gint skipped; - - { - gint dx = (x >> 8) & 0xff; - - if (dx > footprint_x / 2) - left_weight = 0; - else - left_weight = footprint_x / 2 - dx; - - if (0xff - dx > footprint_x / 2) - right_weight = 0; - else - right_weight = footprint_x / 2 - (0xff - dx); - - center_weight = footprint_x - left_weight - right_weight; + left_weight = MAX (footprint_x / 2 - x, 0); + right_weight = MAX (x - footprint_x / 2, 0); + center_weight = footprint_x - left_weight - right_weight; - if (src_x + 1 >= source_width) + if (src_x + 1 >= source_width) { src[2]=src[1]; src[5]=src[4]; src[8]=src[7]; } - if (info->src_y + 1 >= source_height) + if (info->src_y + 1 >= source_height) { src[6]=src[3]; src[7]=src[4]; src[8]=src[5]; } - box_filter (left_weight, center_weight, right_weight, - top_weight, middle_weight, bottom_weight, foosum, - src, dest, bpp); - } + box_filter (left_weight, center_weight, right_weight, + top_weight, middle_weight, bottom_weight, foosum, + src, dest, bpp); + dest[0]=0xff; dest += bpp; - x += xdelta; - - skipped = (x >> 16) - src_x; + x += info->dest_inc; + skipped = x / info->src_dec; if (skipped) { + x -= skipped * info->src_dec; + /* if we changed integer source pixel coordinates in the source * buffer, make sure the src pointers (and their backing tiles) are * correct @@ -1512,8 +1498,8 @@ render_image_tile_fault_nearest (RenderI guchar *dest; gint width; gint tilex; - gint xdelta; gint bpp; + gint src_x; glong x; tile = tile_manager_get_tile (info->src_tiles, @@ -1530,14 +1516,12 @@ render_image_tile_fault_nearest (RenderI width = info->w; + src_x = info->src_x; tilex = info->src_x / TILE_WIDTH; - xdelta = info->xdelta; - do { const guchar *s = src; - gint src_x = x >> 16; gint skipped; switch (bpp) @@ -1552,14 +1536,14 @@ render_image_tile_fault_nearest (RenderI *dest++ = *s++; } - x += xdelta; - - skipped = (x >> 16) - src_x; + x += info->dest_inc; + skipped = x / info->src_dec; if (skipped) { src += skipped * bpp; src_x += skipped; + x -= skipped * info->src_dec; if ((src_x / TILE_WIDTH) != tilex) { @@ -1601,11 +1585,10 @@ render_image_tile_fault_one_row (RenderI sample pair */ gint tilexL; /* the current x-tile indice used for the left sample pair */ - gint xdelta; /* fixed point amount to increment source x - coordinas for each horizontal integer destination - pixel increment */ gint bpp; glong x; + gint src_x; + gint skipped; guint footprint_x; guint footprint_y; @@ -1624,7 +1607,7 @@ render_image_tile_fault_one_row (RenderI source_width = tile_manager_width (info->src_tiles); footprint_y = (1.0/info->scaley) * 256; - footprint_x = (1.0/info->scalex) * 256; + footprint_x = info->dest_inc; foosum = footprint_x * footprint_y; { @@ -1710,6 +1693,7 @@ render_image_tile_fault_one_row (RenderI dest = tile_buf; x = info->xstart; + src_x = info->src_x; width = info->w; @@ -1717,47 +1701,31 @@ render_image_tile_fault_one_row (RenderI tilex1 = (info->src_x + 1) / TILE_WIDTH; tilexL = (info->src_x - 1) / TILE_WIDTH; - xdelta = info->xdelta; - do { - gint src_x = x >> 16; - gint skipped; - - { - gint dx = (x >> 8) & 0xff; - - if (dx > footprint_x / 2) - left_weight = 0; - else - left_weight = footprint_x / 2 - dx; - - if (0xff - dx > footprint_x / 2) - right_weight = 0; - else - right_weight = footprint_x / 2 - (0xff - dx); - - center_weight = footprint_x - left_weight - right_weight; - - if (src_x + 1 >= source_width) - { - src[2]=src[1]; - src[5]=src[4]; - src[8]=src[7]; - } - box_filter (left_weight, center_weight, right_weight, - top_weight, middle_weight, bottom_weight, foosum, - src, dest, bpp); - } + left_weight = MAX (footprint_x / 2 - x, 0); + right_weight = MAX (x - footprint_x / 2, 0); + center_weight = footprint_x - left_weight - right_weight; + + if (src_x + 1 >= source_width) + { + src[2]=src[1]; + src[5]=src[4]; + src[8]=src[7]; + } + box_filter (left_weight, center_weight, right_weight, + top_weight, middle_weight, bottom_weight, foosum, + src, dest, bpp); dest += bpp; - x += xdelta; - - skipped = (x >> 16) - src_x; + x += info->dest_inc; + skipped = x / info->src_dec; if (skipped) { + x -= skipped * info->src_dec; + /* if we changed integer source pixel coordinates in the source * buffer, make sure the src pointers (and their backing tiles) are * correct