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 <string>
12 #include <stdint.h>
13 #include <vector>
14 
15 #include "utils/auto_buffer.h"
16 #include "utils/Color.h"
17 #include "utils/Geometry.h"
18 
19 #ifdef HAS_DX
20 #include <DirectXMath.h>
21 #include <DirectXPackedVector.h>
22 
23 using namespace DirectX;
24 using namespace DirectX::PackedVector;
25 #endif
26 
27 constexpr size_t LOOKUPTABLE_SIZE = 256 * 8;
28 
29 class CTexture;
30 class CRenderSystemBase;
31 
32 struct FT_FaceRec_;
33 struct FT_LibraryRec_;
34 struct FT_GlyphSlotRec_;
35 struct FT_BitmapGlyphRec_;
36 struct FT_StrokerRec_;
37 
38 typedef struct FT_FaceRec_ *FT_Face;
39 typedef struct FT_LibraryRec_ *FT_Library;
40 typedef struct FT_GlyphSlotRec_ *FT_GlyphSlot;
41 typedef struct FT_BitmapGlyphRec_ *FT_BitmapGlyph;
42 typedef struct FT_StrokerRec_ *FT_Stroker;
43 
44 typedef uint32_t character_t;
45 typedef std::vector<character_t> vecText;
46 
47 /*!
48  \ingroup textures
49  \brief
50  */
51 
52 struct SVertex
53 {
54   float x, y, z;
55 #ifdef HAS_DX
56   XMFLOAT4 col;
57 #else
58   unsigned char r, g, b, a;
59 #endif
60   float u, v;
61 };
62 
63 
64 #include "GUIFontCache.h"
65 
66 
67 class CGUIFontTTF
68 {
69   friend class CGUIFont;
70 
71 public:
72   virtual ~CGUIFontTTF();
73 
74   static CGUIFontTTF* CreateGUIFontTTF(const std::string& fileName);
75 
76   void Clear();
77 
78   bool Load(const std::string& strFilename, float height = 20.0f, float aspect = 1.0f, float lineSpacing = 1.0f, bool border = false);
79 
80   void Begin();
81   void End();
82   /* The next two should only be called if we've declared we can do hardware clipping */
CreateVertexBuffer(const std::vector<SVertex> & vertices)83   virtual CVertexBuffer CreateVertexBuffer(const std::vector<SVertex> &vertices) const { assert(false); return CVertexBuffer(); }
DestroyVertexBuffer(CVertexBuffer & bufferHandle)84   virtual void DestroyVertexBuffer(CVertexBuffer &bufferHandle) const {}
85 
GetFileName()86   const std::string& GetFileName() const { return m_strFileName; };
87 
88 protected:
89   explicit CGUIFontTTF(const std::string& strFileName);
90 
91   struct Character
92   {
93     short offsetX, offsetY;
94     float left, top, right, bottom;
95     float advance;
96     character_t letterAndStyle;
97   };
98   void AddReference();
99   void RemoveReference();
100 
101   float GetTextWidthInternal(vecText::const_iterator start, vecText::const_iterator end);
102   float GetCharWidthInternal(character_t ch);
103   float GetTextHeight(float lineSpacing, int numLines) const;
GetTextBaseLine()104   float GetTextBaseLine() const { return (float)m_cellBaseLine; }
105   float GetLineHeight(float lineSpacing) const;
GetFontHeight()106   float GetFontHeight() const { return m_height; }
107 
108   void DrawTextInternal(float x, float y, const std::vector<UTILS::Color> &colors, const vecText &text,
109                             uint32_t alignment, float maxPixelWidth, bool scrolling);
110 
111   float m_height;
112   std::string m_strFilename;
113 
114   // Stuff for pre-rendering for speed
115   inline Character *GetCharacter(character_t letter);
116   bool CacheCharacter(wchar_t letter, uint32_t style, Character *ch);
117   void RenderCharacter(float posX, float posY, const Character *ch, UTILS::Color color, bool roundX, std::vector<SVertex> &vertices);
118   void ClearCharacterCache();
119 
120   virtual CTexture* ReallocTexture(unsigned int& newHeight) = 0;
121   virtual bool CopyCharToTexture(FT_BitmapGlyph bitGlyph, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) = 0;
122   virtual void DeleteHardwareTexture() = 0;
123 
124   // modifying glyphs
125   void SetGlyphStrength(FT_GlyphSlot slot, int glyphStrength);
126   static void ObliqueGlyph(FT_GlyphSlot slot);
127 
128   CTexture* m_texture; // texture that holds our rendered characters (8bit alpha only)
129 
130   unsigned int m_textureWidth;       // width of our texture
131   unsigned int m_textureHeight;      // height of our texture
132   int m_posX;                        // current position in the texture
133   int m_posY;
134 
135   /*! \brief the height of each line in the texture.
136    Accounts for spacing between lines to avoid characters overlapping.
137    */
138   unsigned int GetTextureLineHeight() const;
139   static const unsigned int spacing_between_characters_in_texture;
140 
141   UTILS::Color m_color;
142 
143   Character *m_char;                 // our characters
144   Character *m_charquick[LOOKUPTABLE_SIZE];     // ascii chars (7 styles) here
145   int m_maxChars;                    // size of character array (can be incremented)
146   int m_numChars;                    // the current number of cached characters
147 
148   float m_ellipsesWidth;               // this is used every character (width of '.')
149 
150   unsigned int m_cellBaseLine;
151   unsigned int m_cellHeight;
152 
153   unsigned int m_nestedBeginCount;             // speedups
154 
155   // freetype stuff
156   FT_Face    m_face;
157   FT_Stroker m_stroker;
158 
159   float m_originX;
160   float m_originY;
161 
162   unsigned int m_nTexture;
163 
164   struct CTranslatedVertices
165   {
166     float translateX;
167     float translateY;
168     float translateZ;
169     const CVertexBuffer *vertexBuffer;
170     CRect clip;
CTranslatedVerticesCTranslatedVertices171     CTranslatedVertices(float translateX, float translateY, float translateZ, const CVertexBuffer *vertexBuffer, const CRect &clip) : translateX(translateX), translateY(translateY), translateZ(translateZ), vertexBuffer(vertexBuffer), clip(clip) {}
172   };
173   std::vector<CTranslatedVertices> m_vertexTrans;
174   std::vector<SVertex> m_vertex;
175 
176   float    m_textureScaleX;
177   float    m_textureScaleY;
178 
179   std::string m_strFileName;
180   XUTILS::auto_buffer m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont()
181 
182   CGUIFontCache<CGUIFontCacheStaticPosition, CGUIFontCacheStaticValue> m_staticCache;
183   CGUIFontCache<CGUIFontCacheDynamicPosition, CGUIFontCacheDynamicValue> m_dynamicCache;
184 
185   CRenderSystemBase *m_renderSystem = nullptr;
186 
187 private:
188   virtual bool FirstBegin() = 0;
189   virtual void LastEnd() = 0;
190   CGUIFontTTF(const CGUIFontTTF&) = delete;
191   CGUIFontTTF& operator=(const CGUIFontTTF&) = delete;
192   int m_referenceCount;
193 };
194