mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 14:57:35 +00:00
LibGfx: Increase bit-width of variables used in do_draw_scaled_bitmap
To avoid expensive floating point operations the values are put in the upper half of an integer which is then used for calculations. When the src_rect is sufficiently large (when, say, PixelPaint is zoomed in x100), the precision provided by this strategy with regular 32-bit-long ints is no longer enough. This patch changes the used types to i64, which are 64 bits wide and the shifting is increased to 32 bits. On the 32-bit-arch a i64 doesn't fit in a single register anymore but it's probably okay to trust the compiler to do clever stuff around this issue.
This commit is contained in:
parent
d7578ddebb
commit
de0791b0a1
1 changed files with 7 additions and 6 deletions
|
@ -1088,16 +1088,17 @@ ALWAYS_INLINE static void do_draw_scaled_bitmap(Gfx::Bitmap& target, const IntRe
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_opacity = opacity != 1.0f;
|
bool has_opacity = opacity != 1.0f;
|
||||||
int hscale = (src_rect.width() * (1 << 16)) / dst_rect.width();
|
i64 shift = (i64)1 << 32;
|
||||||
int vscale = (src_rect.height() * (1 << 16)) / dst_rect.height();
|
i64 hscale = (src_rect.width() * shift) / dst_rect.width();
|
||||||
int src_left = src_rect.left() * (1 << 16);
|
i64 vscale = (src_rect.height() * shift) / dst_rect.height();
|
||||||
int src_top = src_rect.top() * (1 << 16);
|
i64 src_left = src_rect.left() * shift;
|
||||||
|
i64 src_top = src_rect.top() * shift;
|
||||||
|
|
||||||
for (int y = clipped_rect.top(); y <= clipped_rect.bottom(); ++y) {
|
for (int y = clipped_rect.top(); y <= clipped_rect.bottom(); ++y) {
|
||||||
auto* scanline = (Color*)target.scanline(y);
|
auto* scanline = (Color*)target.scanline(y);
|
||||||
for (int x = clipped_rect.left(); x <= clipped_rect.right(); ++x) {
|
for (int x = clipped_rect.left(); x <= clipped_rect.right(); ++x) {
|
||||||
auto scaled_x = ((x - dst_rect.x()) * hscale + src_left) >> 16;
|
auto scaled_x = ((x - dst_rect.x()) * hscale + src_left) >> 32;
|
||||||
auto scaled_y = ((y - dst_rect.y()) * vscale + src_top) >> 16;
|
auto scaled_y = ((y - dst_rect.y()) * vscale + src_top) >> 32;
|
||||||
auto src_pixel = get_pixel(source, scaled_x, scaled_y);
|
auto src_pixel = get_pixel(source, scaled_x, scaled_y);
|
||||||
if (has_opacity)
|
if (has_opacity)
|
||||||
src_pixel.set_alpha(src_pixel.alpha() * opacity);
|
src_pixel.set_alpha(src_pixel.alpha() * opacity);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue