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 "utils/Color.h" 12 13 #include <stdint.h> 14 #include <string> 15 #include <vector> 16 17 #ifdef __GNUC__ 18 // under gcc, inline will only take place if optimizations are applied (-O). this will force inline even without optimizations. 19 #define XBMC_FORCE_INLINE __attribute__((always_inline)) 20 #else 21 #define XBMC_FORCE_INLINE 22 #endif 23 24 class CGUIFont; 25 class CScrollInfo; 26 27 // Process will be: 28 29 // 1. String is divided up into a "multiinfo" vector via the infomanager. 30 // 2. The multiinfo vector is then parsed by the infomanager at rendertime and the resultant string is constructed. 31 // 3. This is saved for comparison perhaps. If the same, we are done. If not, go to 4. 32 // 4. The string is then parsed into a vector<CGUIString>. 33 // 5. Each item in the vector is length-calculated, and then layout occurs governed by alignment and wrapping rules. 34 // 6. A new vector<CGUIString> is constructed 35 36 typedef uint32_t character_t; 37 typedef std::vector<character_t> vecText; 38 39 class CGUIString 40 { 41 public: 42 typedef vecText::const_iterator iString; 43 44 CGUIString(iString start, iString end, bool carriageReturn); 45 46 std::string GetAsString() const; 47 48 vecText m_text; 49 bool m_carriageReturn; // true if we have a carriage return here 50 }; 51 52 class CGUITextLayout 53 { 54 public: 55 CGUITextLayout(CGUIFont *font, bool wrap, float fHeight=0.0f, CGUIFont *borderFont = NULL); // this may need changing - we may just use this class to replace CLabelInfo completely 56 57 bool UpdateScrollinfo(CScrollInfo &scrollInfo); 58 59 // main function to render strings 60 void Render(float x, float y, float angle, UTILS::Color color, UTILS::Color shadowColor, uint32_t alignment, float maxWidth, bool solid = false); 61 void RenderScrolling(float x, float y, float angle, UTILS::Color color, UTILS::Color shadowColor, uint32_t alignment, float maxWidth, const CScrollInfo &scrollInfo); 62 void RenderOutline(float x, float y, UTILS::Color color, UTILS::Color outlineColor, uint32_t alignment, float maxWidth); 63 64 /*! \brief Returns the precalculated width and height of the text to be rendered (in constant time). 65 \param width [out] width of text 66 \param height [out] height of text 67 \sa GetTextWidth, CalcTextExtent 68 */ 69 void GetTextExtent(float &width, float &height) const; 70 71 /*! \brief Returns the precalculated width of the text to be rendered (in constant time). 72 \return width of text 73 \sa GetTextExtent, CalcTextExtent 74 */ GetTextWidth()75 float GetTextWidth() const { return m_textWidth; }; 76 77 float GetTextWidth(const std::wstring &text) const; 78 79 /*! \brief Returns the precalculated height of the text to be rendered (in constant time). 80 \return height of text 81 */ GetTextHeight()82 float GetTextHeight() const { return m_textHeight; }; 83 84 bool Update(const std::string &text, float maxWidth = 0, bool forceUpdate = false, bool forceLTRReadingOrder = false); 85 bool UpdateW(const std::wstring &text, float maxWidth = 0, bool forceUpdate = false, bool forceLTRReadingOrder = false); 86 87 /*! \brief Update text from a pre-styled vecText/std::vector<UTILS::Color> combination 88 Allows styled text to be passed directly to the text layout. 89 \param text the styled text to set. 90 \param colors the colors used on the text. 91 \param maxWidth the maximum width for wrapping text, defaults to 0 (no max width). 92 \param forceLTRReadingOrder whether to force left to right reading order, defaults to false. 93 */ 94 void UpdateStyled(const vecText &text, const std::vector<UTILS::Color> &colors, float maxWidth = 0, bool forceLTRReadingOrder = false); 95 96 unsigned int GetTextLength() const; 97 void GetFirstText(vecText &text) const; 98 void Reset(); 99 100 void SetWrap(bool bWrap=true); 101 void SetMaxHeight(float fHeight); 102 103 104 static void DrawText(CGUIFont *font, float x, float y, UTILS::Color color, UTILS::Color shadowColor, const std::string &text, uint32_t align); 105 static void Filter(std::string &text); 106 107 protected: 108 void LineBreakText(const vecText &text, std::vector<CGUIString> &lines); 109 void WrapText(const vecText &text, float maxWidth); 110 static void BidiTransform(std::vector<CGUIString> &lines, bool forceLTRReadingOrder); 111 static std::wstring BidiFlip(const std::wstring& text, 112 bool forceLTRReadingOrder, 113 int* visualToLogicalMap = nullptr); 114 void CalcTextExtent(); 115 void UpdateCommon(const std::wstring &text, float maxWidth, bool forceLTRReadingOrder); 116 117 /*! \brief Returns the text, utf8 encoded 118 \return utf8 text 119 */ 120 std::string GetText() const; 121 122 //! \brief Set the monospaced font to use SetMonoFont(CGUIFont * font)123 void SetMonoFont(CGUIFont* font) { m_monoFont = font; } 124 125 //! \brief Set whether or not to use the monospace font UseMonoFont(bool use)126 void UseMonoFont(bool use) { m_font = use && m_monoFont ? m_monoFont : m_varFont; } 127 128 // our text to render 129 std::vector<UTILS::Color> m_colors; 130 std::vector<CGUIString> m_lines; 131 typedef std::vector<CGUIString>::iterator iLine; 132 133 // the layout and font details 134 CGUIFont *m_font; // has style, colour info 135 CGUIFont *m_borderFont; // only used for outlined text 136 CGUIFont* m_monoFont = nullptr; //!< Mono-space font to use 137 CGUIFont* m_varFont; //!< Varible-space font to use 138 139 bool m_wrap; // wrapping (true if justify is enabled!) 140 float m_maxHeight; 141 // the default color (may differ from the font objects defaults) 142 UTILS::Color m_textColor; 143 144 std::string m_lastUtf8Text; 145 std::wstring m_lastText; 146 bool m_lastUpdateW; ///< true if the last string we updated was the wstring version 147 float m_textWidth; 148 float m_textHeight; 149 private: IsSpace(character_t letter)150 inline bool IsSpace(character_t letter) const XBMC_FORCE_INLINE 151 { 152 return (letter & 0xffff) == L' '; 153 }; CanWrapAtLetter(character_t letter)154 inline bool CanWrapAtLetter(character_t letter) const XBMC_FORCE_INLINE 155 { 156 character_t ch = letter & 0xffff; 157 return ch == L' ' || (ch >=0x4e00 && ch <= 0x9fff); 158 }; 159 static void AppendToUTF32(const std::string &utf8, character_t colStyle, vecText &utf32); 160 static void AppendToUTF32(const std::wstring &utf16, character_t colStyle, vecText &utf32); 161 static void ParseText(const std::wstring &text, uint32_t defaultStyle, UTILS::Color defaultColor, std::vector<UTILS::Color> &colors, vecText &parsedText); 162 }; 163 164