| 1066 | } |
| 1067 | |
| 1068 | LfFont load_font(const char* filepath, uint32_t pixelsize, uint32_t tex_width, uint32_t tex_height, uint32_t line_gap_add) { |
| 1069 | LfFont font = {0}; |
| 1070 | /* Opening the file, reading the content to a buffer and parsing the loaded data with stb_truetype */ |
| 1071 | FILE* file = fopen(filepath, "rb"); |
| 1072 | if (file == NULL) { |
| 1073 | LF_ERROR("Failed to open font file '%s'\n", filepath); |
| 1074 | } |
| 1075 | |
| 1076 | // Loading the content |
| 1077 | fseek(file, 0, SEEK_END); |
| 1078 | long fileSize = ftell(file); |
| 1079 | fseek(file, 0, SEEK_SET); |
| 1080 | uint8_t* buffer = (uint8_t*)malloc(fileSize); |
| 1081 | size_t bytesRead = fread(buffer, 1, fileSize, file); |
| 1082 | fclose(file); |
| 1083 | if (bytesRead != fileSize) { |
| 1084 | LF_ERROR("Failed to read font file '%s'\n", filepath); |
| 1085 | // Handle the error (e.g., free memory and return from the function) |
| 1086 | free(buffer); |
| 1087 | LfFont emptyFont = {0}; // Or whatever initialization you need |
| 1088 | return emptyFont; |
| 1089 | } |
| 1090 | font.font_info = malloc(sizeof(stbtt_fontinfo)); |
| 1091 | |
| 1092 | // Initializing the font with stb_truetype |
| 1093 | stbtt_InitFont((stbtt_fontinfo*)font.font_info, buffer, stbtt_GetFontOffsetForIndex(buffer, 0)); |
| 1094 | |
| 1095 | stbtt_fontinfo* fontinfo = (stbtt_fontinfo*)font.font_info; |
| 1096 | int numglyphs = fontinfo->numGlyphs; |
| 1097 | |
| 1098 | // Loading the font bitmap to memory by using stbtt_BakeFontBitmap |
| 1099 | uint8_t* bitmap = (uint8_t*)malloc(tex_width * tex_height * sizeof(uint32_t)); |
| 1100 | uint8_t* bitmap_4bpp = (uint8_t*)malloc(tex_width * tex_height * 4 * sizeof(uint32_t)); |
| 1101 | font.cdata = malloc(sizeof(stbtt_bakedchar) * numglyphs); |
| 1102 | font.tex_width = tex_width; |
| 1103 | font.tex_height = tex_height; |
| 1104 | font.line_gap_add = line_gap_add; |
| 1105 | font.font_size = pixelsize; |
| 1106 | font.num_glyphs = numglyphs; |
| 1107 | stbtt_BakeFontBitmap(buffer, 0, pixelsize, bitmap, tex_width, tex_height, 32, numglyphs, (stbtt_bakedchar*)font.cdata); |
| 1108 | |
| 1109 | uint32_t bitmap_index = 0; |
| 1110 | for(uint32_t i = 0; i < (uint32_t)(tex_width * tex_height * 4); i++) { |
| 1111 | bitmap_4bpp[i] = bitmap[bitmap_index]; |
| 1112 | if((i + 1) % 4 == 0) { |
| 1113 | bitmap_index++; |
| 1114 | } |
| 1115 | } |
| 1116 | |
| 1117 | // Creating an opengl texture (texture atlas) for the font |
| 1118 | glGenTextures(1, &font.bitmap.id); |
| 1119 | glBindTexture(GL_TEXTURE_2D, font.bitmap.id); |
| 1120 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 1121 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 1122 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
| 1123 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
| 1124 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap_4bpp); |
| 1125 | glGenerateMipmap(GL_TEXTURE_2D); |
no outgoing calls
no test coverage detected