Rework Kfont to store glyph top as offset from top of text row

This commit is contained in:
Josh Holtrop 2023-09-13 13:48:11 -04:00
parent 4fcea6a283
commit 4c67faaad4
2 changed files with 76 additions and 15 deletions

View File

@ -1,5 +1,6 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <ft2build.h>
#include <stdio.h>
#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;
}

View File

@ -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);
}
/**