cocos2dx windows phone平台下CCLabelTTF自動換行的實現

來源:互聯網
上載者:User

標籤:blog   使用   os   io   for   2014   問題   ar   

先吐個槽,剛準備發這條部落格的時候居然發現帳號被盜了,真是有人閑得蛋疼,順便贊一個csdn的客服,處理的很快。


好了,言歸正轉。看了一下,自動換行的實現在CCFreeType這個類裡,這個類的實現只是針對英文的,它採用空格斷句的方式來進行操作,一個word一個word的加,如果發現超過規定的範圍就會換行,但是對於中文來說,這個實現簡直弱爆了,所以就會出現不能自動換行的情況。參考它的實現,做一點小的修改,基本原理如下

1、讀一行文本出來,參考它的實現,算出這個文本的寬度

2、如果這個寬度沒有超過,則直接顯示

3、如果這個寬度走過了,則按等寬字型處理,根據寬度算出來總共應該是幾行,然後按長度進行分隔換行。

注意這個實現有幾個問題:

1、效能問題,其實是在計算出了所有的字之後才發現超過了,這個本來可以發現的更早,但是為了儘可能利用原有的代碼結構,只用先這樣了。

2、是以等寬字型的實現的,這個不一定正確,所以可能會出現某一些還是超過了的情況。


最後附上修改的diff,我使用的是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<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.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<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();


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.