diff --git a/src/fontgen/fontgen.c b/src/fontgen/fontgen.c index 9447612..f97cff0 100644 --- a/src/fontgen/fontgen.c +++ b/src/fontgen/fontgen.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include FT_FREETYPE_H @@ -86,36 +87,43 @@ static void generate_bytes(FILE * file, const uint8_t * bytes, int count) } } -static void generate(const char * d_file_name) +static bool generate(const char * d_file_name) { FILE * fh = fopen(d_file_name, "wb"); fprintf(fh, "module hulk.kfont;\n"); fprintf(fh, "struct CharInfo {\n"); - fprintf(fh, " uint width;\n"); - fprintf(fh, " uint height;\n"); - fprintf(fh, " int top;\n"); - fprintf(fh, " int left;\n"); + fprintf(fh, " /** Glyph bitmap width. */\n"); + fprintf(fh, " ubyte width;\n"); + fprintf(fh, " /** Glyph bitmap height. */\n"); + fprintf(fh, " ubyte height;\n"); + fprintf(fh, " /** Glyph bitmap top offset (descent from top of text row). */\n"); + fprintf(fh, " ubyte top;\n"); + fprintf(fh, " /** Glyph bitmap left offset. */\n"); + fprintf(fh, " ubyte left;\n"); + fprintf(fh, " /** Glyph bitmap. */\n"); fprintf(fh, " const ubyte[] bitmap;\n"); fprintf(fh, "};\n"); fprintf(fh, "struct FontInfo {\n"); - fprintf(fh, " uint line_height;\n"); - fprintf(fh, " uint advance;\n"); - fprintf(fh, " int baseline_offset;\n"); + fprintf(fh, " /** Font line height. */\n"); + fprintf(fh, " ubyte line_height;\n"); + fprintf(fh, " /** Font advance. */\n"); + fprintf(fh, " ubyte advance;\n"); + fprintf(fh, " /** Characters. */\n"); fprintf(fh, " const CharInfo[] chars;\n"); fprintf(fh, "};\n"); + fprintf(fh, "/** Kernel font data. */\n"); fprintf(fh, "__gshared const FontInfo Kfont = {\n"); fprintf(fh, " %du,\n", line_height); fprintf(fh, " %du,\n", max_advance); - fprintf(fh, " %d,\n", baseline_offset); fprintf(fh, " [\n"); for (int i = 0; i < N_CHARS; i++) { fprintf(fh, " /* %d */", i); fprintf(fh, " CharInfo(\n"); - fprintf(fh, " %du,\n", char_infos[i].width); - fprintf(fh, " %du,\n", char_infos[i].height); - fprintf(fh, " %d,\n", char_infos[i].top); - fprintf(fh, " %d,\n", char_infos[i].left); + fprintf(fh, " %du /* width */,\n", char_infos[i].width); + fprintf(fh, " %du /* height */,\n", char_infos[i].height); + fprintf(fh, " %du /* top */,\n", char_infos[i].top); + fprintf(fh, " %du /* left */,\n", char_infos[i].left); if (char_infos[i].width > 0) { fprintf(fh, " [\n"); @@ -131,6 +139,7 @@ static void generate(const char * d_file_name) fprintf(fh, " ],\n"); fprintf(fh, "};\n"); fclose(fh); + return true; } int main(int argc, char * argv[]) @@ -168,7 +177,59 @@ int main(int argc, char * argv[]) line_height = round_up_26_6(face->size->metrics.height); baseline_offset = (line_height - (max_top - min_bottom)) / 2 - min_bottom; - generate(out_file); + if ((line_height < 1) || (line_height > 0xFF)) + { + fprintf(stderr, "Error: invalid line_height %d\n", line_height); + return false; + } + if ((max_advance < 1) || (max_advance > 0xFF)) + { + fprintf(stderr, "Error: invalid max_advance %d\n", max_advance); + return false; + } + + for (int i = 0; i < N_CHARS; i++) + { + if ((char_infos[i].width < 0) || (char_infos[i].width > max_advance)) + { + fprintf(stderr, "Error: invalid character %d width: %d\n", i, char_infos[i].width); + return false; + } + if ((char_infos[i].height < 0) || (char_infos[i].height > line_height)) + { + fprintf(stderr, "Error: invalid character %d height: %d\n", i, char_infos[i].height); + return false; + } + if ((char_infos[i].left < 0) || (char_infos[i].left >= max_advance)) + { + fprintf(stderr, "Error: invalid character %d left: %d\n", i, char_infos[i].left); + return false; + } + /* Adjust character top to be index downward from top of font box. */ + char_infos[i].top = line_height - baseline_offset - char_infos[i].top; + if ((char_infos[i].top < 0) || (char_infos[i].top >= line_height)) + { + fprintf(stderr, "Error: invalid character %d top: %d\n", i, char_infos[i].top); + return false; + } + if ((char_infos[i].left + char_infos[i].width) > max_advance) + { + fprintf(stderr, "Error: character %d left (%d) + width (%d) > advance (%d)\n", + i, char_infos[i].left, char_infos[i].width, max_advance); + return false; + } + if ((char_infos[i].top + char_infos[i].height) > line_height) + { + fprintf(stderr, "Error: character %d top (%d) + height (%d) > line height (%d)\n", + i, char_infos[i].top, char_infos[i].height, line_height); + return false; + } + } + + if (!generate(out_file)) + { + return 1; + } return 0; } diff --git a/src/hulk/console.d b/src/hulk/console.d index a6205b5..dc48e9d 100644 --- a/src/hulk/console.d +++ b/src/hulk/console.d @@ -86,7 +86,7 @@ struct Console private static void render_char(size_t x, size_t y, char ch) { const(CharInfo) * ci = &Kfont.chars[ch]; - Fb.blit_alpha_bitmap(fb_x(x) + ci.left, fb_y(y) + Kfont.line_height - Kfont.baseline_offset - ci.top, ci.bitmap, ci.width, ci.height); + Fb.blit_alpha_bitmap(fb_x(x) + ci.left, fb_y(y) + ci.top, ci.bitmap, ci.width, ci.height); } /**