summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibGfx/Painter.cpp26
-rw-r--r--Userland/Libraries/LibGfx/Painter.h1
2 files changed, 26 insertions, 1 deletions
diff --git a/Userland/Libraries/LibGfx/Painter.cpp b/Userland/Libraries/LibGfx/Painter.cpp
index d6945795b5..a8bfa88be8 100644
--- a/Userland/Libraries/LibGfx/Painter.cpp
+++ b/Userland/Libraries/LibGfx/Painter.cpp
@@ -1100,7 +1100,7 @@ ALWAYS_INLINE static void do_draw_scaled_bitmap(Gfx::Bitmap& target, IntRect con
if (clipped_src_rect.is_empty())
return;
- if constexpr (scaling_mode == Painter::ScalingMode::NearestNeighbor) {
+ if constexpr (scaling_mode == Painter::ScalingMode::NearestNeighbor || scaling_mode == Painter::ScalingMode::SmoothPixels) {
if (dst_rect == clipped_rect && int_src_rect == src_rect && !(dst_rect.width() % int_src_rect.width()) && !(dst_rect.height() % int_src_rect.height())) {
int hfactor = dst_rect.width() / int_src_rect.width();
int vfactor = dst_rect.height() / int_src_rect.height();
@@ -1155,6 +1155,27 @@ ALWAYS_INLINE static void do_draw_scaled_bitmap(Gfx::Bitmap& target, IntRect con
auto bottom = bottom_left.interpolate(bottom_right, x_ratio);
src_pixel = top.interpolate(bottom, y_ratio);
+ } else if constexpr (scaling_mode == Painter::ScalingMode::SmoothPixels) {
+ auto scaled_x1 = clamp(desired_x >> 32, clipped_src_rect.left(), clipped_src_rect.right());
+ auto scaled_x0 = clamp(scaled_x1 - 1, clipped_src_rect.left(), clipped_src_rect.right());
+ auto scaled_y1 = clamp(desired_y >> 32, clipped_src_rect.top(), clipped_src_rect.bottom());
+ auto scaled_y0 = clamp(scaled_y1 - 1, clipped_src_rect.top(), clipped_src_rect.bottom());
+
+ float x_ratio = (desired_x & fractional_mask) / (float)shift;
+ float y_ratio = (desired_y & fractional_mask) / (float)shift;
+
+ float scaled_x_ratio = clamp(x_ratio * dst_rect.width() / (float)src_rect.width(), 0.0f, 1.0f);
+ float scaled_y_ratio = clamp(y_ratio * dst_rect.height() / (float)src_rect.height(), 0.0f, 1.0f);
+
+ auto top_left = get_pixel(source, scaled_x0, scaled_y0);
+ auto top_right = get_pixel(source, scaled_x1, scaled_y0);
+ auto bottom_left = get_pixel(source, scaled_x0, scaled_y1);
+ auto bottom_right = get_pixel(source, scaled_x1, scaled_y1);
+
+ auto top = top_left.interpolate(top_right, scaled_x_ratio);
+ auto bottom = bottom_left.interpolate(bottom_right, scaled_x_ratio);
+
+ src_pixel = top.interpolate(bottom, scaled_y_ratio);
} else {
auto scaled_x = clamp(desired_x >> 32, clipped_src_rect.left(), clipped_src_rect.right());
auto scaled_y = clamp(desired_y >> 32, clipped_src_rect.top(), clipped_src_rect.bottom());
@@ -1179,6 +1200,9 @@ ALWAYS_INLINE static void do_draw_scaled_bitmap(Gfx::Bitmap& target, IntRect con
case Painter::ScalingMode::NearestNeighbor:
do_draw_scaled_bitmap<has_alpha_channel, Painter::ScalingMode::NearestNeighbor>(target, dst_rect, clipped_rect, source, src_rect, get_pixel, opacity);
break;
+ case Painter::ScalingMode::SmoothPixels:
+ do_draw_scaled_bitmap<has_alpha_channel, Painter::ScalingMode::SmoothPixels>(target, dst_rect, clipped_rect, source, src_rect, get_pixel, opacity);
+ break;
case Painter::ScalingMode::BilinearBlend:
do_draw_scaled_bitmap<has_alpha_channel, Painter::ScalingMode::BilinearBlend>(target, dst_rect, clipped_rect, source, src_rect, get_pixel, opacity);
break;
diff --git a/Userland/Libraries/LibGfx/Painter.h b/Userland/Libraries/LibGfx/Painter.h
index 9b5f0012dd..c0e385710d 100644
--- a/Userland/Libraries/LibGfx/Painter.h
+++ b/Userland/Libraries/LibGfx/Painter.h
@@ -36,6 +36,7 @@ public:
enum class ScalingMode {
NearestNeighbor,
+ SmoothPixels,
BilinearBlend,
};