CmTextData.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include "CmFontDesc.h"
  4. #include "CmVector2I.h"
  5. namespace CamelotFramework
  6. {
  7. class TextData
  8. {
  9. private:
  10. /**
  11. * @note Due to the way allocation is handled, this class is not allowed to have a destructor.
  12. */
  13. class TextWord
  14. {
  15. public:
  16. void init(bool spacer);
  17. UINT32 addChar(UINT32 charIdx, const CHAR_DESC& desc);
  18. void addSpace(UINT32 spaceWidth);
  19. UINT32 getWidth() const { return mWidth; }
  20. UINT32 getHeight() const { return mHeight; }
  21. bool isSpacer() const { return mSpacer; }
  22. UINT32 getNumChars() const { return mLastChar == nullptr ? 0 : (mCharsEnd - mCharsStart + 1); }
  23. UINT32 getCharsStart() const { return mCharsStart; }
  24. UINT32 getCharsEnd() const { return mCharsEnd; }
  25. private:
  26. UINT32 mCharsStart, mCharsEnd;
  27. UINT32 mWidth;
  28. UINT32 mHeight;
  29. const CHAR_DESC* mLastChar;
  30. bool mSpacer;
  31. UINT32 mSpaceWidth;
  32. };
  33. /**
  34. * @note Due to the way allocation is handled, this class is not allowed to have a destructor.
  35. */
  36. struct PageInfo
  37. {
  38. UINT32 numQuads;
  39. HTexture texture;
  40. };
  41. public:
  42. /**
  43. * @note Due to the way allocation is handled, this class is not allowed to have a destructor.
  44. */
  45. class CM_EXPORT TextLine
  46. {
  47. public:
  48. UINT32 getWidth() const { return mWidth; }
  49. UINT32 getHeight() const { return mHeight; }
  50. /**
  51. * @brief Returns an offset used to separate two lines.
  52. */
  53. UINT32 getYOffset() const { return mTextData->getLineHeight(); }
  54. /**
  55. * @brief Fills the vertex/uv/index buffers for the specified page, with all the character data
  56. * needed for rendering.
  57. *
  58. * @param page The page.
  59. * @param [out] vertices Pre-allocated array where character vertices will be written.
  60. * @param [out] uvs Pre-allocated array where character uv coordinates will be written.
  61. * @param [out] indexes Pre-allocated array where character indices will be written.
  62. * @param offset Offsets the location at which the method writes to the buffers.
  63. * Counted as number of quads.
  64. * @param size Total number of quads that can fit into the specified buffers.
  65. *
  66. * @return Number of quads that were written.
  67. */
  68. UINT32 fillBuffer(UINT32 page, Vector2* vertices, Vector2* uvs, UINT32* indexes, UINT32 offset, UINT32 size) const;
  69. /**
  70. * @brief Returns the total number of characters on this line.
  71. */
  72. UINT32 getNumChars() const;
  73. /**
  74. * @brief Query if this line was created explicitly due to a newline character.
  75. * As opposed to a line that was created because a word couldn't fit on the previous line.
  76. */
  77. bool hasNewlineChar() const { return mHasNewline; }
  78. private:
  79. friend class TextData;
  80. TextData* mTextData;
  81. UINT32 mWordsStart, mWordsEnd;
  82. UINT32 mWidth;
  83. UINT32 mHeight;
  84. bool mIsEmpty;
  85. bool mHasNewline;
  86. void add(UINT32 charIdx, const CHAR_DESC& charDesc);
  87. void addSpace();
  88. void addWord(UINT32 wordIdx, const TextWord& word);
  89. void init(TextData* textData);
  90. void finalize(bool hasNewlineChar);
  91. bool isEmpty() const { return mIsEmpty; }
  92. UINT32 removeLastWord();
  93. void calculateBounds();
  94. };
  95. public:
  96. CM_EXPORT TextData(const WString& text, const HFont& font, UINT32 fontSize, UINT32 width = 0, UINT32 height = 0, bool wordWrap = false);
  97. CM_EXPORT ~TextData();
  98. CM_EXPORT UINT32 getNumLines() const { return mNumLines; }
  99. CM_EXPORT UINT32 getNumPages() const { return mNumPageInfos; }
  100. CM_EXPORT const TextLine& getLine(UINT32 idx) const { return mLines[idx]; }
  101. CM_EXPORT const HTexture& getTextureForPage(UINT32 page) const;
  102. CM_EXPORT UINT32 getNumQuadsForPage(UINT32 page) const { return mPageInfos[page].numQuads; }
  103. CM_EXPORT UINT32 getWidth() const;
  104. CM_EXPORT UINT32 getHeight() const;
  105. private:
  106. friend class TextLine;
  107. INT32 getBaselineOffset() const;
  108. UINT32 getLineHeight() const;
  109. UINT32 getSpaceWidth() const;
  110. const CHAR_DESC& getChar(UINT32 idx) const { return *mChars[idx]; }
  111. const TextWord& getWord(UINT32 idx) const { return mWords[idx]; }
  112. private:
  113. const CHAR_DESC** mChars;
  114. UINT32 mNumChars;
  115. TextWord* mWords;
  116. UINT32 mNumWords;
  117. TextLine* mLines;
  118. UINT32 mNumLines;
  119. PageInfo* mPageInfos;
  120. UINT32 mNumPageInfos;
  121. void* mData;
  122. HFont mFont;
  123. const FontData* mFontData;
  124. // Static buffers
  125. private:
  126. static CM_THREADLOCAL bool BuffersInitialized;
  127. static CM_THREADLOCAL TextWord* WordBuffer;
  128. static CM_THREADLOCAL UINT32 WordBufferSize;
  129. static CM_THREADLOCAL UINT32 NextFreeWord;
  130. static CM_THREADLOCAL TextLine* LineBuffer;
  131. static CM_THREADLOCAL UINT32 LineBufferSize;
  132. static CM_THREADLOCAL UINT32 NextFreeLine;
  133. static CM_THREADLOCAL PageInfo* PageBuffer;
  134. static CM_THREADLOCAL UINT32 PageBufferSize;
  135. static CM_THREADLOCAL UINT32 NextFreePageInfo;
  136. static void initAlloc();
  137. static UINT32 allocWord(bool spacer);
  138. static UINT32 allocLine(TextData* textData);
  139. static void deallocAll();
  140. static void addCharToPage(UINT32 page, const FontData& fontData);
  141. };
  142. }