diff options
Diffstat (limited to 'Applications/FontEditor')
-rw-r--r-- | Applications/FontEditor/.gitignore | 1 | ||||
-rw-r--r-- | Applications/FontEditor/CMakeLists.txt | 11 | ||||
-rw-r--r-- | Applications/FontEditor/FontEditor.cpp | 372 | ||||
-rw-r--r-- | Applications/FontEditor/FontEditor.h | 58 | ||||
-rw-r--r-- | Applications/FontEditor/GlyphEditorWidget.cpp | 125 | ||||
-rw-r--r-- | Applications/FontEditor/GlyphEditorWidget.h | 60 | ||||
-rw-r--r-- | Applications/FontEditor/GlyphMapWidget.cpp | 168 | ||||
-rw-r--r-- | Applications/FontEditor/GlyphMapWidget.h | 69 | ||||
-rw-r--r-- | Applications/FontEditor/main.cpp | 155 |
9 files changed, 0 insertions, 1019 deletions
diff --git a/Applications/FontEditor/.gitignore b/Applications/FontEditor/.gitignore deleted file mode 100644 index 0e7af5b54f..0000000000 --- a/Applications/FontEditor/.gitignore +++ /dev/null @@ -1 +0,0 @@ -UI_*.h diff --git a/Applications/FontEditor/CMakeLists.txt b/Applications/FontEditor/CMakeLists.txt deleted file mode 100644 index 569ab9a9bd..0000000000 --- a/Applications/FontEditor/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -set(SOURCES - FontEditor.cpp - GlyphEditorWidget.cpp - GlyphMapWidget.cpp - main.cpp -) - -serenity_app(FontEditor ICON app-font-editor) -target_link_libraries(FontEditor LibGUI LibDesktop LibGfx) diff --git a/Applications/FontEditor/FontEditor.cpp b/Applications/FontEditor/FontEditor.cpp deleted file mode 100644 index 56cbf3e06b..0000000000 --- a/Applications/FontEditor/FontEditor.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "FontEditor.h" -#include "GlyphEditorWidget.h" -#include "GlyphMapWidget.h" -#include <AK/StringBuilder.h> -#include <LibGUI/BoxLayout.h> -#include <LibGUI/Button.h> -#include <LibGUI/CheckBox.h> -#include <LibGUI/GroupBox.h> -#include <LibGUI/Label.h> -#include <LibGUI/MessageBox.h> -#include <LibGUI/Painter.h> -#include <LibGUI/SpinBox.h> -#include <LibGUI/TextBox.h> -#include <LibGUI/Window.h> -#include <LibGfx/BitmapFont.h> -#include <LibGfx/Palette.h> -#include <stdlib.h> - -FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&& edited_font) - : m_edited_font(move(edited_font)) - , m_path(path) -{ - set_fill_with_background_color(true); - set_layout<GUI::VerticalBoxLayout>(); - - // Top - auto& main_container = add<GUI::Widget>(); - main_container.set_layout<GUI::HorizontalBoxLayout>(); - main_container.layout()->set_margins({ 4, 4, 4, 4 }); - main_container.set_background_role(Gfx::ColorRole::SyntaxKeyword); - - // Top-Left Glyph Editor and info - auto& editor_container = main_container.add<GUI::Widget>(); - editor_container.set_layout<GUI::VerticalBoxLayout>(); - editor_container.layout()->set_margins({ 4, 4, 4, 4 }); - editor_container.set_background_role(Gfx::ColorRole::SyntaxKeyword); - - m_glyph_editor_widget = editor_container.add<GlyphEditorWidget>(*m_edited_font); - m_glyph_editor_widget->set_fixed_size(m_glyph_editor_widget->preferred_width(), m_glyph_editor_widget->preferred_height()); - - editor_container.set_fixed_width(m_glyph_editor_widget->preferred_width()); - - auto& glyph_width_label = editor_container.add<GUI::Label>(); - glyph_width_label.set_fixed_height(22); - glyph_width_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - glyph_width_label.set_text("Glyph width:"); - - auto& glyph_width_spinbox = editor_container.add<GUI::SpinBox>(); - glyph_width_spinbox.set_min(0); - glyph_width_spinbox.set_max(32); - glyph_width_spinbox.set_value(0); - glyph_width_spinbox.set_enabled(!m_edited_font->is_fixed_width()); - - auto& info_label = editor_container.add<GUI::Label>(); - info_label.set_fixed_height(22); - info_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - info_label.set_text("info_label"); - - /// Top-Right glyph map and font meta data - - auto& map_and_test_container = main_container.add<GUI::Widget>(); - map_and_test_container.set_layout<GUI::VerticalBoxLayout>(); - map_and_test_container.layout()->set_margins({ 4, 4, 4, 4 }); - - m_glyph_map_widget = map_and_test_container.add<GlyphMapWidget>(*m_edited_font); - m_glyph_map_widget->set_fixed_size(m_glyph_map_widget->preferred_width(), m_glyph_map_widget->preferred_height()); - - auto& font_mtest_group_box = map_and_test_container.add<GUI::GroupBox>(); - font_mtest_group_box.set_layout<GUI::VerticalBoxLayout>(); - font_mtest_group_box.layout()->set_margins({ 5, 15, 5, 5 }); - font_mtest_group_box.set_fixed_height(2 * m_edited_font->glyph_height() + 50); - font_mtest_group_box.set_title("Test"); - - auto& demo_label_1 = font_mtest_group_box.add<GUI::Label>(); - demo_label_1.set_font(m_edited_font); - demo_label_1.set_text("quick fox jumps nightly above wizard."); - - auto& demo_label_2 = font_mtest_group_box.add<GUI::Label>(); - demo_label_2.set_font(m_edited_font); - demo_label_2.set_text("QUICK FOX JUMPS NIGHTLY ABOVE WIZARD!"); - - auto& font_metadata_group_box = map_and_test_container.add<GUI::GroupBox>(); - font_metadata_group_box.set_layout<GUI::VerticalBoxLayout>(); - font_metadata_group_box.layout()->set_margins({ 5, 15, 5, 5 }); - font_metadata_group_box.set_fixed_height(275); - font_metadata_group_box.set_title("Font metadata"); - - //// Name Row - auto& namecontainer = font_metadata_group_box.add<GUI::Widget>(); - namecontainer.set_layout<GUI::HorizontalBoxLayout>(); - namecontainer.set_fixed_height(22); - - auto& name_label = namecontainer.add<GUI::Label>(); - name_label.set_fixed_width(100); - name_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - name_label.set_text("Name:"); - - auto& name_textbox = namecontainer.add<GUI::TextBox>(); - name_textbox.set_text(m_edited_font->name()); - name_textbox.on_change = [&] { - m_edited_font->set_name(name_textbox.text()); - }; - - //// Family Row - auto& family_container = font_metadata_group_box.add<GUI::Widget>(); - family_container.set_layout<GUI::HorizontalBoxLayout>(); - family_container.set_fixed_height(22); - - auto& family_label = family_container.add<GUI::Label>(); - family_label.set_fixed_width(100); - family_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - family_label.set_text("Family:"); - - auto& family_textbox = family_container.add<GUI::TextBox>(); - family_textbox.set_text(m_edited_font->family()); - family_textbox.on_change = [&] { - m_edited_font->set_family(family_textbox.text()); - }; - - //// Presentation size Row - auto& presentation_size_container = font_metadata_group_box.add<GUI::Widget>(); - presentation_size_container.set_layout<GUI::HorizontalBoxLayout>(); - presentation_size_container.set_fixed_height(22); - - auto& presentation_size_label = presentation_size_container.add<GUI::Label>(); - presentation_size_label.set_fixed_width(100); - presentation_size_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - presentation_size_label.set_text("Presentation size:"); - - auto& presentation_size_spinbox = presentation_size_container.add<GUI::SpinBox>(); - presentation_size_spinbox.set_min(0); - presentation_size_spinbox.set_max(255); - presentation_size_spinbox.set_value(m_edited_font->presentation_size()); - - //// Weight Row - auto& weight_container = font_metadata_group_box.add<GUI::Widget>(); - weight_container.set_layout<GUI::HorizontalBoxLayout>(); - weight_container.set_fixed_height(22); - - auto& weight_label = weight_container.add<GUI::Label>(); - weight_label.set_fixed_width(100); - weight_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - weight_label.set_text("Weight:"); - - auto& weight_spinbox = weight_container.add<GUI::SpinBox>(); - weight_spinbox.set_min(0); - weight_spinbox.set_max(65535); - weight_spinbox.set_value(m_edited_font->weight()); - - //// Glyph spacing Row - auto& glyph_spacing_container = font_metadata_group_box.add<GUI::Widget>(); - glyph_spacing_container.set_layout<GUI::HorizontalBoxLayout>(); - glyph_spacing_container.set_fixed_height(22); - - auto& glyph_spacing = glyph_spacing_container.add<GUI::Label>(); - glyph_spacing.set_fixed_width(100); - glyph_spacing.set_text_alignment(Gfx::TextAlignment::CenterLeft); - glyph_spacing.set_text("Glyph spacing:"); - - auto& spacing_spinbox = glyph_spacing_container.add<GUI::SpinBox>(); - spacing_spinbox.set_min(0); - spacing_spinbox.set_max(255); - spacing_spinbox.set_value(m_edited_font->glyph_spacing()); - - //// Glyph Height Row - auto& glyph_height_container = font_metadata_group_box.add<GUI::Widget>(); - glyph_height_container.set_layout<GUI::HorizontalBoxLayout>(); - glyph_height_container.set_fixed_height(22); - - auto& glyph_height = glyph_height_container.add<GUI::Label>(); - glyph_height.set_fixed_width(100); - glyph_height.set_text_alignment(Gfx::TextAlignment::CenterLeft); - glyph_height.set_text("Glyph height:"); - - auto& glyph_height_spinbox = glyph_height_container.add<GUI::SpinBox>(); - glyph_height_spinbox.set_min(0); - glyph_height_spinbox.set_max(255); - glyph_height_spinbox.set_value(m_edited_font->glyph_height()); - glyph_height_spinbox.set_enabled(false); - - //// Glyph width Row - auto& glyph_weight_container = font_metadata_group_box.add<GUI::Widget>(); - glyph_weight_container.set_layout<GUI::HorizontalBoxLayout>(); - glyph_weight_container.set_fixed_height(22); - - auto& glyph_header_width_label = glyph_weight_container.add<GUI::Label>(); - glyph_header_width_label.set_fixed_width(100); - glyph_header_width_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - glyph_header_width_label.set_text("Glyph width:"); - - auto& glyph_header_width_spinbox = glyph_weight_container.add<GUI::SpinBox>(); - glyph_header_width_spinbox.set_min(0); - glyph_header_width_spinbox.set_max(255); - glyph_header_width_spinbox.set_value(m_edited_font->glyph_fixed_width()); - glyph_header_width_spinbox.set_enabled(false); - - //// Baseline Row - auto& baseline_container = font_metadata_group_box.add<GUI::Widget>(); - baseline_container.set_layout<GUI::HorizontalBoxLayout>(); - baseline_container.set_fixed_height(22); - - auto& baseline_label = baseline_container.add<GUI::Label>(); - baseline_label.set_fixed_width(100); - baseline_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - baseline_label.set_text("Baseline:"); - - auto& baseline_spinbox = baseline_container.add<GUI::SpinBox>(); - baseline_spinbox.set_min(0); - baseline_spinbox.set_max(m_edited_font->glyph_height() - 1); - baseline_spinbox.set_value(m_edited_font->baseline()); - - //// Mean line Row - auto& mean_line_container = font_metadata_group_box.add<GUI::Widget>(); - mean_line_container.set_layout<GUI::HorizontalBoxLayout>(); - mean_line_container.set_fixed_height(22); - - auto& mean_line_label = mean_line_container.add<GUI::Label>(); - mean_line_label.set_fixed_width(100); - mean_line_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); - mean_line_label.set_text("Mean Line:"); - - auto& mean_line_spinbox = mean_line_container.add<GUI::SpinBox>(); - mean_line_spinbox.set_min(0); - mean_line_spinbox.set_max(m_edited_font->glyph_height() - 1); - mean_line_spinbox.set_value(m_edited_font->mean_line()); - - //// Fixed checkbox Row - auto& fixed_width_checkbox = font_metadata_group_box.add<GUI::CheckBox>(); - fixed_width_checkbox.set_text("Fixed width"); - fixed_width_checkbox.set_checked(m_edited_font->is_fixed_width()); - - // Bottom - auto& bottom_container = add<GUI::Widget>(); - bottom_container.set_layout<GUI::HorizontalBoxLayout>(); - bottom_container.layout()->set_margins({ 8, 0, 8, 8 }); - bottom_container.set_fixed_height(32); - - bottom_container.layout()->add_spacer(); - - auto& save_button = bottom_container.add<GUI::Button>(); - save_button.set_fixed_size(80, 22); - save_button.set_text("Save"); - save_button.on_click = [this](auto) { save_as(m_path); }; - - auto& quit_button = bottom_container.add<GUI::Button>(); - quit_button.set_fixed_size(80, 22); - quit_button.set_text("Quit"); - quit_button.on_click = [](auto) { - exit(0); - }; - - // Event hanglers - auto update_demo = [&] { - demo_label_1.update(); - demo_label_2.update(); - }; - - auto calculate_prefed_sizes = [&] { - int right_site_width = m_edited_font->width("QUICK FOX JUMPS NIGHTLY ABOVE WIZARD!") + 20; - right_site_width = max(right_site_width, m_glyph_map_widget->preferred_width()); - - m_preferred_width = m_glyph_editor_widget->width() + right_site_width + 20; - m_preferred_height = m_glyph_map_widget->relative_rect().height() + 2 * m_edited_font->glyph_height() + 380; - }; - - m_glyph_editor_widget->on_glyph_altered = [this, update_demo](u8 glyph) { - m_glyph_map_widget->update_glyph(glyph); - update_demo(); - }; - - m_glyph_map_widget->on_glyph_selected = [&](size_t glyph) { - m_glyph_editor_widget->set_glyph(glyph); - glyph_width_spinbox.set_value(m_edited_font->glyph_width(m_glyph_map_widget->selected_glyph())); - StringBuilder builder; - builder.appendff("{:#02x} (", glyph); - if (glyph < 128) { - builder.append(glyph); - } else { - builder.append(128 | 64 | (glyph / 64)); - builder.append(128 | (glyph % 64)); - } - builder.append(')'); - info_label.set_text(builder.to_string()); - }; - - fixed_width_checkbox.on_checked = [&, update_demo](bool checked) { - m_edited_font->set_fixed_width(checked); - glyph_width_spinbox.set_enabled(!m_edited_font->is_fixed_width()); - glyph_width_spinbox.set_value(m_edited_font->glyph_width(m_glyph_map_widget->selected_glyph())); - m_glyph_editor_widget->update(); - update_demo(); - }; - - glyph_width_spinbox.on_change = [this, update_demo](int value) { - 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()); - update_demo(); - }; - - weight_spinbox.on_change = [this, update_demo](int value) { - m_edited_font->set_weight(value); - update_demo(); - }; - - presentation_size_spinbox.on_change = [this, update_demo](int value) { - m_edited_font->set_presentation_size(value); - update_demo(); - }; - - spacing_spinbox.on_change = [this, update_demo](int value) { - m_edited_font->set_glyph_spacing(value); - update_demo(); - }; - - baseline_spinbox.on_change = [this, update_demo](int value) { - m_edited_font->set_baseline(value); - m_glyph_editor_widget->update(); - update_demo(); - }; - - mean_line_spinbox.on_change = [this, update_demo](int value) { - m_edited_font->set_mean_line(value); - m_glyph_editor_widget->update(); - update_demo(); - }; - - // init widget - calculate_prefed_sizes(); - m_glyph_map_widget->set_selected_glyph('A'); -} - -FontEditorWidget::~FontEditorWidget() -{ -} - -bool FontEditorWidget::save_as(const String& path) -{ - auto ret_val = m_edited_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; - } - m_path = path; - return true; -} diff --git a/Applications/FontEditor/FontEditor.h b/Applications/FontEditor/FontEditor.h deleted file mode 100644 index ed904e8e7d..0000000000 --- a/Applications/FontEditor/FontEditor.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include <AK/Function.h> -#include <LibGUI/Widget.h> -#include <LibGfx/BitmapFont.h> - -class GlyphEditorWidget; -class GlyphMapWidget; - -class FontEditorWidget final : public GUI::Widget { - C_OBJECT(FontEditorWidget) -public: - virtual ~FontEditorWidget() override; - - int preferred_width() { return m_preferred_width; } - int preferred_height() { return m_preferred_height; } - - bool save_as(const String&); - - const String& path() { return m_path; } - -private: - FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&); - RefPtr<Gfx::BitmapFont> m_edited_font; - - RefPtr<GlyphMapWidget> m_glyph_map_widget; - RefPtr<GlyphEditorWidget> m_glyph_editor_widget; - - String m_path; - int m_preferred_width; - int m_preferred_height; -}; diff --git a/Applications/FontEditor/GlyphEditorWidget.cpp b/Applications/FontEditor/GlyphEditorWidget.cpp deleted file mode 100644 index 6f545c1ccd..0000000000 --- a/Applications/FontEditor/GlyphEditorWidget.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "GlyphEditorWidget.h" -#include <LibGUI/Painter.h> -#include <LibGfx/BitmapFont.h> -#include <LibGfx/Palette.h> - -GlyphEditorWidget::GlyphEditorWidget(Gfx::BitmapFont& mutable_font) - : m_font(mutable_font) -{ - set_relative_rect({ 0, 0, preferred_width(), preferred_height() }); -} - -GlyphEditorWidget::~GlyphEditorWidget() -{ -} - -void GlyphEditorWidget::set_glyph(int glyph) -{ - if (m_glyph == glyph) - return; - m_glyph = glyph; - update(); -} - -void GlyphEditorWidget::paint_event(GUI::PaintEvent& event) -{ - GUI::Frame::paint_event(event); - - GUI::Painter painter(*this); - painter.add_clip_rect(frame_inner_rect()); - painter.add_clip_rect(event.rect()); - painter.fill_rect(frame_inner_rect(), palette().base()); - painter.translate(frame_thickness(), frame_thickness()); - - painter.translate(-1, -1); - for (int y = 1; y < font().glyph_height(); ++y) { - int y_below = y - 1; - bool bold_line = y_below == font().baseline() || y_below == font().mean_line(); - painter.draw_line({ 0, y * m_scale }, { font().max_glyph_width() * m_scale, y * m_scale }, palette().threed_shadow2(), bold_line ? 2 : 1); - } - - 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_bitmap(m_glyph); - - for (int y = 0; y < font().glyph_height(); ++y) { - for (int x = 0; x < font().max_glyph_width(); ++x) { - Gfx::IntRect rect { x * m_scale, y * m_scale, m_scale, m_scale }; - if (x >= font().glyph_width(m_glyph)) { - painter.fill_rect(rect, palette().threed_shadow1()); - } else { - if (bitmap.bit_at(x, y)) - painter.fill_rect(rect, palette().base_text()); - } - } - } -} - -void GlyphEditorWidget::mousedown_event(GUI::MouseEvent& event) -{ - draw_at_mouse(event); -} - -void GlyphEditorWidget::mousemove_event(GUI::MouseEvent& event) -{ - if (event.buttons() & (GUI::MouseButton::Left | GUI::MouseButton::Right)) - draw_at_mouse(event); -} - -void GlyphEditorWidget::draw_at_mouse(const GUI::MouseEvent& event) -{ - bool set = event.buttons() & GUI::MouseButton::Left; - bool unset = event.buttons() & GUI::MouseButton::Right; - if (!(set ^ unset)) - return; - int x = (event.x() - 1) / m_scale; - int y = (event.y() - 1) / m_scale; - auto bitmap = font().glyph_bitmap(m_glyph); - if (x < 0 || x >= bitmap.width()) - return; - if (y < 0 || y >= bitmap.height()) - return; - if (bitmap.bit_at(x, y) == set) - return; - bitmap.set_bit_at(x, y, set); - if (on_glyph_altered) - on_glyph_altered(m_glyph); - update(); -} - -int GlyphEditorWidget::preferred_width() const -{ - return frame_thickness() * 2 + font().max_glyph_width() * m_scale - 1; -} - -int GlyphEditorWidget::preferred_height() const -{ - return frame_thickness() * 2 + font().glyph_height() * m_scale - 1; -} diff --git a/Applications/FontEditor/GlyphEditorWidget.h b/Applications/FontEditor/GlyphEditorWidget.h deleted file mode 100644 index a54c551642..0000000000 --- a/Applications/FontEditor/GlyphEditorWidget.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include <AK/Function.h> -#include <LibGUI/Frame.h> -#include <LibGfx/BitmapFont.h> - -class GlyphEditorWidget final : public GUI::Frame { - C_OBJECT(GlyphEditorWidget) -public: - virtual ~GlyphEditorWidget() override; - - int glyph() const { return m_glyph; } - void set_glyph(int); - - int preferred_width() const; - int preferred_height() const; - - Gfx::BitmapFont& font() { return *m_font; } - const Gfx::BitmapFont& font() const { return *m_font; } - - Function<void(u8)> on_glyph_altered; - -private: - GlyphEditorWidget(Gfx::BitmapFont&); - virtual void paint_event(GUI::PaintEvent&) override; - virtual void mousedown_event(GUI::MouseEvent&) override; - virtual void mousemove_event(GUI::MouseEvent&) override; - - void draw_at_mouse(const GUI::MouseEvent&); - - RefPtr<Gfx::BitmapFont> m_font; - int m_glyph { 0 }; - int m_scale { 10 }; -}; diff --git a/Applications/FontEditor/GlyphMapWidget.cpp b/Applications/FontEditor/GlyphMapWidget.cpp deleted file mode 100644 index ed6a65493f..0000000000 --- a/Applications/FontEditor/GlyphMapWidget.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "GlyphMapWidget.h" -#include <LibGUI/Painter.h> -#include <LibGfx/BitmapFont.h> -#include <LibGfx/Palette.h> - -GlyphMapWidget::GlyphMapWidget(Gfx::BitmapFont& mutable_font) - : m_font(mutable_font) -{ - m_glyph_count = mutable_font.glyph_count(); - set_relative_rect({ 0, 0, preferred_width(), preferred_height() }); - set_focus_policy(GUI::FocusPolicy::StrongFocus); -} - -GlyphMapWidget::~GlyphMapWidget() -{ -} - -int GlyphMapWidget::preferred_width() const -{ - return columns() * (font().max_glyph_width() + m_horizontal_spacing) + 2 + frame_thickness() * 2; -} - -int GlyphMapWidget::preferred_height() const -{ - return rows() * (font().glyph_height() + m_vertical_spacing) + 2 + frame_thickness() * 2; -} - -void GlyphMapWidget::set_selected_glyph(int glyph) -{ - if (m_selected_glyph == glyph) - return; - m_selected_glyph = glyph; - if (on_glyph_selected) - on_glyph_selected(glyph); - update(); -} - -Gfx::IntRect GlyphMapWidget::get_outer_rect(int glyph) const -{ - int row = glyph / columns(); - int column = glyph % columns(); - return Gfx::IntRect { - column * (font().max_glyph_width() + m_horizontal_spacing) + 1, - row * (font().glyph_height() + m_vertical_spacing) + 1, - font().max_glyph_width() + m_horizontal_spacing, - font().glyph_height() + m_horizontal_spacing - } - .translated(frame_thickness(), frame_thickness()); -} - -void GlyphMapWidget::update_glyph(int glyph) -{ - update(get_outer_rect(glyph)); -} - -void GlyphMapWidget::paint_event(GUI::PaintEvent& event) -{ - GUI::Frame::paint_event(event); - - GUI::Painter painter(*this); - painter.add_clip_rect(event.rect()); - - painter.set_font(font()); - painter.fill_rect(frame_inner_rect(), palette().base()); - - for (int glyph = 0; glyph < m_glyph_count; ++glyph) { - Gfx::IntRect outer_rect = get_outer_rect(glyph); - Gfx::IntRect inner_rect( - outer_rect.x() + m_horizontal_spacing / 2, - outer_rect.y() + m_vertical_spacing / 2, - font().max_glyph_width(), - font().glyph_height()); - if (glyph == m_selected_glyph) { - painter.fill_rect(outer_rect, is_focused() ? palette().selection() : palette().inactive_selection()); - painter.draw_glyph(inner_rect.location(), glyph, is_focused() ? palette().selection_text() : palette().inactive_selection_text()); - } else { - painter.draw_glyph(inner_rect.location(), glyph, palette().base_text()); - } - } -} - -void GlyphMapWidget::mousedown_event(GUI::MouseEvent& event) -{ - GUI::Frame::mousedown_event(event); - - // FIXME: This is a silly loop. - for (int glyph = 0; glyph < m_glyph_count; ++glyph) { - if (get_outer_rect(glyph).contains(event.position())) { - set_selected_glyph(glyph); - break; - } - } -} - -void GlyphMapWidget::keydown_event(GUI::KeyEvent& event) -{ - GUI::Frame::keydown_event(event); - - if (event.key() == KeyCode::Key_Up) { - if (selected_glyph() >= m_columns) { - set_selected_glyph(selected_glyph() - m_columns); - return; - } - } - if (event.key() == KeyCode::Key_Down) { - if (selected_glyph() < m_glyph_count - m_columns) { - set_selected_glyph(selected_glyph() + m_columns); - return; - } - } - if (event.key() == KeyCode::Key_Left) { - if (selected_glyph() > 0) { - set_selected_glyph(selected_glyph() - 1); - return; - } - } - if (event.key() == KeyCode::Key_Right) { - if (selected_glyph() < m_glyph_count - 1) { - set_selected_glyph(selected_glyph() + 1); - return; - } - } - if (event.ctrl() && event.key() == KeyCode::Key_Home) { - set_selected_glyph(0); - return; - } - if (event.ctrl() && event.key() == KeyCode::Key_End) { - set_selected_glyph(m_glyph_count - 1); - return; - } - if (!event.ctrl() && event.key() == KeyCode::Key_Home) { - set_selected_glyph(selected_glyph() / m_columns * m_columns); - return; - } - if (!event.ctrl() && event.key() == KeyCode::Key_End) { - int new_selection = selected_glyph() / m_columns * m_columns + (m_columns - 1); - int max = m_glyph_count - 1; - new_selection = clamp(new_selection, 0, max); - set_selected_glyph(new_selection); - return; - } -} diff --git a/Applications/FontEditor/GlyphMapWidget.h b/Applications/FontEditor/GlyphMapWidget.h deleted file mode 100644 index 2c8443a251..0000000000 --- a/Applications/FontEditor/GlyphMapWidget.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include <AK/Function.h> -#include <AK/StdLibExtras.h> -#include <LibGUI/Frame.h> -#include <LibGfx/BitmapFont.h> - -class GlyphMapWidget final : public GUI::Frame { - C_OBJECT(GlyphMapWidget) -public: - virtual ~GlyphMapWidget() override; - - int selected_glyph() const { return m_selected_glyph; } - void set_selected_glyph(int); - - int rows() const { return ceil_div(m_glyph_count, m_columns); } - int columns() const { return m_columns; } - - int preferred_width() const; - int preferred_height() const; - - Gfx::BitmapFont& font() { return *m_font; } - const Gfx::BitmapFont& font() const { return *m_font; } - - void update_glyph(int); - - Function<void(int)> on_glyph_selected; - -private: - explicit GlyphMapWidget(Gfx::BitmapFont&); - virtual void paint_event(GUI::PaintEvent&) override; - virtual void mousedown_event(GUI::MouseEvent&) override; - virtual void keydown_event(GUI::KeyEvent&) override; - - Gfx::IntRect get_outer_rect(int glyph) const; - - RefPtr<Gfx::BitmapFont> m_font; - int m_glyph_count; - int m_columns { 32 }; - int m_horizontal_spacing { 2 }; - int m_vertical_spacing { 2 }; - int m_selected_glyph { 0 }; -}; diff --git a/Applications/FontEditor/main.cpp b/Applications/FontEditor/main.cpp deleted file mode 100644 index f0a72d1d29..0000000000 --- a/Applications/FontEditor/main.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "FontEditor.h" -#include <AK/URL.h> -#include <LibCore/ArgsParser.h> -#include <LibDesktop/Launcher.h> -#include <LibGUI/Action.h> -#include <LibGUI/Application.h> -#include <LibGUI/FilePicker.h> -#include <LibGUI/Icon.h> -#include <LibGUI/Menu.h> -#include <LibGUI/MenuBar.h> -#include <LibGUI/MessageBox.h> -#include <LibGUI/Window.h> -#include <LibGfx/Bitmap.h> -#include <LibGfx/BitmapFont.h> -#include <LibGfx/FontDatabase.h> -#include <LibGfx/Point.h> -#include <stdio.h> - -int main(int argc, char** argv) -{ - if (pledge("stdio shared_buffer thread rpath accept unix cpath wpath fattr unix", nullptr) < 0) { - perror("pledge"); - return 1; - } - - auto app = GUI::Application::construct(argc, argv); - - if (pledge("stdio shared_buffer thread rpath accept cpath wpath unix", nullptr) < 0) { - perror("pledge"); - return 1; - } - - if (!Desktop::Launcher::add_allowed_handler_with_only_specific_urls( - "/bin/Help", - { URL::create_with_file_protocol("/usr/share/man/man1/FontEditor.md") }) - || !Desktop::Launcher::seal_allowlist()) { - warnln("Failed to set up allowed launch URLs"); - return 1; - } - - if (pledge("stdio shared_buffer thread rpath accept cpath wpath", nullptr) < 0) { - perror("pledge"); - return 1; - } - - const char* path = nullptr; - Core::ArgsParser args_parser; - args_parser.add_positional_argument(path, "The font file for editing.", "file", Core::ArgsParser::Required::No); - args_parser.parse(argc, argv); - - RefPtr<Gfx::BitmapFont> edited_font; - if (path == nullptr) { - path = "/tmp/saved.font"; - edited_font = static_ptr_cast<Gfx::BitmapFont>(Gfx::FontDatabase::default_font().clone()); - } else { - edited_font = static_ptr_cast<Gfx::BitmapFont>(Gfx::Font::load_from_file(path)->clone()); - if (!edited_font) { - String message = String::formatted("Couldn't load font: {}\n", path); - GUI::MessageBox::show(nullptr, message, "Font Editor", GUI::MessageBox::Type::Error); - return 1; - } - } - - auto app_icon = GUI::Icon::default_icon("app-font-editor"); - - auto window = GUI::Window::construct(); - window->set_icon(app_icon.bitmap_for_size(16)); - - auto set_edited_font = [&](const String& path, RefPtr<Gfx::BitmapFont>&& font, Gfx::IntPoint point) { - // Convert 256 char font to 384 char font. - if (font->type() == Gfx::FontTypes::Default) - font->set_type(Gfx::FontTypes::LatinExtendedA); - - window->set_title(String::formatted("{} - Font Editor", path)); - auto& font_editor_widget = window->set_main_widget<FontEditorWidget>(path, move(font)); - window->set_rect({ point, { font_editor_widget.preferred_width(), font_editor_widget.preferred_height() } }); - }; - set_edited_font(path, move(edited_font), window->position()); - - auto menubar = GUI::MenuBar::construct(); - - auto& app_menu = menubar->add_menu("Font Editor"); - app_menu.add_action(GUI::CommonActions::make_open_action([&](auto&) { - Optional<String> open_path = GUI::FilePicker::get_open_filepath(window); - if (!open_path.has_value()) - return; - - RefPtr<Gfx::BitmapFont> new_font = static_ptr_cast<Gfx::BitmapFont>(Gfx::Font::load_from_file(open_path.value())->clone()); - 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); - return; - } - - set_edited_font(open_path.value(), move(new_font), window->position()); - })); - app_menu.add_action(GUI::CommonActions::make_save_action([&](auto&) { - FontEditorWidget* editor = static_cast<FontEditorWidget*>(window->main_widget()); - editor->save_as(editor->path()); - })); - app_menu.add_action(GUI::CommonActions::make_save_as_action([&](auto&) { - FontEditorWidget* editor = static_cast<FontEditorWidget*>(window->main_widget()); - LexicalPath lexical_path(editor->path()); - Optional<String> save_path = GUI::FilePicker::get_save_filepath(window, lexical_path.title(), lexical_path.extension()); - if (!save_path.has_value()) - return; - - if (editor->save_as(save_path.value())) - window->set_title(String::formatted("{} - Font Editor", save_path.value())); - })); - app_menu.add_separator(); - app_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { - app->quit(); - return; - })); - - auto& help_menu = menubar->add_menu("Help"); - help_menu.add_action(GUI::CommonActions::make_help_action([](auto&) { - Desktop::Launcher::open(URL::create_with_file_protocol("/usr/share/man/man1/FontEditor.md"), "/bin/Help"); - })); - - help_menu.add_action(GUI::CommonActions::make_about_action("Font Editor", app_icon, window)); - - app->set_menubar(move(menubar)); - - window->show(); - - return app->exec(); -} |