1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 12:27:35 +00:00

Start working on a simple graphical font editor.

Editing fonts by editing text files is really slow and boring.
A simple font editor seems like a good way to take LibGUI for a spin.
This commit is contained in:
Andreas Kling 2019-02-02 08:05:14 +01:00
parent 5e0b7f1a56
commit 6fc3c38324
18 changed files with 390 additions and 19 deletions

View file

@ -9,6 +9,7 @@ public:
static RetainPtr<CharacterBitmap> create_from_ascii(const char* asciiData, unsigned width, unsigned height);
~CharacterBitmap();
bool bit_at(unsigned x, unsigned y) const { return m_bits[y * width() + x] == '#'; }
const char* bits() const { return m_bits; }
Size size() const { return m_size; }

View file

@ -4,6 +4,21 @@
#define DEFAULT_FONT_NAME Liza8x10
static const byte error_glyph_width = 8;
static const byte error_glyph_height = 10;
static constexpr const char* error_glyph {
" #### "
" # # "
" # # "
" # ## # "
" # ## # "
" #### "
" ## "
" ###### "
" ## "
" ## ",
};
static Font* s_default_font;
void Font::initialize()
@ -18,6 +33,22 @@ Font& Font::default_font()
return *s_default_font;
}
RetainPtr<Font> Font::clone() const
{
size_t bytes_per_glyph = glyph_width() * glyph_height();
// FIXME: This is leaked!
char** new_glyphs = static_cast<char**>(malloc(sizeof(char*) * 256));
for (unsigned i = 0; i < 256; ++i) {
new_glyphs[i] = static_cast<char*>(malloc(bytes_per_glyph));
if (i >= m_first_glyph && i <= m_last_glyph) {
memcpy(new_glyphs[i], m_glyphs[i - m_first_glyph], bytes_per_glyph);
} else {
memset(new_glyphs[i], ' ', bytes_per_glyph);
}
}
return adopt(*new Font(new_glyphs, m_glyph_width, m_glyph_height, 0, 255));
}
Font::Font(const char* const* glyphs, byte glyph_width, byte glyph_height, byte first_glyph, byte last_glyph)
: m_glyphs(glyphs)
, m_glyph_width(glyph_width)
@ -25,7 +56,9 @@ Font::Font(const char* const* glyphs, byte glyph_width, byte glyph_height, byte
, m_first_glyph(first_glyph)
, m_last_glyph(last_glyph)
{
m_error_bitmap = CharacterBitmap::create_from_ascii(DEFAULT_FONT_NAME::error_glyph, m_glyph_width, m_glyph_height);
ASSERT(m_glyph_width == error_glyph_width);
ASSERT(m_glyph_height == error_glyph_height);
m_error_bitmap = CharacterBitmap::create_from_ascii(error_glyph, error_glyph_width, error_glyph_height);
for (unsigned ch = 0; ch < 256; ++ch) {
if (ch < m_first_glyph || ch > m_last_glyph) {
m_bitmaps[ch] = m_error_bitmap.copy_ref();

View file

@ -9,6 +9,8 @@ class Font : public Retainable<Font> {
public:
static Font& default_font();
RetainPtr<Font> clone() const;
~Font();
const CharacterBitmap& glyph_bitmap(char ch) const { return *m_bitmaps[(byte)ch]; }
@ -19,7 +21,7 @@ public:
static void initialize();
private:
Font(const char* const* glyphs, byte glyph_width, byte glyph_height, byte firstGlyph, byte lastGlyph);
Font(const char* const* glyphs, byte glyph_width, byte glyph_height, byte first_glyph, byte last_glyph);
const char* const* m_glyphs { nullptr };
mutable RetainPtr<CharacterBitmap> m_bitmaps[256];

View file

@ -7,19 +7,6 @@ static constexpr char last_glyph = '~';
static constexpr byte glyph_width = 8;
static constexpr byte glyph_height = 10;
static constexpr const char* error_glyph {
" #### "
" # # "
" # # "
" # ## # "
" # ## # "
" #### "
" ## "
" ###### "
" ## "
" ## ",
};
static constexpr const char* glyphs[] {
" ## "

View file

@ -36,6 +36,7 @@ public:
void draw_glyph(const Point&, char, Color);
const Font& font() const { return *m_font; }
void set_font(Font& font) { m_font = &font; }
enum class DrawOp { Copy, Xor };
void set_draw_op(DrawOp op) { m_draw_op = op; }