tb_font_renderer.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. #ifndef TB_FONT_RENDERER_H
  6. #define TB_FONT_RENDERER_H
  7. #include "tb_core.h"
  8. #include "tb_bitmap_fragment.h"
  9. #include "tb_renderer.h"
  10. #include "tb_tempbuffer.h"
  11. #include "tb_linklist.h"
  12. #include "tb_font_desc.h"
  13. #include "utf8/utf8.h"
  14. namespace tb {
  15. class TBBitmap;
  16. class TBFontFace;
  17. /** TBFontGlyphData is rendering info used during glyph rendering by TBFontRenderer.
  18. It does not own the data pointers. */
  19. class TBFontGlyphData
  20. {
  21. public:
  22. TBFontGlyphData() : data8(nullptr), data32(nullptr), w(0), h(0), stride(0), rgb(false) {}
  23. ~TBFontGlyphData() {}
  24. uint8 *data8;
  25. uint32 *data32;
  26. int w, h, stride;
  27. bool rgb;
  28. };
  29. /** TBGlyphMetrics contains metrics for a font glyph. */
  30. class TBGlyphMetrics
  31. {
  32. public:
  33. TBGlyphMetrics() : advance(0), x(0), y(0) {}
  34. int16 advance, x, y;
  35. };
  36. /** TBFontMetrics contains metrics for a font face. */
  37. class TBFontMetrics
  38. {
  39. public:
  40. TBFontMetrics() : ascent(0), descent(0), height(0) {}
  41. int16 ascent; ///< Ascent. See TBFontFace::GetAscent()
  42. int16 descent; ///< Descent. See TBFontFace::GetDescent()
  43. int16 height; ///< Height. See TBFontFace::GetHeight()
  44. };
  45. /** TBFontRenderer renders glyphs from a font file. */
  46. class TBFontRenderer : public TBLinkOf<TBFontRenderer>
  47. {
  48. public:
  49. virtual ~TBFontRenderer() {}
  50. /** Open the given font file with this renderer and return a new TBFontFace with it.
  51. return nullptr if the file can't be opened by this renderer. */
  52. virtual TBFontFace *Create(TBFontManager *font_manager, const char *filename,
  53. const TBFontDescription &font_desc) = 0;
  54. virtual bool RenderGlyph(TBFontGlyphData *data, UCS4 cp) = 0;
  55. virtual void GetGlyphMetrics(TBGlyphMetrics *metrics, UCS4 cp) = 0;
  56. virtual TBFontMetrics GetMetrics() = 0;
  57. //virtual int GetKernAdvance(UCS4 cp1, UCS4 cp2) = 0;
  58. };
  59. /** TBFontGlyph holds glyph metrics and bitmap fragment.
  60. There's one of these for all rendered (both successful
  61. and missing) glyphs in TBFontFace. */
  62. class TBFontGlyph : public TBLinkOf<TBFontGlyph>
  63. {
  64. public:
  65. TBFontGlyph(const TBID &hash_id, UCS4 cp);
  66. TBID hash_id;
  67. UCS4 cp;
  68. TBGlyphMetrics metrics; ///< The glyph metrics.
  69. TBBitmapFragment *frag; ///< The bitmap fragment, or nullptr if missing.
  70. bool has_rgb; ///< if true, drawing should ignore text color.
  71. };
  72. /** TBFontGlyphCache caches glyphs for font faces.
  73. Rendered glyphs use bitmap fragments from its fragment manager. */
  74. class TBFontGlyphCache : private TBRendererListener
  75. {
  76. public:
  77. TBFontGlyphCache();
  78. ~TBFontGlyphCache();
  79. /** Get the glyph or nullptr if it is not in the cache. */
  80. TBFontGlyph *GetGlyph(const TBID &hash_id, UCS4 cp);
  81. /** Create the glyph and put it in the cache. Returns the glyph, or nullptr on fail. */
  82. TBFontGlyph *CreateAndCacheGlyph(const TBID &hash_id, UCS4 cp);
  83. /** Create a bitmap fragment for the given glyph and render data. This may drop other
  84. rendered glyphs from the fragment map. Returns the fragment, or nullptr on fail. */
  85. TBBitmapFragment *CreateFragment(TBFontGlyph *glyph, int w, int h, int stride, uint32 *data);
  86. #ifdef TB_RUNTIME_DEBUG_INFO
  87. /** Render the glyph bitmaps on screen, to analyze fragment positioning. */
  88. void Debug();
  89. #endif
  90. // Implementing TBRendererListener
  91. virtual void OnContextLost();
  92. virtual void OnContextRestored();
  93. private:
  94. void DropGlyphFragment(TBFontGlyph *glyph);
  95. TBBitmapFragmentManager m_frag_manager;
  96. TBHashTableAutoDeleteOf<TBFontGlyph> m_glyphs;
  97. TBLinkListOf<TBFontGlyph> m_all_rendered_glyphs;
  98. };
  99. /** TBFontEffect applies an effect on each glyph that is rendered in a TBFontFace. */
  100. class TBFontEffect
  101. {
  102. public:
  103. TBFontEffect();
  104. ~TBFontEffect();
  105. /** Set blur radius. 0 means no blur. */
  106. void SetBlurRadius(int blur_radius);
  107. /** Returns true if the result is in RGB and should not be painted using the color parameter
  108. given to DrawString. In other words: It's a color glyph. */
  109. bool RendersInRGB() const { return false; }
  110. TBFontGlyphData *Render(TBGlyphMetrics *metrics, const TBFontGlyphData *src);
  111. private:
  112. // Blur data
  113. int m_blur_radius;
  114. float *m_tempBuffer;
  115. float *m_kernel;
  116. TBTempBuffer m_blur_temp;
  117. };
  118. /** TBFontFace represents a loaded font that can measure and render strings. */
  119. class TBFontFace
  120. {
  121. public:
  122. TBFontFace(TBFontGlyphCache *glyph_cache, TBFontRenderer *renderer, const TBFontDescription &font_desc);
  123. ~TBFontFace();
  124. /** Render all glyphs needed to display the string. */
  125. bool RenderGlyphs(const char *glyph_str, int glyph_str_len = TB_ALL_TO_TERMINATION);
  126. /** Get the vertical distance (positive) from the horizontal baseline to the highest character coordinate
  127. in a font face. */
  128. int GetAscent() const { return m_metrics.ascent; }
  129. /** Get the vertical distance (positive) from the horizontal baseline to the lowest character coordinate
  130. in the font face. */
  131. int GetDescent() const { return m_metrics.descent; }
  132. /** Get height of the font in pixels. */
  133. int GetHeight() const { return m_metrics.height; }
  134. /** Get the font description that was used to create this font. */
  135. TBFontDescription GetFontDescription() const { return m_font_desc; }
  136. /** Get the effect object, so the effect can be changed.
  137. Note: No glyphs are re-rendered. Only new glyphs are affected. */
  138. TBFontEffect *GetEffect() { return &m_effect; }
  139. /** Draw string at position x, y (marks the upper left corner of the text). */
  140. void DrawString(int x, int y, const TBColor &color, const char *str, int len = TB_ALL_TO_TERMINATION);
  141. /** Measure the width of the given string. Should measure len characters or to the null
  142. termination (whatever comes first). */
  143. int GetStringWidth(const char *str, int len = TB_ALL_TO_TERMINATION);
  144. #ifdef TB_RUNTIME_DEBUG_INFO
  145. /** Render the glyph bitmaps on screen, to analyze fragment positioning. */
  146. void Debug();
  147. #endif
  148. /** Set a background font which will always be rendered behind this one
  149. when calling DrawString. Very usefull to add a shadow effect to a font. */
  150. void SetBackgroundFont(TBFontFace *font, const TBColor &col, int xofs, int yofs);
  151. private:
  152. TBID GetHashId(UCS4 cp) const;
  153. TBFontGlyph *GetGlyph(UCS4 cp, bool render_if_needed);
  154. TBFontGlyph *CreateAndCacheGlyph(UCS4 cp);
  155. void RenderGlyph(TBFontGlyph *glyph);
  156. TBFontGlyphCache *m_glyph_cache;
  157. TBFontRenderer *m_font_renderer;
  158. TBFontDescription m_font_desc;
  159. TBFontMetrics m_metrics;
  160. TBFontEffect m_effect;
  161. TBTempBuffer m_temp_buffer;
  162. TBFontFace *m_bgFont;
  163. int m_bgX;
  164. int m_bgY;
  165. TBColor m_bgColor;
  166. };
  167. /** TBFontInfo provides information about a font file associated with a font id. */
  168. class TBFontInfo
  169. {
  170. public:
  171. /** Get the font filename. */
  172. const char *GetFilename() const { return m_filename; }
  173. /** Get the font name. */
  174. const char *GetName() const { return m_name; }
  175. /** Get the font ID that can be used to create this font from a
  176. TBFontDescription (See TBFontDescription::SetID) */
  177. TBID GetID() const { return m_id; }
  178. private:
  179. friend class TBFontManager;
  180. TBFontInfo(const char *filename, const char *name) : m_filename(filename), m_name(name), m_id(name) {}
  181. TBStr m_filename;
  182. TBStr m_name;
  183. TBID m_id;
  184. };
  185. /** TBFontManager creates and owns font faces (TBFontFace) which are looked up from
  186. TBFontDescription using GetFontFace.
  187. The fonts it can return must first have their file added and indexed (AddFontInfo),
  188. and then created CreateFontFace. Otherwise when asking for a font and it doesn't
  189. exist, it will use the default font.
  190. Font ID 0 is always populated with a dummy font that draws squares. This font is
  191. generally not used for other things than unit testing or as fallback when there is
  192. no font backend implemented yet. Since there is always at least the test font, no
  193. nullptr checks are needed.
  194. */
  195. class TBFontManager
  196. {
  197. public:
  198. TBFontManager();
  199. ~TBFontManager();
  200. /** Add a renderer so fonts supported by the renderer can be created. Ownership of the
  201. renderer is taken, until calling RemoveRenderer. */
  202. void AddRenderer(TBFontRenderer *renderer) { m_font_renderers.AddLast(renderer); }
  203. void RemoveRenderer(TBFontRenderer *renderer) { m_font_renderers.Remove(renderer); }
  204. /** Add TBFontInfo for the given font filename, so it can be loaded and identified
  205. using the font id in a TBFontDescription. */
  206. TBFontInfo *AddFontInfo(const char *filename, const char *name);
  207. /** Get TBFontInfo for the given font id, or nullptr if there is no match. */
  208. TBFontInfo *GetFontInfo(const TBID &id) const;
  209. /** Return true if there is a font loaded that match the given font description. */
  210. bool HasFontFace(const TBFontDescription &font_desc) const;
  211. /** Get a loaded font matching the description, or the default font if there is no exact match.
  212. If there is not even any default font loaded, it will return the test dummy font (rendering
  213. only squares). */
  214. TBFontFace *GetFontFace(const TBFontDescription &font_desc);
  215. /** Create and add a font with the given description. Returns the created font face, or
  216. nullptr on fail. The font is owned by this TBFontManager, and can be recieved from
  217. GetFontFace using the same TBFontDescription. */
  218. TBFontFace *CreateFontFace(const TBFontDescription &font_desc);
  219. /** Set the default font description. This is the font description that will be used by default
  220. for widgets. By default, the default description is using the test dummy font. */
  221. void SetDefaultFontDescription(const TBFontDescription &font_desc) { m_default_font_desc = font_desc; }
  222. TBFontDescription GetDefaultFontDescription() const { return m_default_font_desc; }
  223. /** Return the glyph cache used for fonts created by this font manager. */
  224. TBFontGlyphCache *GetGlyphCache() { return &m_glyph_cache; }
  225. private:
  226. TBHashTableAutoDeleteOf<TBFontInfo> m_font_info;
  227. TBHashTableAutoDeleteOf<TBFontFace> m_fonts;
  228. TBLinkListAutoDeleteOf<TBFontRenderer> m_font_renderers;
  229. TBFontGlyphCache m_glyph_cache;
  230. TBFontDescription m_default_font_desc;
  231. TBFontDescription m_test_font_desc;
  232. };
  233. }; // namespace tb
  234. #endif // TB_FONT_RENDERER_H