Advertisement
Tkap1

Untitled

Aug 16th, 2022
950
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.90 KB | None | 0 0
  1.  
  2.  
  3. #pragma pack(push, 1)
  4. struct s_glyph
  5. {
  6.     int width;
  7.     int height;
  8.     int x_offset;
  9.     int y_offset;
  10.     int left_side_bearing;
  11.     int advance_width;
  12.     float min_x;
  13.     float max_x;
  14.     float min_y;
  15.     float max_y;
  16.     s_v2 uv_min;
  17.     s_v2 uv_max;
  18. };
  19.  
  20. struct s_font
  21. {
  22.     int generated_font_size;
  23.     int ascent;
  24.     int descent;
  25.     int line_gap;
  26.     float scale[max_font_size + 1];
  27.     s_glyph glyphs[128];
  28. };
  29. #pragma pack(pop)
  30.  
  31. {
  32.     constexpr int font_size = 96;
  33.     constexpr int max_chars = 128;
  34.     assert(font_size < max_font_size);
  35.  
  36.  
  37.     s_font font = zero;
  38.  
  39.     font.generated_font_size = font_size;
  40.  
  41.     // @TODO(tkap, 09/07/2022): Make the resulting texture be a power of 2
  42.  
  43.     u8* font_file_data = (u8*)read_binary_file(path, &frame_arena, null, null);
  44.     assert(font_file_data);
  45.  
  46.     stbtt_fontinfo info = zero;
  47.     stbtt_InitFont(&info, font_file_data, stbtt_GetFontOffsetForIndex(font_file_data, 0));
  48.  
  49.     stbtt_GetFontVMetrics(&info, &font.ascent, &font.descent, &font.line_gap);
  50.  
  51.     u8* bitmaps[max_chars] = zero;
  52.  
  53.     float scale = stbtt_ScaleForPixelHeight(&info, (float)font_size);
  54.  
  55.     constexpr int padding = 2;
  56.     int total_width = padding;
  57.     int total_height = 0;
  58.  
  59.  
  60.     for(int c = 0; c < max_chars; c++)
  61.     {
  62.         font.scale[c] = stbtt_ScaleForPixelHeight(&info, (float)c);
  63.  
  64.         s_glyph* glyph = &font.glyphs[c];
  65.  
  66.         bitmaps[c] = stbtt_GetCodepointBitmap(&info, 0, scale, c, &glyph->width, &glyph->height, &glyph->x_offset, &glyph->y_offset);
  67.         stbtt_GetCodepointHMetrics(&info, c, &glyph->advance_width, &glyph->left_side_bearing);
  68.  
  69.         int x0, y0, x1, y1;
  70.         stbtt_GetCodepointBox(&info, c, &x0, &y0, &x1, &y1);
  71.         font.glyphs[c].min_x = x0;
  72.         font.glyphs[c].min_y = y0;
  73.         font.glyphs[c].max_x = x1;
  74.         font.glyphs[c].max_y = y1;
  75.  
  76.  
  77.         total_width += glyph->width + padding;
  78.  
  79.         total_height = max(total_height, glyph->height + padding * 2);
  80.     }
  81.  
  82.     u8* data = (u8*)la_get(&frame_arena, total_width * total_height * 4, true);
  83.  
  84.     {
  85.         int current_x = padding;
  86.         int current_y = padding;
  87.         for(int i = 0; i < max_chars; i++)
  88.         {
  89.             s_glyph* glyph = &font.glyphs[i];
  90.  
  91.             glyph->uv_min.x = current_x / (float)total_width;
  92.             glyph->uv_max.x = (current_x + glyph->width) / (float)total_width;
  93.  
  94.             glyph->uv_min.y = padding / (float)total_height;
  95.             glyph->uv_max.y = (padding + glyph->height) / (float)total_height;
  96.  
  97.             for(int y = 0; y < glyph->height; y++)
  98.             {
  99.                 for(int x = 0; x < glyph->width; x++)
  100.                 {
  101.                     u8* alpha = bitmaps[i];
  102.                     alpha += x + y * glyph->width;
  103.  
  104.                     u8* out = data + ((current_x + x) + (current_y + y) * total_width) * 4;
  105.                     *(out + 0) = 255;
  106.                     *(out + 1) = 255;
  107.                     *(out + 2) = 255;
  108.                     *(out + 3) = *alpha;
  109.                 }
  110.             }
  111.  
  112.             current_x += glyph->width + padding;
  113.  
  114.             stbtt_FreeBitmap(bitmaps[i], null);
  115.         }
  116.     }
  117.  
  118.     buffer_write_(&cursor, &font, sizeof(font));
  119.     buffer_write(&cursor, total_width);
  120.     buffer_write(&cursor, total_height);
  121.     buffer_write_(&cursor, data, total_width * total_height * 4);
  122. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement