kodi
GUIFontTTF.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "GUIFont.h"
12 #include "utils/ColorUtils.h"
13 #include "utils/Geometry.h"
14 
15 #include <memory>
16 #include <stdint.h>
17 #include <string>
18 #include <vector>
19 
20 #include <ft2build.h>
21 #include FT_FREETYPE_H
22 #include <harfbuzz/hb.h>
23 
24 #ifdef HAS_DX
25 #include <DirectXMath.h>
26 #include <DirectXPackedVector.h>
27 
28 using namespace DirectX;
29 using namespace DirectX::PackedVector;
30 #endif
31 
32 class CGraphicContext;
33 class CTexture;
34 class CRenderSystemBase;
35 
36 struct FT_FaceRec_;
37 struct FT_LibraryRec_;
38 struct FT_GlyphSlotRec_;
39 struct FT_BitmapGlyphRec_;
40 struct FT_StrokerRec_;
41 
42 typedef struct FT_FaceRec_* FT_Face;
43 typedef struct FT_LibraryRec_* FT_Library;
44 typedef struct FT_GlyphSlotRec_* FT_GlyphSlot;
45 typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph;
46 typedef struct FT_StrokerRec_* FT_Stroker;
47 
48 typedef uint32_t character_t;
49 typedef std::vector<character_t> vecText;
50 
56 #ifdef HAS_DX
57 struct SVertex
58 {
59  float x, y, z;
60  XMFLOAT4 col;
61  float u, v;
62  float u2, v2;
63 };
64 #else
65 struct SVertex
66 {
67  float x, y, z;
68  unsigned char r, g, b, a;
69  float u, v;
70 };
71 #endif
72 
73 #include "GUIFontCache.h"
74 
75 
77 {
78  // use lookup table for the first 4096 glyphs (almost any letter or symbol) to
79  // speed up GUI rendering and decrease CPU usage and less memory reallocations
80  static constexpr int MAX_GLYPH_IDX = 4096;
81  static constexpr size_t LOOKUPTABLE_SIZE = MAX_GLYPH_IDX * FONT_STYLES_COUNT;
82 
83  friend class CGUIFont;
84 
85 public:
86  virtual ~CGUIFontTTF();
87 
88  static CGUIFontTTF* CreateGUIFontTTF(const std::string& fontIdent);
89 
90  void Clear();
91 
92  bool Load(const std::string& strFilename,
93  float height = 20.0f,
94  float aspect = 1.0f,
95  float lineSpacing = 1.0f,
96  bool border = false);
97 
98  void Begin();
99  void End();
100  /* The next two should only be called if we've declared we can do hardware clipping */
101  virtual CVertexBuffer CreateVertexBuffer(const std::vector<SVertex>& vertices) const
102  {
103  assert(false);
104  return CVertexBuffer();
105  }
106  virtual void DestroyVertexBuffer(CVertexBuffer& bufferHandle) const {}
107 
108  const std::string& GetFontIdent() const { return m_fontIdent; }
109 
110 protected:
111  explicit CGUIFontTTF(const std::string& fontIdent);
112 
113  struct Glyph
114  {
115  hb_glyph_info_t m_glyphInfo{};
116  hb_glyph_position_t m_glyphPosition{};
117 
118  Glyph(const hb_glyph_info_t& glyphInfo, const hb_glyph_position_t& glyphPosition)
119  : m_glyphInfo(glyphInfo), m_glyphPosition(glyphPosition)
120  {
121  }
122  };
123 
124  struct Character
125  {
126  short m_offsetX;
127  short m_offsetY;
128  float m_left;
129  float m_top;
130  float m_right;
131  float m_bottom;
132  float m_advance;
133  FT_UInt m_glyphIndex;
134  character_t m_glyphAndStyle;
135  };
136 
137  struct RunInfo
138  {
139  unsigned int m_startOffset;
140  unsigned int m_endOffset;
141  hb_buffer_t* m_buffer;
142  hb_script_t m_script;
143  hb_glyph_info_t* m_glyphInfos;
144  hb_glyph_position_t* m_glyphPositions;
145  };
146 
147  void AddReference();
148  void RemoveReference();
149 
150  std::vector<Glyph> GetHarfBuzzShapedGlyphs(const vecText& text);
151 
152  float GetTextWidthInternal(const vecText& text);
153  float GetTextWidthInternal(const vecText& text, const std::vector<Glyph>& glyph);
154  float GetCharWidthInternal(character_t ch);
155  float GetTextHeight(float lineSpacing, int numLines) const;
156  float GetTextBaseLine() const { return static_cast<float>(m_cellBaseLine); }
157  float GetLineHeight(float lineSpacing) const;
158  float GetFontHeight() const { return m_height; }
159 
160  void DrawTextInternal(CGraphicContext& context,
161  float x,
162  float y,
163  const std::vector<UTILS::COLOR::Color>& colors,
164  const vecText& text,
165  uint32_t alignment,
166  float maxPixelWidth,
167  bool scrolling,
168  float dx = 0.0f,
169  float dy = 0.0f);
170 
171  float m_height{0.0f};
172 
173  // Stuff for pre-rendering for speed
174  Character* GetCharacter(character_t letter, FT_UInt glyphIndex);
175  bool CacheCharacter(FT_UInt glyphIndex, uint32_t style, Character* ch);
176  void RenderCharacter(CGraphicContext& context,
177  float posX,
178  float posY,
179  const Character* ch,
180  UTILS::COLOR::Color color,
181  bool roundX,
182  std::vector<SVertex>& vertices);
183  void ClearCharacterCache();
184 
185  virtual std::unique_ptr<CTexture> ReallocTexture(unsigned int& newHeight) = 0;
186  virtual bool CopyCharToTexture(FT_BitmapGlyph bitGlyph,
187  unsigned int x1,
188  unsigned int y1,
189  unsigned int x2,
190  unsigned int y2) = 0;
191  virtual void DeleteHardwareTexture() = 0;
192 
193  // modifying glyphs
194  void SetGlyphStrength(FT_GlyphSlot slot, int glyphStrength);
195  static void ObliqueGlyph(FT_GlyphSlot slot);
196 
197  std::unique_ptr<CTexture>
198  m_texture; // texture that holds our rendered characters (8bit alpha only)
199 
200  unsigned int m_textureWidth{0}; // width of our texture
201  unsigned int m_textureHeight{0}; // height of our texture
202  int m_posX{0}; // current position in the texture
203  int m_posY{0};
204 
208  unsigned int GetTextureLineHeight() const;
209  unsigned int GetMaxFontHeight() const;
210 
211  UTILS::COLOR::Color m_color{UTILS::COLOR::NONE};
212 
213  std::vector<Character> m_char; // our characters
214 
215  // room for the first MAX_GLYPH_IDX glyphs in 7 styles
216  Character* m_charquick[LOOKUPTABLE_SIZE]{nullptr};
217 
218  bool m_ellipseCached{false};
219  float m_ellipsesWidth{0.0f}; // this is used every character (width of '.')
220 
221  unsigned int m_cellBaseLine{0};
222  unsigned int m_cellHeight{0};
223  unsigned int m_maxFontHeight{0};
224 
225  unsigned int m_nestedBeginCount{0}; // speedups
226 
227  // freetype stuff
228  FT_Face m_face{nullptr};
229  FT_Stroker m_stroker{nullptr};
230 
231  hb_font_t* m_hbFont{nullptr};
232 
233  float m_originX{0.0f};
234  float m_originY{0.0f};
235 
236  unsigned int m_nTexture{0};
237 
239  {
240  float m_translateX;
241  float m_translateY;
242  float m_translateZ;
243  float m_offsetX; // skews the "raw" mesh before applying UI matrix (useful for scrolling)
244  float m_offsetY;
245  const CVertexBuffer* m_vertexBuffer;
246  CRect m_clip;
247  CTranslatedVertices(float translateX,
248  float translateY,
249  float translateZ,
250  const CVertexBuffer* vertexBuffer,
251  const CRect& clip,
252  float offsetX = 0.0f,
253  float offsetY = 0.0f)
254  : m_translateX(translateX),
255  m_translateY(translateY),
256  m_translateZ(translateZ),
257  m_offsetX(offsetX),
258  m_offsetY(offsetY),
259  m_vertexBuffer(vertexBuffer),
260  m_clip(clip)
261  {
262  }
263  };
264  std::vector<CTranslatedVertices> m_vertexTrans;
265  std::vector<SVertex> m_vertex;
266 
267  float m_textureScaleX{0.0f};
268  float m_textureScaleY{0.0f};
269 
270  const std::string m_fontIdent;
271  std::vector<uint8_t>
272  m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont()
273 
276 
277  CRenderSystemBase* m_renderSystem;
278 
279 private:
280  float GetTabSpaceLength();
281 
282  virtual bool FirstBegin() = 0;
283  virtual void LastEnd() = 0;
284  CGUIFontTTF(const CGUIFontTTF&) = delete;
285  CGUIFontTTF& operator=(const CGUIFontTTF&) = delete;
286  int m_referenceCount{0};
287 };
Definition: GUIFontTTF.h:65
Definition: GUIFontTTF.h:113
Definition: GUIFontTTF.h:238
Definition: GUIFontTTF.h:76
Definition: RenderSystem.h:27
Definition: GUIFontTTF.h:137
Base texture class, subclasses of which depend on the render spec (DX, GL etc.)
Definition: Texture.h:34
Definition: GUIFontCache.h:220
Definition: GUIFontTTF.h:124
Definition: GUIFont.h:110
Definition: GraphicContext.h:60