summaryrefslogtreecommitdiffstats
path: root/xbmc/guilib/GUIFontTTF.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/guilib/GUIFontTTF.h')
-rw-r--r--xbmc/guilib/GUIFontTTF.h279
1 files changed, 279 insertions, 0 deletions
diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
new file mode 100644
index 0000000..2ed2703
--- /dev/null
+++ b/xbmc/guilib/GUIFontTTF.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "GUIFont.h"
+#include "utils/ColorUtils.h"
+#include "utils/Geometry.h"
+
+#include <memory>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <harfbuzz/hb.h>
+
+#ifdef HAS_DX
+#include <DirectXMath.h>
+#include <DirectXPackedVector.h>
+
+using namespace DirectX;
+using namespace DirectX::PackedVector;
+#endif
+
+class CGraphicContext;
+class CTexture;
+class CRenderSystemBase;
+
+struct FT_FaceRec_;
+struct FT_LibraryRec_;
+struct FT_GlyphSlotRec_;
+struct FT_BitmapGlyphRec_;
+struct FT_StrokerRec_;
+
+typedef struct FT_FaceRec_* FT_Face;
+typedef struct FT_LibraryRec_* FT_Library;
+typedef struct FT_GlyphSlotRec_* FT_GlyphSlot;
+typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph;
+typedef struct FT_StrokerRec_* FT_Stroker;
+
+typedef uint32_t character_t;
+typedef std::vector<character_t> vecText;
+
+/*!
+ \ingroup textures
+ \brief
+ */
+
+#ifdef HAS_DX
+struct SVertex
+{
+ float x, y, z;
+ XMFLOAT4 col;
+ float u, v;
+ float u2, v2;
+};
+#else
+struct SVertex
+{
+ float x, y, z;
+ unsigned char r, g, b, a;
+ float u, v;
+};
+#endif
+
+#include "GUIFontCache.h"
+
+
+class CGUIFontTTF
+{
+ // use lookup table for the first 4096 glyphs (almost any letter or symbol) to
+ // speed up GUI rendering and decrease CPU usage and less memory reallocations
+ static constexpr int MAX_GLYPH_IDX = 4096;
+ static constexpr size_t LOOKUPTABLE_SIZE = MAX_GLYPH_IDX * FONT_STYLES_COUNT;
+
+ friend class CGUIFont;
+
+public:
+ virtual ~CGUIFontTTF();
+
+ static CGUIFontTTF* CreateGUIFontTTF(const std::string& fontIdent);
+
+ void Clear();
+
+ bool Load(const std::string& strFilename,
+ float height = 20.0f,
+ float aspect = 1.0f,
+ float lineSpacing = 1.0f,
+ bool border = false);
+
+ void Begin();
+ void End();
+ /* The next two should only be called if we've declared we can do hardware clipping */
+ virtual CVertexBuffer CreateVertexBuffer(const std::vector<SVertex>& vertices) const
+ {
+ assert(false);
+ return CVertexBuffer();
+ }
+ virtual void DestroyVertexBuffer(CVertexBuffer& bufferHandle) const {}
+
+ const std::string& GetFontIdent() const { return m_fontIdent; }
+
+protected:
+ explicit CGUIFontTTF(const std::string& fontIdent);
+
+ struct Glyph
+ {
+ hb_glyph_info_t m_glyphInfo{};
+ hb_glyph_position_t m_glyphPosition{};
+
+ Glyph(const hb_glyph_info_t& glyphInfo, const hb_glyph_position_t& glyphPosition)
+ : m_glyphInfo(glyphInfo), m_glyphPosition(glyphPosition)
+ {
+ }
+ };
+
+ struct Character
+ {
+ short m_offsetX;
+ short m_offsetY;
+ float m_left;
+ float m_top;
+ float m_right;
+ float m_bottom;
+ float m_advance;
+ FT_UInt m_glyphIndex;
+ character_t m_glyphAndStyle;
+ };
+
+ struct RunInfo
+ {
+ unsigned int m_startOffset;
+ unsigned int m_endOffset;
+ hb_buffer_t* m_buffer;
+ hb_script_t m_script;
+ hb_glyph_info_t* m_glyphInfos;
+ hb_glyph_position_t* m_glyphPositions;
+ };
+
+ void AddReference();
+ void RemoveReference();
+
+ std::vector<Glyph> GetHarfBuzzShapedGlyphs(const vecText& text);
+
+ float GetTextWidthInternal(const vecText& text);
+ float GetTextWidthInternal(const vecText& text, const std::vector<Glyph>& glyph);
+ float GetCharWidthInternal(character_t ch);
+ float GetTextHeight(float lineSpacing, int numLines) const;
+ float GetTextBaseLine() const { return static_cast<float>(m_cellBaseLine); }
+ float GetLineHeight(float lineSpacing) const;
+ float GetFontHeight() const { return m_height; }
+
+ void DrawTextInternal(CGraphicContext& context,
+ float x,
+ float y,
+ const std::vector<UTILS::COLOR::Color>& colors,
+ const vecText& text,
+ uint32_t alignment,
+ float maxPixelWidth,
+ bool scrolling);
+
+ float m_height{0.0f};
+
+ // Stuff for pre-rendering for speed
+ Character* GetCharacter(character_t letter, FT_UInt glyphIndex);
+ bool CacheCharacter(FT_UInt glyphIndex, uint32_t style, Character* ch);
+ void RenderCharacter(CGraphicContext& context,
+ float posX,
+ float posY,
+ const Character* ch,
+ UTILS::COLOR::Color color,
+ bool roundX,
+ std::vector<SVertex>& vertices);
+ void ClearCharacterCache();
+
+ virtual std::unique_ptr<CTexture> ReallocTexture(unsigned int& newHeight) = 0;
+ virtual bool CopyCharToTexture(FT_BitmapGlyph bitGlyph,
+ unsigned int x1,
+ unsigned int y1,
+ unsigned int x2,
+ unsigned int y2) = 0;
+ virtual void DeleteHardwareTexture() = 0;
+
+ // modifying glyphs
+ void SetGlyphStrength(FT_GlyphSlot slot, int glyphStrength);
+ static void ObliqueGlyph(FT_GlyphSlot slot);
+
+ std::unique_ptr<CTexture>
+ m_texture; // texture that holds our rendered characters (8bit alpha only)
+
+ unsigned int m_textureWidth{0}; // width of our texture
+ unsigned int m_textureHeight{0}; // height of our texture
+ int m_posX{0}; // current position in the texture
+ int m_posY{0};
+
+ /*! \brief the height of each line in the texture.
+ Accounts for spacing between lines to avoid characters overlapping.
+ */
+ unsigned int GetTextureLineHeight() const;
+ unsigned int GetMaxFontHeight() const;
+
+ UTILS::COLOR::Color m_color{UTILS::COLOR::NONE};
+
+ std::vector<Character> m_char; // our characters
+
+ // room for the first MAX_GLYPH_IDX glyphs in 7 styles
+ Character* m_charquick[LOOKUPTABLE_SIZE]{nullptr};
+
+ bool m_ellipseCached{false};
+ float m_ellipsesWidth{0.0f}; // this is used every character (width of '.')
+
+ unsigned int m_cellBaseLine{0};
+ unsigned int m_cellHeight{0};
+ unsigned int m_maxFontHeight{0};
+
+ unsigned int m_nestedBeginCount{0}; // speedups
+
+ // freetype stuff
+ FT_Face m_face{nullptr};
+ FT_Stroker m_stroker{nullptr};
+
+ hb_font_t* m_hbFont{nullptr};
+
+ float m_originX{0.0f};
+ float m_originY{0.0f};
+
+ unsigned int m_nTexture{0};
+
+ struct CTranslatedVertices
+ {
+ float m_translateX;
+ float m_translateY;
+ float m_translateZ;
+ const CVertexBuffer* m_vertexBuffer;
+ CRect m_clip;
+ CTranslatedVertices(float translateX,
+ float translateY,
+ float translateZ,
+ const CVertexBuffer* vertexBuffer,
+ const CRect& clip)
+ : m_translateX(translateX),
+ m_translateY(translateY),
+ m_translateZ(translateZ),
+ m_vertexBuffer(vertexBuffer),
+ m_clip(clip)
+ {
+ }
+ };
+ std::vector<CTranslatedVertices> m_vertexTrans;
+ std::vector<SVertex> m_vertex;
+
+ float m_textureScaleX{0.0f};
+ float m_textureScaleY{0.0f};
+
+ const std::string m_fontIdent;
+ std::vector<uint8_t>
+ m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont()
+
+ CGUIFontCache<CGUIFontCacheStaticPosition, CGUIFontCacheStaticValue> m_staticCache;
+ CGUIFontCache<CGUIFontCacheDynamicPosition, CGUIFontCacheDynamicValue> m_dynamicCache;
+
+ CRenderSystemBase* m_renderSystem;
+
+private:
+ float GetTabSpaceLength();
+
+ virtual bool FirstBegin() = 0;
+ virtual void LastEnd() = 0;
+ CGUIFontTTF(const CGUIFontTTF&) = delete;
+ CGUIFontTTF& operator=(const CGUIFontTTF&) = delete;
+ int m_referenceCount{0};
+};