Serenity Operating System
1/*
2 * Copyright (c) 2020, the SerenityOS developers.
3 * Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <AK/Utf8View.h>
9#include <LibGfx/Font/BitmapFont.h>
10#include <LibGfx/Font/FontDatabase.h>
11#include <LibTest/TestCase.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15
16#ifdef AK_OS_SERENITY
17# define TEST_INPUT(x) ("/usr/Tests/LibGfx/test-inputs/" x)
18#else
19# define TEST_INPUT(x) ("test-inputs/" x)
20#endif
21
22TEST_CASE(test_fontdatabase_get_by_name)
23{
24 Gfx::FontDatabase::set_default_fonts_lookup_path(TEST_INPUT(""));
25
26 auto name = "Family 12 400 0"sv;
27 auto& font_database = Gfx::FontDatabase::the();
28 EXPECT(!font_database.get_by_name(name)->name().is_null());
29}
30
31TEST_CASE(test_fontdatabase_get)
32{
33 Gfx::FontDatabase::set_default_fonts_lookup_path(TEST_INPUT(""));
34 auto& font_database = Gfx::FontDatabase::the();
35 EXPECT(!font_database.get("Family", 12, 400, Gfx::FontWidth::Normal, 0)->name().is_null());
36}
37
38TEST_CASE(test_fontdatabase_for_each_font)
39{
40 Gfx::FontDatabase::set_default_fonts_lookup_path(TEST_INPUT(""));
41
42 auto& font_database = Gfx::FontDatabase::the();
43 font_database.for_each_font([&](Gfx::Font const& font) {
44 EXPECT(!font.name().is_null());
45 EXPECT(!font.qualified_name().is_null());
46 EXPECT(!font.family().is_null());
47 EXPECT(font.glyph_count() > 0);
48 });
49}
50
51TEST_CASE(test_clone)
52{
53 u8 glyph_height = 1;
54 u8 glyph_width = 1;
55 auto font = Gfx::BitmapFont::create(glyph_height, glyph_width, true, 256);
56
57 auto new_font = font->clone();
58 EXPECT(!new_font->name().is_null());
59 EXPECT(!new_font->qualified_name().is_null());
60 EXPECT(!new_font->family().is_null());
61 EXPECT(new_font->glyph_count() > 0);
62}
63
64TEST_CASE(test_set_name)
65{
66 u8 glyph_height = 1;
67 u8 glyph_width = 1;
68 auto font = Gfx::BitmapFont::create(glyph_height, glyph_width, true, 256);
69
70 auto name = "my newly created font"sv;
71 font->set_name(name);
72
73 EXPECT(!font->name().is_null());
74 EXPECT(font->name().contains(name));
75}
76
77TEST_CASE(test_set_family)
78{
79 u8 glyph_height = 1;
80 u8 glyph_width = 1;
81 auto font = Gfx::BitmapFont::create(glyph_height, glyph_width, true, 256);
82
83 auto family = "my newly created font family"sv;
84 font->set_family(family);
85
86 EXPECT(!font->family().is_null());
87 EXPECT(font->family().contains(family));
88}
89
90TEST_CASE(test_set_glyph_width)
91{
92 u8 glyph_height = 1;
93 u8 glyph_width = 1;
94 auto font = Gfx::BitmapFont::create(glyph_height, glyph_width, true, 256);
95
96 size_t ch = 123;
97 font->set_glyph_width(ch, glyph_width);
98
99 EXPECT(font->glyph_width(ch) == glyph_width);
100}
101
102TEST_CASE(test_set_glyph_spacing)
103{
104 u8 glyph_height = 1;
105 u8 glyph_width = 1;
106 auto font = Gfx::BitmapFont::create(glyph_height, glyph_width, true, 256);
107
108 u8 glyph_spacing = 8;
109 font->set_glyph_spacing(glyph_spacing);
110
111 EXPECT(font->glyph_spacing() == glyph_spacing);
112}
113
114TEST_CASE(test_width)
115{
116 u8 glyph_height = 1;
117 u8 glyph_width = 1;
118 auto font = Gfx::BitmapFont::create(glyph_height, glyph_width, true, 256);
119
120 EXPECT(font->width("A"sv) == glyph_width);
121}
122
123TEST_CASE(test_glyph_or_emoji_width)
124{
125 u8 glyph_height = 1;
126 u8 glyph_width = 1;
127 auto font = Gfx::BitmapFont::create(glyph_height, glyph_width, true, 256);
128
129 Utf8View view { " "sv };
130 auto it = view.begin();
131
132 EXPECT(font->glyph_or_emoji_width(it));
133}
134
135TEST_CASE(test_load_from_file)
136{
137 auto font = Gfx::BitmapFont::load_from_file(TEST_INPUT("TestFont.font"sv));
138 EXPECT(!font->name().is_null());
139}
140
141TEST_CASE(test_write_to_file)
142{
143 u8 glyph_height = 1;
144 u8 glyph_width = 1;
145 auto font = Gfx::BitmapFont::create(glyph_height, glyph_width, true, 256);
146
147 char path[] = "/tmp/new.font.XXXXXX";
148 EXPECT(mkstemp(path) != -1);
149 EXPECT(!font->write_to_file(path).is_error());
150 unlink(path);
151}
152
153TEST_CASE(test_character_set_masking)
154{
155 auto font = Gfx::BitmapFont::try_load_from_file(TEST_INPUT("TestFont.font"sv));
156 EXPECT(!font.is_error());
157
158 auto unmasked_font = font.value()->unmasked_character_set();
159 EXPECT(!unmasked_font.is_error());
160 EXPECT(unmasked_font.value()->glyph_index(0x0041).value() == 0x0041);
161 EXPECT(unmasked_font.value()->glyph_index(0x0100).value() == 0x0100);
162 EXPECT(unmasked_font.value()->glyph_index(0xFFFD).value() == 0xFFFD);
163
164 auto masked_font = unmasked_font.value()->masked_character_set();
165 EXPECT(!masked_font.is_error());
166 EXPECT(masked_font.value()->glyph_index(0x0041).value() == 0x0041);
167 EXPECT(!masked_font.value()->glyph_index(0x0100).has_value());
168 EXPECT(masked_font.value()->glyph_index(0xFFFD).value() == 0x1FD);
169}