修复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 > )
{
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 = , end = word.length();
while (true)
{
while (true)//这个字符比最宽还要宽,则进行截取
{
end--;
FT_BBox validBBox = bbox;
std::vector<TGlyph> validGlyphs;
FTLineInfo validLine = FTLineInfo();
validLine.width = ;
validLine.pen.x = ;
validLine.pen.y = ;
//对UTF8字符进行切割
if (end != word.length())
{
while (true)
{
unsigned char utf8charpart = word.at(end - );
if ((utf8charpart & 0x80) != &&
(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 == )
{
m_currentLine->bbox = validBBox;
}
else
{
m_currentLine->bbox.xMax = validBBox.xMax;
}
break;
}
}
start = end;
end = word.length() + ;
if (start == end - ) break;
bbox = FT_BBox();
endLine();
newLine();
}
}
else
{
if (m_currentLine->width == || bbox.xMax <= maxWidth)
{
m_currentLine->glyphs.insert(m_currentLine->glyphs.end(), glyphs.begin(), glyphs.end());
if (m_currentLine->width == )
{
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 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;
}
修复cocos2dx的Label,WP8下不能换行的问题的更多相关文章
- WP8下实现刮刮乐(橡皮擦)功能
说到刮刮乐这个功能,我们最先想到的是上下两张(长方形)重叠,之后对上面这张图片进行操作. 我的想法是:通过手势,让手指划过的地方变成透明的,底部就会显示了. 那如何让图片变为透明呢?这就要对图片的像素 ...
- linux下与windows下的换行符
[原文有些许错误,已作了修改] 回车符号和换行符号产生背景 关于“回车”(carriage return)和“换行”(line feed)这两个概念的来历和区别.在计算机还没有出现之前,有一种叫做电传 ...
- 解决不同操作系统下git换行符一致性问题
一.不同操系统下的换行符CR回车 LF换行Windows/Dos CRLF \r\nLinux/Unix LF \nMacOS CR \r二.解决方法 打卡git bash,设置core.autocr ...
- ie7 下 float换行问题与vertical-align:middle; 失效问题
声明:web小白的笔记,欢迎大神指点!联系QQ:1522025433. ie7 下 float换行问题 请直接看代码中和代码中的注释: <!doctype html> <html&g ...
- cocos2dx 富文本框,支持换行,支持神情(支持汉字截断无乱码)
cocos2dx 富文本框,支持换行,支持表情(支持汉字截断无乱码) 小工在做了一个游戏聊天功能,里面用到插入表情的富文本和换行的问题: 先看效果,不是你要的效果,可return:(截图由于:输入的问 ...
- 转 DOS(CMD)下批处理换行问题/命令行参数换行 arg ms-dos
DOS(CMD)下批处理换行问题本人经常写一些DOS批处理文件,由于批处理中命令的参考较多且长,写在一行太不容易分辨,所以总想找个办法把一条命令分行来写,今天终于试成功两种方法.一.在CMD下,可以用 ...
- Cocos2d-x之Label
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 在游戏开发中经常会使用标签文字,例如,游戏介绍,玩家积分,菜单选项,文字提示等等. LabelTTF 直接支持使用 TTF 字库 ...
- 修复PHP在64位下序列化(serialize)的字符串在32位机器下反序列
32机器下PHP 整型数值的范围最大不超过2147483647,而有些超出范围的数值在64序列化好的数据标识为整型,在反序列时就可能会出错. 尝试使用以下的办法可以修复此问题 function int ...
- zk label控件内容换行
Label控件本身无法换行,不过div却可以,只要设置了div的宽度,那么就想如果在Label控件外套个div会怎样,结果可喜可乐: <div width="80px"> ...
随机推荐
- [CocoaPods]CocoaPods安装详解
安装CocoaPods之前先安装ruby: 1.安装ruby ruby官网rubygems.org已被屏蔽,替换当前镜像是否为国内镜像. $gem sources --add https://gems ...
- 1,rocketmq 的原理与安装教程
参考文档 http://blog.csdn.net/a19881029/article/details/34446629 https://github.com/alibaba/RocketMQ htt ...
- HoloLens开发手记 - 使用Windows设备控制台 Using Windows Device Portal
Windows设备控制台允许你通过Wi-Fi或USB来远程控制你的HoloLens设备.设备控制台是HoloLens上的一个Web Server,你可以通过PC的浏览器来连接到它.设备控制台包含了很多 ...
- PCA历程详细python代码(原创)
#PCA主成分分析,原文为文末的链接,代码为自己亲自手码 def cov_out1(dx,dy): #第一步:求解x,y各自的均值 mean_x=0 mean_y=0 for i in range(l ...
- web自动化测试(java)---测试过程中遇到的错误合集
摸索测试,不管是安装.调测第一个用例都会遇到各种各样的问题,或是自己的问题或是程序本身设置问题 只有把所有问题记录下来,才对得起自己的经历 1.设置firefox的执行文件错误 Exception i ...
- servlet 请求乱码解决
- underscore.js源码解析【对象】
// Object Functions // ---------------- // Keys in IE < 9 that won't be iterated by `for key in . ...
- RPC的基础:调研EOS插件http_plugin
区块链的应用是基于http服务,这种能力在EOS中是依靠http_plugin插件赋予的. 关键字:通讯模式,add_api,http server,https server,unix server, ...
- HDFS集群数据不均衡处理
一.概述 公司使用是自己搭建的hadoop集群,版本2.7.3,最近发现出现了hdfs数据存储不均衡的现象,其中有一个datanode使用了65%,而有一个只使用了20%.hadoop集群使用的时间长 ...
- Asp.net mvc 5 CRUD代码自动生成工具- vs.net 2013 Saffolding功能扩展
Asp.net mvc 5 CRUD代码自动生成工具 -Visual Studio.net2013 Saffolding功能扩展 上次做过一个<Asp.net webform scaffoldi ...