tb_font_renderer_stb.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // ================================================================================
  2. // == This file is a part of Turbo Badger. (C) 2011-2014, Emil Segerås ==
  3. // == See tb_core.h for more information. ==
  4. // ================================================================================
  5. #include "tb_font_renderer.h"
  6. #include "tb_renderer.h"
  7. #include "tb_system.h"
  8. #ifdef TB_FONT_RENDERER_STB
  9. using namespace tb;
  10. #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
  11. #include "../../ThirdParty/STB/stb_truetype.h"
  12. /** STBFontRenderer renders fonts using stb_truetype.h (http://nothings.org/) */
  13. class STBFontRenderer : public TBFontRenderer
  14. {
  15. public:
  16. STBFontRenderer();
  17. ~STBFontRenderer();
  18. bool Load(const char *filename, int size);
  19. virtual TBFontFace *Create(TBFontManager *font_manager, const char *filename,
  20. const TBFontDescription &font_desc);
  21. virtual TBFontMetrics GetMetrics();
  22. virtual bool RenderGlyph(TBFontGlyphData *dst_bitmap, UCS4 cp);
  23. virtual void GetGlyphMetrics(TBGlyphMetrics *metrics, UCS4 cp);
  24. private:
  25. stbtt_fontinfo font;
  26. unsigned char *ttf_buffer;
  27. unsigned char *render_data;
  28. int font_size;
  29. float scale;
  30. };
  31. STBFontRenderer::STBFontRenderer()
  32. : ttf_buffer(nullptr)
  33. , render_data(nullptr)
  34. {
  35. }
  36. STBFontRenderer::~STBFontRenderer()
  37. {
  38. delete [] ttf_buffer;
  39. delete [] render_data;
  40. }
  41. TBFontMetrics STBFontRenderer::GetMetrics()
  42. {
  43. TBFontMetrics metrics;
  44. int ascent, descent, lineGap;
  45. stbtt_GetFontVMetrics(&font, &ascent, &descent, &lineGap);
  46. metrics.ascent = (int) (ascent * scale + 0.5f);
  47. metrics.descent = (int) ((-descent) * scale + 0.5f);
  48. metrics.height = (int) ((ascent - descent + lineGap) * scale + 0.5f);
  49. return metrics;
  50. }
  51. bool STBFontRenderer::RenderGlyph(TBFontGlyphData *data, UCS4 cp)
  52. {
  53. delete [] render_data;
  54. render_data = stbtt_GetCodepointBitmap(&font, 0, scale, cp, &data->w, &data->h, 0, 0);
  55. data->data8 = render_data;
  56. data->stride = data->w;
  57. data->rgb = false;
  58. return data->data8 ? true : false;
  59. }
  60. void STBFontRenderer::GetGlyphMetrics(TBGlyphMetrics *metrics, UCS4 cp)
  61. {
  62. int advanceWidth, leftSideBearing;
  63. stbtt_GetCodepointHMetrics(&font, cp, &advanceWidth, &leftSideBearing);
  64. metrics->advance = (int) (advanceWidth * scale + 0.5f);
  65. int ix0, iy0, ix1, iy1;
  66. stbtt_GetCodepointBitmapBox(&font, cp, 0, scale, &ix0, &iy0, &ix1, &iy1);
  67. metrics->x = ix0;
  68. metrics->y = iy0;
  69. }
  70. bool STBFontRenderer::Load(const char *filename, int size)
  71. {
  72. TBFile *f = TBFile::Open(filename, TBFile::MODE_READ);
  73. if (!f)
  74. return false;
  75. size_t ttf_buf_size = f->Size();
  76. ttf_buffer = new unsigned char[ttf_buf_size];
  77. if (ttf_buffer)
  78. ttf_buf_size = f->Read(ttf_buffer, 1, ttf_buf_size);
  79. delete f;
  80. if (!ttf_buffer)
  81. return false;
  82. stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0));
  83. font_size = (int) (size * 1.3f); // FIX: Constant taken out of thin air because fonts get too small.
  84. scale = stbtt_ScaleForPixelHeight(&font, (float)font_size);
  85. return true;
  86. }
  87. TBFontFace *STBFontRenderer::Create(TBFontManager *font_manager, const char *filename, const TBFontDescription &font_desc)
  88. {
  89. if (STBFontRenderer *fr = new STBFontRenderer())
  90. {
  91. if (fr->Load(filename, (int) font_desc.GetSize()))
  92. if (TBFontFace *font = new TBFontFace(font_manager->GetGlyphCache(), fr, font_desc))
  93. return font;
  94. delete fr;
  95. }
  96. return nullptr;
  97. }
  98. void register_stb_font_renderer()
  99. {
  100. if (STBFontRenderer *fr = new STBFontRenderer)
  101. g_font_manager->AddRenderer(fr);
  102. }
  103. #endif // TB_FONT_RENDERER_STB