码迷,mamicode.com
首页 > 其他好文 > 详细

Cocos2d-x 3.x 在wp8中调用系统字体的解决方案

时间:2015-01-09 20:53:29      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:

问题和解决方法:

  在使用cocos2d-x设计游戏的时候,字体是个很重要的部分。如果游戏中对字体没有太多的要求,就可以使用平台系统自带的字体,可以节省游戏的尺寸,以及减小游戏运行时所占用的内存。当加载系统字体的时候,wp8平台下就出现了问题。

wp8平台下的系统自带的中文字体有一个叫等线字体的字体库,DengXian.ttf。我们想在代码中使用这个系统字体,比如创建一个标签:

auto label=Label::create("这是简体中文","DengXian",30);
label->setPosition(300,400);
label->setColor(Color3B(255,0,0));
addChild(label);

这样界面中没有任何显示,原因可以到cocos2d-x的源码CCFreeTypeFont.cpp中查看,Cocos2d-x自3.0版本以来的TrueType字体解析都是通过FreeType库,就是封装在了CCFreeTypeFont中了。首先会调用CCFreeTypeFont中的initWithString函数,

技术分享
unsigned char* CCFreeTypeFont::initWithString(const char * text, const FontDefinition& textDefinition, Device::TextAlign align, int &width, int &height, ssize_t& dataLength)
{
......
    
     if(!pBuffer)
    {
        // attempt to load font from Resources fonts folder
        pBuffer = loadFont(textDefinition._fontName.c_str(), &size);
        if(!pBuffer)
        {
         // attempt to load font from System fonts folder
            pBuffer = loadSystemFont(textDefinition._fontName.c_str(), &size);
        }
         if(!pBuffer)
        {
            // attempt to load default font from Resources fonts folder
            pBuffer = loadFont("Arial", &size);
        }
        if(!pBuffer)
        {
            // attempt to load default font from System fonts folder
            pBuffer = loadSystemFont("Arial", &size);
        }

        if(!pBuffer) // font not found!
        {
            return false;
        }

......
}
View Code

代码的其余部分被去掉了。这里就是字体文件的加载,首先调用了loadFont函数,可以参看源码,它会去资源的fonts的文件夹下查找是否含有这种字体的.ttf文件。没有的话就调用loadSystemFont函数去调用系统字体。问题就出在这里,loadSystemFont的定义中:

unsigned char* CCFreeTypeFont::loadSystemFont(const char *pFontName, ssize_t *size) 
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
    return nullptr;
#else
......
}

如果是wp8平台,直接返回了一个空值。wp的字体文件就放在c:\Windows\Fonts的路径下面,所以这里我们要自己改一下代码,去wp系统中查找这个字体,添加的代码如下:

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
    std::string fontName(pFontName);
    if (fontName.find(".ttf") == -1)
            fontName += ".ttf";
    CCLog("FontName:%s", fontName.c_str());
    std::string fontPath = "C:\\Windows\\Fonts\\" + fontName;
    return CCFileUtils::sharedFileUtils()->getFileData(fontPath.c_str(), "rb", size);
#else

此时你会发现,中文字体还是没有显示,但是现在已经可以显示英文之类的了,说明已经找到了这个字体文件。现在的问题其实是字符编码不符合cocos2d-x要求的UTF-8的编码方式,只要将中文字符转码就可以了。

通过查找资料,找到两个解决方案:

1、使用cocos2d-x自己的转换函数CCUnicodeToUtf8 ,定义在CCWinRTUtils.h。这个很容易,直接在文件上面加上#include"CCWinRTUtils.h"即可使用,将上面的Label创建更改如下:

auto label=Label::create(CCUnicodeToUtf8(L"这是简体中文"),"DengXian",30);

此时运行项目,就可以看到中文显示了。但是这种方法不是跨平台的,仅局限在WP上使用。要想跨平台的话,可以使用c++代码自己实现编码的转换,如下:

2、在Classes文件下创建一个头文件,WstrToUTF8.h。里面只定义了一个函数:

技术分享
#ifndef WStrToUTF8_H_
#define WStrToUTF8_H_
#include<iostream>

std::string WStrToUTF8(const std::wstring& src)
{
    std::string dest;
    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));
            dest.push_back(0x80 | ((w >> 12) & 0x3f));
            dest.push_back(0x80 | ((w >> 6) & 0x3f));
            dest.push_back(0x80 | (w & 0x3f));
        }
        else
            dest.push_back(?);
    }
       return dest;
}

#endif
View Code

此时,在需要转换的文件下引用次头文件,就可以使用了。

auto label=Label::create(WStrToUTF8(L"这是简体中文"),"DengXian",30);

以上就是Cocos2d-x 3.x 在wp8中调用系统字体的解决方案。

 

Cocos2d-x 3.x 在wp8中调用系统字体的解决方案

标签:

原文地址:http://www.cnblogs.com/Monte/p/4214039.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!