gen_incs.c (5280B)
1 #include <raylib.h> 2 3 #include <stddef.h> 4 #include <stdint.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 9 #include "config.h" 10 11 #define function static 12 13 #define ISSPACE(a) ((a) == ' ' || (a) == '\t') 14 15 typedef struct {uint8_t *data; ptrdiff_t len;} str8; 16 17 function str8 18 read_whole_file(char *name, str8 *mem) 19 { 20 str8 res = {0}; 21 FILE *fp = fopen(name, "r"); 22 23 if (!fp) { 24 fputs("Failed to open file!\n", stdout); 25 exit(1); 26 } 27 28 fseek(fp, 0, SEEK_END); 29 res.len = ftell(fp); 30 rewind(fp); 31 32 if (mem->len < res.len) { 33 fputs("Not enough space for reading file!\n", stdout); 34 exit(1); 35 } 36 res.data = mem->data; 37 res.len = fread(res.data, 1, res.len, fp); 38 fclose(fp); 39 40 mem->data += res.len; 41 mem->len -= res.len; 42 43 return res; 44 } 45 46 /* NOTE: modified from raylib */ 47 function void 48 export_font_as_code(char *font_path, char *output_name, int font_size, str8 mem) 49 { 50 str8 raw = read_whole_file(font_path, &mem); 51 Font font = {0}; 52 font.baseSize = font_size; 53 font.glyphCount = 95; 54 font.glyphPadding = 4; 55 56 font.glyphs = LoadFontData(raw.data, raw.len, font.baseSize, 0, font.glyphCount, FONT_DEFAULT); 57 if (font.glyphs == NULL) { 58 printf("Failed to load font data: %s\n", font_path); 59 exit(1); 60 } 61 62 Image atlas = GenImageFontAtlas(font.glyphs, &font.recs, font.glyphCount, font.baseSize, 63 font.glyphPadding, 0); 64 65 FILE *fp = fopen(output_name, "w"); 66 if (fp == NULL) { 67 printf("Failed to open output font file: %s\n", output_name); 68 exit(1); 69 } 70 71 char suffix[256]; 72 strncpy(suffix, GetFileNameWithoutExt(output_name), 256 - 1); 73 74 #define TEXT_BYTES_PER_LINE 16 75 76 int image_data_size = GetPixelDataSize(atlas.width, atlas.height, atlas.format); 77 int comp_data_size = 0; 78 unsigned char *comp_data = CompressData(atlas.data, image_data_size, &comp_data_size); 79 80 // Save font image data (compressed) 81 fprintf(fp, "#define COMPRESSED_DATA_SIZE_FONT_%s %i\n\n", TextToUpper(suffix), comp_data_size); 82 fprintf(fp, "// Font image pixels data compressed (DEFLATE)\n"); 83 fprintf(fp, "// NOTE: Original pixel data simplified to GRAYSCALE\n"); 84 fprintf(fp, "static unsigned char fontData_%s[COMPRESSED_DATA_SIZE_FONT_%s] = { ", suffix, TextToUpper(suffix)); 85 for (int i = 0; i < comp_data_size - 1; i++) fprintf(fp, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%02x,\n " : "0x%02x, "), comp_data[i]); 86 fprintf(fp, "0x%02x };\n\n", comp_data[comp_data_size - 1]); 87 RL_FREE(comp_data); 88 89 // Save font recs data 90 fprintf(fp, "// Font characters rectangles data\n"); 91 fprintf(fp, "static Rectangle fontRecs_%s[%i] = {\n", suffix, font.glyphCount); 92 for (int i = 0; i < font.glyphCount; i++) 93 fprintf(fp, " { %1.0f, %1.0f, %1.0f , %1.0f },\n", font.recs[i].x, font.recs[i].y, font.recs[i].width, font.recs[i].height); 94 fprintf(fp, "};\n\n"); 95 96 // Save font glyphs data 97 // NOTE: Glyphs image data not saved (grayscale pixels), it could be generated from image and recs 98 fprintf(fp, "// Font glyphs info data\n"); 99 fprintf(fp, "// NOTE: No glyphs.image data provided\n"); 100 fprintf(fp, "static GlyphInfo fontGlyphs_%s[%i] = {\n", suffix, font.glyphCount); 101 for (int i = 0; i < font.glyphCount; i++) 102 fprintf(fp, " { %i, %i, %i, %i, { 0 }},\n", font.glyphs[i].value, font.glyphs[i].offsetX, font.glyphs[i].offsetY, font.glyphs[i].advanceX); 103 fprintf(fp, "};\n\n"); 104 105 // Custom font loading function 106 fprintf(fp, "// Font loading function: %s\n", suffix); 107 fprintf(fp, "static Font LoadFont_%s(void)\n{\n", suffix); 108 fprintf(fp, " Font font = { 0 };\n\n"); 109 fprintf(fp, " font.baseSize = %i;\n", font.baseSize); 110 fprintf(fp, " font.glyphCount = %i;\n", font.glyphCount); 111 fprintf(fp, " font.glyphPadding = %i;\n\n", font.glyphPadding); 112 fprintf(fp, " // Custom font loading\n"); 113 fprintf(fp, " // NOTE: Compressed font image data (DEFLATE), it requires DecompressData() function\n"); 114 fprintf(fp, " int fontDataSize_%s = 0;\n", suffix); 115 fprintf(fp, " unsigned char *data = DecompressData(fontData_%s, COMPRESSED_DATA_SIZE_FONT_%s, &fontDataSize_%s);\n", suffix, TextToUpper(suffix), suffix); 116 fprintf(fp, " Image imFont = { data, %i, %i, 1, %i };\n\n", atlas.width, atlas.height, atlas.format); 117 fprintf(fp, " // Load texture from image\n"); 118 fprintf(fp, " font.texture = LoadTextureFromImage(imFont);\n"); 119 fprintf(fp, " UnloadImage(imFont); // Uncompressed data can be unloaded from memory\n\n"); 120 fprintf(fp, " // Assign glyph recs and info data directly\n"); 121 fprintf(fp, " // WARNING: This font data must not be unloaded\n"); 122 fprintf(fp, " font.recs = fontRecs_%s;\n", suffix); 123 fprintf(fp, " font.glyphs = fontGlyphs_%s;\n\n", suffix); 124 fprintf(fp, " return font;\n"); 125 fprintf(fp, "}\n"); 126 127 fclose(fp); 128 } 129 130 int 131 main(void) 132 { 133 static uint8_t mem[2u * 1024u * 1024u]; 134 str8 smem = {.data = mem, .len = sizeof(mem)}; 135 136 SetTraceLogLevel(LOG_NONE); 137 int font_sizes[] = { FONT_SIZE, FONT_SIZE/2 }; 138 for (unsigned int i = 0; i < sizeof(font_sizes)/sizeof(*font_sizes); i++) { 139 str8 tmem = smem; 140 str8 rmem = smem; 141 size_t tlen = snprintf((char *)tmem.data, tmem.len, "out/lora_sb_%d_inc.h", i); 142 rmem.len -= (tlen + 1); 143 rmem.data += (tlen + 1); 144 export_font_as_code("assets/Lora-SemiBold.ttf", (char *)tmem.data, font_sizes[i], rmem); 145 } 146 147 return 0; 148 }