diff --git a/Makefile b/Makefile index 37a9e97c..400d8e36 100644 --- a/Makefile +++ b/Makefile @@ -36,8 +36,10 @@ tools/ttf2fonts/ttf2fonts: tools/ttf2font/ttf2font.cpp tools/ttf2font/Makefile cd tools/ttf2font; $(MAKE) C43S_FONT=fonts/C43StandardFont.ttf -fonts/C43SFont.cc: ttf2font $(C43S_FONT) - tools/ttf2font/ttf2font -s 32 C43SFont $(C43S_FONT) $@ +fonts/EditorFont.cc: ttf2font $(C43S_FONT) + tools/ttf2font/ttf2font -s 60 EditorFont $(C43S_FONT) $@ +fonts/StackFont.cc: ttf2font $(C43S_FONT) + tools/ttf2font/ttf2font -s 40 StackFont $(C43S_FONT) $@ debug-%: $(MAKE) $* OPT=debug @@ -96,7 +98,9 @@ CXX_SOURCES += \ src/algebraic.cc \ src/arithmetic.cc \ src/font.cc \ - fonts/C43SFont.cc + fonts/EditorFont.cc \ + fonts/StackFont.cc + # Generate the sized variants of decimal128 diff --git a/sim/simulator.pro b/sim/simulator.pro index 20fdf726..c4884231 100644 --- a/sim/simulator.pro +++ b/sim/simulator.pro @@ -52,7 +52,8 @@ SOURCES += \ ../src/algebraic.cc \ ../src/arithmetic.cc \ ../src/font.cc \ - ../fonts/C43SFont.cc \ + ../fonts/EditorFont.cc \ + ../fonts/StackFont.cc \ ../src/tests.cc HEADERS += \ diff --git a/src/font.cc b/src/font.cc index 97b6c585..2d1eef09 100644 --- a/src/font.cc +++ b/src/font.cc @@ -206,6 +206,19 @@ private: } FontCache; +font::fuint sparse_font::height() +// ---------------------------------------------------------------------------- +// Return the font height from its data +// ---------------------------------------------------------------------------- +{ + // Scan the font data + byte *p = payload(); + size_t UNUSED size = leb128(p); + fuint height = leb128(p); + return height; +} + + bool sparse_font::glyph(utf8code codepoint, glyph_info &g) const // ---------------------------------------------------------------------------- // Return the bitmap address and update coordinate info for a sparse font @@ -231,13 +244,12 @@ bool sparse_font::glyph(utf8code codepoint, glyph_info &g) const " Range %u-%u (%u codepoints)", firstCP, firstCP + numCPs, numCPs); - // Check end of font ranges - if (!firstCP && !numCPs) - return false; - - // Check if we are past the current code point - if (firstCP > codepoint) + // Check end of font ranges, or if past current codepoint + if ((!firstCP && !numCPs) || firstCP > codepoint) + { + record(sparse_fonts, "Code point %u not found", codepoint); return false; + } fuint lastCP = firstCP + numCPs; bool in = codepoint >= firstCP && codepoint < lastCP; @@ -292,6 +304,19 @@ bool sparse_font::glyph(utf8code codepoint, glyph_info &g) const } +font::fuint dense_font::height() +// ---------------------------------------------------------------------------- +// Return the font height from its data +// ---------------------------------------------------------------------------- +{ + // Scan the font data + byte *p = payload(); + size_t UNUSED size = leb128(p); + fuint height = leb128(p); + return height; +} + + bool dense_font::glyph(utf8code codepoint, glyph_info &g) const // ---------------------------------------------------------------------------- // Return the bitmap address and update coordinate info for a dense font @@ -320,13 +345,12 @@ bool dense_font::glyph(utf8code codepoint, glyph_info &g) const fuint firstCP = leb128(p); fuint numCPs = leb128(p); - // Check end of font ranges - if (!firstCP && !numCPs) - return false; - - // Check if we are past the current code point - if (firstCP > codepoint) - return false; + // Check end of font ranges, or if past current codepoint + if ((!firstCP && !numCPs) || firstCP > codepoint) + { + record(dense_fonts, "Code point %u not found", codepoint); + return false; + } fuint lastCP = firstCP + numCPs; bool in = codepoint >= firstCP && codepoint < lastCP; @@ -363,7 +387,59 @@ bool dense_font::glyph(utf8code codepoint, glyph_info &g) const } -bool dmcp_font::glyph(utf8code codepoint, glyph_info &g) const +static const byte dmcpFontRPL[] +// ---------------------------------------------------------------------------- +// RPL object representing the various DMCP fonts +// ---------------------------------------------------------------------------- +{ + object::ID_dmcp_font, 0, // lib_mono + object::ID_dmcp_font, 1, + object::ID_dmcp_font, 2, + object::ID_dmcp_font, 3, + object::ID_dmcp_font, 4, + object::ID_dmcp_font, 5, + + object::ID_dmcp_font, 10, // Free42 (fixed size, very small) + + object::ID_dmcp_font, 18, // skr_mono + object::ID_dmcp_font, 21, // skr_mono + +}; + + +// In the DM42 DMCP - Not fully Unicode capable +const dmcp_font_p LibMonoFont10x17 = (dmcp_font_p) (dmcpFontRPL + 0); +const dmcp_font_p LibMonoFont11x18 = (dmcp_font_p) (dmcpFontRPL + 2); +const dmcp_font_p LibMonoFont12x20 = (dmcp_font_p) (dmcpFontRPL + 4); +const dmcp_font_p LibMonoFont14x22 = (dmcp_font_p) (dmcpFontRPL + 6); +const dmcp_font_p LibMonoFont17x25 = (dmcp_font_p) (dmcpFontRPL + 8); +const dmcp_font_p LibMonoFont17x28 = (dmcp_font_p) (dmcpFontRPL + 10); +const dmcp_font_p Free42Font = (dmcp_font_p) (dmcpFontRPL + 12); +const dmcp_font_p SkrMono13x18 = (dmcp_font_p) (dmcpFontRPL + 14); +const dmcp_font_p SkrMono18x24 = (dmcp_font_p) (dmcpFontRPL + 16); + +const font_p HeaderFont = LibMonoFont10x17; +const font_p CursorFont = LibMonoFont17x25; +const font_p ErrorFont = LibMonoFont14x22; + +font::fuint dmcp_font::height() +// ---------------------------------------------------------------------------- +// Return the font height from its data +// ---------------------------------------------------------------------------- +{ + // Switch to the correct DMCP font + int fontnr = index(); + if (fontnr >= 11 && fontnr <= 16) // Use special DMCP index for Free42 fonts + fontnr = -(fontnr - 10); + lcd_switchFont(fReg, fontnr); + + // Check if codepoint is within font range + const line_font_t *f = fReg->f; + return f->height; +} + + +bool dmcp_font::glyph(utf8code utf8cp, glyph_info &g) const // ---------------------------------------------------------------------------- // Return the bitmap address and update coordinate info for a DMCP font // ---------------------------------------------------------------------------- @@ -401,6 +477,7 @@ bool dmcp_font::glyph(utf8code codepoint, glyph_info &g) const { // Map Unicode code points to corresonding entry in DMCP charset byte_p synthesized = nullptr; + utf8code codepoint = utf8cp; switch(codepoint) { case L'รท': codepoint = 0x80; break; @@ -501,6 +578,9 @@ bool dmcp_font::glyph(utf8code codepoint, glyph_info &g) const g.advance = g.w; return true; } + + record(dmcp_fonts, "Code point %u not found (utf8 %u)", + codepoint, utf8cp); return false; } diff --git a/src/font.h b/src/font.h index eaed0066..9639a980 100644 --- a/src/font.h +++ b/src/font.h @@ -30,6 +30,7 @@ // **************************************************************************** #include "object.h" +#include "utf8.h" RECORDER_DECLARE(fonts); @@ -59,7 +60,30 @@ struct font : object fuint advance; // X advance to next character fuint height; // Y advance to next line }; - bool glyph(utf8code codepoint, glyph_info &g) const; + bool glyph(utf8code codepoint, glyph_info &g) const; + fuint width(utf8code codepoint) const + { + glyph_info g; + if (glyph(codepoint, g)) + return g.advance; + return 0; + } + fuint width(utf8 text) const + { + fuint result = 0; + for (utf8 p = text; *p; p = utf8_next(p)) + result += width(utf8_codepoint(p)); + return result; + } + fuint height(utf8code codepoint) const + { + glyph_info g; + if (glyph(codepoint, g)) + return g.advance; + return 0; + } + fuint height() const; + OBJECT_HANDLER(font); OBJECT_PARSER(font); @@ -76,6 +100,7 @@ struct sparse_font : font sparse_font(id type = ID_sparse_font): font(type) {} static id static_type() { return ID_sparse_font; } bool glyph(utf8code codepoint, glyph_info &g) const; + fuint height(); }; typedef const sparse_font *sparse_font_p; @@ -88,6 +113,7 @@ struct dense_font : font dense_font(id type = ID_dense_font): font(type) {} static id static_type() { return ID_dense_font; } bool glyph(utf8code codepoint, glyph_info &g) const; + fuint height(); }; typedef const dense_font *dense_font_p; @@ -111,6 +137,7 @@ struct dmcp_font : font fint index() const { byte *p = payload(); return leb128(p); } bool glyph(utf8code codepoint, glyph_info &g) const; + fuint height(); }; typedef const dmcp_font *dmcp_font_p; @@ -131,5 +158,41 @@ inline bool font::glyph(utf8code codepoint, glyph_info &g) const return false; } +inline font::fuint font::height() const +// ---------------------------------------------------------------------------- +// Dynamic dispatch to the available font classes +// ---------------------------------------------------------------------------- +{ + switch(type()) + { + case ID_sparse_font: return ((sparse_font *)this)->height(); + case ID_dense_font: return ((dense_font *)this)->height(); + case ID_dmcp_font: return ((dmcp_font *)this)->height(); + default: + record(fonts_error, "Unexpectd font type %d", type()); + } + return false; +} + + +// Generated during the build process +extern const font_p EditorFont; +extern const font_p StackFont; + +// Fonts for various parts of the user interface +extern const font_p HeaderFont; +extern const font_p CursorFont; +extern const font_p ErrorFont; + +// In the DM42 DMCP - Not fully Unicode capable +extern const dmcp_font_p LibMonoFont10x17; +extern const dmcp_font_p LibMonoFont11x18; +extern const dmcp_font_p LibMonoFont12x20; +extern const dmcp_font_p LibMonoFont14x22; +extern const dmcp_font_p LibMonoFont17x25; +extern const dmcp_font_p LibMonoFont17x28; +extern const dmcp_font_p SkrMono13x18; +extern const dmcp_font_p SkrMono18x24; +extern const dmcp_font_p Free42Font; #endif // FONT_H diff --git a/tools/ttf2font/ttf2font.cpp b/tools/ttf2font/ttf2font.cpp index 1b1fef99..0fb4fbb8 100644 --- a/tools/ttf2font/ttf2font.cpp +++ b/tools/ttf2font/ttf2font.cpp @@ -576,7 +576,7 @@ void processFont(cstring fontName, dense[b]); fprintf(output, "\n};\n"); fprintf(output, - "const dense_font *%s = (dense_font *) %s_dense_data;\n", + "const font_p %s = (dense_font_p) %s_dense_data;\n", fontName, fontName); } @@ -593,7 +593,7 @@ void processFont(cstring fontName, sparse[b]); fprintf(output, "\n};\n"); fprintf(output, - "const sparse_font *%s = (sparse_font *) %s_sparse_data;\n", + "const font_p %s = (sparse_font_p) %s_sparse_data;\n", fontName, fontName); }