First spit a groove, just ready to send this blog when actually found that the account was stolen, really someone idle egg pain, by the way praise a CSDN customer service, processing quickly.
All right, the words go to the right. Look, the implementation of the automatic line-wrapping in Ccfreetype this class, the implementation of this class is only for the English, it uses a space segmentation method to operate, a word a word of the addition, if found beyond the specified range will be wrapped, but for the Chinese, this implementation is simply weak explosion, Therefore, there will be no automatic line-wrapping situation. Refer to its implementation, do a little bit of modification, the basic principle is as follows
1, read a line of text out, refer to its implementation, calculate the width of the text
2. If this width is not exceeded, the direct display
3, if this width has passed, then according to the width of the font processing, according to the breadth of the total should be a few lines, and then separated by the length of the line.
Note that this implementation has several problems:
1, performance problems, in fact, in the calculation of all the words after the discovery of more than, this could have been found earlier, but in order to use the original code structure as far as possible, only with the first such.
2, is the realization of the equal width of the font, this is not necessarily correct, so there may be some or more than the situation.
Finally, I enclose the modified diff, which I am using in version 2.2.4.
diff --git a/cocos2d-x-2.2.4/cocos2dx/platform/winrt/CCFreeTypeFont.cpp b/cocos2d-x-2.2.4/cocos2dx/platform/winrt/CCFreeTypeFont.cpp
index 9886d0a..46489af 100644
--- a/cocos2d-x-2.2.4/cocos2dx/platform/winrt/CCFreeTypeFont.cpp
+++ b/cocos2d-x-2.2.4/cocos2dx/platform/winrt/CCFreeTypeFont.cpp
@@ -368,13 +368,67 @@ FT_Error CCFreeTypeFont::addWord(const std::string& word)
return error;
}
+FT_Error CCFreeTypeFont::addLine(wchar_t* line, int size, bool wrap)
+{
+ std::vector<TGlyph> glyphs; // glyphs for the word
+ FT_BBox bbox; // bounding box containing all of the glyphs in the word
+ int maxWidth = m_inWidth ? m_inWidth : m_windowWidth;
+
+ FT_Vector pen = m_currentLine->pen;
+ FT_Error error = initWordGlyphs(glyphs, line, size, pen);
+ if (!error)
+ {
+ compute_bbox(glyphs, &bbox);
+ if (!wrap || bbox.xMax <= maxWidth)
+ {
+ m_currentLine->pen = pen;
+ m_currentLine->glyphs.insert(m_currentLine->glyphs.end(), glyphs.begin(), glyphs.end());
+ if (m_currentLine->width == 0)
+ {
+ m_currentLine->bbox = bbox;
+ }
+ else
+ {
+ m_currentLine->bbox.xMax = bbox.xMax;
+ }
+ m_currentLine->width = m_currentLine->bbox.xMax - m_currentLine->bbox.xMin;
+ }
+ else
+ {
+ int width = bbox.xMax;
+ int lines = width / maxWidth + 1;
+ float fline = float(width) / float(maxWidth);
+ int lineWidth = int(size / fline);
+ int offset = 0;
+ for (int i = 0; i < lines; i++)
+ {
+ if (i)
+ {
+ newLine();
+ }
+ wchar_t* buffer = line + offset;
+ int buffer_len = size - offset;
+ if (buffer_len > lineWidth)
+ {
+ buffer_len = lineWidth;
+ }
+ offset += buffer_len;
+ addLine(buffer, buffer_len, false);
+ if (i < lines - 1)
+ {
+ endLine();
+ }
+ }
+ }
+ }
+ return error;
+}
+
FT_Error CCFreeTypeFont::initGlyphs(const char* text)
{
FT_Error error = 0;
std::stringstream stringStream(text);
std::string line;
- vector<std::string> lines;
- vector<std::string> words;
m_textWidth = 0;
m_textHeight = 0;
@@ -387,19 +441,21 @@ FT_Error CCFreeTypeFont::initGlyphs(const char* text)
{
newLine();
- std::size_t prev = 0, pos;
- while ((pos = line.find_first_of(" ", prev)) != std::string::npos)
- {
- if (pos > prev)
- {
- addWord(line.substr(prev, pos-prev));
- }
- prev = pos + 1;
- }
- if (prev < line.length())
- {
- addWord(line.substr(prev, std::string::npos));
- }
+ wchar_t * pwszBuffer = nullptr;
+
+ int num_chars = line.size();
+ int nBufLen = num_chars + 1;
+ pwszBuffer = new wchar_t[nBufLen];
+ if (!pwszBuffer)
+ {
+ return -1;
+ }
+
+ memset(pwszBuffer, 0, nBufLen);
+ num_chars = MultiByteToWideChar(CP_UTF8, 0, line.c_str(), num_chars, pwszBuffer, nBufLen);
+ pwszBuffer[num_chars] = '\0';
+ error = addLine(pwszBuffer, num_chars, true);
+ CC_SAFE_DELETE_ARRAY(pwszBuffer);
endLine();
}
@@ -513,6 +569,64 @@ FT_Error CCFreeTypeFont::initWordGlyphs(std::vector<TGlyph>& glyphs, const std::
return error;
}
+FT_Error CCFreeTypeFont::initWordGlyphs(std::vector<TGlyph>& glyphs, wchar_t* word, int size, FT_Vector& pen)
+{
+ FT_GlyphSlot slot = m_face->glyph;
+ FT_UInt glyph_index;
+ FT_UInt previous = 0;
+ FT_Error error = 0;
+ PGlyph glyph;
+ unsigned int numGlyphs = 0;
+
+ glyphs.clear();
+ glyphs.resize(size);
+ FT_Bool useKerning = FT_HAS_KERNING(m_face);
+
+ for (int n = 0; n < size; n++)
+ {
+ glyph = &glyphs[numGlyphs];
+
+ /* convert character code to glyph index */
+ FT_ULong c = word[n];
+ glyph_index = FT_Get_Char_Index(m_face, c);
+
+ if (useKerning && previous && glyph_index)
+ {
+ FT_Vector delta;
+ FT_Get_Kerning(m_face, previous, glyph_index,
+ FT_KERNING_DEFAULT, &delta);
+ pen.x += delta.x >> 6;
+ }
+
+ /* store current pen position */
+ glyph->pos = pen;
+ glyph->index = glyph_index;
+
+ /* load glyph image into the slot without rendering */
+ error = FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT);
+ if (error)
+ continue; /* ignore errors, jump to next glyph */
+
+ /* extract glyph image and store it in our table */
+ error = FT_Get_Glyph(m_face->glyph, &glyph->image);
+ if (error)
+ continue; /* ignore errors, jump to next glyph */
+
+ /* translate the glyph image now */
+ FT_Glyph_Transform(glyph->image, 0, &glyph->pos);
+
+ /* increment pen position */
+ pen.x += slot->advance.x >> 6;
+
+ /* record current glyph index */
+ previous = glyph_index;
+
+ numGlyphs++;
+ }
+
+ return error;
+}
+
void CCFreeTypeFont::compute_bbox(std::vector<TGlyph>& glyphs, FT_BBox *abbox)
{
FT_BBox bbox;
diff --git a/cocos2d-x-2.2.4/cocos2dx/platform/winrt/CCFreeTypeFont.h b/cocos2d-x-2.2.4/cocos2dx/platform/winrt/CCFreeTypeFont.h
index 4c1cc3e..a325071 100644
--- a/cocos2d-x-2.2.4/cocos2dx/platform/winrt/CCFreeTypeFont.h
+++ b/cocos2d-x-2.2.4/cocos2dx/platform/winrt/CCFreeTypeFont.h
@@ -100,6 +100,7 @@ private:
FT_Error CCFreeTypeFont::initGlyphs(const char* text);
FT_Error CCFreeTypeFont::initWordGlyphs(std::vector<TGlyph>& glyphs, const std::string& text, FT_Vector& pen);
+ FT_Error CCFreeTypeFont::initWordGlyphs(std::vector<TGlyph>& glyphs, wchar_t* word, int size, FT_Vector& pen);
void compute_bbox(std::vector<TGlyph>& glyphs, FT_BBox *abbox);
@@ -114,6 +115,7 @@ private:
FT_Vector getPenForAlignment(FTLineInfo* pInfo, CCImage::ETextAlign eAlignMask, int lineNumber, int totalLines);
FT_Error addWord(const std::string& word);
+ FT_Error addLine(wchar_t* line, int size, bool wrap);
void newLine();
void endLine();