注: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下不能换行的问题的更多相关文章

  1. WP8下实现刮刮乐(橡皮擦)功能

    说到刮刮乐这个功能,我们最先想到的是上下两张(长方形)重叠,之后对上面这张图片进行操作. 我的想法是:通过手势,让手指划过的地方变成透明的,底部就会显示了. 那如何让图片变为透明呢?这就要对图片的像素 ...

  2. linux下与windows下的换行符

    [原文有些许错误,已作了修改] 回车符号和换行符号产生背景 关于“回车”(carriage return)和“换行”(line feed)这两个概念的来历和区别.在计算机还没有出现之前,有一种叫做电传 ...

  3. 解决不同操作系统下git换行符一致性问题

    一.不同操系统下的换行符CR回车 LF换行Windows/Dos CRLF \r\nLinux/Unix LF \nMacOS CR \r二.解决方法 打卡git bash,设置core.autocr ...

  4. ie7 下 float换行问题与vertical-align:middle; 失效问题

    声明:web小白的笔记,欢迎大神指点!联系QQ:1522025433. ie7 下 float换行问题 请直接看代码中和代码中的注释: <!doctype html> <html&g ...

  5. cocos2dx 富文本框,支持换行,支持神情(支持汉字截断无乱码)

    cocos2dx 富文本框,支持换行,支持表情(支持汉字截断无乱码) 小工在做了一个游戏聊天功能,里面用到插入表情的富文本和换行的问题: 先看效果,不是你要的效果,可return:(截图由于:输入的问 ...

  6. 转 DOS(CMD)下批处理换行问题/命令行参数换行 arg ms-dos

    DOS(CMD)下批处理换行问题本人经常写一些DOS批处理文件,由于批处理中命令的参考较多且长,写在一行太不容易分辨,所以总想找个办法把一条命令分行来写,今天终于试成功两种方法.一.在CMD下,可以用 ...

  7. Cocos2d-x之Label

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 在游戏开发中经常会使用标签文字,例如,游戏介绍,玩家积分,菜单选项,文字提示等等.      LabelTTF 直接支持使用 TTF 字库 ...

  8. 修复PHP在64位下序列化(serialize)的字符串在32位机器下反序列

    32机器下PHP 整型数值的范围最大不超过2147483647,而有些超出范围的数值在64序列化好的数据标识为整型,在反序列时就可能会出错. 尝试使用以下的办法可以修复此问题 function int ...

  9. zk label控件内容换行

    Label控件本身无法换行,不过div却可以,只要设置了div的宽度,那么就想如果在Label控件外套个div会怎样,结果可喜可乐: <div width="80px"> ...

随机推荐

  1. Swift5 语言指南(五) 基本运算符

    一个运营商是一个特殊的符号,或者你使用来检查,更改或合并值的短语.例如,加法运算符(+)添加两个数字,如,和逻辑AND运算符()组合两个布尔值,如.let i = 1 + 2&&if  ...

  2. spring-boot(hello world)

    重拾程序,想不到从java开始,最近两周开搞web,从基本框架开始,仅做个人学习记录,遗漏之处望请海涵. 1.基本准备 开发环境win7: IDE  myeclipse Version: 2017 C ...

  3. Telerik for AJAX RadGrid控件

    作为一名.net小白,今天分享一下telerik知识的学习.熟悉ASP.NET Web Form的都知道Grid View或者是List View等表格控件,所以今天和大家分享一下telerik Ra ...

  4. python3模块: os

    简介 os模块主要用于提供系统高级别的操作. 常用方法 os.access(path, mode) # 检验权限模式 os.chdir(path) # 改变当前工作目录 os.chflags(path ...

  5. Tomcat简介

    Tomcat简单的说就是一个运行JAVA的网络服务器,底层是Socket的一个程序,它也是JSP和Serlvet的一个容器. 如果你学过html,css,你会知道你写的页面只能自己访问,别人不能远程访 ...

  6. Ubuntu18.04 安装 VMwareTools

    VMwareTools作用: 1.增强虚拟显卡和硬盘性能.以及同步虚拟机与主机时钟的驱动程序. 2.可以从物理主机直接往虚拟机里面拖文件. 3.鼠标进入虚拟机后可以直接出来,无需按CTRL+ALT才可 ...

  7. Android_自适应布局

    1.屏幕相关概念1.1分辨率是指屏幕上有横竖各有多少个像素1.2屏幕尺寸指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸android将屏幕大小分为四个级别(smal ...

  8. Spring boot CommandLineRunner接口使用例子

    前言 Spring boot的CommandLineRunner接口主要用于实现在应用初始化后,去执行一段代码块逻辑,这段初始化代码在整个应用生命周期内只会执行一次. 如何使用CommandLineR ...

  9. struts2 拦截器弊端

    struts2 怎样在action内获得fielderror

  10. Jenkins之使用Pyinstaller构建Python应用程序

    目录 1. 极简概述 2. Jenkins配置 2.1 安装JDK 2.2 安装Jenkins 3. 安装Docker 4. 使用PyInstaller构建Python应用程序 4.1 Fork 一个 ...