summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthankyouverycool <66646555+thankyouverycool@users.noreply.github.com>2021-09-09 07:41:08 -0400
committerAndreas Kling <kling@serenityos.org>2021-09-19 00:58:59 +0200
commita486415f03771989cb1c5871454a3f47e0256824 (patch)
tree68f0196ade1b2f4e0e270cfb46b658be55b5b875
parent9bcfdfc03b6c2f8e4b002b4d9002ea81338795bb (diff)
downloadserenity-a486415f03771989cb1c5871454a3f47e0256824.zip
FontEditor: Update editor to handle new font format
The editor now unmasks fonts on load, mapping their glyphs to the complete unicode character set, and masks them upon saving to reduce disk space. This is a naive approach in terms of memory usage and can be improved but whose immediate goal is to allow editing any glyph without concern for range allocation.
-rw-r--r--Userland/Applications/FontEditor/FontEditor.cpp24
-rw-r--r--Userland/Applications/FontEditor/FontEditor.h2
-rw-r--r--Userland/Applications/FontEditor/FontEditorWindow.gml9
-rw-r--r--Userland/Applications/FontEditor/GlyphEditorWidget.cpp16
-rw-r--r--Userland/Applications/FontEditor/GlyphMapWidget.cpp12
-rw-r--r--Userland/Applications/FontEditor/GlyphMapWidget.h3
-rw-r--r--Userland/Applications/FontEditor/NewFontDialog.cpp17
-rw-r--r--Userland/Applications/FontEditor/NewFontDialog.h4
-rw-r--r--Userland/Applications/FontEditor/NewFontDialogPage1.gml25
-rw-r--r--Userland/Applications/FontEditor/main.cpp5
10 files changed, 26 insertions, 91 deletions
diff --git a/Userland/Applications/FontEditor/FontEditor.cpp b/Userland/Applications/FontEditor/FontEditor.cpp
index d98ce12049..17b4f0532a 100644
--- a/Userland/Applications/FontEditor/FontEditor.cpp
+++ b/Userland/Applications/FontEditor/FontEditor.cpp
@@ -119,7 +119,6 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
m_family_textbox = *find_descendant_of_type_named<GUI::TextBox>("family_textbox");
m_presentation_spinbox = *find_descendant_of_type_named<GUI::SpinBox>("presentation_spinbox");
m_weight_combobox = *find_descendant_of_type_named<GUI::ComboBox>("weight_combobox");
- m_type_combobox = *find_descendant_of_type_named<GUI::ComboBox>("type_combobox");
m_spacing_spinbox = *find_descendant_of_type_named<GUI::SpinBox>("spacing_spinbox");
m_mean_line_spinbox = *find_descendant_of_type_named<GUI::SpinBox>("mean_line_spinbox");
m_baseline_spinbox = *find_descendant_of_type_named<GUI::SpinBox>("baseline_spinbox");
@@ -170,7 +169,7 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
if (new_font_wizard->exec() == GUI::Dialog::ExecOK) {
auto metadata = new_font_wizard->new_font_metadata();
- RefPtr<Gfx::BitmapFont> new_font = Gfx::BitmapFont::create(metadata.glyph_height, metadata.glyph_width, metadata.is_fixed_width, metadata.type);
+ RefPtr<Gfx::BitmapFont> new_font = Gfx::BitmapFont::create(metadata.glyph_height, metadata.glyph_width, metadata.is_fixed_width, 0x110000);
if (!new_font) {
GUI::MessageBox::show(window(), "Failed to create new font.", "Font Editor", GUI::MessageBox::Type::Error);
return;
@@ -208,7 +207,7 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
GUI::MessageBox::show(window(), message, "Font Editor", GUI::MessageBox::Type::Error);
return;
}
- RefPtr<Gfx::BitmapFont> new_font = static_ptr_cast<Gfx::BitmapFont>(bitmap_font->clone());
+ RefPtr<Gfx::BitmapFont> new_font = static_ptr_cast<Gfx::BitmapFont>(bitmap_font->unmasked_character_set());
if (!new_font) {
String message = String::formatted("Couldn't load font: {}\n", open_path.value());
GUI::MessageBox::show(window(), message, "Font Editor", GUI::MessageBox::Type::Error);
@@ -396,12 +395,6 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
did_modify_font();
};
- m_type_combobox->on_change = [this](auto&, const auto& index) {
- m_edited_font->set_type(static_cast<Gfx::FontTypes>(index.row()));
- m_glyph_map_widget->reprobe_font();
- did_modify_font();
- };
-
m_presentation_spinbox->on_change = [this, update_demo](int value) {
m_edited_font->set_presentation_size(value);
update_demo();
@@ -487,16 +480,6 @@ void FontEditorWidget::initialize(const String& path, RefPtr<Gfx::BitmapFont>&&
i++;
}
- m_font_type_list.clear();
- StringBuilder type_count;
- for (int i = 0; i < Gfx::FontTypes::__Count; i++) {
- type_count.appendff("{}", Gfx::BitmapFont::type_name_by_type(static_cast<Gfx::FontTypes>(i)));
- m_font_type_list.append(type_count.to_string());
- type_count.clear();
- }
- m_type_combobox->set_model(*GUI::ItemListModel<String>::create(m_font_type_list));
- m_type_combobox->set_selected_index(m_edited_font->type());
-
m_fixed_width_checkbox->set_checked(m_edited_font->is_fixed_width());
m_glyph_map_widget->set_selected_glyph('A');
@@ -562,7 +545,8 @@ void FontEditorWidget::initialize_menubar(GUI::Window& window)
bool FontEditorWidget::save_as(const String& path)
{
- auto ret_val = m_edited_font->write_to_file(path);
+ auto saved_font = m_edited_font->masked_character_set();
+ auto ret_val = saved_font->write_to_file(path);
if (!ret_val) {
GUI::MessageBox::show(window(), "The font file could not be saved.", "Save failed", GUI::MessageBox::Type::Error);
return false;
diff --git a/Userland/Applications/FontEditor/FontEditor.h b/Userland/Applications/FontEditor/FontEditor.h
index 13e9da8bf2..d78311e363 100644
--- a/Userland/Applications/FontEditor/FontEditor.h
+++ b/Userland/Applications/FontEditor/FontEditor.h
@@ -73,7 +73,6 @@ private:
RefPtr<GUI::Widget> m_left_column_container;
RefPtr<GUI::Widget> m_glyph_editor_container;
RefPtr<GUI::ComboBox> m_weight_combobox;
- RefPtr<GUI::ComboBox> m_type_combobox;
RefPtr<GUI::SpinBox> m_spacing_spinbox;
RefPtr<GUI::SpinBox> m_baseline_spinbox;
RefPtr<GUI::SpinBox> m_mean_line_spinbox;
@@ -87,6 +86,5 @@ private:
String m_path;
Vector<String> m_font_weight_list;
- Vector<String> m_font_type_list;
bool m_font_metadata { true };
};
diff --git a/Userland/Applications/FontEditor/FontEditorWindow.gml b/Userland/Applications/FontEditor/FontEditorWindow.gml
index 45c9b8bc4c..0ccf0577d6 100644
--- a/Userland/Applications/FontEditor/FontEditorWindow.gml
+++ b/Userland/Applications/FontEditor/FontEditorWindow.gml
@@ -207,15 +207,6 @@
text: "Fixed width"
autosize: true
}
-
- @GUI::Widget {
- fixed_width: 12
- }
-
- @GUI::ComboBox {
- name: "type_combobox"
- model_only: true
- }
}
}
}
diff --git a/Userland/Applications/FontEditor/GlyphEditorWidget.cpp b/Userland/Applications/FontEditor/GlyphEditorWidget.cpp
index 9a25ed3e71..8844d73113 100644
--- a/Userland/Applications/FontEditor/GlyphEditorWidget.cpp
+++ b/Userland/Applications/FontEditor/GlyphEditorWidget.cpp
@@ -39,7 +39,7 @@ void GlyphEditorWidget::delete_glyph()
{
if (on_undo_event)
on_undo_event();
- auto bitmap = font().glyph(m_glyph).glyph_bitmap();
+ auto bitmap = font().raw_glyph(m_glyph).glyph_bitmap();
for (int x = 0; x < bitmap.width(); x++)
for (int y = 0; y < bitmap.height(); y++)
bitmap.set_bit_at(x, y, false);
@@ -56,7 +56,7 @@ void GlyphEditorWidget::cut_glyph()
void GlyphEditorWidget::copy_glyph()
{
- auto bitmap = font().glyph(m_glyph).glyph_bitmap();
+ auto bitmap = font().raw_glyph(m_glyph).glyph_bitmap();
u8 bits[bitmap.width()][bitmap.height()];
for (int x = 0; x < bitmap.width(); x++) {
for (int y = 0; y < bitmap.height(); y++) {
@@ -105,7 +105,7 @@ void GlyphEditorWidget::paste_glyph()
}
}
- auto bitmap = font().glyph(m_glyph).glyph_bitmap();
+ auto bitmap = font().raw_glyph(m_glyph).glyph_bitmap();
for (int x = 0; x < min(bitmap.width(), buffer_width.value()); x++) {
for (int y = 0; y < min(bitmap.height(), buffer_height.value()); y++) {
if (bits[x][y])
@@ -138,7 +138,7 @@ void GlyphEditorWidget::paint_event(GUI::PaintEvent& event)
for (int x = 1; x < font().max_glyph_width(); ++x)
painter.draw_line({ x * m_scale, 0 }, { x * m_scale, font().glyph_height() * m_scale }, palette().threed_shadow2());
- auto bitmap = font().glyph(m_glyph).glyph_bitmap();
+ auto bitmap = font().raw_glyph(m_glyph).glyph_bitmap();
for (int y = 0; y < font().glyph_height(); ++y) {
for (int x = 0; x < font().max_glyph_width(); ++x) {
@@ -155,7 +155,7 @@ void GlyphEditorWidget::paint_event(GUI::PaintEvent& event)
bool GlyphEditorWidget::is_glyph_empty()
{
- auto bitmap = font().glyph(m_glyph).glyph_bitmap();
+ auto bitmap = font().raw_glyph(m_glyph).glyph_bitmap();
for (int x = 0; x < bitmap.width(); x++)
for (int y = 0; y < bitmap.height(); y++)
if (bitmap.bit_at(x, y))
@@ -176,7 +176,7 @@ void GlyphEditorWidget::mousedown_event(GUI::MouseEvent& event)
draw_at_mouse(event);
} else {
memset(m_movable_bits, 0, sizeof(m_movable_bits));
- auto bitmap = font().glyph(m_glyph).glyph_bitmap();
+ auto bitmap = font().raw_glyph(m_glyph).glyph_bitmap();
for (int x = s_max_width; x < s_max_width + bitmap.width(); x++)
for (int y = s_max_height; y < s_max_height + bitmap.height(); y++)
m_movable_bits[x][y] = bitmap.bit_at(x - s_max_width, y - s_max_height);
@@ -221,7 +221,7 @@ void GlyphEditorWidget::draw_at_mouse(const GUI::MouseEvent& event)
return;
int x = (event.x() - 1) / m_scale;
int y = (event.y() - 1) / m_scale;
- auto bitmap = font().glyph(m_glyph).glyph_bitmap();
+ auto bitmap = font().raw_glyph(m_glyph).glyph_bitmap();
if (x < 0 || x >= bitmap.width())
return;
if (y < 0 || y >= bitmap.height())
@@ -238,7 +238,7 @@ void GlyphEditorWidget::move_at_mouse(const GUI::MouseEvent& event)
{
int x_delta = ((event.x() - 1) / m_scale) - x_offset;
int y_delta = ((event.y() - 1) / m_scale) - y_offset;
- auto bitmap = font().glyph(m_glyph).glyph_bitmap();
+ auto bitmap = font().raw_glyph(m_glyph).glyph_bitmap();
if (abs(x_delta) > bitmap.width() || abs(y_delta) > bitmap.height())
return;
for (int x = 0; x < bitmap.width(); x++) {
diff --git a/Userland/Applications/FontEditor/GlyphMapWidget.cpp b/Userland/Applications/FontEditor/GlyphMapWidget.cpp
index 4de7103948..b88e3d9b9c 100644
--- a/Userland/Applications/FontEditor/GlyphMapWidget.cpp
+++ b/Userland/Applications/FontEditor/GlyphMapWidget.cpp
@@ -25,7 +25,6 @@ void GlyphMapWidget::initialize(Gfx::BitmapFont& mutable_font)
if (m_font == mutable_font)
return;
m_font = mutable_font;
- m_glyph_count = mutable_font.glyph_count();
m_selected_glyph = 0;
vertical_scrollbar().set_step(font().glyph_height() + m_vertical_spacing);
}
@@ -33,6 +32,8 @@ void GlyphMapWidget::initialize(Gfx::BitmapFont& mutable_font)
void GlyphMapWidget::resize_event(GUI::ResizeEvent& event)
{
int event_width = event.size().width() - this->vertical_scrollbar().width() - (frame_thickness() * 2) - m_horizontal_spacing;
+ int event_height = event.size().height() - (frame_thickness() * 2);
+ m_visible_glyphs = (event_width * event_height) / (font().max_glyph_width() * font().glyph_height());
m_columns = max(event_width / (font().max_glyph_width() + m_horizontal_spacing), 1);
m_rows = ceil_div(m_glyph_count, m_columns);
@@ -90,7 +91,10 @@ void GlyphMapWidget::paint_event(GUI::PaintEvent& event)
painter.set_font(font());
painter.fill_rect(widget_inner_rect(), palette().inactive_window_title());
- for (int glyph = 0; glyph < m_glyph_count; ++glyph) {
+ int scroll_steps = this->vertical_scrollbar().value() / this->vertical_scrollbar().step();
+ int first_visible_glyph = scroll_steps * columns();
+
+ for (int glyph = first_visible_glyph; glyph <= first_visible_glyph + m_visible_glyphs && glyph < m_glyph_count; ++glyph) {
Gfx::IntRect outer_rect = get_outer_rect(glyph);
Gfx::IntRect inner_rect(
outer_rect.x() + m_horizontal_spacing / 2,
@@ -99,9 +103,9 @@ void GlyphMapWidget::paint_event(GUI::PaintEvent& event)
font().glyph_height());
if (glyph == m_selected_glyph) {
painter.fill_rect(outer_rect, is_focused() ? palette().selection() : palette().inactive_selection());
- if (m_font->contains_glyph(glyph))
+ if (m_font->raw_glyph_width(glyph))
painter.draw_glyph(inner_rect.location(), glyph, is_focused() ? palette().selection_text() : palette().inactive_selection_text());
- } else if (m_font->contains_glyph(glyph)) {
+ } else if (m_font->raw_glyph_width(glyph)) {
painter.fill_rect(outer_rect, palette().base());
painter.draw_glyph(inner_rect.location(), glyph, palette().base_text());
}
diff --git a/Userland/Applications/FontEditor/GlyphMapWidget.h b/Userland/Applications/FontEditor/GlyphMapWidget.h
index a2dbcb4897..af95f6e050 100644
--- a/Userland/Applications/FontEditor/GlyphMapWidget.h
+++ b/Userland/Applications/FontEditor/GlyphMapWidget.h
@@ -41,10 +41,11 @@ private:
Gfx::IntRect get_outer_rect(int glyph) const;
RefPtr<Gfx::BitmapFont> m_font;
- int m_glyph_count { 384 };
+ int m_glyph_count { 0x110000 };
int m_columns { 32 };
int m_rows { 12 };
int m_horizontal_spacing { 2 };
int m_vertical_spacing { 2 };
int m_selected_glyph { 0 };
+ int m_visible_glyphs { 0 };
};
diff --git a/Userland/Applications/FontEditor/NewFontDialog.cpp b/Userland/Applications/FontEditor/NewFontDialog.cpp
index 3d6a61c44b..f6024a3226 100644
--- a/Userland/Applications/FontEditor/NewFontDialog.cpp
+++ b/Userland/Applications/FontEditor/NewFontDialog.cpp
@@ -134,30 +134,14 @@ NewFontDialog::NewFontDialog(GUI::Window* parent_window)
m_name_textbox = m_font_properties_page->body_widget().find_descendant_of_type_named<GUI::TextBox>("name_textbox");
m_family_textbox = m_font_properties_page->body_widget().find_descendant_of_type_named<GUI::TextBox>("family_textbox");
- m_type_combobox = m_font_properties_page->body_widget().find_descendant_of_type_named<GUI::ComboBox>("type_combobox");
- m_type_info_label = m_font_properties_page->body_widget().find_descendant_of_type_named<GUI::Label>("type_info_label");
m_weight_combobox = m_font_properties_page->body_widget().find_descendant_of_type_named<GUI::ComboBox>("weight_combobox");
m_presentation_spinbox = m_font_properties_page->body_widget().find_descendant_of_type_named<GUI::SpinBox>("presentation_spinbox");
- m_type_info_label->set_text("\xE2\x84\xB9\t");
- m_type_info_label->set_tooltip("Font type governs maximum glyph count");
-
for (auto& it : GUI::font_weight_names)
m_font_weight_list.append(it.name);
m_weight_combobox->set_model(*GUI::ItemListModel<String>::create(m_font_weight_list));
m_weight_combobox->set_selected_index(3);
- StringBuilder type_count;
- for (int i = 0; i < Gfx::FontTypes::__Count; i++) {
- type_count.appendff("{} ({})",
- Gfx::BitmapFont::type_name_by_type(static_cast<Gfx::FontTypes>(i)),
- Gfx::BitmapFont::glyph_count_by_type(static_cast<Gfx::FontTypes>(i)));
- m_font_type_list.append(type_count.to_string());
- type_count.clear();
- }
- m_type_combobox->set_model(*GUI::ItemListModel<String>::create(m_font_type_list));
- m_type_combobox->set_selected_index(0);
-
m_presentation_spinbox->set_value(12);
m_font_properties_page->on_page_enter = [&]() {
@@ -225,7 +209,6 @@ void NewFontDialog::save_metadata()
m_new_font_metadata.name = m_name_textbox->text();
m_new_font_metadata.family = m_family_textbox->text();
m_new_font_metadata.weight = GUI::name_to_weight(m_weight_combobox->text());
- m_new_font_metadata.type = static_cast<Gfx::FontTypes>(m_type_combobox->selected_index());
m_new_font_metadata.presentation_size = m_presentation_spinbox->value();
m_new_font_metadata.baseline = m_baseline_spinbox->value();
diff --git a/Userland/Applications/FontEditor/NewFontDialog.h b/Userland/Applications/FontEditor/NewFontDialog.h
index 85724436b5..6245848ed4 100644
--- a/Userland/Applications/FontEditor/NewFontDialog.h
+++ b/Userland/Applications/FontEditor/NewFontDialog.h
@@ -36,7 +36,6 @@ private:
u16 weight;
String name;
String family;
- Gfx::FontTypes type;
bool is_fixed_width;
} m_new_font_metadata;
@@ -47,8 +46,6 @@ private:
RefPtr<GUI::WizardPage> m_font_properties_page;
RefPtr<GUI::TextBox> m_name_textbox;
RefPtr<GUI::TextBox> m_family_textbox;
- RefPtr<GUI::ComboBox> m_type_combobox;
- RefPtr<GUI::Label> m_type_info_label;
RefPtr<GUI::ComboBox> m_weight_combobox;
RefPtr<GUI::SpinBox> m_presentation_spinbox;
@@ -62,6 +59,5 @@ private:
RefPtr<GUI::CheckBox> m_fixed_width_checkbox;
Vector<String> m_font_list;
- Vector<String> m_font_type_list;
Vector<String> m_font_weight_list;
};
diff --git a/Userland/Applications/FontEditor/NewFontDialogPage1.gml b/Userland/Applications/FontEditor/NewFontDialogPage1.gml
index 2f372622dc..d70bc5a793 100644
--- a/Userland/Applications/FontEditor/NewFontDialogPage1.gml
+++ b/Userland/Applications/FontEditor/NewFontDialogPage1.gml
@@ -4,7 +4,7 @@
}
@GUI::Widget {
- fixed_height: 160
+ fixed_height: 138
layout: @GUI::VerticalBoxLayout {
}
@@ -47,29 +47,6 @@
}
@GUI::Label {
- fixed_width: 100
- text_alignment: "CenterLeft"
- text: "Type:"
- }
-
- @GUI::ComboBox {
- name: "type_combobox"
- fixed_width: 180
- model_only: true
- }
-
- @GUI::Label {
- name: "type_info_label"
- text_alignment: "CenterLeft"
- autosize: true
- }
- }
-
- @GUI::Widget {
- layout: @GUI::HorizontalBoxLayout {
- }
-
- @GUI::Label {
text: "Weight:"
fixed_width: 100
text_alignment: "CenterLeft"
diff --git a/Userland/Applications/FontEditor/main.cpp b/Userland/Applications/FontEditor/main.cpp
index 4c87e48ee0..cca06c4ed7 100644
--- a/Userland/Applications/FontEditor/main.cpp
+++ b/Userland/Applications/FontEditor/main.cpp
@@ -52,7 +52,8 @@ int main(int argc, char** argv)
RefPtr<Gfx::BitmapFont> edited_font;
if (path == nullptr) {
- edited_font = static_ptr_cast<Gfx::BitmapFont>(Gfx::FontDatabase::default_font().clone());
+ auto bitmap_font = static_ptr_cast<Gfx::BitmapFont>(Gfx::FontDatabase::default_font().clone());
+ edited_font = static_ptr_cast<Gfx::BitmapFont>(bitmap_font->unmasked_character_set());
} else {
auto bitmap_font = Gfx::BitmapFont::load_from_file(path);
if (!bitmap_font) {
@@ -60,7 +61,7 @@ int main(int argc, char** argv)
GUI::MessageBox::show(nullptr, message, "Font Editor", GUI::MessageBox::Type::Error);
return 1;
}
- edited_font = static_ptr_cast<Gfx::BitmapFont>(bitmap_font->clone());
+ edited_font = static_ptr_cast<Gfx::BitmapFont>(bitmap_font->unmasked_character_set());
if (!edited_font) {
String message = String::formatted("Couldn't load font: {}\n", path);
GUI::MessageBox::show(nullptr, message, "Font Editor", GUI::MessageBox::Type::Error);