From fc2ab110cca3e366b38125196318609ac328b315 Mon Sep 17 00:00:00 2001 From: andyque Date: Thu, 17 Jul 2014 17:58:40 +0800 Subject: [PATCH] fix richText utf8 error --- cocos/ui/UIRichText.cpp | 57 +++++++++++++------ .../UIRichTextTest/UIRichTextTest.cpp | 2 +- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/cocos/ui/UIRichText.cpp b/cocos/ui/UIRichText.cpp index 6bff82c007..2a2f2bd7a4 100644 --- a/cocos/ui/UIRichText.cpp +++ b/cocos/ui/UIRichText.cpp @@ -26,26 +26,47 @@ #include "platform/CCFileUtils.h" #include "2d/CCLabel.h" #include "2d/CCSprite.h" +#include "base/ccUTF8.h" NS_CC_BEGIN namespace ui { -static int _calcCharCount(const char * pszText) +static std::string utf8_substr(const std::string& str, unsigned long start, unsigned long leng) { - int n = 0; - char ch = 0; - while ((ch = *pszText)) + if (leng==0) { - CC_BREAK_IF(! ch); - - if (0x80 != (0xC0 & ch)) - { - ++n; - } - ++pszText; + return ""; } - return n; + unsigned long c, i, ix, q, min=std::string::npos, max=std::string::npos; + for (q=0, i=0, ix=str.length(); i < ix; i++, q++) + { + if (q==start) + { + min = i; + } + if (q <= start+leng || leng==std::string::npos) + { + max = i; + } + + c = (unsigned char) str[i]; + + if (c<=127) i+=0; + else if ((c & 0xE0) == 0xC0) i+=1; + else if ((c & 0xF0) == 0xE0) i+=2; + else if ((c & 0xF8) == 0xF0) i+=3; + else return "";//invalid utf8 + } + if (q <= start+leng || leng == std::string::npos) + { + max = i; + } + if (min==std::string::npos || max==std::string::npos) + { + return ""; + } + return str.substr(min,max); } bool RichElement::init(int tag, const Color3B &color, GLubyte opacity) @@ -295,20 +316,20 @@ void RichText::handleTextRenderer(const std::string& text, const std::string& fo { float overstepPercent = (-_leftSpaceWidth) / textRendererWidth; std::string curText = text; - size_t stringLength = _calcCharCount(text.c_str()); + size_t stringLength = StringUtils::getCharacterCountInUTF8String(text); int leftLength = stringLength * (1.0f - overstepPercent); - std::string leftWords = curText.substr(0, leftLength); - std::string cutWords = curText.substr(leftLength, curText.length()-1); + std::string leftWords = utf8_substr(curText,0,leftLength); + std::string cutWords = utf8_substr(curText, leftLength, curText.length()-1); if (leftLength > 0) { Label* leftRenderer = nullptr; if (fileExist) { - leftRenderer = Label::createWithTTF(leftWords.substr(0, leftLength).c_str(), fontName, fontSize); - } + leftRenderer = Label::createWithTTF(utf8_substr(leftWords, 0, leftLength), fontName, fontSize); + } else { - leftRenderer = Label::createWithSystemFont(leftWords.substr(0, leftLength).c_str(), fontName, fontSize); + leftRenderer = Label::createWithSystemFont(utf8_substr(leftWords, 0, leftLength), fontName, fontSize); } if (leftRenderer) { diff --git a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIRichTextTest/UIRichTextTest.cpp b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIRichTextTest/UIRichTextTest.cpp index d69288aa6b..20c44bda18 100644 --- a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIRichTextTest/UIRichTextTest.cpp +++ b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIRichTextTest/UIRichTextTest.cpp @@ -42,7 +42,7 @@ bool UIRichTextTest::init() _richText->ignoreContentAdaptWithSize(false); _richText->setContentSize(Size(100, 100)); - RichElementText* re1 = RichElementText::create(1, Color3B::WHITE, 255, "This color is white. ", "Helvetica", 10); + RichElementText* re1 = RichElementText::create(1, Color3B::WHITE, 255, "中国中国中国中国中国中国中国中国中国中国中国中国中国中国中国", "Marker Felt", 10); RichElementText* re2 = RichElementText::create(2, Color3B::YELLOW, 255, "And this is yellow. ", "Helvetica", 10); RichElementText* re3 = RichElementText::create(3, Color3B::BLUE, 255, "This one is blue. ", "Helvetica", 10); RichElementText* re4 = RichElementText::create(4, Color3B::GREEN, 255, "And green. ", "Helvetica", 10);