修复cocos2dx的Label,WP8下不能换行的问题
注:2014年12月23日有內(nèi)存/性能優(yōu)化更新,內(nèi)容在下面分割線后
?
搞了幾個(gè)小時(shí),這個(gè)頭疼的問(wèn)題,我給出代碼吧。
?
找到?
libcocos2d/platform/winrt/CCFreeTypeFont.cpp
(其中l(wèi)ibcocos2d是項(xiàng)目名)然后將其中的函數(shù)?addWord 替換為我提供的即可。實(shí)在找不到文件的同學(xué)直接搜索吧。
需要注意的是我只簡(jiǎn)單處理了一下,所以中文下只支持UTF8字符串,非UTF8字符串會(huì)出問(wèn)題。當(dāng)然英文環(huán)境下任然是用默認(rèn)邏輯。
我的cocos2dx版本是 3.2,如果你的版本不是這個(gè),存在個(gè)別差異,那就自己改改吧。
希望大家拿走代碼的時(shí)候在下面評(píng)論一下,好提高我分享的積極性,你懂得。
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);/*判斷添加進(jìn)去后整個(gè)line是否顯示寬度大于設(shè)定寬度,是的話進(jìn)行截取*/if (Application::getInstance()->getCurrentLanguage() == LanguageType::CHINESE && bbox.xMax > maxWidth){std:size_t start = 0, end = word.length();while (true){while (true)//這個(gè)字符比最寬還要寬,則進(jìn)行截取 {end--;FT_BBox validBBox = bbox;std::vector<TGlyph> validGlyphs;FTLineInfo validLine = FTLineInfo();validLine.width = 0;validLine.pen.x = 0;validLine.pen.y = 0;//對(duì)UTF8字符進(jìn)行切割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; }?========================================快樂(lè)的分割線?========================================
?
謝謝?@請(qǐng)讓我過(guò)好不好 ?的反饋。我仔細(xì)調(diào)試后發(fā)現(xiàn)造成內(nèi)存占用過(guò)大的原因是中途逐字符計(jì)算換行加載成的圖像沒(méi)有釋放掉。并且算法是先計(jì)算整個(gè)字符串長(zhǎng)度,然后逐漸從尾部減小一個(gè)字符從新計(jì)算,當(dāng)小于最大寬度時(shí)候進(jìn)行換行從新執(zhí)行上面的計(jì)算。這種算法性能很低,因此我改為了從第一個(gè)字符開始計(jì)算,當(dāng)算的字符超過(guò)一行,則使用上個(gè)字符的位置進(jìn)行換行。
?
其實(shí)還有優(yōu)化的空間,因?yàn)橹鹱址?jì)算調(diào)用的是做事情比較多余的函數(shù),但我沒(méi)有那么多時(shí)間細(xì)扣了,下面貼出代碼,與分割線之前的版本類似替換系統(tǒng)的 addWord 函數(shù)即可:
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);/*判斷添加進(jìn)去后整個(gè)line是否顯示寬度大于設(shè)定寬度,是的話進(jìn)行截取*/if (Application::getInstance()->getCurrentLanguage() == LanguageType::CHINESE && bbox.xMax > maxWidth){std:size_t start = 0, end = -1, lastValidEnd = 0;while (true){while (true)//這個(gè)字符比最寬還要寬,則進(jìn)行截取{end++;FT_BBox validBBox = bbox;std::vector<TGlyph> validGlyphs;FTLineInfo validLine;validLine.width = 0;validLine.pen.x = 0;validLine.pen.y = 0;//對(duì)UTF8字符進(jìn)行切割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; }
轉(zhuǎn)載于:https://www.cnblogs.com/newcj/p/3901134.html
超強(qiáng)干貨來(lái)襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的修复cocos2dx的Label,WP8下不能换行的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在html页面提交值到动态页面时出现中文
- 下一篇: httpd配置详解