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