diff --git a/Userland/Applications/FontEditor/FontEditor.cpp b/Userland/Applications/FontEditor/FontEditor.cpp index 5f6864571d9..73ed91b2d60 100644 --- a/Userland/Applications/FontEditor/FontEditor.cpp +++ b/Userland/Applications/FontEditor/FontEditor.cpp @@ -254,11 +254,9 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr&& m_undo_action = GUI::CommonActions::make_undo_action([&](auto&) { undo(); }); - m_undo_action->set_enabled(false); m_redo_action = GUI::CommonActions::make_redo_action([&](auto&) { redo(); }); - m_redo_action->set_enabled(false); m_open_preview_action = GUI::Action::create("&Preview Font", { Mod_Ctrl, Key_P }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/find.png"), [&](auto&) { if (!m_font_preview_window) m_font_preview_window = create_font_preview_window(*this); @@ -423,6 +421,7 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr&& }; m_glyph_editor_width_spinbox->on_change = [this, update_demo, update_statusbar](int value) { + m_undo_stack->push(make(*m_undo_glyph)); m_edited_font->set_glyph_width(m_glyph_map_widget->selected_glyph(), value); m_glyph_editor_widget->update(); m_glyph_map_widget->update_glyph(m_glyph_map_widget->selected_glyph()); @@ -432,6 +431,7 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr&& }; m_glyph_editor_present_checkbox->on_checked = [this, update_demo, update_statusbar](bool checked) { + m_undo_stack->push(make(*m_undo_glyph)); m_edited_font->set_glyph_width(m_glyph_map_widget->selected_glyph(), checked ? m_edited_font->glyph_fixed_width() : 0); m_glyph_editor_widget->update(); m_glyph_map_widget->update_glyph(m_glyph_map_widget->selected_glyph()); @@ -549,6 +549,8 @@ void FontEditorWidget::initialize(const String& path, RefPtr&& m_redo_action->set_enabled(m_undo_stack->can_redo()); did_modify_font(); }; + m_undo_action->set_enabled(false); + m_redo_action->set_enabled(false); if (on_initialize) on_initialize(); @@ -625,8 +627,18 @@ void FontEditorWidget::undo() if (!m_undo_stack->can_undo()) return; m_undo_stack->undo(); + auto glyph = m_undo_glyph->restored_code_point(); + auto glyph_width = m_undo_glyph->restored_width(); + m_glyph_map_widget->set_selected_glyph(glyph); + m_glyph_map_widget->scroll_to_glyph(glyph); + if (m_edited_font->is_fixed_width()) { + m_glyph_editor_present_checkbox->set_checked(glyph_width > 0, GUI::AllowCallback::No); + } else { + m_glyph_editor_width_spinbox->set_value(glyph_width, GUI::AllowCallback::No); + } + m_edited_font->set_glyph_width(m_glyph_map_widget->selected_glyph(), glyph_width); m_glyph_editor_widget->update(); - m_glyph_map_widget->update(); + m_glyph_map_widget->update_glyph(glyph); if (m_font_preview_window) m_font_preview_window->update(); } @@ -636,8 +648,18 @@ void FontEditorWidget::redo() if (!m_undo_stack->can_redo()) return; m_undo_stack->redo(); + auto glyph = m_undo_glyph->restored_code_point(); + auto glyph_width = m_undo_glyph->restored_width(); + m_glyph_map_widget->set_selected_glyph(glyph); + m_glyph_map_widget->scroll_to_glyph(glyph); + if (m_edited_font->is_fixed_width()) { + m_glyph_editor_present_checkbox->set_checked(glyph_width > 0, GUI::AllowCallback::No); + } else { + m_glyph_editor_width_spinbox->set_value(glyph_width, GUI::AllowCallback::No); + } + m_edited_font->set_glyph_width(m_glyph_map_widget->selected_glyph(), glyph_width); m_glyph_editor_widget->update(); - m_glyph_map_widget->update(); + m_glyph_map_widget->update_glyph(glyph); if (m_font_preview_window) m_font_preview_window->update(); } diff --git a/Userland/Applications/FontEditor/UndoGlyph.h b/Userland/Applications/FontEditor/UndoGlyph.h index 63e571248cb..d5e326107b6 100644 --- a/Userland/Applications/FontEditor/UndoGlyph.h +++ b/Userland/Applications/FontEditor/UndoGlyph.h @@ -21,26 +21,34 @@ public: { auto state = adopt_ref(*new UndoGlyph(m_code_point, *m_font)); auto glyph = font().glyph(m_code_point).glyph_bitmap(); - for (int x = 0; x < glyph.width(); x++) - for (int y = 0; y < glyph.height(); y++) + for (int x = 0; x < font().max_glyph_width(); x++) + for (int y = 0; y < font().glyph_height(); y++) state->m_bits[x][y] = glyph.bit_at(x, y); + state->m_width = glyph.width(); return state; } void restore_state(const UndoGlyph& state) const { auto bitmap = font().glyph(state.m_code_point).glyph_bitmap(); - for (int x = 0; x < bitmap.width(); x++) - for (int y = 0; y < bitmap.height(); y++) + for (int x = 0; x < font().max_glyph_width(); x++) + for (int y = 0; y < font().glyph_height(); y++) bitmap.set_bit_at(x, y, state.m_bits[x][y]); + m_restored_width = state.m_width; + m_restored_code_point = state.m_code_point; } void set_code_point(size_t point) { m_code_point = point; } void set_font(Gfx::BitmapFont& font) { m_font = font; } const Gfx::BitmapFont& font() const { return *m_font; } + u8 restored_width() const { return m_restored_width; } + u32 restored_code_point() const { return m_restored_code_point; } private: size_t m_code_point; RefPtr m_font; u8 m_bits[32][36] = {}; + u8 m_width { 0 }; + mutable u8 m_restored_width { 0 }; + mutable u32 m_restored_code_point { 0 }; }; class GlyphUndoCommand : public GUI::Command {