【转载】cocos2d-x 2.1下使用CCLabelTTF显示汉字的问题

http://blog.itpub.net/14466241/viewspace-752027/

作者:朱先忠


本文结合自己的学习结果,并主要参考如下内容形成:

http://blog.csdn.net/tkokof1/article/details/7426706(移动开发之浅析cocos2d-x的中文支持问题 
http://bbs.csdn.net/topics/390285784(cocos2d-x 2.0 iconv.h问题)


在我前面的一篇文章中,曾经记下了一种使用CCLabelBMFont,结合BMFont字体编辑器软件在Android及Win32平台上显示汉字的技术。

但是,感觉上面这种方案还是明显存在不足。
首先,需要把使用到的汉字全部整理到一个UNICIDE编码的文本文件中(在开发过程中,这个文件的内容可能需要不断地修改)。这一步倒也不算怎么麻烦。

然后,使用BMFont字体编辑器软件导入上面UNICODE 编码的文本文件,并生成字体文件.fnt。

再接下来,把上面的文字根据需要分块整理到UNICODE编码的XML文件中。

最后,在程序中调用并解析上面的XML文件,并结合.fnt文件,显示中文。



接下来要介绍的是使用CCLabelTTF显示汉字的问题。这种方案速度更快,在Android及Win32平台上显示汉字自然也没有问题。相关技术主要来自于:

http://blog.csdn.net/tkokof1/article/details/7426706

我只是稍微整理了一下而已。

方案一:使用cocos2d-x自带的iconv库(在WIN32下),还要下载一个。


需要:
1,在你的工程中添加对头文件cocos2dx\platform\third_party\win32\iconv\iconv.h的引用。
2,相应的库引用:cocos2dx\platform\third_party\win32\libraries\libiconv.lib。

代码如下:(先写两个工具函数)
bool IConvConvert(const char *from_charset, const char *to_charset, const char *inbuf, int inlen, char *outbuf, int outlen) 
{
    iconv_t cd = iconv_open(to_charset, from_charset);
    if (cd == 0) return false;
    const char **pin = &inbuf;
    char **pout = &outbuf;
    memset(outbuf,0,outlen);
    size_t ret = iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
    iconv_close(cd);
    return ret == (size_t)(-1) ? false : true;
}

std::string IConvConvert_GBKToUTF8(const std::string& str)
{
    const char* textIn = str.c_str();
    char textOut[256];
    bool ret = IConvConvert("gb2312", "utf-8", textIn, strlen(textIn),textOut, 256);
    return ret ? string(textOut) : string();
}

使用方法简单:

        std::string text = IConvConvert_GBKToUTF8("你好世界");
       CCLabelTTF* pLblChinese = CCLabelTTF::create(text.c_str(), "Arial", 24);

但是,遗憾的是, cocos2d-x 仅自带了适合于WIN32的 iconv 库,对于其中平台的没有带。
不过,不要紧,上面提到的iconv库可以轻松搞到。具体细节在http://bbs.csdn.net/topics/390285784上有介绍。我把它摘要在此:

 问题已解决,现给出解决方案:
下一个iconv库放到跟Classes同级目录,然后在iconv库根目录下编写Android.mk文件,内容:
LOCAL_PATH:= $(call my-dir)
#libiconv.so
include $(CLEAR_VARS)
LOCAL_MODULE := libiconv
LOCAL_CFLAGS := \
  -Wno-multichar \
  -DAndroid \
  -DLIBDIR="c" \
  -DBUILDING_LIBICONV \
  -DIN_LIBRARY

LOCAL_SRC_FILES := \
  libcharset/lib/localcharset.c \
  lib/iconv.c \
  lib/relocatable.c

LOCAL_C_INCLUDES += \
  $(LOCAL_PATH)/include \
  $(LOCAL_PATH)/libcharset \
  $(LOCAL_PATH)/lib \
  $(LOCAL_PATH)/libcharset/include \
  $(LOCAL_PATH)/srclib
include $(BUILD_STATIC_LIBRARY)

在Classes目录下的Android.mk文件里加入:
LOCAL_C_INCLUDES += \
  $(LOCAL_PATH)/../iconv/include \
  $(LOCAL_PATH)/../libiconv/libcharset \
  $(LOCAL_PATH)/../libiconv/lib \
  $(LOCAL_PATH)/../libiconv/libcharset/include \
  $(LOCAL_PATH)/../libiconv/srclib \
  $(LOCAL_PATH)/../iconv

LOCAL_WHOLE_STATIC_LIBRARIES += libiconv

$(call import-module,iconv)

这样就可以了~~

方案二:结合上面原理,自己开发(极力推荐)


//! convert from wstring to UTF8 using self-coding-converting

inline void WStrToUTF8(std::string& dest, const wstring& src){

dest.clear();

for (size_t i = 0; i < src.size(); i++){

wchar_t w = src[i];

if (w <= 0x7f)

dest.push_back((char)w);

else if (w <= 0x7ff){

dest.push_back(0xc0 | ((w >> 6)& 0x1f));

dest.push_back(0x80| (w & 0x3f));

}

else if (w <= 0xffff){

dest.push_back(0xe0 | ((w >> 12)& 0x0f));

dest.push_back(0x80| ((w >> 6) & 0x3f));

dest.push_back(0x80| (w & 0x3f));

}

else if (sizeof(wchar_t) > 2 && w <= 0x10ffff){

dest.push_back(0xf0 | ((w >> 18)& 0x07)); // wchar_t 4-bytes situation

dest.push_back(0x80| ((w >> 12) & 0x3f));

dest.push_back(0x80| ((w >> 6) & 0x3f));

dest.push_back(0x80| (w & 0x3f));

}

else

dest.push_back('?');

}

}

//! simple warpper

inline std::string WStrToUTF8(const std::wstring& str){

std::string result;

WStrToUTF8(result, str);

return result;

}

// add a label shows "Hello World"

// create and initialize a label

std::string text = WStrToUTF8(L"你好世界");

CCLabelTTF* pLabel = CCLabelTTF::labelWithString(text.c_str(), "Arial", 24);


总结

上面几种方案我都试验过了,OK。

剩下还有一个问题就是,使用CCLabelTTF显示中文时,如何使用自定义字体的问题了。以后再讨论................

--the end


因为需要修改一个RichText,所以再次找到了显示中文的问题。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值