1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 23:47:45 +00:00

LibGfx: Add abstraction to load BitmapFont from a FixedMemoryStream

We'll use this to load from a Core::Resource in a later commit.
This commit is contained in:
Andrew Kaster 2023-10-17 11:52:31 -06:00 committed by Andrew Kaster
parent a4c7d9a374
commit 897f4d05eb
2 changed files with 13 additions and 6 deletions

View file

@ -188,9 +188,9 @@ BitmapFont::~BitmapFont()
}
}
ErrorOr<NonnullRefPtr<BitmapFont>> BitmapFont::try_load_from_mapped_file(NonnullOwnPtr<Core::MappedFile> mapped_file)
ErrorOr<NonnullRefPtr<BitmapFont>> BitmapFont::try_load_from_stream(FixedMemoryStream& stream)
{
auto& header = *TRY(mapped_file->read_in_place<FontFileHeader const>());
auto& header = *TRY(stream.read_in_place<FontFileHeader const>());
if (memcmp(header.magic, "!Fnt", 4))
return Error::from_string_literal("Gfx::BitmapFont::load_from_memory: Incompatible header");
if (header.name[sizeof(header.name) - 1] != '\0')
@ -204,23 +204,29 @@ ErrorOr<NonnullRefPtr<BitmapFont>> BitmapFont::try_load_from_mapped_file(Nonnull
// FIXME: These ReadonlyFoo -> Foo casts are awkward, and only needed because BitmapFont is
// sometimes editable and sometimes not. Splitting it into editable/non-editable classes
// would make this a lot cleaner.
ReadonlyBytes readonly_range_mask = TRY(mapped_file->read_in_place<u8 const>(header.range_mask_size));
ReadonlyBytes readonly_range_mask = TRY(stream.read_in_place<u8 const>(header.range_mask_size));
Bytes range_mask { const_cast<u8*>(readonly_range_mask.data()), readonly_range_mask.size() };
for (size_t i = 0; i < header.range_mask_size; ++i)
glyph_count += 256 * popcount(range_mask[i]);
ReadonlyBytes readonly_rows = TRY(mapped_file->read_in_place<u8 const>(glyph_count * bytes_per_glyph));
ReadonlyBytes readonly_rows = TRY(stream.read_in_place<u8 const>(glyph_count * bytes_per_glyph));
Bytes rows { const_cast<u8*>(readonly_rows.data()), readonly_rows.size() };
ReadonlySpan<u8> readonly_widths = TRY(mapped_file->read_in_place<u8 const>(glyph_count));
ReadonlySpan<u8> readonly_widths = TRY(stream.read_in_place<u8 const>(glyph_count));
Span<u8> widths { const_cast<u8*>(readonly_widths.data()), readonly_widths.size() };
if (!mapped_file->is_eof())
if (!stream.is_eof())
return Error::from_string_literal("Gfx::BitmapFont::load_from_memory: Trailing data in file");
auto name = TRY(String::from_utf8(ReadonlyBytes { header.name, strlen(header.name) }));
auto family = TRY(String::from_utf8(ReadonlyBytes { header.family, strlen(header.family) }));
auto font = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) BitmapFont(move(name), move(family), rows, widths, !header.is_variable_width, header.glyph_width, header.glyph_height, header.glyph_spacing, range_mask, header.baseline, header.mean_line, header.presentation_size, header.weight, header.slope)));
return font;
}
ErrorOr<NonnullRefPtr<BitmapFont>> BitmapFont::try_load_from_mapped_file(NonnullOwnPtr<Core::MappedFile> mapped_file)
{
auto font = TRY(try_load_from_stream(*mapped_file));
font->m_mapped_file = move(mapped_file);
return font;
}