修复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 word FT_BBox bbox; // bounding box containing all of the glyphs in the word int 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 函数即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | FT_Error CCFreeTypeFont::addWord( const std:: string & word) { 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; 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; } |
作者:newcj
出处:http://newcj.cnblogs.com/
欢迎转载,但还请尊重劳动果实,保留此段声明并注明原文链接。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析