COCOS2DX Cclabelttf Automatic line wrapping implementation under Windows Phone platform

Source: Internet
Author: User
Tags diff



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();





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.