修复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
修复cocos2dx的Label,WP8下不能换行的问题相关推荐
- 解决不同操作系统下git换行符一致性问题
解决不同操作系统下git换行符一致性问题 参考文章: (1)解决不同操作系统下git换行符一致性问题 (2)https://www.cnblogs.com/warking/p/5718648.html ...
- python怎么输入两行_python交互模式下输入换行/输入多行命令的方法
先给大家介绍下python交互模式下输入换行/输入多行命令的方法 换行方法 \ 如: >>> print 'aaa'; \ ... print 'bbb'; \ ... print ...
- cocos2d-x+lua开发模式下编辑器的选择
cocos2d-x+lua开发模式下编辑器的选择 原本打算直接用CocosIDE的,毕竟是官方出品,并且支持Android远程调试,windows下的调试也非常方便,调试的信息也非常全,智能提示也不错 ...
- linux下与windows下的换行符
来源:http://blog.csdn.net/wjcquking/article/details/6634504 回车符号和换行符号产生背景 关于"回车"(carriage re ...
- safair下html换行产生的间距设置font-size:0无效
问题:safair下html换行产生的间距设置font-size:0无效, 解决方法:letter-spacing设负值
- 回车、换行、空格的ASCII码值(不同OS平台下文件换行定义)
回车.换行.空格的ASCII码值(不同OS平台下文件换行定义) 回车,ASCII码13(十六进制:0x0D),"\r" 换行,ASCII码10(十六进制:0x0A),"\ ...
- linux和pe修复win10启动项,pe下如何重建win10引导?pe下win10引导修复图文教程
[文章导读] 随着win10系统的流行,越来越多的小伙伴经常遇到win10系统引导丢失的情况,我们知道win10系统现在采用的是uefi引导,以前的一些修复工具都只能修复传统模式mbr格式下的硬引导, ...
- txt在linux下换行符,Linux下的换行符\n\r以及txt和word文档的使用
Linux doc by: zollty WINDOWS下记事本编写的文档和LINUX下VIM或者GEDIT等编写的文档的不同! 例如WINDOWS下编写的SH脚本,放到LINUX下执行可能会出错 ...
- arcgis 中label feature太长换行_MapGIS转换为ArcGIS小结
MapGIS到ArcGIS数据转换 1.面(区)图层:通过Map2Shp格式转换软件转换(能保证属性和图形数据不丢失) 2.线图层:通过MapGIS文件转换模板转换(能保证属性和图形数据不丢失) 3. ...
最新文章
- NOIP2012 DAY1 T2 国王游戏
- Travis CI : 最小的分布式系统(一)
- pyBoard Mini从安装到简单测试
- Html和CSS的关系
- Codeforces Beta Round #1 A,B,C
- 程序员过关斩将-- 喷一喷坑爹的面向UI编程
- 上传SVN丢失.a文件的问题
- Fast Paxos
- Python集合(set)类型的操作
- 【C语言重点难点精讲】C语言指针
- java字符编码详解_Java中字符编码格式详解
- cad解除块的快捷命令_cad退出块编辑_cad常用快捷键命令表_cad打印快捷键
- 【渝粤教育】广东开放大学 计量基础知识 形成性考核 (48)
- linux双核cpu调试软死锁问题,记一次linux通过jstack定位CPU使用过高问题或排查线上死锁问题...
- ir2110驱动占空比不能太高
- 《东周列国志》第五十回 东门遂援立子倭 赵宣子桃园强谏
- onenote使用python开发_我应该用onenote还是印象笔记?
- 真的有必要读研究生吗?
- Doris0.13.15升级至0.14.12.4故障[Bug] NPE when replaying CheckConsistencyJob
- 技术党求生骚操作!手把手教你做一只口红色号识别器!