mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:37:46 +00:00
WindowServer: Load multiple scaled versions of Bitmaps and Cursors
This enables rendering of mixed-scale screen layouts with e.g. high resolution cursors and window button icons on high-dpi screens while using lower resolution bitmaps on regular screens.
This commit is contained in:
parent
aa15bf81e4
commit
61af9d882e
15 changed files with 269 additions and 99 deletions
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <AK/LexicalPath.h>
|
||||
#include <WindowServer/Cursor.h>
|
||||
#include <WindowServer/Screen.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
|
||||
namespace WindowServer {
|
||||
|
@ -77,6 +78,7 @@ CursorParams CursorParams::parse_from_filename(const StringView& cursor_path, co
|
|||
return { default_hotspot };
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
@ -93,37 +95,66 @@ CursorParams CursorParams::constrained(const Gfx::Bitmap& bitmap) const
|
|||
}
|
||||
}
|
||||
if (params.m_have_hotspot)
|
||||
params.m_hotspot = params.m_hotspot.constrained(rect);
|
||||
params.m_hotspot.constrain(rect);
|
||||
else
|
||||
params.m_hotspot = rect.center();
|
||||
return params;
|
||||
}
|
||||
|
||||
Cursor::Cursor(NonnullRefPtr<Gfx::Bitmap>&& bitmap, const CursorParams& cursor_params)
|
||||
: m_bitmap(move(bitmap))
|
||||
, m_params(cursor_params.constrained(*m_bitmap))
|
||||
, m_rect(m_bitmap->rect())
|
||||
Cursor::Cursor(NonnullRefPtr<Gfx::Bitmap>&& bitmap, int scale_factor, const CursorParams& cursor_params)
|
||||
: m_params(cursor_params.constrained(*bitmap))
|
||||
, m_rect(bitmap->rect())
|
||||
{
|
||||
m_bitmaps.set(scale_factor, move(bitmap));
|
||||
if (m_params.frames() > 1) {
|
||||
VERIFY(m_rect.width() % m_params.frames() == 0);
|
||||
m_rect.set_width(m_rect.width() / m_params.frames());
|
||||
}
|
||||
}
|
||||
|
||||
Cursor::~Cursor()
|
||||
{
|
||||
}
|
||||
|
||||
NonnullRefPtr<Cursor> Cursor::create(NonnullRefPtr<Gfx::Bitmap>&& bitmap)
|
||||
NonnullRefPtr<Cursor> Cursor::create(NonnullRefPtr<Gfx::Bitmap>&& bitmap, int scale_factor)
|
||||
{
|
||||
auto hotspot = bitmap->rect().center();
|
||||
return adopt_ref(*new Cursor(move(bitmap), CursorParams(hotspot)));
|
||||
return adopt_ref(*new Cursor(move(bitmap), scale_factor, CursorParams(hotspot)));
|
||||
}
|
||||
|
||||
NonnullRefPtr<Cursor> Cursor::create(NonnullRefPtr<Gfx::Bitmap>&& bitmap, const StringView& filename)
|
||||
RefPtr<Cursor> Cursor::create(const StringView& filename, const StringView& default_filename)
|
||||
{
|
||||
auto default_hotspot = bitmap->rect().center();
|
||||
return adopt_ref(*new Cursor(move(bitmap), CursorParams::parse_from_filename(filename, default_hotspot)));
|
||||
auto cursor = adopt_ref(*new Cursor());
|
||||
if (cursor->load(filename, default_filename))
|
||||
return cursor;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool Cursor::load(const StringView& filename, const StringView& default_filename)
|
||||
{
|
||||
bool did_load_any = false;
|
||||
bool first = true;
|
||||
|
||||
auto load_bitmap = [&](const StringView& path, int scale_factor) {
|
||||
auto bitmap = Gfx::Bitmap::load_from_file(path, scale_factor);
|
||||
if (bitmap) {
|
||||
did_load_any = true;
|
||||
if (first) {
|
||||
m_params = CursorParams::parse_from_filename(filename, bitmap->rect().center());
|
||||
m_rect = bitmap->rect();
|
||||
first = false;
|
||||
}
|
||||
m_bitmaps.set(scale_factor, bitmap.release_nonnull());
|
||||
}
|
||||
};
|
||||
|
||||
Screen::for_each_scale_factor_in_use([&](int scale_factor) {
|
||||
load_bitmap(filename, scale_factor);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
if (!did_load_any) {
|
||||
Screen::for_each_scale_factor_in_use([&](int scale_factor) {
|
||||
load_bitmap(default_filename, scale_factor);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
return did_load_any;
|
||||
}
|
||||
|
||||
RefPtr<Cursor> Cursor::create(Gfx::StandardCursor standard_cursor)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue