#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <ft2build.h> #include FT_FREETYPE_H #define array_size(a) (sizeof(a) / sizeof((a)[0])) #define FONT "FiraMonoOT-Regular.otf" static FT_Library freetype; static FT_Face font_face; static _Noreturn void die(const char *fmt, ...) { va_list args; va_start(args, fmt); fprintf(stderr, "Error: "); vfprintf(stderr, fmt, args); va_end(args); fputc('\n', stderr); exit(1); } int main(void) { int err; err = FT_Init_FreeType(&freetype); if (err) die("Failed to initialize freetype."); err = FT_New_Face(freetype, FONT, 0, &font_face); if (err) die("Failed to open font."); err = FT_Set_Pixel_Sizes(font_face, 16, 16); if (err) die("Failed to set font size."); FT_ULong charcode; FT_UInt index; FT_GlyphSlot slot = font_face->glyph; uint16_t interval_starts[128] = {}; uint8_t interval_sizes[128] = {}; int num_intervals = 0; uint16_t charcodes[1024] = {}; uint32_t bitmap_offsets[1024] = {}; int num_glyphs = 0; uint8_t bitmap_bytes[1024 * 1024] = {}; int num_bitmap_bytes = 0; charcode = FT_Get_First_Char(font_face, &index); while (index != 0) { bool choose = (charcode == 0) || (32 <= charcode && charcode <= 126) || (0x80 <= charcode && charcode <= 0xff) || (0x2000 <= charcode && charcode <= 0x206f) || (0x2500 <= charcode && charcode <= 0x257f) || (charcode == 0x25c9); if (choose) { charcodes[num_glyphs] = charcode; err = FT_Load_Glyph(font_face, index, FT_LOAD_RENDER); if (err) die("Failed to load glyph."); bitmap_offsets[num_glyphs] = num_bitmap_bytes; num_glyphs++; bitmap_bytes[num_bitmap_bytes++] = (uint8_t)slot->bitmap_top; bitmap_bytes[num_bitmap_bytes++] = (uint8_t)slot->bitmap_left; bitmap_bytes[num_bitmap_bytes++] = (uint8_t)slot->bitmap.rows; bitmap_bytes[num_bitmap_bytes++] = (uint8_t)slot->bitmap.width; int num_pixels = slot->bitmap.rows * slot->bitmap.width; for (int i = 0; i < num_pixels; i++) bitmap_bytes[num_bitmap_bytes++] = slot->bitmap.buffer[i]; } charcode = FT_Get_Next_Char(font_face, charcode, &index); } if (num_glyphs > 0) { interval_starts[0] = charcodes[0]; interval_sizes[0] = 1; for (int i = 1; i < num_glyphs; i++) { if (charcodes[i - 1] + 1 != charcodes[i]) { num_intervals++; interval_starts[num_intervals] = charcodes[i]; } interval_sizes[num_intervals]++; } num_intervals++; } int fds[2]; pipe(fds); if (fork() == 0) { close(fds[1]); dup2(fds[0], 0); close(fds[0]); execlp("fmt", "fmt", "--prefix= ", (char *)NULL); } close(fds[0]); dup2(fds[1], 1); close(fds[1]); printf("static const uint16_t interval_starts[%d] = {\n\n ", num_intervals); for (int i = 0; i < num_intervals; i++) { printf("%u, ", (unsigned)interval_starts[i]); } printf("\n\n};\n\n"); printf("static const uint8_t interval_sizes[%d] = {\n\n ", num_intervals); for (int i = 0; i < num_intervals; i++) { printf("%u, ", (unsigned)interval_sizes[i]); } printf("\n\n};\n\n"); printf("static const uint16_t bitmap_offsets[%d] = {\n\n ", num_glyphs); for (int i = 0; i < num_glyphs; i++) { printf("%u, ", (unsigned)bitmap_offsets[i]); } printf("\n\n};\n\n"); printf("static const uint8_t bitmap_bytes[%d] = {\n\n ", num_bitmap_bytes); for (int i = 0; i < num_bitmap_bytes; i++) { printf("%u, ", (unsigned)bitmap_bytes[i]); } printf("\n\n};\n"); fflush(stdout); close(1); wait(NULL); return 0; }