|
|
@@ -6,26 +6,73 @@
|
|
|
|
|
|
namespace BansheeEngine
|
|
|
{
|
|
|
+ /**
|
|
|
+ * @brief This object takes as input a string, a font and optionally some constraints (like word wrap)
|
|
|
+ * and outputs a set of character data you may use for rendering or metrics.
|
|
|
+ */
|
|
|
class TextData
|
|
|
{
|
|
|
private:
|
|
|
/**
|
|
|
+ * @brief Represents a single word as a set of characters, or optionally just a blank space
|
|
|
+ * of a certain length.
|
|
|
+ *
|
|
|
* @note Due to the way allocation is handled, this class is not allowed to have a destructor.
|
|
|
*/
|
|
|
class TextWord
|
|
|
{
|
|
|
public:
|
|
|
+ /**
|
|
|
+ * @brief Initializes the word and signals if it just a space (or multiple spaces), or
|
|
|
+ * an actual word with letters.
|
|
|
+ */
|
|
|
void init(bool spacer);
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Appends a new character to the word.
|
|
|
+ *
|
|
|
+ * @param charIdx Sequential index of the character in the original string.
|
|
|
+ * @param desc Character description from the font.
|
|
|
+ *
|
|
|
+ * @returns How many pixels did the added character expand the word by.
|
|
|
+ */
|
|
|
UINT32 addChar(UINT32 charIdx, const CHAR_DESC& desc);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Adds a space to the word. Word must have previously have been declared as
|
|
|
+ * a "spacer".
|
|
|
+ */
|
|
|
void addSpace(UINT32 spaceWidth);
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Returns the width of the word in pixels.
|
|
|
+ */
|
|
|
UINT32 getWidth() const { return mWidth; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns height of the word in pixels.
|
|
|
+ */
|
|
|
UINT32 getHeight() const { return mHeight; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns true if word is a spacer. Spacers contain just a space
|
|
|
+ * of a certain length with no actual characters.
|
|
|
+ */
|
|
|
bool isSpacer() const { return mSpacer; }
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Returns the number of characters in the word.
|
|
|
+ */
|
|
|
UINT32 getNumChars() const { return mLastChar == nullptr ? 0 : (mCharsEnd - mCharsStart + 1); }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns the index of the starting character in the word.
|
|
|
+ */
|
|
|
UINT32 getCharsStart() const { return mCharsStart; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns the index of the last character in the word.
|
|
|
+ */
|
|
|
UINT32 getCharsEnd() const { return mCharsEnd; }
|
|
|
|
|
|
private:
|
|
|
@@ -40,6 +87,9 @@ namespace BansheeEngine
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
+ * @brief Contains information about a single texture page that contains rendered
|
|
|
+ * character data.
|
|
|
+ *
|
|
|
* @note Due to the way allocation is handled, this class is not allowed to have a destructor.
|
|
|
*/
|
|
|
struct PageInfo
|
|
|
@@ -50,92 +100,196 @@ namespace BansheeEngine
|
|
|
|
|
|
public:
|
|
|
/**
|
|
|
+ * @brief Represents a single line as a set of words.
|
|
|
+ *
|
|
|
* @note Due to the way allocation is handled, this class is not allowed to have a destructor.
|
|
|
*/
|
|
|
class CM_EXPORT TextLine
|
|
|
{
|
|
|
public:
|
|
|
+ /**
|
|
|
+ * @brief Returns width of the line in pixels.
|
|
|
+ */
|
|
|
UINT32 getWidth() const { return mWidth; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns height of the line in pixels.
|
|
|
+ */
|
|
|
UINT32 getHeight() const { return mHeight; }
|
|
|
|
|
|
/**
|
|
|
- * @brief Returns an offset used to separate two lines.
|
|
|
- */
|
|
|
+ * @brief Returns an offset used to separate two lines.
|
|
|
+ */
|
|
|
UINT32 getYOffset() const { return mTextData->getLineHeight(); }
|
|
|
|
|
|
/**
|
|
|
- * @brief Fills the vertex/uv/index buffers for the specified page, with all the character data
|
|
|
- * needed for rendering.
|
|
|
- *
|
|
|
- * @param page The page.
|
|
|
- * @param [out] vertices Pre-allocated array where character vertices will be written.
|
|
|
- * @param [out] uvs Pre-allocated array where character uv coordinates will be written.
|
|
|
- * @param [out] indexes Pre-allocated array where character indices will be written.
|
|
|
- * @param offset Offsets the location at which the method writes to the buffers.
|
|
|
- * Counted as number of quads.
|
|
|
- * @param size Total number of quads that can fit into the specified buffers.
|
|
|
- *
|
|
|
- * @return Number of quads that were written.
|
|
|
- */
|
|
|
+ * @brief Fills the vertex/uv/index buffers for the specified page, with all the character data
|
|
|
+ * needed for rendering.
|
|
|
+ *
|
|
|
+ * @param page The page.
|
|
|
+ * @param [out] vertices Pre-allocated array where character vertices will be written.
|
|
|
+ * @param [out] uvs Pre-allocated array where character uv coordinates will be written.
|
|
|
+ * @param [out] indexes Pre-allocated array where character indices will be written.
|
|
|
+ * @param offset Offsets the location at which the method writes to the buffers.
|
|
|
+ * Counted as number of quads.
|
|
|
+ * @param size Total number of quads that can fit into the specified buffers.
|
|
|
+ *
|
|
|
+ * @return Number of quads that were written.
|
|
|
+ */
|
|
|
UINT32 fillBuffer(UINT32 page, Vector2* vertices, Vector2* uvs, UINT32* indexes, UINT32 offset, UINT32 size) const;
|
|
|
|
|
|
/**
|
|
|
- * @brief Returns the total number of characters on this line.
|
|
|
- */
|
|
|
+ * @brief Returns the total number of characters on this line.
|
|
|
+ */
|
|
|
UINT32 getNumChars() const;
|
|
|
|
|
|
/**
|
|
|
- * @brief Query if this line was created explicitly due to a newline character.
|
|
|
- * As opposed to a line that was created because a word couldn't fit on the previous line.
|
|
|
- */
|
|
|
+ * @brief Query if this line was created explicitly due to a newline character.
|
|
|
+ * As opposed to a line that was created because a word couldn't fit on the previous line.
|
|
|
+ */
|
|
|
bool hasNewlineChar() const { return mHasNewline; }
|
|
|
private:
|
|
|
friend class TextData;
|
|
|
|
|
|
- TextData* mTextData;
|
|
|
- UINT32 mWordsStart, mWordsEnd;
|
|
|
-
|
|
|
- UINT32 mWidth;
|
|
|
- UINT32 mHeight;
|
|
|
-
|
|
|
- bool mIsEmpty;
|
|
|
- bool mHasNewline;
|
|
|
-
|
|
|
+ /**
|
|
|
+ * @brief Appends a new character to the line.
|
|
|
+ *
|
|
|
+ * @param charIdx Sequential index of the character in the original string.
|
|
|
+ * @param desc Character description from the font.
|
|
|
+ */
|
|
|
void add(UINT32 charIdx, const CHAR_DESC& charDesc);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Appends a space to the line.
|
|
|
+ */
|
|
|
void addSpace();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Adds a new word to the line.
|
|
|
+ *
|
|
|
+ * @param wordIdx Sequential index of the word in the original string.
|
|
|
+ * Spaces are counted as words as well.
|
|
|
+ * @param word Description of the word.
|
|
|
+ */
|
|
|
void addWord(UINT32 wordIdx, const TextWord& word);
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Initializes the line. Must be called after construction.
|
|
|
+ */
|
|
|
void init(TextData* textData);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Finalizes the line. Do not add new characters/words after a line has
|
|
|
+ * been finalized.
|
|
|
+ *
|
|
|
+ * @param hasNewlineChar Set to true if line was create due to an explicit newline char.
|
|
|
+ * As opposed to a line that was created because a word couldn't fit
|
|
|
+ * on the previous line.
|
|
|
+ */
|
|
|
void finalize(bool hasNewlineChar);
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Returns true if the line contains no words.
|
|
|
+ */
|
|
|
bool isEmpty() const { return mIsEmpty; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Removes last word from the line and returns its sequential index.
|
|
|
+ */
|
|
|
UINT32 removeLastWord();
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Calculates the line width and height in pixels.
|
|
|
+ */
|
|
|
void calculateBounds();
|
|
|
+
|
|
|
+ private:
|
|
|
+ TextData* mTextData;
|
|
|
+ UINT32 mWordsStart, mWordsEnd;
|
|
|
+
|
|
|
+ UINT32 mWidth;
|
|
|
+ UINT32 mHeight;
|
|
|
+
|
|
|
+ bool mIsEmpty;
|
|
|
+ bool mHasNewline;
|
|
|
};
|
|
|
|
|
|
public:
|
|
|
+ /**
|
|
|
+ * @brief Initializes a new text data using the specified string and font. Text will attempt to fit into
|
|
|
+ * the provided area. It will wrap words to new line if it doesn't fit and is enabled. If word wrap
|
|
|
+ * isn't possible the text will be clipped. If the specified area is zero size then the text
|
|
|
+ * will not be clipped or word wrapped in any way.
|
|
|
+ *
|
|
|
+ * After this object is constructed you may call various getter methods to get needed information.
|
|
|
+ */
|
|
|
CM_EXPORT TextData(const WString& text, const HFont& font, UINT32 fontSize, UINT32 width = 0, UINT32 height = 0, bool wordWrap = false);
|
|
|
CM_EXPORT ~TextData();
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Returns the number of lines that were generated.
|
|
|
+ */
|
|
|
CM_EXPORT UINT32 getNumLines() const { return mNumLines; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns the number of font pages references by the used characters.
|
|
|
+ */
|
|
|
CM_EXPORT UINT32 getNumPages() const { return mNumPageInfos; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns the height of a line in pixels.
|
|
|
+ */
|
|
|
CM_EXPORT UINT32 getLineHeight() const;
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Gets information describing a single line at the specified index.
|
|
|
+ */
|
|
|
CM_EXPORT const TextLine& getLine(UINT32 idx) const { return mLines[idx]; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns font texture for the provided page index.
|
|
|
+ */
|
|
|
CM_EXPORT const HTexture& getTextureForPage(UINT32 page) const;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns the number of quads used by all the characters in the provided page.
|
|
|
+ */
|
|
|
CM_EXPORT UINT32 getNumQuadsForPage(UINT32 page) const { return mPageInfos[page].numQuads; }
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Returns the width of the actual text in pixels.
|
|
|
+ */
|
|
|
CM_EXPORT UINT32 getWidth() const;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns the height of the actual text in pixels.
|
|
|
+ */
|
|
|
CM_EXPORT UINT32 getHeight() const;
|
|
|
|
|
|
private:
|
|
|
friend class TextLine;
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Returns Y offset that determines the line on which the characters are placed.
|
|
|
+ * In pixels.
|
|
|
+ */
|
|
|
INT32 getBaselineOffset() const;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Returns the width of a single space in pixels.
|
|
|
+ */
|
|
|
UINT32 getSpaceWidth() const;
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Gets a description of a single character referenced by its sequential index
|
|
|
+ * based on the original string.
|
|
|
+ */
|
|
|
const CHAR_DESC& getChar(UINT32 idx) const { return *mChars[idx]; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Gets a description of a single word referenced by its sequential index
|
|
|
+ * based on the original string.
|
|
|
+ */
|
|
|
const TextWord& getWord(UINT32 idx) const { return mWords[idx]; }
|
|
|
|
|
|
private:
|
|
|
@@ -156,7 +310,7 @@ namespace BansheeEngine
|
|
|
HFont mFont;
|
|
|
const FontData* mFontData;
|
|
|
|
|
|
- // Static buffers
|
|
|
+ // Static buffers used to reduce runtime memory allocation
|
|
|
private:
|
|
|
static CM_THREADLOCAL bool BuffersInitialized;
|
|
|
|
|
|
@@ -172,11 +326,36 @@ namespace BansheeEngine
|
|
|
static CM_THREADLOCAL UINT32 PageBufferSize;
|
|
|
static CM_THREADLOCAL UINT32 NextFreePageInfo;
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Allocates an initial set of buffers that will be reused while parsing
|
|
|
+ * text data.
|
|
|
+ */
|
|
|
static void initAlloc();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Allocates a new word and adds it to the buffer. Returns index of the word
|
|
|
+ * in the word buffer.
|
|
|
+ *
|
|
|
+ * @param spacer Specify true if the word is only to contain spaces. (Spaces are considered
|
|
|
+ * a special type of word).
|
|
|
+ */
|
|
|
static UINT32 allocWord(bool spacer);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Allocates a new line and adds it to the buffer. Returns index of the line
|
|
|
+ * in the line buffer.
|
|
|
+ */
|
|
|
static UINT32 allocLine(TextData* textData);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Resets all allocation counters.
|
|
|
+ */
|
|
|
static void deallocAll();
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Increments the count of characters for the referenced page, and optionally
|
|
|
+ * creates page info if it doesn't already exist.
|
|
|
+ */
|
|
|
static void addCharToPage(UINT32 page, const FontData& fontData);
|
|
|
};
|
|
|
}
|