font_manager.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  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. #if BX_COMPILER_MSVC
  7. # pragma warning(push)
  8. # pragma warning(disable: 4100) // DISABLE warning C4100: '' : unreferenced formal parameter
  9. # pragma warning(disable: 4146) // DISABLE warning C4146: unary minus operator applied to unsigned type, result still unsigned
  10. # pragma warning(disable: 4700) // DISABLE warning C4700: uninitialized local variable 'temp' used
  11. # pragma warning(disable: 4701) // DISABLE warning C4701: potentially uninitialized local variable '' used
  12. # include <freetype/freetype.h>
  13. # pragma warning(pop)
  14. #else
  15. # include <freetype/freetype.h>
  16. #endif // BX_COMPILER_MSVC
  17. #include <edtaa3/edtaa3func.h>
  18. #include <edtaa3/edtaa3func.cpp>
  19. #include <wchar.h> // wcslen
  20. #include "font_manager.h"
  21. #include "../cube_atlas.h"
  22. #if BGFX_CONFIG_USE_TINYSTL
  23. namespace tinystl
  24. {
  25. //struct bgfx_allocator
  26. //{
  27. //static void* static_allocate(size_t _bytes);
  28. //static void static_deallocate(void* _ptr, size_t /*_bytes*/);
  29. //};
  30. } // namespace tinystl
  31. //# define TINYSTL_ALLOCATOR tinystl::bgfx_allocator
  32. # include <TINYSTL/unordered_map.h>
  33. //# include <TINYSTL/unordered_set.h>
  34. namespace stl = tinystl;
  35. #else
  36. # include <unordered_map>
  37. namespace std
  38. { namespace tr1
  39. {}
  40. }
  41. namespace stl
  42. {
  43. using namespace std;
  44. using namespace std::tr1;
  45. }
  46. #endif // BGFX_CONFIG_USE_TINYSTL
  47. struct FTHolder
  48. {
  49. FT_Library library;
  50. FT_Face face;
  51. };
  52. class FontManager::TrueTypeFont
  53. {
  54. public:
  55. TrueTypeFont();
  56. ~TrueTypeFont();
  57. /// Initialize from an external buffer
  58. /// @remark The ownership of the buffer is external, and you must ensure it stays valid up to this object lifetime
  59. /// @return true if the initialization succeed
  60. bool init(const uint8_t* _buffer, uint32_t _bufferSize, int32_t _fontIndex, uint32_t _pixelHeight);
  61. /// return the font descriptor of the current font
  62. FontInfo getFontInfo();
  63. /// raster a glyph as 8bit alpha to a memory buffer
  64. /// update the GlyphInfo according to the raster strategy
  65. /// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(char)
  66. bool bakeGlyphAlpha(CodePoint_t _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
  67. /// raster a glyph as 32bit subpixel rgba to a memory buffer
  68. /// update the GlyphInfo according to the raster strategy
  69. /// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(uint32_t)
  70. bool bakeGlyphSubpixel(CodePoint_t _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
  71. /// raster a glyph as 8bit signed distance to a memory buffer
  72. /// update the GlyphInfo according to the raster strategy
  73. /// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(char)
  74. bool bakeGlyphDistance(CodePoint_t _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
  75. private:
  76. FTHolder* m_font;
  77. };
  78. FontManager::TrueTypeFont::TrueTypeFont() : m_font(NULL)
  79. {
  80. }
  81. FontManager::TrueTypeFont::~TrueTypeFont()
  82. {
  83. if (m_font != NULL)
  84. {
  85. FTHolder* holder = (FTHolder*) m_font;
  86. FT_Done_Face(holder->face);
  87. FT_Done_FreeType(holder->library);
  88. delete m_font;
  89. m_font = NULL;
  90. }
  91. }
  92. bool FontManager::TrueTypeFont::init(const uint8_t* _buffer, uint32_t _bufferSize, int32_t _fontIndex, uint32_t _pixelHeight)
  93. {
  94. BX_CHECK( (_bufferSize > 256
  95. && _bufferSize < 100000000), "TrueType buffer size is suspicious");
  96. BX_CHECK( (_pixelHeight > 4
  97. && _pixelHeight < 128), "TrueType buffer size is suspicious");
  98. BX_CHECK(m_font == NULL, "TrueTypeFont already initialized");
  99. FTHolder* holder = new FTHolder();
  100. // Initialize Freetype library
  101. FT_Error error = FT_Init_FreeType(&holder->library);
  102. if (error)
  103. {
  104. delete holder;
  105. return false;
  106. }
  107. error = FT_New_Memory_Face(holder->library, _buffer, _bufferSize, _fontIndex, &holder->face);
  108. if (error == FT_Err_Unknown_File_Format)
  109. {
  110. // the font file could be opened and read, but it appears
  111. //that its font format is unsupported
  112. FT_Done_FreeType(holder->library);
  113. delete holder;
  114. return false;
  115. }
  116. else if (error)
  117. {
  118. // another error code means that the font file could not
  119. // be opened or read, or simply that it is broken...
  120. FT_Done_FreeType(holder->library);
  121. delete holder;
  122. return false;
  123. }
  124. // Select unicode charmap
  125. error = FT_Select_Charmap(holder->face, FT_ENCODING_UNICODE);
  126. if (error)
  127. {
  128. FT_Done_Face(holder->face);
  129. FT_Done_FreeType(holder->library);
  130. return false;
  131. }
  132. //set size in pixels
  133. error = FT_Set_Pixel_Sizes(holder->face, 0, _pixelHeight);
  134. if (error)
  135. {
  136. FT_Done_Face(holder->face);
  137. FT_Done_FreeType(holder->library);
  138. return false;
  139. }
  140. m_font = holder;
  141. return true;
  142. }
  143. FontInfo FontManager::TrueTypeFont::getFontInfo()
  144. {
  145. BX_CHECK(m_font != NULL, "TrueTypeFont not initialized");
  146. FTHolder* holder = (FTHolder*) m_font;
  147. //todo manage unscalable font
  148. BX_CHECK(FT_IS_SCALABLE(holder->face), "Font is unscalable");
  149. FT_Size_Metrics metrics = holder->face->size->metrics;
  150. FontInfo outFontInfo;
  151. outFontInfo.scale = 1.0f;
  152. outFontInfo.ascender = metrics.ascender / 64.0f;
  153. outFontInfo.descender = metrics.descender / 64.0f;
  154. outFontInfo.lineGap = (metrics.height - metrics.ascender + metrics.descender) / 64.0f;
  155. outFontInfo.underline_position = FT_MulFix(holder->face->underline_position, metrics.y_scale) / 64.0f;
  156. outFontInfo.underline_thickness = FT_MulFix(holder->face->underline_thickness, metrics.y_scale) / 64.0f;
  157. return outFontInfo;
  158. }
  159. bool FontManager::TrueTypeFont::bakeGlyphAlpha(CodePoint_t _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer)
  160. {
  161. BX_CHECK(m_font != NULL, "TrueTypeFont not initialized");
  162. FTHolder* holder = (FTHolder*) m_font;
  163. _glyphInfo.glyphIndex = FT_Get_Char_Index(holder->face, _codePoint);
  164. FT_GlyphSlot slot = holder->face->glyph;
  165. FT_Error error = FT_Load_Glyph(holder->face, _glyphInfo.glyphIndex, FT_LOAD_DEFAULT);
  166. if (error)
  167. {
  168. return false;
  169. }
  170. FT_Glyph glyph;
  171. error = FT_Get_Glyph(slot, &glyph);
  172. if (error)
  173. {
  174. return false;
  175. }
  176. error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
  177. if (error)
  178. {
  179. return false;
  180. }
  181. FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
  182. int32_t x = bitmap->left;
  183. int32_t y = -bitmap->top;
  184. int32_t w = bitmap->bitmap.width;
  185. int32_t h = bitmap->bitmap.rows;
  186. _glyphInfo.offset_x = (float) x;
  187. _glyphInfo.offset_y = (float) y;
  188. _glyphInfo.width = (float) w;
  189. _glyphInfo.height = (float) h;
  190. _glyphInfo.advance_x = (float)slot->advance.x / 64.0f;
  191. _glyphInfo.advance_y = (float)slot->advance.y / 64.0f;
  192. int32_t charsize = 1;
  193. int32_t depth = 1;
  194. int32_t stride = bitmap->bitmap.pitch;
  195. for (int32_t ii = 0; ii < h; ++ii)
  196. {
  197. memcpy(_outBuffer + (ii * w) * charsize * depth,
  198. bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
  199. }
  200. FT_Done_Glyph(glyph);
  201. return true;
  202. }
  203. bool FontManager::TrueTypeFont::bakeGlyphSubpixel(CodePoint_t _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer)
  204. {
  205. BX_CHECK(m_font != NULL, "TrueTypeFont not initialized");
  206. FTHolder* holder = (FTHolder*) m_font;
  207. _glyphInfo.glyphIndex = FT_Get_Char_Index(holder->face, _codePoint);
  208. FT_GlyphSlot slot = holder->face->glyph;
  209. FT_Error error = FT_Load_Glyph(holder->face, _glyphInfo.glyphIndex, FT_LOAD_DEFAULT);
  210. if (error)
  211. {
  212. return false;
  213. }
  214. FT_Glyph glyph;
  215. error = FT_Get_Glyph(slot, &glyph);
  216. if (error)
  217. {
  218. return false;
  219. }
  220. error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_LCD, 0, 1);
  221. if (error)
  222. {
  223. return false;
  224. }
  225. FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
  226. int32_t x = bitmap->left;
  227. int32_t y = -bitmap->top;
  228. int32_t w = bitmap->bitmap.width;
  229. int32_t h = bitmap->bitmap.rows;
  230. _glyphInfo.offset_x = (float) x;
  231. _glyphInfo.offset_y = (float) y;
  232. _glyphInfo.width = (float) w;
  233. _glyphInfo.height = (float) h;
  234. _glyphInfo.advance_x = (float)slot->advance.x / 64.0f;
  235. _glyphInfo.advance_y = (float)slot->advance.y / 64.0f;
  236. int32_t charsize = 1;
  237. int32_t depth = 3;
  238. int32_t stride = bitmap->bitmap.pitch;
  239. for (int32_t ii = 0; ii < h; ++ii)
  240. {
  241. memcpy(_outBuffer + (ii * w) * charsize * depth,
  242. bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
  243. }
  244. FT_Done_Glyph(glyph);
  245. return true;
  246. }
  247. //TODO optimize: remove dynamic allocation and convert double to float
  248. void make_distance_map(unsigned char* img, unsigned char* outImg, unsigned int width, unsigned int height)
  249. {
  250. short* xdist = (short*) malloc(width * height * sizeof(short) );
  251. short* ydist = (short*) malloc(width * height * sizeof(short) );
  252. double* gx = (double*) calloc(width * height, sizeof(double) );
  253. double* gy = (double*) calloc(width * height, sizeof(double) );
  254. double* data = (double*) calloc(width * height, sizeof(double) );
  255. double* outside = (double*) calloc(width * height, sizeof(double) );
  256. double* inside = (double*) calloc(width * height, sizeof(double) );
  257. uint32_t ii;
  258. // Convert img into double (data)
  259. double img_min = 255, img_max = -255;
  260. for (ii = 0; ii < width * height; ++ii)
  261. {
  262. double v = img[ii];
  263. data[ii] = v;
  264. if (v > img_max)
  265. {
  266. img_max = v;
  267. }
  268. if (v < img_min)
  269. {
  270. img_min = v;
  271. }
  272. }
  273. // Rescale image levels between 0 and 1
  274. for (ii = 0; ii < width * height; ++ii)
  275. {
  276. data[ii] = (img[ii] - img_min) / (img_max - img_min);
  277. }
  278. // Compute outside = edtaa3(bitmap); % Transform background (0's)
  279. computegradient(data, width, height, gx, gy);
  280. edtaa3(data, gx, gy, width, height, xdist, ydist, outside);
  281. for (ii = 0; ii < width * height; ++ii)
  282. {
  283. if (outside[ii] < 0)
  284. {
  285. outside[ii] = 0.0;
  286. }
  287. }
  288. // Compute inside = edtaa3(1-bitmap); % Transform foreground (1's)
  289. memset(gx, 0, sizeof(double) * width * height);
  290. memset(gy, 0, sizeof(double) * width * height);
  291. for (ii = 0; ii < width * height; ++ii)
  292. {
  293. data[ii] = 1.0 - data[ii];
  294. }
  295. computegradient(data, width, height, gx, gy);
  296. edtaa3(data, gx, gy, width, height, xdist, ydist, inside);
  297. for (ii = 0; ii < width * height; ++ii)
  298. {
  299. if (inside[ii] < 0)
  300. {
  301. inside[ii] = 0.0;
  302. }
  303. }
  304. // distmap = outside - inside; % Bipolar distance field
  305. unsigned char* out = outImg; //(unsigned char *) malloc( width * height * sizeof(unsigned char) );
  306. for (ii = 0; ii < width * height; ++ii)
  307. {
  308. //out[i] = 127 - outside[i]*8;
  309. //if(out[i]<0) out[i] = 0;
  310. //out[i] += inside[i]*16;
  311. //if(out[i]>255) out[i] = 255;
  312. outside[ii] -= inside[ii];
  313. outside[ii] = 128 + outside[ii] * 16;
  314. //if(outside[i] > 8) outside[i] = 8;
  315. //if(inside[i] > 8) outside[i] = 8;
  316. //outside[i] = 128 - inside[i]*8 + outside[i]*8;
  317. if (outside[ii] < 0)
  318. {
  319. outside[ii] = 0;
  320. }
  321. if (outside[ii] > 255)
  322. {
  323. outside[ii] = 255;
  324. }
  325. out[ii] = 255 - (unsigned char) outside[ii];
  326. //out[i] = (unsigned char) outside[i];
  327. }
  328. free(xdist);
  329. free(ydist);
  330. free(gx);
  331. free(gy);
  332. free(data);
  333. free(outside);
  334. free(inside);
  335. }
  336. bool FontManager::TrueTypeFont::bakeGlyphDistance(CodePoint_t _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer)
  337. {
  338. BX_CHECK(m_font != NULL, "TrueTypeFont not initialized");
  339. FTHolder* holder = (FTHolder*) m_font;
  340. _glyphInfo.glyphIndex = FT_Get_Char_Index(holder->face, _codePoint);
  341. FT_Int32 loadMode = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
  342. FT_Render_Mode renderMode = FT_RENDER_MODE_NORMAL;
  343. FT_GlyphSlot slot = holder->face->glyph;
  344. FT_Error error = FT_Load_Glyph(holder->face, _glyphInfo.glyphIndex, loadMode);
  345. if (error)
  346. {
  347. return false;
  348. }
  349. FT_Glyph glyph;
  350. error = FT_Get_Glyph(slot, &glyph);
  351. if (error)
  352. {
  353. return false;
  354. }
  355. error = FT_Glyph_To_Bitmap(&glyph, renderMode, 0, 1);
  356. if (error)
  357. {
  358. return false;
  359. }
  360. FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
  361. int32_t x = bitmap->left;
  362. int32_t y = -bitmap->top;
  363. int32_t w = bitmap->bitmap.width;
  364. int32_t h = bitmap->bitmap.rows;
  365. _glyphInfo.offset_x = (float) x;
  366. _glyphInfo.offset_y = (float) y;
  367. _glyphInfo.width = (float) w;
  368. _glyphInfo.height = (float) h;
  369. _glyphInfo.advance_x = (float)slot->advance.x / 64.0f;
  370. _glyphInfo.advance_y = (float)slot->advance.y / 64.0f;
  371. int32_t charsize = 1;
  372. int32_t depth = 1;
  373. int32_t stride = bitmap->bitmap.pitch;
  374. for (int32_t ii = 0; ii < h; ++ii)
  375. {
  376. memcpy(_outBuffer + (ii * w) * charsize * depth,
  377. bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
  378. }
  379. FT_Done_Glyph(glyph);
  380. if (w * h > 0)
  381. {
  382. uint32_t dw = 6;
  383. uint32_t dh = 6;
  384. if (dw < 2)
  385. {
  386. dw = 2;
  387. }
  388. if (dh < 2)
  389. {
  390. dh = 2;
  391. }
  392. uint32_t nw = w + dw * 2;
  393. uint32_t nh = h + dh * 2;
  394. BX_CHECK(nw * nh < 128 * 128, "buffer overflow");
  395. uint32_t buffSize = nw * nh * sizeof(uint8_t);
  396. uint8_t* alphaImg = (uint8_t*) malloc(buffSize);
  397. memset(alphaImg, 0, nw * nh * sizeof(uint8_t) );
  398. //copy the original buffer to the temp one
  399. for (uint32_t ii = dh; ii < nh - dh; ++ii)
  400. {
  401. memcpy(alphaImg + ii * nw + dw, _outBuffer + (ii - dh) * w, w);
  402. }
  403. make_distance_map(alphaImg, _outBuffer, nw, nh);
  404. free(alphaImg);
  405. _glyphInfo.offset_x -= (float) dw;
  406. _glyphInfo.offset_y -= (float) dh;
  407. _glyphInfo.width = (float) nw;
  408. _glyphInfo.height = (float) nh;
  409. }
  410. return true;
  411. }
  412. typedef stl::unordered_map<CodePoint_t, GlyphInfo> GlyphHash_t;
  413. // cache font data
  414. struct FontManager::CachedFont
  415. {
  416. CachedFont()
  417. {
  418. trueTypeFont = NULL; masterFontHandle.idx = -1;
  419. }
  420. FontInfo fontInfo;
  421. GlyphHash_t cachedGlyphs;
  422. FontManager::TrueTypeFont* trueTypeFont;
  423. // an handle to a master font in case of sub distance field font
  424. FontHandle masterFontHandle;
  425. int16_t padding;
  426. };
  427. const uint16_t MAX_OPENED_FILES = 64;
  428. const uint16_t MAX_OPENED_FONT = 64;
  429. const uint32_t MAX_FONT_BUFFER_SIZE = 512 * 512 * 4;
  430. FontManager::FontManager(Atlas* _atlas)
  431. : m_ownAtlas(false)
  432. , m_atlas(_atlas)
  433. , m_fontHandles(MAX_OPENED_FONT)
  434. , m_filesHandles(MAX_OPENED_FILES)
  435. {
  436. init();
  437. }
  438. FontManager::FontManager(uint32_t _textureSideWidth)
  439. : m_ownAtlas(true)
  440. , m_atlas(new Atlas(_textureSideWidth) )
  441. , m_fontHandles(MAX_OPENED_FONT)
  442. , m_filesHandles(MAX_OPENED_FILES)
  443. {
  444. init();
  445. }
  446. void FontManager::init()
  447. {
  448. m_cachedFiles = new CachedFile[MAX_OPENED_FILES];
  449. m_cachedFonts = new CachedFont[MAX_OPENED_FONT];
  450. m_buffer = new uint8_t[MAX_FONT_BUFFER_SIZE];
  451. const uint32_t W = 3;
  452. // Create filler rectangle
  453. uint8_t buffer[W * W * 4];
  454. memset(buffer, 255, W * W * 4);
  455. m_blackGlyph.width = W;
  456. m_blackGlyph.height = W;
  457. ///make sure the black glyph doesn't bleed by using a one pixel inner outline
  458. m_blackGlyph.regionIndex = m_atlas->addRegion(W, W, buffer, AtlasRegion::TYPE_GRAY, 1);
  459. }
  460. FontManager::~FontManager()
  461. {
  462. BX_CHECK(m_fontHandles.getNumHandles() == 0, "All the fonts must be destroyed before destroying the manager");
  463. delete[] m_cachedFonts;
  464. BX_CHECK(m_filesHandles.getNumHandles() == 0, "All the font files must be destroyed before destroying the manager");
  465. delete[] m_cachedFiles;
  466. delete[] m_buffer;
  467. if (m_ownAtlas)
  468. {
  469. delete m_atlas;
  470. }
  471. }
  472. TrueTypeHandle FontManager::loadTrueTypeFromFile(const char* _fontPath)
  473. {
  474. FILE* pFile;
  475. pFile = fopen(_fontPath, "rb");
  476. if (pFile == NULL)
  477. {
  478. TrueTypeHandle invalid = BGFX_INVALID_HANDLE;
  479. return invalid;
  480. }
  481. // Go to the end of the file.
  482. if (fseek(pFile, 0L, SEEK_END) == 0)
  483. {
  484. // Get the size of the file.
  485. long bufsize = ftell(pFile);
  486. if (bufsize == -1)
  487. {
  488. fclose(pFile);
  489. TrueTypeHandle invalid = BGFX_INVALID_HANDLE;
  490. return invalid;
  491. }
  492. uint8_t* buffer = new uint8_t[bufsize];
  493. // Go back to the start of the file.
  494. fseek(pFile, 0L, SEEK_SET);
  495. // Read the entire file into memory.
  496. uint32_t newLen = fread( (void*)buffer, sizeof(char), bufsize, pFile);
  497. if (newLen == 0)
  498. {
  499. fclose(pFile);
  500. delete[] buffer;
  501. TrueTypeHandle invalid = BGFX_INVALID_HANDLE;
  502. return invalid;
  503. }
  504. fclose(pFile);
  505. uint16_t id = m_filesHandles.alloc();
  506. BX_CHECK(id != bx::HandleAlloc::invalid, "No more room for files");
  507. m_cachedFiles[id].buffer = buffer;
  508. m_cachedFiles[id].bufferSize = bufsize;
  509. TrueTypeHandle ret = {id};
  510. return ret;
  511. }
  512. //TODO validate font
  513. TrueTypeHandle invalid = BGFX_INVALID_HANDLE;
  514. return invalid;
  515. }
  516. TrueTypeHandle FontManager::loadTrueTypeFromMemory(const uint8_t* _buffer, uint32_t _size)
  517. {
  518. uint16_t id = m_filesHandles.alloc();
  519. BX_CHECK(id != bx::HandleAlloc::invalid, "Invalid handle used");
  520. m_cachedFiles[id].buffer = new uint8_t[_size];
  521. m_cachedFiles[id].bufferSize = _size;
  522. memcpy(m_cachedFiles[id].buffer, _buffer, _size);
  523. //TODO validate font
  524. TrueTypeHandle ret = {id};
  525. return ret;
  526. }
  527. void FontManager::unloadTrueType(TrueTypeHandle _handle)
  528. {
  529. BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  530. delete m_cachedFiles[_handle.idx].buffer;
  531. m_cachedFiles[_handle.idx].bufferSize = 0;
  532. m_cachedFiles[_handle.idx].buffer = NULL;
  533. m_filesHandles.free(_handle.idx);
  534. }
  535. FontHandle FontManager::createFontByPixelSize(TrueTypeHandle _tt_handle, uint32_t _typefaceIndex, uint32_t _pixelSize, FontType _fontType)
  536. {
  537. BX_CHECK(bgfx::invalidHandle != _tt_handle.idx, "Invalid handle used");
  538. TrueTypeFont* ttf = new TrueTypeFont();
  539. if (!ttf->init(m_cachedFiles[_tt_handle.idx].buffer, m_cachedFiles[_tt_handle.idx].bufferSize, _typefaceIndex, _pixelSize) )
  540. {
  541. delete ttf;
  542. FontHandle invalid = BGFX_INVALID_HANDLE;
  543. return invalid;
  544. }
  545. uint16_t fontIdx = m_fontHandles.alloc();
  546. BX_CHECK(fontIdx != bx::HandleAlloc::invalid, "Invalid handle used");
  547. m_cachedFonts[fontIdx].trueTypeFont = ttf;
  548. m_cachedFonts[fontIdx].fontInfo = ttf->getFontInfo();
  549. m_cachedFonts[fontIdx].fontInfo.fontType = _fontType;
  550. m_cachedFonts[fontIdx].fontInfo.pixelSize = _pixelSize;
  551. m_cachedFonts[fontIdx].cachedGlyphs.clear();
  552. m_cachedFonts[fontIdx].masterFontHandle.idx = -1;
  553. FontHandle ret = {fontIdx};
  554. return ret;
  555. }
  556. FontHandle FontManager::createScaledFontToPixelSize(FontHandle _baseFontHandle, uint32_t _pixelSize)
  557. {
  558. BX_CHECK(bgfx::invalidHandle != _baseFontHandle.idx, "Invalid handle used");
  559. CachedFont& font = m_cachedFonts[_baseFontHandle.idx];
  560. FontInfo& fontInfo = font.fontInfo;
  561. FontInfo newFontInfo = fontInfo;
  562. newFontInfo.pixelSize = _pixelSize;
  563. newFontInfo.scale = (float)_pixelSize / (float) fontInfo.pixelSize;
  564. newFontInfo.ascender = (newFontInfo.ascender * newFontInfo.scale);
  565. newFontInfo.descender = (newFontInfo.descender * newFontInfo.scale);
  566. newFontInfo.lineGap = (newFontInfo.lineGap * newFontInfo.scale);
  567. newFontInfo.underline_thickness = (newFontInfo.underline_thickness * newFontInfo.scale);
  568. newFontInfo.underline_position = (newFontInfo.underline_position * newFontInfo.scale);
  569. uint16_t fontIdx = m_fontHandles.alloc();
  570. BX_CHECK(fontIdx != bx::HandleAlloc::invalid, "Invalid handle used");
  571. m_cachedFonts[fontIdx].cachedGlyphs.clear();
  572. m_cachedFonts[fontIdx].fontInfo = newFontInfo;
  573. m_cachedFonts[fontIdx].trueTypeFont = NULL;
  574. m_cachedFonts[fontIdx].masterFontHandle = _baseFontHandle;
  575. FontHandle ret = {fontIdx};
  576. return ret;
  577. }
  578. FontHandle FontManager::loadBakedFontFromFile(const char* /*fontPath*/, const char* /*descriptorPath*/)
  579. {
  580. //assert(false); //TODO implement
  581. FontHandle invalid = BGFX_INVALID_HANDLE;
  582. return invalid;
  583. }
  584. FontHandle FontManager::loadBakedFontFromMemory(const uint8_t* /*imageBuffer*/, uint32_t /*imageSize*/, const uint8_t* /*descriptorBuffer*/, uint32_t /*descriptorSize*/)
  585. {
  586. //assert(false); //TODO implement
  587. FontHandle invalid = BGFX_INVALID_HANDLE;
  588. return invalid;
  589. }
  590. void FontManager::destroyFont(FontHandle _handle)
  591. {
  592. BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  593. if (m_cachedFonts[_handle.idx].trueTypeFont != NULL)
  594. {
  595. delete m_cachedFonts[_handle.idx].trueTypeFont;
  596. m_cachedFonts[_handle.idx].trueTypeFont = NULL;
  597. }
  598. m_cachedFonts[_handle.idx].cachedGlyphs.clear();
  599. m_fontHandles.free(_handle.idx);
  600. }
  601. bool FontManager::preloadGlyph(FontHandle _handle, const wchar_t* _string)
  602. {
  603. BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  604. CachedFont& font = m_cachedFonts[_handle.idx];
  605. //if truetype present
  606. if (font.trueTypeFont != NULL)
  607. {
  608. //parse string
  609. for (uint32_t ii = 0, end = wcslen(_string); ii < end; ++ii)
  610. {
  611. //if glyph cached, continue
  612. CodePoint_t codePoint = _string[ii];
  613. if (!preloadGlyph(_handle, codePoint) )
  614. {
  615. return false;
  616. }
  617. }
  618. return true;
  619. }
  620. return false;
  621. }
  622. bool FontManager::preloadGlyph(FontHandle _handle, CodePoint_t _codePoint)
  623. {
  624. BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  625. CachedFont& font = m_cachedFonts[_handle.idx];
  626. FontInfo& fontInfo = font.fontInfo;
  627. //check if glyph not already present
  628. GlyphHash_t::iterator iter = font.cachedGlyphs.find(_codePoint);
  629. if (iter != font.cachedGlyphs.end() )
  630. {
  631. return true;
  632. }
  633. //if truetype present
  634. if (font.trueTypeFont != NULL)
  635. {
  636. GlyphInfo glyphInfo;
  637. //bake glyph as bitmap to buffer
  638. switch (font.fontInfo.fontType)
  639. {
  640. case FONT_TYPE_ALPHA:
  641. font.trueTypeFont->bakeGlyphAlpha(_codePoint, glyphInfo, m_buffer);
  642. break;
  643. //case FONT_TYPE_LCD:
  644. //font.m_trueTypeFont->bakeGlyphSubpixel(codePoint, glyphInfo, m_buffer);
  645. //break;
  646. case FONT_TYPE_DISTANCE:
  647. font.trueTypeFont->bakeGlyphDistance(_codePoint, glyphInfo, m_buffer);
  648. break;
  649. case FONT_TYPE_DISTANCE_SUBPIXEL:
  650. font.trueTypeFont->bakeGlyphDistance(_codePoint, glyphInfo, m_buffer);
  651. break;
  652. default:
  653. BX_CHECK(false, "TextureType not supported yet");
  654. }
  655. //copy bitmap to texture
  656. if (!addBitmap(glyphInfo, m_buffer) )
  657. {
  658. return false;
  659. }
  660. glyphInfo.advance_x = (glyphInfo.advance_x * fontInfo.scale);
  661. glyphInfo.advance_y = (glyphInfo.advance_y * fontInfo.scale);
  662. glyphInfo.offset_x = (glyphInfo.offset_x * fontInfo.scale);
  663. glyphInfo.offset_y = (glyphInfo.offset_y * fontInfo.scale);
  664. glyphInfo.height = (glyphInfo.height * fontInfo.scale);
  665. glyphInfo.width = (glyphInfo.width * fontInfo.scale);
  666. // store cached glyph
  667. font.cachedGlyphs[_codePoint] = glyphInfo;
  668. return true;
  669. }
  670. else
  671. {
  672. //retrieve glyph from parent font if any
  673. if (font.masterFontHandle.idx != bgfx::invalidHandle)
  674. {
  675. if (preloadGlyph(font.masterFontHandle, _codePoint) )
  676. {
  677. GlyphInfo glyphInfo;
  678. getGlyphInfo(font.masterFontHandle, _codePoint, glyphInfo);
  679. glyphInfo.advance_x = (glyphInfo.advance_x * fontInfo.scale);
  680. glyphInfo.advance_y = (glyphInfo.advance_y * fontInfo.scale);
  681. glyphInfo.offset_x = (glyphInfo.offset_x * fontInfo.scale);
  682. glyphInfo.offset_y = (glyphInfo.offset_y * fontInfo.scale);
  683. glyphInfo.height = (glyphInfo.height * fontInfo.scale);
  684. glyphInfo.width = (glyphInfo.width * fontInfo.scale);
  685. // store cached glyph
  686. font.cachedGlyphs[_codePoint] = glyphInfo;
  687. return true;
  688. }
  689. }
  690. }
  691. return false;
  692. }
  693. const FontInfo& FontManager::getFontInfo(FontHandle _handle)
  694. {
  695. BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
  696. return m_cachedFonts[_handle.idx].fontInfo;
  697. }
  698. bool FontManager::getGlyphInfo(FontHandle _handle, CodePoint_t _codePoint, GlyphInfo& _outInfo)
  699. {
  700. GlyphHash_t::iterator iter = m_cachedFonts[_handle.idx].cachedGlyphs.find(_codePoint);
  701. if (iter == m_cachedFonts[_handle.idx].cachedGlyphs.end() )
  702. {
  703. if (preloadGlyph(_handle, _codePoint) )
  704. {
  705. iter = m_cachedFonts[_handle.idx].cachedGlyphs.find(_codePoint);
  706. }
  707. else
  708. {
  709. return false;
  710. }
  711. }
  712. _outInfo = iter->second;
  713. return true;
  714. }
  715. bool FontManager::addBitmap(GlyphInfo& _glyphInfo, const uint8_t* _data)
  716. {
  717. _glyphInfo.regionIndex = m_atlas->addRegion( (uint16_t) ceil(_glyphInfo.width), (uint16_t) ceil(_glyphInfo.height), _data, AtlasRegion::TYPE_GRAY);
  718. return true;
  719. }