Serenity Operating System
1/*
2 * Copyright (c) 2020, the SerenityOS developers.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include "MultiScaleBitmaps.h"
8#include "Screen.h"
9
10namespace WindowServer {
11
12Gfx::Bitmap const& MultiScaleBitmaps::bitmap(int scale_factor) const
13{
14 auto it = m_bitmaps.find(scale_factor);
15 if (it == m_bitmaps.end()) {
16 it = m_bitmaps.find(1);
17 if (it == m_bitmaps.end())
18 it = m_bitmaps.begin();
19 }
20 // We better found *something*
21 if (it == m_bitmaps.end()) {
22 dbgln("Could not find any bitmap in this MultiScaleBitmaps");
23 VERIFY_NOT_REACHED();
24 }
25 return it->value;
26}
27
28Gfx::Bitmap const* MultiScaleBitmaps::find_bitmap(int scale_factor) const
29{
30 auto it = m_bitmaps.find(scale_factor);
31 return it != m_bitmaps.end() ? it->value.ptr() : nullptr;
32}
33
34RefPtr<MultiScaleBitmaps> MultiScaleBitmaps::create_empty()
35{
36 return adopt_ref(*new MultiScaleBitmaps());
37}
38
39RefPtr<MultiScaleBitmaps> MultiScaleBitmaps::create(StringView filename, StringView default_filename)
40{
41 auto per_scale_bitmap = adopt_ref(*new MultiScaleBitmaps());
42 if (per_scale_bitmap->load(filename, default_filename))
43 return per_scale_bitmap;
44 return {};
45}
46
47bool MultiScaleBitmaps::load(StringView filename, StringView default_filename)
48{
49 Optional<Gfx::BitmapFormat> bitmap_format;
50 bool did_load_any = false;
51
52 m_bitmaps.clear(); // If we're reloading the bitmaps get rid of the old ones
53
54 auto add_bitmap = [&](StringView path, int scale_factor) {
55 auto bitmap_or_error = Gfx::Bitmap::load_from_file(path, scale_factor);
56 if (bitmap_or_error.is_error())
57 return;
58 auto bitmap = bitmap_or_error.release_value_but_fixme_should_propagate_errors();
59 auto bitmap_format = bitmap->format();
60 if (m_format == Gfx::BitmapFormat::Invalid || m_format == bitmap_format) {
61 if (m_format == Gfx::BitmapFormat::Invalid)
62 m_format = bitmap_format;
63
64 did_load_any = true;
65 m_bitmaps.set(scale_factor, move(bitmap));
66 } else {
67 // Gracefully ignore, we have at least one bitmap already
68 dbgln("Bitmap {} (scale {}) has format inconsistent with the other per-scale bitmaps", path, bitmap->scale());
69 }
70 };
71
72 Screen::for_each_scale_factor_in_use([&](int scale_factor) {
73 add_bitmap(filename, scale_factor);
74 return IterationDecision::Continue;
75 });
76 if (!did_load_any && !default_filename.is_null() && !default_filename.is_empty()) {
77 Screen::for_each_scale_factor_in_use([&](int scale_factor) {
78 add_bitmap(default_filename, scale_factor);
79 return IterationDecision::Continue;
80 });
81 }
82 return did_load_any;
83}
84
85void MultiScaleBitmaps::add_bitmap(int scale_factor, NonnullRefPtr<Gfx::Bitmap>&& bitmap)
86{
87 auto bitmap_format = bitmap->format();
88 if (m_format == Gfx::BitmapFormat::Invalid || m_format == bitmap_format) {
89 if (m_format == Gfx::BitmapFormat::Invalid)
90 m_format = bitmap_format;
91 m_bitmaps.set(scale_factor, move(bitmap));
92 } else {
93 dbgln("MultiScaleBitmaps::add_bitmap (scale {}) has format inconsistent with the other per-scale bitmaps", bitmap->scale());
94 VERIFY_NOT_REACHED(); // The caller of this function should have made sure it is consistent!
95 }
96}
97
98}