text_buffer_manager.cpp 28 KB

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