注: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. 在Shell脚本中获取指定进程的PID

    注意这条命令用反引号(Tab上面的那个键)括起来,作用类似于${ } processId = ` ps -ef | grep fms.jar | grep -v grep | awk '{print ...

  2. 物体检测,Error: maximum box coordinate value is too large

    使用ssd目标检测,出现error:maximum box coordinate value is larger than 1.100000: ] [1.325] 主要原因在于,用labelImg 标 ...

  3. php 对数组按照字符串长度排序

    $file = file('zong.txt'); usort($file, 'sortByLen'); $handle = fopen('zong2.txt', 'a'); foreach ($fi ...

  4. 移动端自动化测试-AppiumApi接口详解

    Appium 初始化配置信息(Desired Capabilities),Desired Capabilities实际上就是一个字典,它主要用于向Appium Server提供初始化配置参数,如:想要 ...

  5. koa2搭建服务器

    首先初始化项目 npm init -y 安装koa2 npm install koa --save 项目根目录 新建 index.js //这是最基本的服务 const Koa = require(' ...

  6. SQL 必知必会·笔记<10>联结表

    可伸缩(scale) 能够适应不断增加的工作量而不失败.设计良好的数据库或应用程序 称为可伸缩性好(scale well). 联结(JOIN) 联结(JOIN)是一种机制,用来在一条SELECT 语句 ...

  7. SpringBoot+Mybatis+Pagehelper分页

    1.pom.xml <!-- mybatis分页插件 --> <dependency> <groupId>com.github.pagehelper</gro ...

  8. Vue.js的复用组件开发流程

    本文由蔡述雄发表 接下来我们会详细分析下如何完成由多个组件组成一个复用组件的开发流程. 下面先看看我们的需求 列表组件quiList.vue 本节我们主要要完成这样一个列表功能,每一行的列表是一个组件 ...

  9. 【PyTorch深度学习60分钟快速入门 】Part5:数据并行化

      在本节中,我们将学习如何利用DataParallel使用多个GPU. 在PyTorch中使用多个GPU非常容易,你可以使用下面代码将模型放在GPU上: model.gpu() 然后,你可以将所有张 ...

  10. 了解Job和JobDeatil ,JobDataMap (三)

    一:定义 Job:实现任务逻辑的接口. JobDeatil:JobDeatil为Job提供了许多设置属性,以及JobDataMap成员变量属性,他用来储存特定的Job实例状态信息,调度器需要使用Job ...