text_buffer_manager.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. /* Copyright 2013 Jeremie Roy. All rights reserved.
  2. * License: http://www.opensource.org/licenses/BSD-2-Clause
  3. */
  4. #include "text_buffer_manager.h"
  5. #include "../cube_atlas.h"
  6. #include <bx/bx.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include <stddef.h> /* offsetof */
  11. #define MAX_TEXT_BUFFER_COUNT 64
  12. #define MAX_BUFFERED_CHARACTERS 8192
  13. long int fsize(FILE* _file)
  14. {
  15. long int pos = ftell(_file);
  16. fseek(_file, 0L, SEEK_END);
  17. long int size = ftell(_file);
  18. fseek(_file, pos, SEEK_SET);
  19. return size;
  20. }
  21. static const bgfx::Memory* loadShader(const char* _shaderPath, const char* _shaderName)
  22. {
  23. char out[512];
  24. strcpy(out, _shaderPath);
  25. strcat(out, _shaderName);
  26. strcat(out, ".bin");
  27. FILE* file = fopen(out, "rb");
  28. if (NULL != file)
  29. {
  30. uint32_t size = (uint32_t)fsize(file);
  31. const bgfx::Memory* mem = bgfx::alloc(size+1);
  32. /*size_t ignore =*/ fread(mem->data, 1, size, file);
  33. /*BX_UNUSED(ignore);*/
  34. fclose(file);
  35. mem->data[mem->size-1] = '\0';
  36. return mem;
  37. }
  38. return NULL;
  39. }
  40. // Table from Flexible and Economical UTF-8 Decoder
  41. // Copyright (c) 2008-2009 Bjoern Hoehrmann <[email protected]>
  42. // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
  43. static const uint8_t utf8d[] = {
  44. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
  45. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
  46. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
  47. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
  48. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
  49. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
  50. 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
  51. 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
  52. 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
  53. 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
  54. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
  55. 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
  56. 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
  57. 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
  58. };
  59. #define UTF8_ACCEPT 0
  60. #define UTF8_REJECT 1
  61. inline uint32_t utf8_decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
  62. uint32_t type = utf8d[byte];
  63. *codep = (*state != UTF8_ACCEPT) ?
  64. (byte & 0x3fu) | (*codep << 6) :
  65. (0xff >> type) & (byte);
  66. *state = utf8d[256 + *state*16 + type];
  67. return *state;
  68. }
  69. inline int utf8_strlen(uint8_t* s, size_t* count) {
  70. uint32_t codepoint;
  71. uint32_t state = 0;
  72. for (*count = 0; *s; ++s)
  73. if (!utf8_decode(&state, &codepoint, *s))
  74. *count += 1;
  75. return state != UTF8_ACCEPT;
  76. }
  77. class TextBuffer
  78. {
  79. public:
  80. /// TextBuffer is bound to a fontManager for glyph retrieval
  81. /// @remark the ownership of the manager is not taken
  82. TextBuffer(FontManager* _fontManager);
  83. ~TextBuffer();
  84. void setStyle(uint32_t _flags = STYLE_NORMAL) { m_styleFlags = _flags; }
  85. void setTextColor(uint32_t _rgba = 0x000000FF) { m_textColor = toABGR(_rgba); }
  86. void setBackgroundColor(uint32_t _rgba = 0x000000FF) { m_backgroundColor = toABGR(_rgba); }
  87. void setOverlineColor(uint32_t _rgba = 0x000000FF) { m_overlineColor = toABGR(_rgba); }
  88. void setUnderlineColor(uint32_t _rgba = 0x000000FF) { m_underlineColor = toABGR(_rgba); }
  89. void setStrikeThroughColor(uint32_t _rgba = 0x000000FF) { m_strikeThroughColor = toABGR(_rgba); }
  90. void setPenPosition(float _x, float _y) { m_penX = _x; m_penY = _y; }
  91. /// return the size of the text
  92. //Rectangle measureText(FontHandle _fontHandle, const char * _string);
  93. //Rectangle measureText(FontHandle _fontHandle, const wchar_t * _string);
  94. /// append an ASCII/utf-8 string to the buffer using current pen position and color
  95. void appendText(FontHandle _fontHandle, const char * _string);
  96. /// append a wide char unicode string to the buffer using current pen position and color
  97. void appendText(FontHandle _fontHandle, const wchar_t * _string);
  98. /// Clear the text buffer and reset its state (pen/color)
  99. void clearTextBuffer();
  100. /// get pointer to the vertex buffer to submit it to the graphic card
  101. const uint8_t* getVertexBuffer(){ return (uint8_t*) m_vertexBuffer; }
  102. /// number of vertex in the vertex buffer
  103. uint32_t getVertexCount(){ return m_vertexCount; }
  104. /// size in bytes of a vertex
  105. uint32_t getVertexSize(){ return sizeof(TextVertex); }
  106. /// get a pointer to the index buffer to submit it to the graphic
  107. const uint16_t* getIndexBuffer(){ return m_indexBuffer; }
  108. /// number of index in the index buffer
  109. uint32_t getIndexCount(){ return m_indexCount; }
  110. /// size in bytes of an index
  111. uint32_t getIndexSize(){ return sizeof(uint16_t); }
  112. uint32_t getTextColor(){ return toABGR(m_textColor); }
  113. private:
  114. void appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo);
  115. void verticalCenterLastLine(float _txtDecalY, float _top, float _bottom);
  116. uint32_t toABGR(uint32_t _rgba)
  117. {
  118. return (((_rgba >> 0) & 0xff) << 24) |
  119. (((_rgba >> 8) & 0xff) << 16) |
  120. (((_rgba >> 16) & 0xff) << 8) |
  121. (((_rgba >> 24) & 0xff) << 0);
  122. }
  123. uint32_t m_styleFlags;
  124. // color states
  125. uint32_t m_textColor;
  126. uint32_t m_backgroundColor;
  127. uint32_t m_overlineColor;
  128. uint32_t m_underlineColor;
  129. uint32_t m_strikeThroughColor;
  130. //position states
  131. float m_penX;
  132. float m_penY;
  133. float m_originX;
  134. float m_originY;
  135. float m_lineAscender;
  136. float m_lineDescender;
  137. float m_lineGap;
  138. ///
  139. FontManager* m_fontManager;
  140. void setVertex(uint32_t _i, float _x, float _y, uint32_t _rgba, uint8_t _style = STYLE_NORMAL)
  141. {
  142. m_vertexBuffer[_i].x = _x;
  143. m_vertexBuffer[_i].y = _y;
  144. m_vertexBuffer[_i].rgba = _rgba;
  145. m_styleBuffer[_i] = _style;
  146. }
  147. struct TextVertex
  148. {
  149. float x,y;
  150. int16_t u,v,w,t;
  151. uint32_t rgba;
  152. };
  153. TextVertex* m_vertexBuffer;
  154. uint16_t* m_indexBuffer;
  155. uint8_t* m_styleBuffer;
  156. uint32_t m_vertexCount;
  157. uint32_t m_indexCount;
  158. uint32_t m_lineStartIndex;
  159. };
  160. TextBuffer::TextBuffer(FontManager* _fontManager)
  161. {
  162. m_styleFlags = STYLE_NORMAL;
  163. //0xAABBGGRR
  164. m_textColor = 0xFFFFFFFF;
  165. m_backgroundColor = 0xFFFFFFFF;
  166. m_backgroundColor = 0xFFFFFFFF;
  167. m_overlineColor = 0xFFFFFFFF;
  168. m_underlineColor = 0xFFFFFFFF;
  169. m_strikeThroughColor = 0xFFFFFFFF;
  170. m_penX = 0;
  171. m_penY = 0;
  172. m_originX = 0;
  173. m_originY = 0;
  174. m_lineAscender = 0;
  175. m_lineDescender = 0;
  176. m_lineGap = 0;
  177. m_fontManager = _fontManager;
  178. m_vertexBuffer = new TextVertex[MAX_BUFFERED_CHARACTERS * 4];
  179. m_indexBuffer = new uint16_t[MAX_BUFFERED_CHARACTERS * 6];
  180. m_styleBuffer = new uint8_t[MAX_BUFFERED_CHARACTERS * 4];
  181. m_vertexCount = 0;
  182. m_indexCount = 0;
  183. m_lineStartIndex = 0;
  184. }
  185. TextBuffer::~TextBuffer()
  186. {
  187. delete[] m_vertexBuffer;
  188. delete[] m_indexBuffer;
  189. }
  190. void TextBuffer::appendText(FontHandle _fontHandle, const char * _string)
  191. {
  192. GlyphInfo glyph;
  193. const FontInfo& font = m_fontManager->getFontInfo(_fontHandle);
  194. if(m_vertexCount == 0)
  195. {
  196. m_originX = m_penX;
  197. m_originY = m_penY;
  198. m_lineDescender = 0;// font.m_descender;
  199. m_lineAscender = 0;//font.m_ascender;
  200. }
  201. uint32_t codepoint;
  202. uint32_t state = 0;
  203. for (; *_string; ++_string)
  204. if (!utf8_decode(&state, &codepoint, *_string))
  205. {
  206. if(m_fontManager->getGlyphInfo(_fontHandle, (CodePoint_t)codepoint, glyph))
  207. {
  208. appendGlyph((CodePoint_t)codepoint, font, glyph);
  209. }else
  210. {
  211. BX_CHECK(false, "Glyph not found");
  212. }
  213. }
  214. //printf("U+%04X\n", codepoint);
  215. if (state != UTF8_ACCEPT)
  216. {
  217. // assert(false && "The string is not well-formed");
  218. return; //"The string is not well-formed\n"
  219. }
  220. }
  221. void TextBuffer::appendText(FontHandle _fontHandle, const wchar_t * _string)
  222. {
  223. GlyphInfo glyph;
  224. const FontInfo& font = m_fontManager->getFontInfo(_fontHandle);
  225. if(m_vertexCount == 0)
  226. {
  227. m_originX = m_penX;
  228. m_originY = m_penY;
  229. m_lineDescender = 0;// font.m_descender;
  230. m_lineAscender = 0;//font.m_ascender;
  231. m_lineGap = 0;
  232. }
  233. //parse string
  234. for( uint32_t ii=0, end = wcslen(_string) ; ii < end; ++ii )
  235. {
  236. //if glyph cached, continue
  237. uint32_t _codePoint = _string[ii];
  238. if(m_fontManager->getGlyphInfo(_fontHandle, _codePoint, glyph))
  239. {
  240. appendGlyph(_codePoint, font, glyph);
  241. }else
  242. {
  243. BX_CHECK(false, "Glyph not found");
  244. }
  245. }
  246. }
  247. /*
  248. TextBuffer::Rectangle TextBuffer::measureText(FontHandle _fontHandle, const char * _string)
  249. {
  250. }
  251. TextBuffer::Rectangle TextBuffer::measureText(FontHandle _fontHandle, const wchar_t * _string)
  252. {
  253. }
  254. */
  255. void TextBuffer::clearTextBuffer()
  256. {
  257. m_vertexCount = 0;
  258. m_indexCount = 0;
  259. m_lineStartIndex = 0;
  260. m_lineAscender = 0;
  261. m_lineDescender = 0;
  262. }
  263. void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo)
  264. {
  265. //handle newlines
  266. if(_codePoint == L'\n' )
  267. {
  268. m_penX = m_originX;
  269. m_penY -= m_lineDescender;
  270. m_penY += m_lineGap;
  271. m_lineDescender = 0;
  272. m_lineAscender = 0;
  273. m_lineStartIndex = m_vertexCount;
  274. return;
  275. }
  276. if( _font.m_ascender > m_lineAscender || (_font.m_descender < m_lineDescender) )
  277. {
  278. if( _font.m_descender < m_lineDescender )
  279. {
  280. m_lineDescender = _font.m_descender;
  281. m_lineGap = _font.m_lineGap;
  282. }
  283. float txtDecals = (_font.m_ascender - m_lineAscender);
  284. m_lineAscender = _font.m_ascender;
  285. m_lineGap = _font.m_lineGap;
  286. m_penY += txtDecals;
  287. verticalCenterLastLine((txtDecals), (m_penY - m_lineAscender), (m_penY - m_lineDescender+m_lineGap));
  288. }
  289. //handle kerning
  290. float kerning = 0;
  291. /*
  292. if( previous && markup->font->kerning )
  293. {
  294. kerning = texture_glyph_get_kerning( glyph, previous );
  295. }
  296. */
  297. m_penX += kerning * _font.m_scale;
  298. GlyphInfo& blackGlyph = m_fontManager->getBlackGlyph();
  299. if( m_styleFlags & STYLE_BACKGROUND && m_backgroundColor & 0xFF000000)
  300. {
  301. float x0 = ( m_penX - kerning );
  302. float y0 = ( m_penY - m_lineAscender);
  303. float x1 = ( (float)x0 + (_glyphInfo.m_advance_x));
  304. float y1 = ( m_penY - m_lineDescender + m_lineGap );
  305. m_fontManager->getAtlas()->packUV(blackGlyph.m_regionIndex, (uint8_t*)m_vertexBuffer,sizeof(TextVertex) *m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex));
  306. setVertex(m_vertexCount+0, x0, y0, m_backgroundColor,STYLE_BACKGROUND);
  307. setVertex(m_vertexCount+1, x0, y1, m_backgroundColor,STYLE_BACKGROUND);
  308. setVertex(m_vertexCount+2, x1, y1, m_backgroundColor,STYLE_BACKGROUND);
  309. setVertex(m_vertexCount+3, x1, y0, m_backgroundColor,STYLE_BACKGROUND);
  310. m_indexBuffer[m_indexCount + 0] = m_vertexCount+0;
  311. m_indexBuffer[m_indexCount + 1] = m_vertexCount+1;
  312. m_indexBuffer[m_indexCount + 2] = m_vertexCount+2;
  313. m_indexBuffer[m_indexCount + 3] = m_vertexCount+0;
  314. m_indexBuffer[m_indexCount + 4] = m_vertexCount+2;
  315. m_indexBuffer[m_indexCount + 5] = m_vertexCount+3;
  316. m_vertexCount += 4;
  317. m_indexCount += 6;
  318. }
  319. if( m_styleFlags & STYLE_UNDERLINE && m_underlineColor & 0xFF000000)
  320. {
  321. float x0 = ( m_penX - kerning );
  322. float y0 = (m_penY - m_lineDescender/2 );
  323. float x1 = ( (float)x0 + (_glyphInfo.m_advance_x));
  324. float y1 = y0+_font.m_underline_thickness;
  325. m_fontManager->getAtlas()->packUV(blackGlyph.m_regionIndex, (uint8_t*)m_vertexBuffer,sizeof(TextVertex) *m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex));
  326. setVertex(m_vertexCount+0, x0, y0, m_underlineColor,STYLE_UNDERLINE);
  327. setVertex(m_vertexCount+1, x0, y1, m_underlineColor,STYLE_UNDERLINE);
  328. setVertex(m_vertexCount+2, x1, y1, m_underlineColor,STYLE_UNDERLINE);
  329. setVertex(m_vertexCount+3, x1, y0, m_underlineColor,STYLE_UNDERLINE);
  330. m_indexBuffer[m_indexCount + 0] = m_vertexCount+0;
  331. m_indexBuffer[m_indexCount + 1] = m_vertexCount+1;
  332. m_indexBuffer[m_indexCount + 2] = m_vertexCount+2;
  333. m_indexBuffer[m_indexCount + 3] = m_vertexCount+0;
  334. m_indexBuffer[m_indexCount + 4] = m_vertexCount+2;
  335. m_indexBuffer[m_indexCount + 5] = m_vertexCount+3;
  336. m_vertexCount += 4;
  337. m_indexCount += 6;
  338. }
  339. if( m_styleFlags & STYLE_OVERLINE && m_overlineColor & 0xFF000000)
  340. {
  341. float x0 = ( m_penX - kerning );
  342. float y0 = (m_penY - _font.m_ascender );
  343. float x1 = ( (float)x0 + (_glyphInfo.m_advance_x));
  344. float y1 = y0+_font.m_underline_thickness;
  345. m_fontManager->getAtlas()->packUV(blackGlyph.m_regionIndex, (uint8_t*)m_vertexBuffer,sizeof(TextVertex) *m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex));
  346. setVertex(m_vertexCount+0, x0, y0, m_overlineColor,STYLE_OVERLINE);
  347. setVertex(m_vertexCount+1, x0, y1, m_overlineColor,STYLE_OVERLINE);
  348. setVertex(m_vertexCount+2, x1, y1, m_overlineColor,STYLE_OVERLINE);
  349. setVertex(m_vertexCount+3, x1, y0, m_overlineColor,STYLE_OVERLINE);
  350. m_indexBuffer[m_indexCount + 0] = m_vertexCount+0;
  351. m_indexBuffer[m_indexCount + 1] = m_vertexCount+1;
  352. m_indexBuffer[m_indexCount + 2] = m_vertexCount+2;
  353. m_indexBuffer[m_indexCount + 3] = m_vertexCount+0;
  354. m_indexBuffer[m_indexCount + 4] = m_vertexCount+2;
  355. m_indexBuffer[m_indexCount + 5] = m_vertexCount+3;
  356. m_vertexCount += 4;
  357. m_indexCount += 6;
  358. }
  359. if( m_styleFlags & STYLE_STRIKE_THROUGH && m_strikeThroughColor & 0xFF000000)
  360. {
  361. float x0 = ( m_penX - kerning );
  362. float y0 = (m_penY - _font.m_ascender/3 );
  363. float x1 = ( (float)x0 + (_glyphInfo.m_advance_x) );
  364. float y1 = y0+_font.m_underline_thickness;
  365. m_fontManager->getAtlas()->packUV(blackGlyph.m_regionIndex, (uint8_t*)m_vertexBuffer,sizeof(TextVertex) *m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex));
  366. setVertex(m_vertexCount+0, x0, y0, m_strikeThroughColor,STYLE_STRIKE_THROUGH);
  367. setVertex(m_vertexCount+1, x0, y1, m_strikeThroughColor,STYLE_STRIKE_THROUGH);
  368. setVertex(m_vertexCount+2, x1, y1, m_strikeThroughColor,STYLE_STRIKE_THROUGH);
  369. setVertex(m_vertexCount+3, x1, y0, m_strikeThroughColor,STYLE_STRIKE_THROUGH);
  370. m_indexBuffer[m_indexCount + 0] = m_vertexCount+0;
  371. m_indexBuffer[m_indexCount + 1] = m_vertexCount+1;
  372. m_indexBuffer[m_indexCount + 2] = m_vertexCount+2;
  373. m_indexBuffer[m_indexCount + 3] = m_vertexCount+0;
  374. m_indexBuffer[m_indexCount + 4] = m_vertexCount+2;
  375. m_indexBuffer[m_indexCount + 5] = m_vertexCount+3;
  376. m_vertexCount += 4;
  377. m_indexCount += 6;
  378. }
  379. //handle glyph
  380. float x0_precise = m_penX + (_glyphInfo.m_offset_x);
  381. float x0 = ( x0_precise);
  382. float y0 = ( m_penY + (_glyphInfo.m_offset_y));
  383. float x1 = ( x0 + _glyphInfo.m_width );
  384. float y1 = ( y0 + _glyphInfo.m_height );
  385. m_fontManager->getAtlas()->packUV(_glyphInfo.m_regionIndex, (uint8_t*)m_vertexBuffer, sizeof(TextVertex) *m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex));
  386. setVertex(m_vertexCount+0, x0, y0, m_textColor);
  387. setVertex(m_vertexCount+1, x0, y1, m_textColor);
  388. setVertex(m_vertexCount+2, x1, y1, m_textColor);
  389. setVertex(m_vertexCount+3, x1, y0, m_textColor);
  390. m_indexBuffer[m_indexCount + 0] = m_vertexCount+0;
  391. m_indexBuffer[m_indexCount + 1] = m_vertexCount+1;
  392. m_indexBuffer[m_indexCount + 2] = m_vertexCount+2;
  393. m_indexBuffer[m_indexCount + 3] = m_vertexCount+0;
  394. m_indexBuffer[m_indexCount + 4] = m_vertexCount+2;
  395. m_indexBuffer[m_indexCount + 5] = m_vertexCount+3;
  396. m_vertexCount += 4;
  397. m_indexCount += 6;
  398. //TODO see what to do when doing subpixel rendering
  399. m_penX += _glyphInfo.m_advance_x;
  400. }
  401. void TextBuffer::verticalCenterLastLine(float _dy, float _top, float _bottom)
  402. {
  403. for( uint32_t ii=m_lineStartIndex; ii < m_vertexCount; ii+=4 )
  404. {
  405. if( m_styleBuffer[ii] == STYLE_BACKGROUND)
  406. {
  407. m_vertexBuffer[ii+0].y = _top;
  408. m_vertexBuffer[ii+1].y = _bottom;
  409. m_vertexBuffer[ii+2].y = _bottom;
  410. m_vertexBuffer[ii+3].y = _top;
  411. }else{
  412. m_vertexBuffer[ii+0].y += _dy;
  413. m_vertexBuffer[ii+1].y += _dy;
  414. m_vertexBuffer[ii+2].y += _dy;
  415. m_vertexBuffer[ii+3].y += _dy;
  416. }
  417. }
  418. }
  419. // ****************************************************************
  420. TextBufferManager::TextBufferManager(FontManager* _fontManager):m_fontManager(_fontManager), m_textBufferHandles(MAX_TEXT_BUFFER_COUNT)
  421. {
  422. m_textBuffers = new BufferCache[MAX_TEXT_BUFFER_COUNT];
  423. }
  424. TextBufferManager::~TextBufferManager()
  425. {
  426. BX_CHECK(m_textBufferHandles.getNumHandles() == 0, "All the text buffers must be destroyed before destroying the manager");
  427. delete[] m_textBuffers;
  428. bgfx::destroyUniform(u_texColor);
  429. bgfx::destroyUniform(u_inverse_gamma);
  430. bgfx::destroyProgram(m_basicProgram);
  431. bgfx::destroyProgram(m_distanceProgram);
  432. bgfx::destroyProgram(m_distanceSubpixelProgram);
  433. }
  434. void TextBufferManager::init(const char* _shaderPath)
  435. {
  436. m_vertexDecl.begin();
  437. m_vertexDecl.add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float);
  438. m_vertexDecl.add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Int16, true);
  439. m_vertexDecl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
  440. m_vertexDecl.end();
  441. u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1iv);
  442. u_inverse_gamma = bgfx::createUniform("u_inverse_gamma", bgfx::UniformType::Uniform1f);
  443. const bgfx::Memory* mem;
  444. mem = loadShader(_shaderPath, "vs_font_basic");
  445. bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem);
  446. mem = loadShader(_shaderPath, "fs_font_basic");
  447. bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem);
  448. m_basicProgram = bgfx::createProgram(vsh, fsh);
  449. bgfx::destroyVertexShader(vsh);
  450. bgfx::destroyFragmentShader(fsh);
  451. mem = loadShader(_shaderPath, "vs_font_distance_field");
  452. vsh = bgfx::createVertexShader(mem);
  453. mem = loadShader(_shaderPath, "fs_font_distance_field");
  454. fsh = bgfx::createFragmentShader(mem);
  455. m_distanceProgram = bgfx::createProgram(vsh, fsh);
  456. bgfx::destroyVertexShader(vsh);
  457. bgfx::destroyFragmentShader(fsh);
  458. mem = loadShader(_shaderPath, "vs_font_distance_field_subpixel");
  459. vsh = bgfx::createVertexShader(mem);
  460. mem = loadShader(_shaderPath, "fs_font_distance_field_subpixel");
  461. fsh = bgfx::createFragmentShader(mem);
  462. m_distanceSubpixelProgram = bgfx::createProgram(vsh, fsh);
  463. bgfx::destroyVertexShader(vsh);
  464. bgfx::destroyFragmentShader(fsh);
  465. }
  466. TextBufferHandle TextBufferManager::createTextBuffer(FontType _type, BufferType _bufferType)
  467. {
  468. uint16_t textIdx = m_textBufferHandles.alloc();
  469. BufferCache& bc = m_textBuffers[textIdx];
  470. bc.m_textBuffer = new TextBuffer(m_fontManager);
  471. bc.m_fontType = _type;
  472. bc.m_bufferType = _bufferType;
  473. bc.m_indexBufferHandle = bgfx::invalidHandle;
  474. bc.m_vertexBufferHandle = bgfx::invalidHandle;
  475. TextBufferHandle ret = {textIdx};
  476. return ret;
  477. }
  478. void TextBufferManager::destroyTextBuffer(TextBufferHandle _handle)
  479. {
  480. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  481. BufferCache& bc = m_textBuffers[_handle.idx];
  482. m_textBufferHandles.free(_handle.idx);
  483. delete bc.m_textBuffer;
  484. bc.m_textBuffer = NULL;
  485. if(bc.m_vertexBufferHandle == bgfx::invalidHandle ) return;
  486. switch(bc.m_bufferType)
  487. {
  488. case STATIC:
  489. {
  490. bgfx::IndexBufferHandle ibh;
  491. bgfx::VertexBufferHandle vbh;
  492. ibh.idx = bc.m_indexBufferHandle;
  493. vbh.idx = bc.m_vertexBufferHandle;
  494. bgfx::destroyIndexBuffer(ibh);
  495. bgfx::destroyVertexBuffer(vbh);
  496. }
  497. break;
  498. case DYNAMIC:
  499. bgfx::DynamicIndexBufferHandle ibh;
  500. bgfx::DynamicVertexBufferHandle vbh;
  501. ibh.idx = bc.m_indexBufferHandle;
  502. vbh.idx = bc.m_vertexBufferHandle;
  503. bgfx::destroyDynamicIndexBuffer(ibh);
  504. bgfx::destroyDynamicVertexBuffer(vbh);
  505. break;
  506. case TRANSIENT: //naturally destroyed
  507. break;
  508. }
  509. }
  510. void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, uint8_t _id, int32_t _depth)
  511. {
  512. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  513. BufferCache& bc = m_textBuffers[_handle.idx];
  514. uint32_t indexSize = bc.m_textBuffer->getIndexCount() * bc.m_textBuffer->getIndexSize();
  515. uint32_t vertexSize = bc.m_textBuffer->getVertexCount() * bc.m_textBuffer->getVertexSize();
  516. const bgfx::Memory* mem;
  517. bgfx::setTexture(0, u_texColor, m_fontManager->getAtlas()->getTextureHandle());
  518. float inverse_gamme = 1.0f/2.2f;
  519. bgfx::setUniform(u_inverse_gamma, &inverse_gamme);
  520. switch (bc.m_fontType)
  521. {
  522. case FONT_TYPE_ALPHA:
  523. bgfx::setProgram(m_basicProgram);
  524. bgfx::setState( BGFX_STATE_RGB_WRITE | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) );
  525. break;
  526. case FONT_TYPE_DISTANCE:
  527. bgfx::setProgram(m_distanceProgram);
  528. bgfx::setState( BGFX_STATE_RGB_WRITE | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) );
  529. break;
  530. case FONT_TYPE_DISTANCE_SUBPIXEL:
  531. bgfx::setProgram(m_distanceSubpixelProgram);
  532. bgfx::setState( BGFX_STATE_RGB_WRITE |BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_INV_SRC_COLOR) , bc.m_textBuffer->getTextColor());
  533. break;
  534. }
  535. switch(bc.m_bufferType)
  536. {
  537. case STATIC:
  538. {
  539. bgfx::IndexBufferHandle ibh;
  540. bgfx::VertexBufferHandle vbh;
  541. if(bc.m_vertexBufferHandle == bgfx::invalidHandle)
  542. {
  543. mem = bgfx::alloc(indexSize);
  544. memcpy(mem->data, bc.m_textBuffer->getIndexBuffer(), indexSize);
  545. ibh = bgfx::createIndexBuffer(mem);
  546. mem = bgfx::alloc(vertexSize);
  547. memcpy(mem->data, bc.m_textBuffer->getVertexBuffer(), vertexSize);
  548. vbh = bgfx::createVertexBuffer(mem, m_vertexDecl);
  549. bc.m_indexBufferHandle = ibh.idx ;
  550. bc.m_vertexBufferHandle = vbh.idx;
  551. }else
  552. {
  553. ibh.idx = bc.m_indexBufferHandle;
  554. vbh.idx = bc.m_vertexBufferHandle;
  555. }
  556. bgfx::setVertexBuffer(vbh, bc.m_textBuffer->getVertexCount());
  557. bgfx::setIndexBuffer(ibh, bc.m_textBuffer->getIndexCount());
  558. }break;
  559. case DYNAMIC:
  560. {
  561. bgfx::DynamicIndexBufferHandle ibh;
  562. bgfx::DynamicVertexBufferHandle vbh;
  563. if(bc.m_vertexBufferHandle == bgfx::invalidHandle)
  564. {
  565. mem = bgfx::alloc(indexSize);
  566. memcpy(mem->data, bc.m_textBuffer->getIndexBuffer(), indexSize);
  567. ibh = bgfx::createDynamicIndexBuffer(mem);
  568. mem = bgfx::alloc(vertexSize);
  569. memcpy(mem->data, bc.m_textBuffer->getVertexBuffer(), vertexSize);
  570. vbh = bgfx::createDynamicVertexBuffer(mem, m_vertexDecl);
  571. bc.m_indexBufferHandle = ibh.idx ;
  572. bc.m_vertexBufferHandle = vbh.idx;
  573. }else
  574. {
  575. ibh.idx = bc.m_indexBufferHandle;
  576. vbh.idx = bc.m_vertexBufferHandle;
  577. mem = bgfx::alloc(indexSize);
  578. memcpy(mem->data, bc.m_textBuffer->getIndexBuffer(), indexSize);
  579. bgfx::updateDynamicIndexBuffer(ibh, mem);
  580. mem = bgfx::alloc(vertexSize);
  581. memcpy(mem->data, bc.m_textBuffer->getVertexBuffer(), vertexSize);
  582. bgfx::updateDynamicVertexBuffer(vbh, mem);
  583. }
  584. bgfx::setVertexBuffer(vbh, bc.m_textBuffer->getVertexCount());
  585. bgfx::setIndexBuffer(ibh, bc.m_textBuffer->getIndexCount());
  586. }break;
  587. case TRANSIENT:
  588. {
  589. bgfx::TransientIndexBuffer tib;
  590. bgfx::TransientVertexBuffer tvb;
  591. bgfx::allocTransientIndexBuffer(&tib, bc.m_textBuffer->getIndexCount());
  592. bgfx::allocTransientVertexBuffer(&tvb, bc.m_textBuffer->getVertexCount(), m_vertexDecl);
  593. memcpy(tib.data, bc.m_textBuffer->getIndexBuffer(), indexSize);
  594. memcpy(tvb.data, bc.m_textBuffer->getVertexBuffer(), vertexSize);
  595. bgfx::setVertexBuffer(&tvb, bc.m_textBuffer->getVertexCount());
  596. bgfx::setIndexBuffer(&tib, bc.m_textBuffer->getIndexCount());
  597. }break;
  598. }
  599. bgfx::submit(_id, _depth);
  600. }
  601. void TextBufferManager::submitTextBufferMask(TextBufferHandle /*_handle*/, uint32_t /*_viewMask*/, int32_t /*_depth*/)
  602. {
  603. //TODO
  604. BX_CHECK(false, "TODO TODO");
  605. }
  606. void TextBufferManager::setStyle(TextBufferHandle _handle, uint32_t _flags )
  607. {
  608. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  609. BufferCache& bc = m_textBuffers[_handle.idx];
  610. bc.m_textBuffer->setStyle(_flags);
  611. }
  612. void TextBufferManager::setTextColor(TextBufferHandle _handle, uint32_t _rgba )
  613. {
  614. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  615. BufferCache& bc = m_textBuffers[_handle.idx];
  616. bc.m_textBuffer->setTextColor(_rgba);
  617. }
  618. void TextBufferManager::setBackgroundColor(TextBufferHandle _handle, uint32_t _rgba )
  619. {
  620. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  621. BufferCache& bc = m_textBuffers[_handle.idx];
  622. bc.m_textBuffer->setBackgroundColor(_rgba);
  623. }
  624. void TextBufferManager::setOverlineColor(TextBufferHandle _handle, uint32_t _rgba )
  625. {
  626. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  627. BufferCache& bc = m_textBuffers[_handle.idx];
  628. bc.m_textBuffer->setOverlineColor(_rgba);
  629. }
  630. void TextBufferManager::setUnderlineColor(TextBufferHandle _handle, uint32_t _rgba )
  631. {
  632. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  633. BufferCache& bc = m_textBuffers[_handle.idx];
  634. bc.m_textBuffer->setUnderlineColor(_rgba);
  635. }
  636. void TextBufferManager::setStrikeThroughColor(TextBufferHandle _handle, uint32_t _rgba )
  637. {
  638. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  639. BufferCache& bc = m_textBuffers[_handle.idx];
  640. bc.m_textBuffer->setStrikeThroughColor(_rgba);
  641. }
  642. void TextBufferManager::setPenPosition(TextBufferHandle _handle, float _x, float _y)
  643. {
  644. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  645. BufferCache& bc = m_textBuffers[_handle.idx];
  646. bc.m_textBuffer->setPenPosition(_x,_y);
  647. }
  648. void TextBufferManager::appendText(TextBufferHandle _handle, FontHandle _fontHandle, const char * _string)
  649. {
  650. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  651. BufferCache& bc = m_textBuffers[_handle.idx];
  652. bc.m_textBuffer->appendText(_fontHandle, _string);
  653. }
  654. void TextBufferManager::appendText(TextBufferHandle _handle, FontHandle _fontHandle, const wchar_t * _string)
  655. {
  656. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  657. BufferCache& bc = m_textBuffers[_handle.idx];
  658. bc.m_textBuffer->appendText(_fontHandle, _string);
  659. }
  660. void TextBufferManager::clearTextBuffer(TextBufferHandle _handle)
  661. {
  662. BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  663. BufferCache& bc = m_textBuffers[_handle.idx];
  664. bc.m_textBuffer->clearTextBuffer();
  665. }