cocos2dx中RichText富文本的换行问题
2015-10-25 09:13
881 查看
wod开飞行太难谁特么的有空刷声望啊!还不如写博客!
关于富文本什么的,之前在南京那家公司做一个国外外包iOS应用项目的时候曾经做过一个,当时的感觉是——很难。因为需要处理wordwrap,而又没找到适合ios系统控件的文本宽度计算算法,当时的处理是直接使用Label控件一个个去匹配适应,然后超过4行的文本,计算时间就想当长了,所以当时找了一堆都是使用html+js做富文本编辑器的。当然这算题外话,因为cocos2dx的RichText没有换行算法选项,也就没有这个问题,但那逗逼的换行算法也是坑了我…(cocos2dx 3.3)
所谓富文本,大体就是图片等其他东西和文本混排,很多情况下图片等看作文本单元排布。以一般思路来说,也就是做个展示容器,容器接收文本和图片等的片段,然后容器内封装了对排布的处理方法。而cocos2dx的RichText控件也就是这么做的。
cocos2dx的富文本换行算法…相当的…有想法?…这是相当令人无语的…写法…上代码:
简单来说,就是…如果超长了,用unicode字符数乘以超长的…长度比,然后字符串直接截取对应的字符个数来换行…那么,面对例如
还好他们没去做word wrap处理…还好产品没给我说需要加word wrap换行…
于是我把
主要代码:
工程源码(使用cocos2dx3.3):
github
关于富文本什么的,之前在南京那家公司做一个国外外包iOS应用项目的时候曾经做过一个,当时的感觉是——很难。因为需要处理wordwrap,而又没找到适合ios系统控件的文本宽度计算算法,当时的处理是直接使用Label控件一个个去匹配适应,然后超过4行的文本,计算时间就想当长了,所以当时找了一堆都是使用html+js做富文本编辑器的。当然这算题外话,因为cocos2dx的RichText没有换行算法选项,也就没有这个问题,但那逗逼的换行算法也是坑了我…(cocos2dx 3.3)
所谓富文本,大体就是图片等其他东西和文本混排,很多情况下图片等看作文本单元排布。以一般思路来说,也就是做个展示容器,容器接收文本和图片等的片段,然后容器内封装了对排布的处理方法。而cocos2dx的RichText控件也就是这么做的。
cocos2dx的富文本换行算法…相当的…有想法?…这是相当令人无语的…写法…上代码:
UIRichText.cpp: size_t stringLength = StringUtils::getCharacterCountInUTF8String(text); int leftLength = stringLength * (1.0f - overstepPercent); std::string leftWords = Helper::getSubStringOfUTF8String(curText,0,leftLength); std::string cutWords = Helper::getSubStringOfUTF8String(curText, leftLength, stringLength - leftLength);
简单来说,就是…如果超长了,用unicode字符数乘以超长的…长度比,然后字符串直接截取对应的字符个数来换行…那么,面对例如
测试文本测试文本测试文本123443211234或是
123443211234测试文本测试文本测试文本这种要么头重脚轻要么臀部过大的字符串,放进一个element中塞给UIRichText之后,见到的不是吞文本就是断行了…
还好他们没去做word wrap处理…还好产品没给我说需要加word wrap换行…
于是我把
handleTextRenderer这块儿稍微改了下,在原来个数计算的基础上加了两块操作——超了切,短了补,现在运行基本正常——暂时没发现不正常的情况。
主要代码:
Label* leftRenderer = nullptr; if (leftWords.length() > 0) { if (fileExist) { leftRenderer = Label::createWithTTF(leftWords, fontName, fontSize); } else { leftRenderer = Label::createWithSystemFont(leftWords, fontName, fontSize); } } if (!leftRenderer) { return; } // 处理需截文本字宽度不均,前半部分超出的情况 例如 "测试文本测试文本12341234",取宽度10/16 前半部分宽度10则超出很多 while (true) { if (leftWords.length() > 0) { leftRenderer->setString(leftWords); float leftRendererWidth = leftRenderer->getContentSize().width; tmpLeftSpaceWidth = _leftSpaceWidth; tmpLeftSpaceWidth -= leftRendererWidth; if (tmpLeftSpaceWidth < 0.0f) { int leftWordsLen = (int)leftWords.length(); if (leftWordsLen <= 0) { break; } else { //cut char one by one to get the fit length while (true) { leftLength -= 1; leftWords = Helper::getSubStringOfUTF8String(curText, 0, leftLength); cutWords = Helper::getSubStringOfUTF8String(curText, leftLength, stringLength - leftLength); if (leftWords.length() == 0) { break; } if (leftWords.length() < leftWordsLen) { break; } } } } else { //if _leftSpaceWidth > 0 break break; } } else { //if leftWords is empty, break break; } } // 处理需截文本字宽度不均,后半部分超出的情况 例如 "12341234测试文本测试文本",取宽度10/16 前半部分宽度10则缺少很多 std::string lastLeftWords = leftWords; std::string lastCutWords = cutWords; float lastTmpLeftSpaceWidth = tmpLeftSpaceWidth; while (true) { if (cutWords.length() > 0) { int leftWordsLen = (int)leftWords.length(); while (true) { leftLength += 1; leftWords = Helper::getSubStringOfUTF8String(curText, 0, leftLength); cutWords = Helper::getSubStringOfUTF8String(curText, leftLength, stringLength - leftLength); if (cutWords.length() == 0) { break; } if (leftWords.length() > leftWordsLen) { break; } } leftRenderer->setString(leftWords); float leftRendererWidth = leftRenderer->getContentSize().width; tmpLeftSpaceWidth = _leftSpaceWidth; tmpLeftSpaceWidth -= leftRendererWidth; if (tmpLeftSpaceWidth < 0.0f) { leftWords = lastLeftWords; cutWords = lastCutWords; tmpLeftSpaceWidth = lastTmpLeftSpaceWidth; leftRenderer->setString(leftWords); break; } else { lastLeftWords = leftWords; lastCutWords = cutWords; lastTmpLeftSpaceWidth = tmpLeftSpaceWidth; } } else { //if cutWords is empty, break leftWords = lastLeftWords; cutWords = lastCutWords; tmpLeftSpaceWidth = lastTmpLeftSpaceWidth; leftRenderer->setString(leftWords); break; } } _leftSpaceWidth = tmpLeftSpaceWidth; leftRenderer->setColor(color); leftRenderer->setOpacity(opacity); pushToContainer(leftRenderer); _leftSpaceWidth = tmpLeftSpaceWidth; addNewLine(); handleTextRenderer(cutWords.c_str(), fontName, fontSize, color, opacity);
工程源码(使用cocos2dx3.3):
github
相关文章推荐
- 界面的滑动01(cocos3.8)
- 初学cocos2dx-lua之Mac配置sumblime Text3 编译lua
- cocos2d-lua集成Mob-SMSSDK-for-android
- [Cocos2d塔防游戏开发]Cocos2dx-3.X完成塔防游戏《王国保卫战》--防御塔(三)之初级炮塔
- Cocos2d-x 3.8.1学习之路:(2)从windows到android
- Cocos2D-x内存管理的原则
- Cocos2d-JS使用log方法控制台无法打印出结果
- Cocos2d-JS屏幕适配
- Cocos2d-x下Lua调用自定义C++类和函数的最佳实践
- android台 cocos2d-x 翻阅相册数据
- cocos2d-x项目目录梳理
- cocos-2d HelloWorld项目运行报错解决
- Protobuf2.6集成到cocos2dx(Android和ios平台)
- cocos2d-x-3.5 android 编译
- Cocos2d入门--3--小球运动
- Cocos2d-X采用CCScrollView创建滚动视图
- cocos2d平台游戏移到windows平台运行
- cocos2dx之EditBox
- cocos2dx-------------------------------------Speed && Follow
- cocos2d-x引擎目录结构分析