free_glyph.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #ifndef FREE_GLYPH_H
  2. #define FREE_GLYPH_H
  3. #include <stdbool.h>
  4. #include <stdint.h>
  5. #include <ft2build.h>
  6. #include FT_FREETYPE_H
  7. #include "vec2.h"
  8. #include "vec4.h"
  9. #include "glyph_attr.h"
  10. #include "simple_render.h"
  11. struct glyph_info {
  12. struct vec2i64 a;
  13. struct {
  14. uint32_t w;
  15. uint32_t h;
  16. int32_t l;
  17. int32_t t;
  18. } b;
  19. float tx;
  20. };
  21. struct free_glyph_atlas {
  22. uint32_t font_tex;
  23. struct vec2ui atlas_dim;
  24. struct glyph_info g_infos[128];
  25. };
  26. struct free_glyph_atlas fga_create(FT_Face font_face);
  27. float fga_calc_col(const struct free_glyph_atlas *fga, const struct app *app,
  28. const char *cstr, size_t cstr_size,
  29. struct vec2f pos, size_t index);
  30. float fga_calc_col_buffer(const struct free_glyph_atlas *fga,
  31. const struct app *app);
  32. void fga_calc(struct free_glyph_atlas *fga, struct simple_render *sr,
  33. const struct app *app, const char *cstr, size_t cstr_size,
  34. struct vec2f pos, struct vec4f fg_color, struct vec4f bg_color);
  35. void fga_calc_buffer(struct free_glyph_atlas *fga, struct simple_render *sr,
  36. const struct app *app, struct vec2f pos);
  37. void fga_load_texture_atlas_or_exit(struct free_glyph_atlas *fga,
  38. FT_Face font_face);
  39. struct vec2ui fga_calc_atlas_dimensions(FT_Face font_face);
  40. #if defined(FREE_GLYPH_IMP) || defined(IMP)
  41. #include "shader.h"
  42. #include "gl_util.h"
  43. struct free_glyph_atlas
  44. fga_create(FT_Face font_face)
  45. {
  46. struct free_glyph_atlas fga = {0};
  47. fga_load_texture_atlas_or_exit(&fga, font_face);
  48. return fga;
  49. }
  50. float
  51. fga_calc_col(const struct free_glyph_atlas *fga, const struct app *app,
  52. const char *cstr, size_t cstr_size, struct vec2f pos,
  53. size_t index)
  54. {
  55. struct vec2f pen = pos;
  56. struct vec2f dim = vec2f_from_ui(fga->atlas_dim);
  57. if ( index > cstr_size ) {
  58. index = cstr_size - 1;
  59. }
  60. for ( size_t i = 0; i < index; ++i ) {
  61. char c = cstr[i];
  62. if ( c == '\n' ) {
  63. pen.x = 0;
  64. pen.y -= dim.y;
  65. continue;
  66. }
  67. struct glyph_info gi = fga->g_infos[(int64_t)c];
  68. if ( c == '\t' ) {
  69. c = ' ';
  70. gi = fga->g_infos[(int64_t)c];
  71. gi.a.x *= app->cfg.tab_size;
  72. }
  73. pen.x += (float) gi.a.x;
  74. pen.y += (float) gi.a.y;
  75. }
  76. return pen.x;
  77. }
  78. float
  79. fga_calc_col_buffer(const struct free_glyph_atlas *fga,
  80. const struct app *app)
  81. {
  82. return fga_calc_col(fga, app, app->buf.data.items,
  83. app->buf.data.size, vec2fs(0),
  84. app->buf.cur);
  85. }
  86. /* struct free_glyph_atlas */
  87. /* fga_calc(struct free_glyph_atlas fga, struct app app, */
  88. /* const char *cstr, size_t cstr_size, struct vec2f pos, */
  89. /* struct vec4f fg_color, struct vec4f bg_color) */
  90. /* { */
  91. /* struct vec2f pen = pos; */
  92. /* struct vec2f dim = vec2f_from_ui(fga->atlas_dim); */
  93. /* for ( size_t i = 0; i < cstr_size; ++i ) { */
  94. /* char c = cstr[i]; */
  95. /* if ( c == '\n' ) { */
  96. /* pen.x = 0; */
  97. /* pen.y -= dim.y; */
  98. /* continue; */
  99. /* } */
  100. /* struct glyph_info gi = fga->g_infos[(int64_t)c]; */
  101. /* if ( c == '\t' ) { */
  102. /* c = ' '; */
  103. /* gi = fga->g_infos[(int64_t)c]; */
  104. /* gi.a.x *= app.cfg.tab_size; */
  105. /* } */
  106. /* float w = (float)gi.b.w; */
  107. /* float h = (float)gi.b.h; */
  108. /* struct free_glyph gly = { */
  109. /* .pos = { */
  110. /* pen.x + (float) gi.b.l, */
  111. /* pen.y + (float) gi.b.t */
  112. /* }, */
  113. /* .size = {w, -h}, */
  114. /* .uv_pos = { gi.tx, 0.0f }, */
  115. /* .uv_size = { w / dim.x, h / dim.y }, */
  116. /* .fg_color = fg_color, */
  117. /* .bg_color = bg_color, */
  118. /* }; */
  119. /* pen.x += (float) gi.a.x; */
  120. /* pen.y += (float) gi.a.y; */
  121. /* DA_APPEND(fga->glyphs, gly); */
  122. /* } */
  123. /* return fga; */
  124. /* } */
  125. /* struct free_glyph_atlas */
  126. /* fga_calc_buffer(struct free_glyph_atlas fga, */
  127. /* struct app app, */
  128. /* struct vec2f size) */
  129. /* { */
  130. /* return fga_calc(fga, app, */
  131. /* app.buf.data.items, app.buf.data.size, */
  132. /* size, vec4fs(1), vec4fs(0)); */
  133. /* } */
  134. void
  135. fga_load_texture_atlas_or_exit(struct free_glyph_atlas *fga,
  136. FT_Face font_face)
  137. {
  138. struct vec2ui dim = fga_calc_atlas_dimensions(font_face);
  139. fga->atlas_dim = dim;
  140. glActiveTexture(GL_TEXTURE0);
  141. glGenTextures(1, &fga->font_tex);
  142. glBindTexture(GL_TEXTURE_2D, fga->font_tex);
  143. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  144. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  145. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  146. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  147. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  148. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, (int32_t)dim.x, (int32_t)dim.y,
  149. 0, GL_RED, GL_UNSIGNED_BYTE, 0);
  150. FT_GlyphSlot g = font_face->glyph;
  151. uint64_t x = 0;
  152. for ( uint64_t i = 0; i < 128; ++i ) {
  153. if ( FT_Load_Char(font_face, i, FT_LOAD_RENDER) ) {
  154. fprintf(stderr, "[ERROR] Failed to load char: %c\n",
  155. (char)i);
  156. exit(EXIT_FAILURE);
  157. }
  158. if ( FT_Render_Glyph(g, FT_RENDER_MODE_NORMAL) ) {
  159. fprintf(stderr, "[ERROR] Failed to render char: %c\n",
  160. (char)i);
  161. exit(EXIT_FAILURE);
  162. }
  163. glTexSubImage2D(GL_TEXTURE_2D, 0, (int32_t) x, 0,
  164. (int32_t) g->bitmap.width,
  165. (int32_t) g->bitmap.rows,
  166. GL_RED, GL_UNSIGNED_BYTE,
  167. g->bitmap.buffer);
  168. fga->g_infos[i] = (struct glyph_info) {
  169. .a = {
  170. .x = g->advance.x >> 6,
  171. .y = g->advance.y >> 6,
  172. },
  173. .b = {
  174. .w = g->bitmap.width,
  175. .h = g->bitmap.rows,
  176. .l = g->bitmap_left,
  177. .t = g->bitmap_top,
  178. },
  179. .tx = ((float) x) / ((float) dim.x),
  180. };
  181. x += g->bitmap.width;
  182. }
  183. }
  184. struct vec2ui
  185. fga_calc_atlas_dimensions(FT_Face font_face)
  186. {
  187. struct vec2ui dim = {0};
  188. for ( uint64_t i = 0; i < 128; ++i ) {
  189. if ( FT_Load_Char(font_face, i, FT_LOAD_RENDER) ) {
  190. fprintf(stderr, "[WARNING] Failed to load char: %c\n",
  191. (char)i);
  192. continue;
  193. }
  194. dim.x += font_face->glyph->bitmap.width;
  195. uint32_t row = font_face->glyph->bitmap.rows;
  196. dim.y = ( dim.y < row ) * row
  197. + ( ! (dim.y < row) ) * dim.y;
  198. }
  199. return dim;
  200. }
  201. #endif /* defined(FREE_GLYPH_IMP) || defined(IMP) */
  202. #endif