Everywhere: Use Rect::scaled_to_fit_within() and Rect::scaled_to_cover()

This is a slight behavior change in some places. Some places did

    (r.size().to_type<float>() * max(scale_x, scale_y)).to_type<int>();

After this commit, the semantics are now like `(...).to_rounded<int>()`,
that is we no longer sometimes omit a column or row in the fitted
direction.
This commit is contained in:
Nico Weber committed 2026-07-26 10:13:47 -04:00
1 parent 35d63ed139
commit 44d5e571df
7 files changed
+21 -49

No files matched your search

+13 -15
View File
@@ -6,6 +6,7 @@
#import "View.h"
#include <LibGfx/Rect.h>
#include <LibMedia/PlaybackManager.h>
@interface View ()
@@ -16,6 +17,16 @@
}
@end
static Gfx::FloatRect gfx_rect_from_ns_rect(NSRect rect)
{
return Gfx::FloatRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
}
static NSRect ns_rect_from_gfx_rect(Gfx::FloatRect rect)
{
return NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
}
static NSBitmapImageRep* ns_from_gfx(RefPtr<Gfx::Bitmap> bitmap_p)
{
if (!bitmap_p)
@@ -106,22 +117,9 @@ static NSBitmapImageRep* ns_from_gfx(RefPtr<Gfx::Bitmap> bitmap_p)
if (!_currentFrame)
return;
NSSize view_size = self.bounds.size;
NSSize image_size = [_currentFrame size];
CGFloat view_aspect = view_size.width / view_size.height;
CGFloat image_aspect = image_size.width / image_size.height;
NSRect destination_rect;
if (image_aspect > view_aspect) {
CGFloat height = view_size.width / image_aspect;
destination_rect = NSMakeRect(0, (view_size.height - height) / 2, view_size.width, height);
} else {
CGFloat width = view_size.height * image_aspect;
destination_rect = NSMakeRect((view_size.width - width) / 2, 0, width, view_size.height);
}
[_currentFrame drawInRect:destination_rect];
auto image_rect = gfx_rect_from_ns_rect(NSMakeRect(0, 0, image_size.width, image_size.height));
[_currentFrame drawInRect:ns_rect_from_gfx_rect(image_rect.scaled_to_fit_within(gfx_rect_from_ns_rect(self.bounds)))];
}
@end
@@ -148,10 +148,7 @@ void MonitorWidget::redraw_desktop_if_needed()
painter.draw_scaled_bitmap(m_desktop_bitmap->rect(), *m_wallpaper_bitmap, m_wallpaper_bitmap->rect(), 1.f, Gfx::ScalingMode::BilinearBlend);
} else if (m_desktop_wallpaper_mode == "Fill"sv) {
auto wallpaper_rect = m_wallpaper_bitmap->rect();
auto scale_x = static_cast<float>(m_desktop_bitmap->width()) / wallpaper_rect.width();
auto scale_y = static_cast<float>(m_desktop_bitmap->height()) / wallpaper_rect.height();
auto new_size = (wallpaper_rect.size().to_type<float>() * max(scale_x, scale_y)).to_type<int>();
auto stretched_rect = Gfx::IntRect({}, new_size).centered_within(m_desktop_bitmap->rect());
auto stretched_rect = wallpaper_rect.scaled_to_cover(m_desktop_bitmap->rect());
painter.draw_scaled_bitmap(stretched_rect, *m_wallpaper_bitmap, wallpaper_rect, 1.0f, Gfx::ScalingMode::BilinearBlend);
} else {
VERIFY_NOT_REACHED();
@@ -115,19 +115,8 @@ void PresenterWidget::resize_web_view(Gfx::IntSize const& size)
if (!m_current_presentation)
return;
auto normative_size = m_current_presentation->normative_size().to_type<float>();
float widget_ratio = static_cast<float>(size.width()) / static_cast<float>(size.height());
float wh_ratio = normative_size.width() / normative_size.height();
Gfx::IntRect rect;
if (widget_ratio >= wh_ratio) {
rect.set_width(static_cast<int>(ceilf(static_cast<float>(size.height()) * wh_ratio)));
rect.set_height(size.height());
} else {
float hw_ratio = normative_size.height() / normative_size.width();
rect.set_width(size.width());
rect.set_height(static_cast<int>(ceilf(static_cast<float>(size.width()) * hw_ratio)));
}
auto normative_rect = Gfx::IntRect { {}, m_current_presentation->normative_size() };
auto rect = normative_rect.scaled_to_fit_within({ {}, size });
m_web_view->set_relative_rect(rect.centered_within(this->rect()));
}
@@ -24,15 +24,7 @@ void AlbumCoverVisualizationWidget::paint_event(GUI::PaintEvent& event)
auto const& cover = m_file_cover ? m_file_cover : m_album_cover;
if (cover) {
auto album_cover_rect = cover->rect();
auto height_ratio = frame_inner_rect().height() / (float)album_cover_rect.height();
auto width_ratio = frame_inner_rect().width() / (float)album_cover_rect.width();
auto scale = min(height_ratio, width_ratio);
Gfx::IntRect fitted_rect = { 0, 0, (int)(album_cover_rect.width() * scale), (int)(album_cover_rect.height() * scale) };
fitted_rect.center_within(frame_inner_rect());
auto fitted_rect = cover->rect().scaled_to_fit_within(frame_inner_rect());
painter.draw_scaled_bitmap(fitted_rect, *cover, cover->rect(), 1.0f);
} else {
if (!m_serenity_bg)
@@ -728,8 +728,7 @@ static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> render_thumbnail(StringView path)
auto thumbnail = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, thumbnail_size));
double scale = min(thumbnail_size.width() / (double)bitmap->width(), thumbnail_size.height() / (double)bitmap->height());
auto destination = Gfx::IntRect(0, 0, (int)(bitmap->width() * scale), (int)(bitmap->height() * scale)).centered_within(thumbnail->rect());
auto destination = bitmap->rect().scaled_to_fit_within(thumbnail->rect());
Painter painter(thumbnail);
painter.draw_scaled_bitmap(destination, *bitmap, bitmap->rect(), 1.f, Gfx::ScalingMode::BoxSampling);
+2 -2
View File
@@ -14,8 +14,8 @@ void VectorGraphic::draw_into(Painter& painter, IntRect const& dest, AffineTrans
// Apply the transform then center within destination rectangle (this ignores any translation from the transform):
// This allows you to easily rotate or flip the image before painting.
auto transformed_rect = transform.map(FloatRect { {}, size() });
auto scale = min(float(dest.width()) / transformed_rect.width(), float(dest.height()) / transformed_rect.height());
auto centered = FloatRect { {}, transformed_rect.size().scaled(scale) }.centered_within(dest.to_type<float>());
auto centered = transformed_rect.scaled_to_fit_within(dest.to_type<float>());
auto scale = centered.width() / transformed_rect.width();
auto view_transform = AffineTransform {}
.translate(centered.location())
.multiply(AffineTransform {}.scale(scale, scale))
@@ -864,10 +864,7 @@ void Compositor::update_wallpaper_bitmap()
if (m_wallpaper_mode == WallpaperMode::Fill) {
auto wallpaper_rect = m_wallpaper->rect();
auto scale_x = static_cast<float>(screen.width()) / wallpaper_rect.width();
auto scale_y = static_cast<float>(screen.height()) / wallpaper_rect.height();
auto new_size = (wallpaper_rect.size().to_type<float>() * max(scale_x, scale_y)).to_type<int>();
auto stretched_rect = Gfx::IntRect({}, new_size).centered_within(screen.rect());
auto stretched_rect = wallpaper_rect.scaled_to_cover(screen.rect());
painter.draw_scaled_bitmap(stretched_rect, *m_wallpaper, wallpaper_rect, 1.0f, Gfx::ScalingMode::BilinearBlend);
}