Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma pack(push, 1)
- struct s_glyph
- {
- int width;
- int height;
- int x_offset;
- int y_offset;
- int left_side_bearing;
- int advance_width;
- float min_x;
- float max_x;
- float min_y;
- float max_y;
- s_v2 uv_min;
- s_v2 uv_max;
- };
- struct s_font
- {
- int generated_font_size;
- int ascent;
- int descent;
- int line_gap;
- float scale[max_font_size + 1];
- s_glyph glyphs[128];
- };
- #pragma pack(pop)
- {
- constexpr int font_size = 96;
- constexpr int max_chars = 128;
- assert(font_size < max_font_size);
- s_font font = zero;
- font.generated_font_size = font_size;
- // @TODO(tkap, 09/07/2022): Make the resulting texture be a power of 2
- u8* font_file_data = (u8*)read_binary_file(path, &frame_arena, null, null);
- assert(font_file_data);
- stbtt_fontinfo info = zero;
- stbtt_InitFont(&info, font_file_data, stbtt_GetFontOffsetForIndex(font_file_data, 0));
- stbtt_GetFontVMetrics(&info, &font.ascent, &font.descent, &font.line_gap);
- u8* bitmaps[max_chars] = zero;
- float scale = stbtt_ScaleForPixelHeight(&info, (float)font_size);
- constexpr int padding = 2;
- int total_width = padding;
- int total_height = 0;
- for(int c = 0; c < max_chars; c++)
- {
- font.scale[c] = stbtt_ScaleForPixelHeight(&info, (float)c);
- s_glyph* glyph = &font.glyphs[c];
- bitmaps[c] = stbtt_GetCodepointBitmap(&info, 0, scale, c, &glyph->width, &glyph->height, &glyph->x_offset, &glyph->y_offset);
- stbtt_GetCodepointHMetrics(&info, c, &glyph->advance_width, &glyph->left_side_bearing);
- int x0, y0, x1, y1;
- stbtt_GetCodepointBox(&info, c, &x0, &y0, &x1, &y1);
- font.glyphs[c].min_x = x0;
- font.glyphs[c].min_y = y0;
- font.glyphs[c].max_x = x1;
- font.glyphs[c].max_y = y1;
- total_width += glyph->width + padding;
- total_height = max(total_height, glyph->height + padding * 2);
- }
- u8* data = (u8*)la_get(&frame_arena, total_width * total_height * 4, true);
- {
- int current_x = padding;
- int current_y = padding;
- for(int i = 0; i < max_chars; i++)
- {
- s_glyph* glyph = &font.glyphs[i];
- glyph->uv_min.x = current_x / (float)total_width;
- glyph->uv_max.x = (current_x + glyph->width) / (float)total_width;
- glyph->uv_min.y = padding / (float)total_height;
- glyph->uv_max.y = (padding + glyph->height) / (float)total_height;
- for(int y = 0; y < glyph->height; y++)
- {
- for(int x = 0; x < glyph->width; x++)
- {
- u8* alpha = bitmaps[i];
- alpha += x + y * glyph->width;
- u8* out = data + ((current_x + x) + (current_y + y) * total_width) * 4;
- *(out + 0) = 255;
- *(out + 1) = 255;
- *(out + 2) = 255;
- *(out + 3) = *alpha;
- }
- }
- current_x += glyph->width + padding;
- stbtt_FreeBitmap(bitmaps[i], null);
- }
- }
- buffer_write_(&cursor, &font, sizeof(font));
- buffer_write(&cursor, total_width);
- buffer_write(&cursor, total_height);
- buffer_write_(&cursor, data, total_width * total_height * 4);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement