Cocos2d-x 3.x 在wp8中调用系统字体的解决方案
问题和解决方法:
在使用cocos2d-x设计游戏的时候,字体是个很重要的部分。如果游戏中对字体没有太多的要求,就可以使用平台系统自带的字体,可以节省游戏的尺寸,以及减小游戏运行时所占用的内存。当加载系统字体的时候,wp8平台下就出现了问题。
wp8平台下的系统自带的中文字体有一个叫等线字体的字体库,DengXian.ttf。我们想在代码中使用这个系统字体,比如创建一个标签:
auto label=Label::create("这是简体中文","DengXian",);
label->setPosition(,);
label->setColor(Color3B(,,));
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;
} ......
}
代码的其余部分被去掉了。这里就是字体文件的加载,首先调用了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") == -)
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",);
此时运行项目,就可以看到中文显示了。但是这种方法不是跨平台的,仅局限在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 = ; 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 >> ) & 0x1f));
dest.push_back(0x80 | (w & 0x3f));
}
else if (w <= 0xffff)
{
dest.push_back(0xe0 | ((w >> ) & 0x0f));
dest.push_back(0x80 | ((w >> ) & 0x3f));
dest.push_back(0x80 | (w & 0x3f));
}
else if (sizeof(wchar_t) > && w <= 0x10ffff)
{
dest.push_back(0xf0 | ((w >> ) & 0x07));
dest.push_back(0x80 | ((w >> ) & 0x3f));
dest.push_back(0x80 | ((w >> ) & 0x3f));
dest.push_back(0x80 | (w & 0x3f));
}
else
dest.push_back('?');
}
return dest;
} #endif
此时,在需要转换的文件下引用次头文件,就可以使用了。
auto label=Label::create(WStrToUTF8(L"这是简体中文"),"DengXian",);
以上就是Cocos2d-x 3.x 在wp8中调用系统字体的解决方案。
Cocos2d-x 3.x 在wp8中调用系统字体的解决方案的更多相关文章
- iOS程序中调用系统自带应用(短信,邮件,浏览器,地图,appstore,拨打电话,iTunes,iBooks )
在网上找到了下在记录下来以后方便用 在程序中调用系统自带的应用,比如我进入程序的时候,希望直接调用safar来打开一个网页,下面是一个简单的使用:
- Java乔晓松-android中调用系统拍照功能并显示拍照的图片
android中调用系统拍照功能并显示拍照的图片 如果你是拍照完,利用onActivityResult获取data数据,把data数据转换成Bitmap数据,这样获取到的图片,是拍照的照片的缩略图 代 ...
- Android中调用系统所装的软件打开文件(转)
Android中调用系统所装的软件打开文件(转) 在应用中如何调用系统所装的软件打开一个文件,这是我们经常碰到的问题,下面是我所用到的一种方法,和大家一起分享一下! 这个是打开文件的一个方法: /** ...
- WPF中取得系统字体列表
原文:WPF中取得系统字体列表 在GDI+中,我们可以通过如下方式取得系统所有字体: foreach(FontFamily f in FontFamily.Families){ // 处理代码} ...
- C#在winform中调用系统控制台输出
在Winform程序中有时候调试会通过Console.Write()方式输出一些信息,这些信息是在Visual Studio的输出窗口显示. 所以就会想,能不能调用系统的Cmd窗口输出呢,经过一番查阅 ...
- IOS中调用系统的电话、短信、邮件、浏览功能
iOS开发系列--通讯录.蓝牙.内购.GameCenter.iCloud.Passbook系统服务开发汇总 2015-01-13 09:16 by KenshinCui, 26990 阅读, 35 评 ...
- iphone开发中调用系统打电话功能
iphone开发中调用打电话功能,一般有2种: 1.系统的打电话代码,不返回当前程序: Java代码 [[UIApplication sharedApplication] openURL:[NSURL ...
- android中调用系统的发送短信、发送邮件、打电话功能
1 调用发送短信功能: Uri smsToUri = Uri.parse("smsto:"); Intent sendIntent = new Intent(Intent.ACT ...
- IOS中调用系统拨打电话发送短信
一.调用打电话界面 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat ...
随机推荐
- centos7 防火墙一些相关设置 开机添加静态路由 特殊的方法
参考文献: https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/7/html/security_guide/s ...
- 逻辑斯蒂回归(Logistic Regression)
逻辑回归名字比较古怪,看上去是回归,却是一个简单的二分类模型. 逻辑回归的模型是如下形式: 其中x是features,θ是feature的权重,σ是sigmoid函数.将θ0视为θ0*x0(x0取值为 ...
- 小项目,吃货联盟,java初级小项目,源代码
1:项目的实现效果.功能如图所示. 2:项目的源代码如下: import java.util.Scanner; /** * 吃货联盟订餐管理系统 * */ public class OrderingM ...
- Dependency Injection in ASP.NET Web API 2 Using Unity
What is Dependency Injection? A dependency is any object that another object requires. For example, ...
- mysql 不能插入中文和显示中文
一)不能显示中文解决办法: 参考:http://bbs3.chinaunix.net/thread-880131-1-1.html 1:windows平台,因为windows操作系统默认的是用了gb2 ...
- 【求助】win 2008 R2 远程桌面多用户,破解最大连接数2的限制
[求助]win 2008 R2 远程桌面多用户,破解最大连接数2的限制. 1. 本地组策略设置的是“允许的RD最大连接数 5”. 2. 远程桌面仍然只能有两个连接在线. 3. 后来发现是下面这个设置限 ...
- JAVA面试相关
2017 最新java面试题(技术面试) http://www.importnew.com/17232.html importNew-JAVA面试上篇 importNew-JAVA面试下篇 https ...
- uva-10054-欧拉回路
题意:一个项链上面的每一个珠子有俩种颜色,前面一个珠子后面的颜色和后面珠子的前面颜色一样,有一天它断了, 一个人去搜集,问,搜集到的珠子能不能再次串成项链 原以为是链表,原来链表这组数据过不了. 71 ...
- windows安装python运行环境使用pycharm
pycharm下载地址: https://www.jetbrains.com/zh/pycharm/download/download-thanks.html 安装教程: https://blog.c ...
- oracle使用随笔
一,centos 7安装桌面环境 首先使用命令yum grouplist查看可以使用的group ,第一步,命令安装Gnome Desktop,第二步,yum groupinstall "X ...