mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:17:34 +00:00
FontEditor: Improve error handling opening, saving and editing fonts
Adds fallible functions for opening and saving fonts and cutting and copying selections. FontEditor now falls back on a guaranteed default BitmapFont on startup. Fixes crashing on start when the default system font is set to TrueType.
This commit is contained in:
parent
e9a150c87c
commit
807bd6da6c
3 changed files with 35 additions and 40 deletions
|
@ -118,14 +118,15 @@ ErrorOr<void> MainWidget::create_actions()
|
||||||
Optional<String> open_path = GUI::FilePicker::get_open_filepath(window(), {}, "/res/fonts/"sv);
|
Optional<String> open_path = GUI::FilePicker::get_open_filepath(window(), {}, "/res/fonts/"sv);
|
||||||
if (!open_path.has_value())
|
if (!open_path.has_value())
|
||||||
return;
|
return;
|
||||||
open_file(open_path.value());
|
if (auto result = open_file(open_path.value()); result.is_error())
|
||||||
|
show_error("Failed to open font"sv, result.error());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_save_action = GUI::CommonActions::make_save_action([&](auto&) {
|
m_save_action = GUI::CommonActions::make_save_action([&](auto&) {
|
||||||
if (m_path.is_empty())
|
if (m_path.is_empty())
|
||||||
m_save_as_action->activate();
|
return m_save_as_action->activate();
|
||||||
else
|
if (auto result = save_file(m_path); result.is_error())
|
||||||
save_file(m_path);
|
show_error("Failed to save font"sv, result.error());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_save_as_action = GUI::CommonActions::make_save_as_action([&](auto&) {
|
m_save_as_action = GUI::CommonActions::make_save_as_action([&](auto&) {
|
||||||
|
@ -133,15 +134,18 @@ ErrorOr<void> MainWidget::create_actions()
|
||||||
Optional<String> save_path = GUI::FilePicker::get_save_filepath(window(), lexical_path.title(), lexical_path.extension());
|
Optional<String> save_path = GUI::FilePicker::get_save_filepath(window(), lexical_path.title(), lexical_path.extension());
|
||||||
if (!save_path.has_value())
|
if (!save_path.has_value())
|
||||||
return;
|
return;
|
||||||
save_file(save_path.value());
|
if (auto result = save_file(save_path.value()); result.is_error())
|
||||||
|
show_error("Failed to save font"sv, result.error());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_cut_action = GUI::CommonActions::make_cut_action([&](auto&) {
|
m_cut_action = GUI::CommonActions::make_cut_action([&](auto&) {
|
||||||
cut_selected_glyphs();
|
if (auto result = cut_selected_glyphs(); result.is_error())
|
||||||
|
show_error("Failed to cut selection"sv, result.error());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_copy_action = GUI::CommonActions::make_copy_action([&](auto&) {
|
m_copy_action = GUI::CommonActions::make_copy_action([&](auto&) {
|
||||||
copy_selected_glyphs();
|
if (auto result = copy_selected_glyphs(); result.is_error())
|
||||||
|
show_error("Failed to copy selection"sv, result.error());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_paste_action = GUI::CommonActions::make_paste_action([&](auto&) {
|
m_paste_action = GUI::CommonActions::make_paste_action([&](auto&) {
|
||||||
|
@ -667,19 +671,15 @@ ErrorOr<void> MainWidget::initialize_menubar(GUI::Window& window)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWidget::save_file(String const& path)
|
ErrorOr<void> MainWidget::save_file(String const& path)
|
||||||
{
|
{
|
||||||
auto saved_font = m_edited_font->masked_character_set();
|
auto masked_font = TRY(m_edited_font->masked_character_set());
|
||||||
auto ret_val = saved_font->write_to_file(path);
|
TRY(masked_font->write_to_file(path));
|
||||||
if (!ret_val) {
|
|
||||||
GUI::MessageBox::show(window(), "The font file could not be saved."sv, "Save failed"sv, GUI::MessageBox::Type::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_path = path;
|
m_path = path;
|
||||||
m_undo_stack->set_current_unmodified();
|
m_undo_stack->set_current_unmodified();
|
||||||
window()->set_modified(false);
|
window()->set_modified(false);
|
||||||
update_title();
|
update_title();
|
||||||
return true;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::set_show_font_metadata(bool show)
|
void MainWidget::set_show_font_metadata(bool show)
|
||||||
|
@ -698,18 +698,11 @@ void MainWidget::set_show_unicode_blocks(bool show)
|
||||||
m_unicode_block_container->set_visible(m_unicode_blocks);
|
m_unicode_block_container->set_visible(m_unicode_blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWidget::open_file(String const& path)
|
ErrorOr<void> MainWidget::open_file(String const& path)
|
||||||
{
|
{
|
||||||
auto bitmap_font = Gfx::BitmapFont::load_from_file(path);
|
auto unmasked_font = TRY(TRY(Gfx::BitmapFont::try_load_from_file(path))->unmasked_character_set());
|
||||||
if (!bitmap_font) {
|
TRY(initialize(path, move(unmasked_font)));
|
||||||
String message = String::formatted("Couldn't load font: {}\n", path);
|
return {};
|
||||||
GUI::MessageBox::show(window(), message, "Font Editor"sv, GUI::MessageBox::Type::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto new_font = bitmap_font->unmasked_character_set();
|
|
||||||
window()->set_modified(false);
|
|
||||||
MUST(initialize(path, move(new_font)));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::push_undo()
|
void MainWidget::push_undo()
|
||||||
|
@ -880,7 +873,8 @@ void MainWidget::drop_event(GUI::DropEvent& event)
|
||||||
if (!request_close())
|
if (!request_close())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
open_file(urls.first().path());
|
if (auto result = open_file(urls.first().path()); result.is_error())
|
||||||
|
show_error("Failed to load font"sv, result.error());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -896,7 +890,7 @@ void MainWidget::set_scale_and_save(i32 scale)
|
||||||
m_glyph_editor_widget->set_fixed_size(m_glyph_editor_widget->preferred_width(), m_glyph_editor_widget->preferred_height());
|
m_glyph_editor_widget->set_fixed_size(m_glyph_editor_widget->preferred_width(), m_glyph_editor_widget->preferred_height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::copy_selected_glyphs()
|
ErrorOr<void> MainWidget::copy_selected_glyphs()
|
||||||
{
|
{
|
||||||
size_t bytes_per_glyph = Gfx::GlyphBitmap::bytes_per_row() * edited_font().glyph_height();
|
size_t bytes_per_glyph = Gfx::GlyphBitmap::bytes_per_row() * edited_font().glyph_height();
|
||||||
auto selection = m_glyph_map_widget->selection().normalized();
|
auto selection = m_glyph_map_widget->selection().normalized();
|
||||||
|
@ -904,8 +898,8 @@ void MainWidget::copy_selected_glyphs()
|
||||||
auto* widths = m_edited_font->widths() + selection.start();
|
auto* widths = m_edited_font->widths() + selection.start();
|
||||||
|
|
||||||
ByteBuffer buffer;
|
ByteBuffer buffer;
|
||||||
buffer.append(rows, bytes_per_glyph * selection.size());
|
TRY(buffer.try_append(rows, bytes_per_glyph * selection.size()));
|
||||||
buffer.append(widths, selection.size());
|
TRY(buffer.try_append(widths, selection.size()));
|
||||||
|
|
||||||
HashMap<String, String> metadata;
|
HashMap<String, String> metadata;
|
||||||
metadata.set("start", String::number(selection.start()));
|
metadata.set("start", String::number(selection.start()));
|
||||||
|
@ -913,12 +907,15 @@ void MainWidget::copy_selected_glyphs()
|
||||||
metadata.set("width", String::number(edited_font().max_glyph_width()));
|
metadata.set("width", String::number(edited_font().max_glyph_width()));
|
||||||
metadata.set("height", String::number(edited_font().glyph_height()));
|
metadata.set("height", String::number(edited_font().glyph_height()));
|
||||||
GUI::Clipboard::the().set_data(buffer.bytes(), "glyph/x-fonteditor", metadata);
|
GUI::Clipboard::the().set_data(buffer.bytes(), "glyph/x-fonteditor", metadata);
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::cut_selected_glyphs()
|
ErrorOr<void> MainWidget::cut_selected_glyphs()
|
||||||
{
|
{
|
||||||
copy_selected_glyphs();
|
TRY(copy_selected_glyphs());
|
||||||
delete_selected_glyphs();
|
delete_selected_glyphs();
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::paste_glyphs()
|
void MainWidget::paste_glyphs()
|
||||||
|
|
|
@ -37,8 +37,8 @@ public:
|
||||||
ErrorOr<void> initialize(String const& path, RefPtr<Gfx::BitmapFont>&&);
|
ErrorOr<void> initialize(String const& path, RefPtr<Gfx::BitmapFont>&&);
|
||||||
ErrorOr<void> initialize_menubar(GUI::Window&);
|
ErrorOr<void> initialize_menubar(GUI::Window&);
|
||||||
|
|
||||||
bool open_file(String const&);
|
ErrorOr<void> open_file(String const&);
|
||||||
bool save_file(String const&);
|
ErrorOr<void> save_file(String const&);
|
||||||
bool request_close();
|
bool request_close();
|
||||||
void update_title();
|
void update_title();
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ private:
|
||||||
void set_scale(i32);
|
void set_scale(i32);
|
||||||
void set_scale_and_save(i32);
|
void set_scale_and_save(i32);
|
||||||
|
|
||||||
void copy_selected_glyphs();
|
ErrorOr<void> copy_selected_glyphs();
|
||||||
void cut_selected_glyphs();
|
ErrorOr<void> cut_selected_glyphs();
|
||||||
void paste_glyphs();
|
void paste_glyphs();
|
||||||
void delete_selected_glyphs();
|
void delete_selected_glyphs();
|
||||||
|
|
||||||
|
|
|
@ -46,11 +46,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
TRY(font_editor->initialize_menubar(*window));
|
TRY(font_editor->initialize_menubar(*window));
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
auto success = font_editor->open_file(path);
|
TRY(font_editor->open_file(path));
|
||||||
if (!success)
|
|
||||||
return 1;
|
|
||||||
} else {
|
} else {
|
||||||
auto mutable_font = static_ptr_cast<Gfx::BitmapFont>(Gfx::FontDatabase::default_font().clone())->unmasked_character_set();
|
auto mutable_font = TRY(TRY(Gfx::BitmapFont::try_load_from_file("/res/fonts/KaticaRegular10.font"))->unmasked_character_set());
|
||||||
TRY(font_editor->initialize({}, move(mutable_font)));
|
TRY(font_editor->initialize({}, move(mutable_font)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue