stb_easy_font.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // stb_easy_font.h - v0.5 - bitmap font for 3D rendering - public domain
  2. // Sean Barrett, Feb 2015
  3. //
  4. // Easy-to-deploy,
  5. // reasonably compact,
  6. // extremely inefficient performance-wise,
  7. // crappy-looking,
  8. // ASCII-only,
  9. // bitmap font for use in 3D APIs.
  10. //
  11. // Intended for when you just want to get some text displaying
  12. // in a 3D app as quickly as possible.
  13. //
  14. // Doesn't use any textures, instead builds characters out of quads.
  15. //
  16. // DOCUMENTATION:
  17. //
  18. // int stb_easy_font_width(char *text)
  19. //
  20. // Takes a string without newlines and returns the horizontal size.
  21. //
  22. // int stb_easy_font_print(float x, float y,
  23. // char *text, unsigned char color[4],
  24. // void *vertex_buffer, int vbuf_size)
  25. //
  26. // Takes a string (which can contain '\n') and fills out a
  27. // vertex buffer with renderable data to draw the string.
  28. // Output data assumes increasing x is rightwards, increasing y
  29. // is downwards.
  30. //
  31. // The vertex data is divided into quads, i.e. there are four
  32. // vertices in the vertex buffer for each quad.
  33. //
  34. // The vertices are stored in an interleaved format:
  35. //
  36. // x:float
  37. // y:float
  38. // z:float
  39. // color:uint8[4]
  40. //
  41. // You can ignore z and color if you get them from elsewhere
  42. // This format was chosen in the hopes it would make it
  43. // easier for you to reuse existing buffer-drawing code.
  44. //
  45. // If you pass in NULL for color, it becomes 255,255,255,255.
  46. //
  47. // Returns the number of quads.
  48. //
  49. // If the buffer isn't large enough, it will truncate.
  50. // Expect it to use an average of ~270 bytes per character.
  51. //
  52. // If your API doesn't draw quads, build a reusable index
  53. // list that allows you to render quads as indexed triangles.
  54. //
  55. // void stb_easy_font_spacing(float spacing)
  56. //
  57. // Use positive values to expand the space between characters,
  58. // and small negative values (no smaller than -1.5) to contract
  59. // the space between characters.
  60. //
  61. // E.g. spacing = 1 adds one "pixel" of spacing between the
  62. // characters. spacing = -1 is reasonable but feels a bit too
  63. // compact to me; -0.5 is a reasonable compromise as long as
  64. // you're scaling the font up.
  65. //
  66. // SAMPLE CODE:
  67. //
  68. // Here's sample code for old OpenGL; it's a lot more complicated
  69. // to make work on modern APIs, and that's your problem.
  70. //
  71. #if 0
  72. void print_string(float x, float y, char *text, float r, float g, float b)
  73. {
  74. static char buffer[99999]; // ~500 chars
  75. int num_quads;
  76. num_quads = stb_easy_font_print(x, y, text, NULL, buffer, sizeof(buffer));
  77. glColor3f(r,g,b);
  78. glEnableClientState(GL_VERTEX_ARRAY);
  79. glVertexPointer(2, GL_FLOAT, 16, buffer);
  80. glDrawArrays(GL_QUADS, 0, num_quads*4);
  81. glDisableClientState(GL_VERTEX_ARRAY);
  82. }
  83. #endif
  84. #ifndef INCLUDE_STB_EASY_FONT_H
  85. #define INCLUDE_STB_EASY_FONT_H
  86. #include <stdlib.h>
  87. struct {
  88. unsigned char advance;
  89. unsigned char h_seg;
  90. unsigned char v_seg;
  91. } stb_easy_font_charinfo[96] = {
  92. { 5, 0, 0 }, { 3, 0, 0 }, { 5, 1, 1 }, { 7, 1, 4 },
  93. { 7, 3, 7 }, { 7, 6, 12 }, { 7, 8, 19 }, { 4, 16, 21 },
  94. { 4, 17, 22 }, { 4, 19, 23 }, { 23, 21, 24 }, { 23, 22, 31 },
  95. { 20, 23, 34 }, { 22, 23, 36 }, { 19, 24, 36 }, { 21, 25, 36 },
  96. { 6, 25, 39 }, { 6, 27, 43 }, { 6, 28, 45 }, { 6, 30, 49 },
  97. { 6, 33, 53 }, { 6, 34, 57 }, { 6, 40, 58 }, { 6, 46, 59 },
  98. { 6, 47, 62 }, { 6, 55, 64 }, { 19, 57, 68 }, { 20, 59, 68 },
  99. { 21, 61, 69 }, { 22, 66, 69 }, { 21, 68, 69 }, { 7, 73, 69 },
  100. { 9, 75, 74 }, { 6, 78, 81 }, { 6, 80, 85 }, { 6, 83, 90 },
  101. { 6, 85, 91 }, { 6, 87, 95 }, { 6, 90, 96 }, { 7, 92, 97 },
  102. { 6, 96,102 }, { 5, 97,106 }, { 6, 99,107 }, { 6,100,110 },
  103. { 6,100,115 }, { 7,101,116 }, { 6,101,121 }, { 6,101,125 },
  104. { 6,102,129 }, { 7,103,133 }, { 6,104,140 }, { 6,105,145 },
  105. { 7,107,149 }, { 6,108,151 }, { 7,109,155 }, { 7,109,160 },
  106. { 7,109,165 }, { 7,118,167 }, { 6,118,172 }, { 4,120,176 },
  107. { 6,122,177 }, { 4,122,181 }, { 23,124,182 }, { 22,129,182 },
  108. { 4,130,182 }, { 22,131,183 }, { 6,133,187 }, { 22,135,191 },
  109. { 6,137,192 }, { 22,139,196 }, { 5,144,197 }, { 22,147,198 },
  110. { 6,150,202 }, { 19,151,206 }, { 21,152,207 }, { 6,155,209 },
  111. { 3,160,210 }, { 23,160,211 }, { 22,164,216 }, { 22,165,220 },
  112. { 22,167,224 }, { 22,169,228 }, { 21,171,232 }, { 21,173,233 },
  113. { 5,178,233 }, { 22,179,234 }, { 23,180,238 }, { 23,180,243 },
  114. { 23,180,248 }, { 22,189,248 }, { 22,191,252 }, { 5,196,252 },
  115. { 3,203,252 }, { 5,203,253 }, { 22,210,253 }, { 0,214,253 },
  116. };
  117. unsigned char stb_easy_font_hseg[214] = {
  118. 97,37,69,84,28,51,2,18,10,49,98,41,65,25,81,105,33,9,97,1,97,37,37,36,
  119. 81,10,98,107,3,100,3,99,58,51,4,99,58,8,73,81,10,50,98,8,73,81,4,10,50,
  120. 98,8,25,33,65,81,10,50,17,65,97,25,33,25,49,9,65,20,68,1,65,25,49,41,
  121. 11,105,13,101,76,10,50,10,50,98,11,99,10,98,11,50,99,11,50,11,99,8,57,
  122. 58,3,99,99,107,10,10,11,10,99,11,5,100,41,65,57,41,65,9,17,81,97,3,107,
  123. 9,97,1,97,33,25,9,25,41,100,41,26,82,42,98,27,83,42,98,26,51,82,8,41,
  124. 35,8,10,26,82,114,42,1,114,8,9,73,57,81,41,97,18,8,8,25,26,26,82,26,82,
  125. 26,82,41,25,33,82,26,49,73,35,90,17,81,41,65,57,41,65,25,81,90,114,20,
  126. 84,73,57,41,49,25,33,65,81,9,97,1,97,25,33,65,81,57,33,25,41,25,
  127. };
  128. unsigned char stb_easy_font_vseg[253] = {
  129. 4,2,8,10,15,8,15,33,8,15,8,73,82,73,57,41,82,10,82,18,66,10,21,29,1,65,
  130. 27,8,27,9,65,8,10,50,97,74,66,42,10,21,57,41,29,25,14,81,73,57,26,8,8,
  131. 26,66,3,8,8,15,19,21,90,58,26,18,66,18,105,89,28,74,17,8,73,57,26,21,
  132. 8,42,41,42,8,28,22,8,8,30,7,8,8,26,66,21,7,8,8,29,7,7,21,8,8,8,59,7,8,
  133. 8,15,29,8,8,14,7,57,43,10,82,7,7,25,42,25,15,7,25,41,15,21,105,105,29,
  134. 7,57,57,26,21,105,73,97,89,28,97,7,57,58,26,82,18,57,57,74,8,30,6,8,8,
  135. 14,3,58,90,58,11,7,74,43,74,15,2,82,2,42,75,42,10,67,57,41,10,7,2,42,
  136. 74,106,15,2,35,8,8,29,7,8,8,59,35,51,8,8,15,35,30,35,8,8,30,7,8,8,60,
  137. 36,8,45,7,7,36,8,43,8,44,21,8,8,44,35,8,8,43,23,8,8,43,35,8,8,31,21,15,
  138. 20,8,8,28,18,58,89,58,26,21,89,73,89,29,20,8,8,30,7,
  139. };
  140. typedef struct
  141. {
  142. unsigned char c[4];
  143. } stb_easy_font_color;
  144. static int stb_easy_font_draw_segs(float x, float y, unsigned char *segs, int num_segs, int vertical, stb_easy_font_color c, char *vbuf, int vbuf_size, int offset)
  145. {
  146. int i,j;
  147. for (i=0; i < num_segs; ++i) {
  148. int len = segs[i] & 7;
  149. x += (float) ((segs[i] >> 3) & 1);
  150. if (len && offset+64 <= vbuf_size) {
  151. float y0 = y + (float) (segs[i]>>4);
  152. for (j=0; j < 4; ++j) {
  153. * (float *) (vbuf+offset+0) = x + (j==1 || j==2 ? (vertical ? 1 : len) : 0);
  154. * (float *) (vbuf+offset+4) = y0 + ( j >= 2 ? (vertical ? len : 1) : 0);
  155. * (float *) (vbuf+offset+8) = 0.f;
  156. * (stb_easy_font_color *) (vbuf+offset+12) = c;
  157. offset += 16;
  158. }
  159. }
  160. }
  161. return offset;
  162. }
  163. float stb_easy_font_spacing_val = 0;
  164. static void stb_easy_font_spacing(float spacing)
  165. {
  166. stb_easy_font_spacing_val = spacing;
  167. }
  168. static int stb_easy_font_print(float x, float y, char *text, unsigned char color[4], void *vertex_buffer, int vbuf_size)
  169. {
  170. char *vbuf = (char *) vertex_buffer;
  171. float start_x = x;
  172. int offset = 0;
  173. stb_easy_font_color c = { 255,255,255,255 }; // use structure copying to avoid needing depending on memcpy()
  174. if (color) { c.c[0] = color[0]; c.c[1] = color[1]; c.c[2] = color[2]; c.c[3] = color[3]; }
  175. while (*text && offset < vbuf_size) {
  176. if (*text == '\n') {
  177. y += 12;
  178. x = start_x;
  179. } else {
  180. unsigned char advance = stb_easy_font_charinfo[*text-32].advance;
  181. float y_ch = advance & 16 ? y+1 : y;
  182. int h_seg, v_seg, num_h, num_v;
  183. h_seg = stb_easy_font_charinfo[*text-32 ].h_seg;
  184. v_seg = stb_easy_font_charinfo[*text-32 ].v_seg;
  185. num_h = stb_easy_font_charinfo[*text-32+1].h_seg - h_seg;
  186. num_v = stb_easy_font_charinfo[*text-32+1].v_seg - v_seg;
  187. offset = stb_easy_font_draw_segs(x, y_ch, &stb_easy_font_hseg[h_seg], num_h, 0, c, vbuf, vbuf_size, offset);
  188. offset = stb_easy_font_draw_segs(x, y_ch, &stb_easy_font_vseg[v_seg], num_v, 1, c, vbuf, vbuf_size, offset);
  189. x += advance & 15;
  190. x += stb_easy_font_spacing_val;
  191. }
  192. ++text;
  193. }
  194. return (unsigned) offset/64;
  195. }
  196. static int stb_easy_font_width(char *text)
  197. {
  198. int len = 0;
  199. while (*text) {
  200. len += stb_easy_font_charinfo[*text-32].advance & 15;
  201. len += stb_easy_font_spacing_val;
  202. ++text;
  203. }
  204. return len;
  205. }
  206. #endif