mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-21 02:08:12 +03: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
Notes:
sideshowbarker
2024-07-18 04:19:22 +09:00
Author: https://github.com/TobyAsE Commit: https://github.com/SerenityOS/serenity/commit/de0791b0a1e Pull-request: https://github.com/SerenityOS/serenity/pull/9941 Issue: https://github.com/SerenityOS/serenity/issues/9889 Reviewed-by: https://github.com/FireFox317
@ -1088,16 +1088,17 @@ ALWAYS_INLINE static void do_draw_scaled_bitmap(Gfx::Bitmap& target, const IntRe
|
||||
}
|
||||
|
||||
bool has_opacity = opacity != 1.0f;
|
||||
int hscale = (src_rect.width() * (1 << 16)) / dst_rect.width();
|
||||
int vscale = (src_rect.height() * (1 << 16)) / dst_rect.height();
|
||||
int src_left = src_rect.left() * (1 << 16);
|
||||
int src_top = src_rect.top() * (1 << 16);
|
||||
i64 shift = (i64)1 << 32;
|
||||
i64 hscale = (src_rect.width() * shift) / dst_rect.width();
|
||||
i64 vscale = (src_rect.height() * shift) / dst_rect.height();
|
||||
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) {
|
||||
auto* scanline = (Color*)target.scanline(y);
|
||||
for (int x = clipped_rect.left(); x <= clipped_rect.right(); ++x) {
|
||||
auto scaled_x = ((x - dst_rect.x()) * hscale + src_left) >> 16;
|
||||
auto scaled_y = ((y - dst_rect.y()) * vscale + src_top) >> 16;
|
||||
auto scaled_x = ((x - dst_rect.x()) * hscale + src_left) >> 32;
|
||||
auto scaled_y = ((y - dst_rect.y()) * vscale + src_top) >> 32;
|
||||
auto src_pixel = get_pixel(source, scaled_x, scaled_y);
|
||||
if (has_opacity)
|
||||
src_pixel.set_alpha(src_pixel.alpha() * opacity);
|
||||
|
Loading…
Reference in New Issue
Block a user