1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:38:11 +00:00
serenity/Userland/Services/WindowServer/MultiScaleBitmaps.cpp
Tom 61af9d882e 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.
2021-06-20 14:57:26 +02:00

70 lines
2.2 KiB
C++

/*
* Copyright (c) 2020, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "MultiScaleBitmaps.h"
#include "Screen.h"
namespace WindowServer {
const Gfx::Bitmap& MultiScaleBitmaps::bitmap(int scale_factor) const
{
auto it = m_bitmaps.find(scale_factor);
if (it == m_bitmaps.end()) {
it = m_bitmaps.find(1);
if (it == m_bitmaps.end())
it = m_bitmaps.begin();
}
// We better found *something*
if (it == m_bitmaps.end()) {
dbgln("Could not find any bitmap in this MultiScaleBitmaps");
VERIFY_NOT_REACHED();
}
return it->value;
}
RefPtr<MultiScaleBitmaps> MultiScaleBitmaps::create(StringView const& filename, StringView const& default_filename)
{
auto per_scale_bitmap = adopt_ref(*new MultiScaleBitmaps());
if (per_scale_bitmap->load(filename, default_filename))
return per_scale_bitmap;
return {};
}
bool MultiScaleBitmaps::load(StringView const& filename, StringView const& default_filename)
{
Optional<Gfx::BitmapFormat> bitmap_format;
bool did_load_any = false;
auto add_bitmap = [&](StringView const& path, int scale_factor) {
auto bitmap = Gfx::Bitmap::load_from_file(path, scale_factor);
if (bitmap) {
auto bitmap_format = bitmap->format();
if (m_format == Gfx::BitmapFormat::Invalid || m_format == bitmap_format) {
if (m_format == Gfx::BitmapFormat::Invalid)
m_format = bitmap_format;
did_load_any = true;
m_bitmaps.set(scale_factor, bitmap.release_nonnull());
} else {
dbgln("Bitmap {} (scale {}) has format inconsistent with the other per-scale bitmaps", path, bitmap->scale());
}
}
};
Screen::for_each_scale_factor_in_use([&](int scale_factor) {
add_bitmap(filename, scale_factor);
return IterationDecision::Continue;
});
if (!did_load_any && !default_filename.is_null() && !default_filename.is_empty()) {
Screen::for_each_scale_factor_in_use([&](int scale_factor) {
add_bitmap(default_filename, scale_factor);
return IterationDecision::Continue;
});
}
return did_load_any;
}
}