Implementation of CCLabelTTF automatic line feed on cocos2dx windows phone platform

Source: Internet
Author: User

Implementation of CCLabelTTF automatic line feed on cocos2dx windows phone platform

Let's talk about it first. When I was about to send this blog, I found that my account was stolen. It was really a waste of time. By the way, I liked a csdn customer service and handled it very quickly.


All right. After reading it, the implementation of automatic line feed is in the CCFreeType class. The implementation of this class is only for English. It uses space-separated sentences for operations, and adds a word to a word, if a line break is found to exceed the specified range, but for Chinese, this implementation is almost weak, so there will be a situation where the line break cannot be automatically entered. Refer to its implementation and make minor modifications. The basic principles are as follows:

1. Read a line of text and calculate the width of the text based on its implementation.

2. If the width is not exceeded

3. If the width has passed, the font size is equal to the width. The total number of rows is calculated based on the width, and the line feed is separated by length.

Note:

1. performance problems are discovered only after all words are computed. This can be found earlier, but in order to make full use of the original code structure, this is the only option.

2. It is implemented with an equal-width font. This is not necessarily correct, so some situations may still exceed.


The modified diff is attached. I use 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.cppindex 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
 
   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
  
    lines;-    vector
   
     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
    
     & glyphs, const std::        return error; } +FT_Error CCFreeTypeFont::initWordGlyphs(std::vector
     
      & 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
      
       & 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.hindex 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
       
        & glyphs, const std::string& text, FT_Vector& pen);+ FT_Error CCFreeTypeFont::initWordGlyphs(std::vector
        
         & glyphs, wchar_t* word, int size, FT_Vector& pen); void compute_bbox(std::vector
         
          & 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.