修复cocos2dx的Label,WP8下不能换行的问题
注:2014年12月23日有內存/性能優化更新,內容在下面分割線后
?
搞了幾個小時,這個頭疼的問題,我給出代碼吧。
?
找到?
libcocos2d/platform/winrt/CCFreeTypeFont.cpp
(其中libcocos2d是項目名)然后將其中的函數?addWord 替換為我提供的即可。實在找不到文件的同學直接搜索吧。
需要注意的是我只簡單處理了一下,所以中文下只支持UTF8字符串,非UTF8字符串會出問題。當然英文環境下任然是用默認邏輯。
我的cocos2dx版本是 3.2,如果你的版本不是這個,存在個別差異,那就自己改改吧。
希望大家拿走代碼的時候在下面評論一下,好提高我分享的積極性,你懂得。
FT_Error CCFreeTypeFont::addWord(const std::string& word) {std::vector<TGlyph> glyphs; // glyphs for the wordFT_BBox bbox; // bounding box containing all of the glyphs in the wordint maxWidth = m_inWidth ? m_inWidth : m_windowWidth;std::string newWord;if(m_currentLine->width > 0) {newWord = ' ' + word;} else{newWord = word;}FT_Error error = initWordGlyphs(glyphs, newWord, m_currentLine->pen);if(!error) {compute_bbox(glyphs, &bbox);/*判斷添加進去后整個line是否顯示寬度大于設定寬度,是的話進行截取*/if (Application::getInstance()->getCurrentLanguage() == LanguageType::CHINESE && bbox.xMax > maxWidth){std:size_t start = 0, end = word.length();while (true){while (true)//這個字符比最寬還要寬,則進行截取 {end--;FT_BBox validBBox = bbox;std::vector<TGlyph> validGlyphs;FTLineInfo validLine = FTLineInfo();validLine.width = 0;validLine.pen.x = 0;validLine.pen.y = 0;//對UTF8字符進行切割if (end != word.length()){while (true){unsigned char utf8charpart = word.at(end - 1);if ((utf8charpart & 0x80) != 0 &&(utf8charpart & 0xe0) != 0xc0 &&(utf8charpart & 0xf0) != 0xe0 &&(utf8charpart & 0xf8) != 0xf0){end--;}else{end--;break;}}}std::string validStr = word.substr(start, end - start);FT_Error validError = initWordGlyphs(validGlyphs, validStr, validLine.pen);if (validError) break;compute_bbox(validGlyphs, &validBBox);if (validBBox.xMax <= maxWidth){m_currentLine->glyphs.insert(validLine.glyphs.end(), validGlyphs.begin(), validGlyphs.end());if (m_currentLine->width == 0){m_currentLine->bbox = validBBox;}else{m_currentLine->bbox.xMax = validBBox.xMax;}break;}}start = end;end = word.length() + 1;if (start == end - 1) break;bbox = FT_BBox();endLine();newLine();}}else{if (m_currentLine->width == 0 || bbox.xMax <= maxWidth){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{endLine();newLine();addWord(word);}}}return error; }?========================================快樂的分割線?========================================
?
謝謝?@請讓我過好不好 ?的反饋。我仔細調試后發現造成內存占用過大的原因是中途逐字符計算換行加載成的圖像沒有釋放掉。并且算法是先計算整個字符串長度,然后逐漸從尾部減小一個字符從新計算,當小于最大寬度時候進行換行從新執行上面的計算。這種算法性能很低,因此我改為了從第一個字符開始計算,當算的字符超過一行,則使用上個字符的位置進行換行。
?
其實還有優化的空間,因為逐字符計算調用的是做事情比較多余的函數,但我沒有那么多時間細扣了,下面貼出代碼,與分割線之前的版本類似替換系統的 addWord 函數即可:
FT_Error CCFreeTypeFont::addWord(const std::string& word) {std::vector<TGlyph> glyphs; // glyphs for the wordFT_BBox bbox; // bounding box containing all of the glyphs in the wordint maxWidth = m_inWidth ? m_inWidth : m_windowWidth;std::string newWord;if(m_currentLine->width > 0) {newWord = ' ' + word;} else{newWord = word;}FT_Error error = initWordGlyphs(glyphs, newWord, m_currentLine->pen);if(!error) {compute_bbox(glyphs, &bbox);/*判斷添加進去后整個line是否顯示寬度大于設定寬度,是的話進行截取*/if (Application::getInstance()->getCurrentLanguage() == LanguageType::CHINESE && bbox.xMax > maxWidth){std:size_t start = 0, end = -1, lastValidEnd = 0;while (true){while (true)//這個字符比最寬還要寬,則進行截取{end++;FT_BBox validBBox = bbox;std::vector<TGlyph> validGlyphs;FTLineInfo validLine;validLine.width = 0;validLine.pen.x = 0;validLine.pen.y = 0;//對UTF8字符進行切割while (true){end++;if (end == word.length()) break;unsigned char utf8charpart = word.at(end);if (!((utf8charpart & 0x80) != 0 &&(utf8charpart & 0xe0) != 0xc0 &&(utf8charpart & 0xf0) != 0xe0 &&(utf8charpart & 0xf8) != 0xf0)){break;}}std::string validStr = word.substr(start, end - start);FT_Error validError = initWordGlyphs(validGlyphs, validStr, validLine.pen);if (validError) break;compute_bbox(validGlyphs, &validBBox);if (validBBox.xMax < maxWidth && end != word.length()){lastValidEnd = end;for (auto glyph = validGlyphs.begin(); glyph != validGlyphs.end(); ++glyph){FT_Done_Glyph(glyph->image);}continue;}else{std::string validStr = word.substr(start, lastValidEnd - start);lastValidEnd = end;FT_Error validError = initWordGlyphs(validGlyphs, validStr, validLine.pen);if (validError) break;compute_bbox(validGlyphs, &validBBox);m_currentLine->glyphs.insert(validLine.glyphs.end(), validGlyphs.begin(), validGlyphs.end());if (m_currentLine->width == 0){m_currentLine->bbox = validBBox;}else{m_currentLine->bbox.xMax = validBBox.xMax;}break;}}start = lastValidEnd;end = lastValidEnd;if (end == word.length()) break;FT_BBox emptybbox;bbox = emptybbox;endLine();newLine();}}else{if (m_currentLine->width == 0 || bbox.xMax <= maxWidth){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{endLine();newLine();addWord(word);}}}return error; }
轉載于:https://www.cnblogs.com/newcj/p/3901134.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的修复cocos2dx的Label,WP8下不能换行的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在html页面提交值到动态页面时出现中文
- 下一篇: httpd配置详解